Saturday 28 January 2017

Reclaimed Wood Kitchen Tidy



I live in a small flat, and in the kitchen there's not a lot of storage. As a result, the bins (general waste & recycling) have always just lived in the corner of the room. It's not a major issue, but bins aren't exactly nice to look at, made worse given that it's an open plan kitchen shared with the lounge area.

I found a couple of solid wood bedframes that were otherwise destined for the landfill, and took them apart, and used the timber to build this kitchen tidy unit. There's not really any new or ground-breaking techniques to document, so the rest of this is predominantly a photo post.

I'm pleased with the result, and I plan to do more reclaimed wood projects in the future - as all the timber was reclaimed, the only material cost ended up being the wood dye and varnish, which makes woodworking much more affordable.


A photo posted by Anthony (@darkmidnight_diy) on


Wednesday 4 January 2017

Archer and "The Last Leg"-inspired 'Phrasing' button


The inspiration

 

In some ways my workplace is very much like this - anything that could be misconstrued as an innuendo, even remotely, will inevitably have people calling out "hey, phrasing!", "That's what she said..." etc, etc.

Combining that with this "Bullshit button" from The Last Leg:


.. and I had an idea.


To cap it all off, at work we were having a clear out of some cupboards, and I found this:


It plays a dog-barking noise when pressed. I'm told it was used for some kind of team building thing long before I joined the company. Weird.
By this point it must be pretty obvious where this project is headed...

The teardown
First things first, see how much space in the button there is to work with, and what parts can be reused.

The single PCB contains a controller under a blob of epoxy, as was expected, so I'll need to replace that. However, the same PCB contains the actual button, so it'll need to stay in place. To allow that I just cut the traces connecting the button to the PCB, and scraped off some of the solder mask in order to provide connection points for my replacement controller.


The electronics

As this was intended to be a quick and easy project, I had to make do with what I could find in my electronics junk box. I couldn't use the same MP3 trick that I used in the Swear Jar project, as what I had available was too large for the buttons' case.

Whichever controller I used needed to have enough memory to store the audio data, which ruled out a lot of micros, so I ended up recycling an old arduino micro (ATMega328)

To make room for the arduino, the battery compartment had to be removed - I would instead use coin cell batteries. This would still work, but come at the cost of a reduced battery life.

The audio

To capture the original audio, I used the same technique I covered here to create a WAV file. After using Audacity to crop and edit down the relevant clip (Archer saying "Uh, Phrasing"), I used the EncodeAudio application from HiLoTech to turn it into a header file (sounddata.h in the code below)


The software
The code used on the arduino was based around the PCMAudio example, but I needed to modify it to incorporate some power saving - to account for the reduced capacity of the coin cell batteries. Code listed below:

#include <stdint.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#define SAMPLE_RATE 8000

#include "sounddata.h"

int ledPin = 13;
int speakerPin = 11;
volatile uint16_t sample;
byte lastSample;


void stopPlayback() {
    TIMSK1 &= ~_BV(OCIE1A);
    TCCR1B &= ~_BV(CS10);
    TCCR2B &= ~_BV(CS10);
    digitalWrite(speakerPin, LOW);
}

ISR(TIMER1_COMPA_vect) {
    if (sample >= sounddata_length) {
        if (sample == sounddata_length + lastSample) {
            stopPlayback();
        }
        else {
            if(speakerPin==11){
                OCR2A = sounddata_length + lastSample - sample;
            } else {
                OCR2B = sounddata_length + lastSample - sample;
            }
        }
    }
    else {
        if(speakerPin==11){
            OCR2A = pgm_read_byte(&sounddata_data[sample]);
        } else {
            OCR2B = pgm_read_byte(&sounddata_data[sample]);
        }
    }
    ++sample;
}

void startPlayback() {
    pinMode(speakerPin, OUTPUT);

    ASSR &= ~(_BV(EXCLK) | _BV(AS2));

    TCCR2A |= _BV(WGM21) | _BV(WGM20);
    TCCR2B &= ~_BV(WGM22);

    if(speakerPin==11){
        TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
        TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
        TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

        OCR2A = pgm_read_byte(&sounddata_data[0]);
    } else {
        TCCR2A = (TCCR2A | _BV(COM2B1)) & ~_BV(COM2B0);
        TCCR2A &= ~(_BV(COM2A1) | _BV(COM2A0));
        TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

        OCR2B = pgm_read_byte(&sounddata_data[0]);
    }

    cli();

    TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
    TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));

    TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);

    OCR1A = F_CPU / SAMPLE_RATE;

    TIMSK1 |= _BV(OCIE1A);

    lastSample = pgm_read_byte(&sounddata_data[sounddata_length-1]);
    sample = 0;
    sei();
}

int wakePin = 2;

void setup(){
    pinMode(wakePin, INPUT);
    pinMode(ledPin, OUTPUT);
    
    
    attachInterrupt(0, wakeUpNow, LOW);
    
    startPlayback();
}

void loop(){}
void wakeUpNow(){
    startPlayback();
    sleepNow();
}

void sleepNow() { 
    set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
 
    sleep_enable();    
    attachInterrupt(0,wakeUpNow, LOW); 
    sleep_mode();            
    sleep_disable();
    detachInterrupt(0);
} 

The finish
Some finishing touches, and it's done!