Thursday, January 24, 2013

Infrared Sonic Screwdriver completed

Finally I've been able to finish this project. I've been spending time on uni work, but session 3 final exams will be coming up soon. After that I'll have more free time! I scratched up the plastic case while pulling apart and reassembling, but it functions exactly as I want. Overall I'm pretty happy with the result.

Design choices and restrictions
My choices of where to fit all the components were limited to either the handle or the cylinder near the top. The handle has more space (even with the batteries), but would be way to awkward to fit everything and required more work with excess bits of plastic and springy bits to cut off. The top cylinder piece contained the original electronics and speaker to flash LEDs and make sonic screwdriver type noises. It would be cool to keep, but there wasn't enough space for that.

After carving out all the excess bits of plastic I had just enough space for a DIP8 chip and a few other components. From my breadboard prototype I could easily use everything except for the giant 40pin microcontroller. The best uC I could find was the PIC12F1840 from Element14. There actually wasn't a lot of chips that met my requirements. Most didn't have enough memory or had crap timer resolution. I think the limiting factor was my choice of package. Seems more pins = more cool stuff and I'm not able to use anything smaller than DIP style chips.

Next, was the problem of power consumption. The uC could be set to an ultra low power mode and I could switch the IR receiver on only when needed, but that adds complexity and possibly components. To keep things simple I added a power switch. I have no idea how long the batteries will last though!

For input I have just 1 button and for output there is the status and infrared LEDs. Since both playback and recording mode need to be accessible from the 1 button I decided that the screwdriver should be used like this:
1. Power switch on = pulse from status LED.
2. click button = pulse status LED & transmit infrared data in EEPROM.
3a. hold button = status LED rapid flash, then status LED steady on. (ready to begin recording)
3b(i). Aim a remote at the sensor and press a button. The signal will be written to EEPROM and the status LED will go out.
3b(ii). Or click the button to clear the memory & cancel recording. Status LED will go out.

I've also changed the way the infrared LED is being powered. I'm controlling both PWM and IR signal timing on the positive side instead of separating between positive and negative sides of the LED. This means I only need 1 pin from the microcontroller and it means I only need 1 transistor to avoid pulling big current directly through the microntroller pin. It's probably the way I should've done it from the start, but it didn't occur to me until later on.
Circuit diagram, but i've left out the power switch.

Playback and recording
To record the signal I'm still using the method counting the time passed each time the IR signal flips between 1 and 0. Since i'm using a 16bit timer I'm writing the data to a 200 byte SignalData array to record a maximum of 100 bit flips. After the signal ends, the data is copied from the array to the EEPROM. It would be simpler to write directly to EEPROM, but found that the write speed was too slow and the signal data would change multiple times before each byte was written.

Playback is simply a matter of iterating through all the bytes recorded in the EEPROM and copying them back to the SignalData array. Once there I can playback the signal. The playback method is similar to before, but slightly more complicated. The IR LED has to switched on/off at intervals matching the recorded signal data, but while the LED is on it has to be modulated at 38kHz. I chose to drive the LED (via NPN transistor) from the PWM output pin (pin RA5). Now I only have to turn PWM on and off with the IR timing data. I had originally thought to switch between RA5 input and output modes. That would turn the signal on in output mode and turn it off in input mode. I think it switches too slow between input and output because the transmitted signal looked wrong on my oscilloscope unless I slowed the signal timer way down. In the end I turned the timer that drove the PWM on and off. The only down side is that sometimes the end of the transmission will result in the IR LED being stuck on. I guess it depends at what point in the PWM cycle the timer is switched off. To fix this problem I still switch RA5 between input and output mode, but only once at the beginning and end.

Not much to say here. Just a bunch of epoxy glue, hot glue, soldering and patience. I guess my soldering could be better, but soldering components directly together without overheating them is very tricky!


MPLABX Project
2013-05-12 edit: There are improvements to made in the program code especially in regards to variable naming and referencing individual bits. Didn't know "PORTxbits.x" reference existed at the time! But I won't be making any changes since the compiled code would give the same functionality as what is being used now.