Sunday, February 21, 2010

Good progress. Prototype done.

I got myself a programmer, some PICs and started to learn. I had to do the compulsory "blinking LED" but after that I continued to see if I could do what I wanted.



Bought a programmer and some PICs
Yep, as I said, I ordered a PIC programmer. I didn't choose Microchip's own for some reason but went for the PIC-MCP-USB made by Olimex. I ordered mine from a Swedish distributor called Lawicel.

Here's what the programmer looks like:

The good thing about it is that it both has a large socket for inserting chips in as well as a ICSP (In Circuit Serial Programming) connector, allowing you to program the PIC while it's still in the application, assuming you have taken the right precautions in the wiring.

Lawicel don't sell separate PICs so I ordered some, along with some other "good to have"-stuff, from a Swedish retailer called electrokit.

Now, with a programmer and some PICs, I was ready to start learning...

The blinking LED
Computer application software programmers do the "Hello world!" example.
Microcontroller programmers do the blinking LED example.
I wasn't going to make any exception.
It took me a while to figure out how to make the correct ICSP connections and do the wiring as well as learning some PIC instructions and finding my way around the datasheet.
Remember, this IS my first time using a PIC and only my second time using a microcontroller at all. On top of that I hadn't programmed any assembler for over 10 years so it took a little while getting back into it.
After I had finally managed to get the LED to blink I decided it was time to try to do what I really wanted.

Checking the schematics
I needed to know exactly how I should do this and even if I had looked at it roughly before, just to get an idea whether it would be possible at all or not, I wanted to double-check.
The schematics for the CPU board and the panel board are on different pages in the schematics for the Poly 61 and naturally extremely messy due to the bad photocopy and low resolution.
So, I drew the important parts on a piece of paper to make sure I knew what was involved in the detection of buttons being pressed.

Here's my little "relevant circuitry" drawing :)


The little box surrounded by dashed lines in the top right of the drawing contains the actual switches I want to bypass. I didn't want to clutter the drawing too much so I didn't connected the datalines D0 and D1 to the CPU, but obviously they are in the original schematic :)

In my previous post I showed an idea for how I was imagining my electronic switces to work. I realized it was not the best solution so, in place of the diodes connected to the PIC I put an NPN transistor to use as a switch paralell with the physical switch. I don't know how much current the OR-gate providing the adress selection signal is sinking so I didn't want to torture it any more than necessary, so in the end I decided to go for N-channel enhancement type MOSFETs instead. By using MOSFETs I won't get any base-emitter current flowing into the LS-chip of the OR-gate and I guess I'll have a slightly lower power consumption overall as well. For the MOSFET transistors I chose the type 2N7000.
I was thinking of using opto-couplers but it requires more space and didn't seem necessary.

I also corrected some mistakes with the rotary encoder after trying it out for a while. I though my encoder was like a gray code encoder, shifting one bit for every "click", but it turns out that every click causes both lines to make a short pulse which overlaps the other one, but in different order depending on if you turn the encoder clock wise or counter clock wise.

Building the prototype
Here is the (so far) final schematic for my modification:


I built the circuit for the encoder on a lab board (bread board) to test it out first. One thing was missing though, the address select line. So, I dug up a 555 I had in my stash of ancient chips and made it generate short low pulses as substitute.
I also placed a 7805 on the board to stabilize my power supply, in case I happened to fiddle with the knobs by mistake. I didn't want to fry anything. I replaced the diodes by the MOSFET transistors with regular LEDs and used low value resistors for current limiting instead of pull-up values so I could see the LED's light up.

Here's what the board looks like switched on:

The red LED to the right is just to remind me that the board has power :)
Otherwise to the right is the 7805 and the ICSP wires (most of them disconnected).
To the left is the PIC12F629 I am using.
The black rotary encoder can be seen in the middle, and to the left of it is the NE555 which generates the address pulses.
Finally to the left are the two MOSFETs each with an LED (green and red).

Encoder problems
The encoder works like this:
When you turn it one click it will generate a pulse on two pins, one before the other but overlapping. Here's a screenshot from my oscilloscope of a "clean" pulse train when the encoder is turned one way. I don't remember which but it's not important, just replace blue with red when turning the other direction.


The "click" on the encoder is between the each pulse-pair.

I figured all I need to do is to keep checking the signals and see which one goes high first and then wait for both to go low again.
Unfortunately this is not an ideal world. I had some problems with contact bounce in the encoder.

Look at the example I captured with my scope:

Here you see that the blue signal tends to jump up and down when going low as well as the red signal's tendency to jump up and down when going high. This made my code which just looked for the first rising signal a bit useless.
The effect was that when turning the knob one click in one direction I got the blink on the corresponding LED but sometimes I got a blink on the other LED as well. I had to make the code a bit more robust.
So, I added some delays when reading the signals, hoping to avoid the contact bounce. But, I still had problems with false triggers in the opposite direction.

I made some more readings with the oscilloscope and saw things like this:

See how the blue signal goes low for a long time and then goes high again for a bit. It's almost an entire millisecond. I know, it doesn't sound like much but in this case it is :) Anyway, I decided I can't rely on delays alone so I made some more robust approach in the signal detection, requiring both signals to go high as before but resetting the procedure and ignoring the signals if they both go low. That way I avoid the glitches in the beginning and end of the pulses.
I might miss some pulses this way if they are glitchy but at least I don't think I will make any false triggers so I think the trade-off is worth it.

Some nice results
After a couple of nights of adjusting my code and experimenting with putting capacitors on the encoder pins, I got a good solution without the need for any capacitors.

Below is a clip of the blinking LED (yay) and also a demonstration of the prototype set up on the board.
The music is written by me but it's not the entire song. It was too long for the video and I didn't know what else to put so I just faded it in and out :)
Hope you enjoy it anyway. I might put the complete song on youtube.

1 comment: