Saturday, August 23, 2014

6502 Virtual Trainer: Calculator Program


After I got my new Hakko FX-888, the first thing I did was solder the trainer to perfboard. It took some time to get used to the new iron but the board turned out well:


The FT232 cable connects to a few header pins soldered to a piece of perfboard connected perpendicularly to the main board by more pins that are bent at an angle. They make header pins at an angle but I used the last of mine on the board I made for programming the Z16F. There was also room to add some sockets and pins that can be used to program the MSP430, as well as power and status LEDs.

After using the board for about a week I had a strange error where the chip jumped to address 8080 on reset instead of 8000 which is stored at the reset vector. After some investigating, it seems there was a short between the Vcc pin of the IO expander and the pin controlling A7 of the 6502's address bus. On the back side of the board there was clearly no bridge which had me stumped but it worked fine after scraping away some of the flux between the joints. The problem reappeared after a week or two but was fixed again by cleaning the space between the joints. In frustration I ordered a W65C02 thinking the chip might have been damaged due to some acidental bus contention that had happened during testing. It seems that the pinout is a little different from the W65C816 I am using but it will still be useful because I plan to use it for an improved version of the trainer.

With the software I have made a little progress as well. The PC software skips sending any uninitialized memory and with a few other tweaks can program the whole 64kB memory in less than 3 seconds, down from 6 seconds. The microcontroller firmware is also a little better. Compiling with the -o3 flag in GCC brings average cycles per second up to about 16,000 from 12,000. However, setting the update rate to 100ms from 200ms to make typing more comfortable brings it back to around 14,000.

To learn 6502 assembly I decided to make a little test calculator program. It has turned out to be a really good way to get to know the chip, even though it has taken a lot longer than I expected. Below is a screenshot.


On the left is a text window for the 4-function RPN stack. It has 10 levels and each element is 8 bytes of packed BCD. This is convenient because the 6502 has a BCD mode. On the right is a window to enter formulas which can be graphed, like the first three, or repeated like the Celsius and Fahrenheit conversions. Formulas and graph colors can be selected with the dip switches. The toggle switch at the bottom selects between the two text windows and an LED above each window shows which one is selected. All of this could be done with a keyboard interface but I wanted to show off some of the peripherals that can be used. There is also a timer peripheral ticking every 500ms that the program reads to draw a flashing cursor in whichever of the two input text windows is active. The last peripheral is a multiplication ROM that works when single stepping the processor but not when running from SRAM yet.

There are still several improvements to be made to the trainer but I am done working on it for the moment. My plan is to port the code I have to an STM32 which will be much faster and also be able to store all 64kB of the 6502 address space in its internal RAM.

Thursday, July 3, 2014

Quiz Buzzer

About a month ago a friend of mine called and asked if I could make a buzzer system for a quiz game for students. Unfortunately, I only had two days until the competition and I did not get it working in time. Hopefully, I can fix it and send it to them to be used at the next competition in a few months.

The plan was that each of ten students would have a button connected to a buzzer by a few meters of wire and the first to press the button after a question was asked would cause a sound and light to go off. The connectors are RCA style and the buttons are from an automotive store.


These lead to an A42 enclosure I was able to sample from Serpac. The enclosure felt really sturdy but the plastic was surprisingly easy to cut and work with with just a knife. I will definitely use them again when I need an enclosure. The circuit itself was fairly simple with just an MSP430 microcontroller, buzzer, two 595 shift registers, and two 165 shift registers. I did not get around to adding the LEDs, although the firmware does use the shift registers to turn on the correct light when someone buzzes in.


To control things I made a separate detachable board with a 16x2 LCD. It will be easier to transport if the cable is detachable and it will also let me add a longer cable if the judges doing the scoring need to sit farther away from the enclosure. Other than the LCD, the board has a 555 to generate negative voltage for the LCD contrast and another 595 shift register to run the LCD. It also has buttons to change the time given to answer and to reset the counter.


For the cable I used Cat-5 again and this may be part of the reason it does not work correctly. For the connector I wanted to make something that would only plug in one way so that people other than me could use it without fear of plugging it in backwards and shorting something. Each side has a pin that can only be connected one way.


A project like this would take me a week at least but I tried to finish in two days because my friends needed it. The night before I stayed up soldering until 7am and when I finally switched it on, the LCD came on as expected and the buzzer sounded when I pressed one of the contestants buttons, but it made a high pitched screeching noise when it was finished buzzing. When I turned it off and tried again the LCD wouldn't display anything and only worked some of the time when I tried it again, so we weren't able to use it in the competition after all.

Why did it fail? In retrospect, I have had problems with this particular LCD in the past. When I was working on my calculator project I noticed that the LCD would often not work when being driven directly by a microcontroller but worked fine when being driven from a shift register like in this project. I'm not sure why it worked before and not now but the fact that it was flaky before might be a clue to my problem. Also, maybe my assumption that it will always work at voltages less than 5v is not correct or maybe supplying negative voltage to the display somehow has consequences. On the other hand, I observed the same faulty behavior with the contrast left unconnected. Another source of problems could be the Cat-5 Ethernet cable I am using for wiring. Each pair is twisted together and running a separate signal through each side of the pair instead of grounding one side might be leading to signal corruption. Finally, the loud screeching of the piezo buzzer is something I will have to figure out as well. Hopefully, when I understand more about this it will help me straighten things out with my clock project also.

Going from nothing to a nearly complete project in only two days was a lot of work, but in the end there was not enough time to troubleshoot problems. When I move into my new apartment next month I will have time to figure everything out and then I can send the working system back to Kyrgyzstan for my friends to use.

Monday, June 30, 2014

Clock Modification

The unfinished clock without the arms
For Christmas 2012 I got a battery powered alarm clock. It felt pretty sturdy but only plays a beep when the alarm goes off and it does not have a backlight. There was plenty of room inside the case so I decided to add a microcontroller to play the unofficial national anthem of Kyrgyzstan Кыргыз Жери (Kyrgyz Jeri) instead of just the beep. Although I have been working on it on and off for the past few months I have not gotten the bugs worked out.

The mechanism inside the clock runs from one AA battery and has a small buzzer that looks like a piezo. The positive side of the battery is connected directly to the buzzer by a wire. The other side of the buzzer is connected to a chip under an epoxy blob that switches the buzzer on and off. The 1.5v of the AA battery is not enough to run the MSP430 I am using so I wired in two AAA batteries. The clock case has just enough room for the extra batteries and a small piece of protoboard for the microcontroller. I opened the mechanism to solder in some wires so that the microcontroller can monitor the line switching the buzzer and drive the buzzer directly instead. One of the small gears inside quickly melted from the heat given off by the soldering iron a few inches away. Luckily, all of the local clocks use a similar mechanism and I replaced the whole thing for about $1. The wires from the mechanism are connected to a switch so that the buzzer can either be run by the microcontroller or by the original clock in case the extra batteries die. Another feature the clock is missing is a light, so I wired in an RGB LED I bought a few years ago. It has a light so that it can be used as a backlight but it also flashes colors in time with the music when the alarm goes off.


At first I tried soldering components directly to a DIP socket but this was surprisingly difficult, so I added everything to a small piece of left of protoboard. The AAA batteries are too big to fit in the clock case side by side so I couldn't use a battery holder. Instead I soldered wires directly to the batteries. This will make them hard to change but hopefully the MSP430 will use very little power waiting for the alarm to go off. Once I got everything soldered, the microcontroller would play the music it should but it would not stop playing even when it was disconnected from the line switching the signal. This is a problem I still have not figured out but I'm sure it has something to do with fluctuating signals in the circuit.


There were a number of other strange problems as well. The P1IES register used to enable edge selects for interrupts on the MSP430 sometimes gives the wrong value when you read from it. It would be useful to read it in an interrupt to know which phase of the cycle the interrupt was last configured to fire for. There was also a problem working with 32-bit values. It seems that doing math with constants and assigning the result to an unsigned long does not automatically promote the constants involved to 32-bit values as well. When I got the wrong value, I tried it out on a PC and got the expected value, which was a little perplexing. It seems that constants default to the bit size of the processor, which seems silly from a portability point of view. To have the constants treated as longs, the L prefix has to be added. Another strange thing that happened was that the buzzer always made a high-pitched whining even when not being driven. The batteries for the microcontroller also drained alarmingly fast. It turns out that both of those problems are related to the buzzer being electromechanical instead of a piezo. These buzzers do not charge and stop current from flowing like a piezo. It seems they only have about 40 ohms of resistance and this is why the batteries drained so quickly.

There are still a lot of bugs to be worked out but I hope to make progress soon and finish this little project quickly.

Monday, June 23, 2014

6502 Virtual Trainer: Update

Lately I have been working on several different projects and I have made a lot of progress on the 6502 Virtual Trainer. The first step was connecting the PC interface to an MSP430 over UART. This was easy because I have done it in other projects. Microchip let me sample some MCP23S17 IO expanders and I was really excited to be able to try them out to read and write the pins of the 6502. Unfortunately, they were a little finicky to get going because the datasheet incorrectly lists the reset pin as an output instead of an input.  They do save a lot of space, though, because five shift registers would be needed to replace them. After that was solved, I was able to single-step the processor as I intended but only at about 90 cycles per second. For comparison's sake, with the processor doing nothing else, that is a little too slow to type comfortably. At the beginning I knew this would be slow but that is much slower than I expected. The bottleneck seems to be the USB<->serial layer since the program sends lots of small packets of data instead of small numbers of large packets. To speed this up, I send 10 bytes of op codes every packet. Then the MSP430 can use the data sent if it needs to read a byte that is near. It will have to request more data if a jump takes place or data is read from another location in memory but in general this improvement led to a speed up of about 150 cycles per second. This was still not as fast as I had hoped for so I decided to keep a copy of all of the memory on an SPI SRAM chip. For this I used a 23LC1024, also from Microchip, which holds 128k. Using an SPI SRAM might seem to make less sense than just hooking up a typical parallel SRAM but by letting the microcontroller control the memory I can hold extra information about the data such as which bytes have not been initialized and which should be ROM. This will let me break when reads and writes that would be illegal are performed. Even during testing this turned out to be useful as it is easy for a beginner to assembly to write something like LDX $FF instead of LDX #$FF. As a compromise the MSP430 runs the 6502 as fast as possible then pauses and updates the PC every 200ms or when 64 bytes of memory have been modified, whichever comes first. Another way to speed things up was to increase the COM port speed from the 230,400 bps max of the MSComm control I'm using with Visual Basic 6 to 1,000,000 bps. At 1,200,000 bps the MSP430 could not keep up running the 6502 and reading data. With these changes I can run the 6502 at about 12,000 cycles per second. This is still pretty slow but fast enough to play with for learning purposes. To test things I made a few programs including one that draws a faded red pattern like below:

Tuesday, May 13, 2014

RPN Scientific Calculator: Case

After a few months of work, the case for my calculator is finally finished. Back in January I made a post with a picture of the clad I soldered together for the case. My plan at the time was to stuff all of the internals of the calculator into the case over the course of a few days but it ended up taking much longer.


The first hurdle was figuring out how to attach the front and back plates to the case. In the end I settled on epoxy. The first one I tried was still oily after 24 hours and did not hold very well but a much cheaper one held extremely well and I used it to glue four bolts to either side of the case body. Oddly enough the epoxy turned the clad green pretty quickly. From there I made holes with a box cutter in the front and back pieces for the bolts. Cutting out the hole for the keypad and LCD in the front piece of clad with a box cutter and wire cutters was a real chore and I don't plan on working with clad ever again without something like a dremel. For spacers between the clad and components I used rubber erasers.


These are cheap and easy to work with. My only fear is that they may dry out and crack someday. At first I tried gluing one of the plastic battery holders to an eraser with epoxy but surprisingly the bond was very weak. Super glue worked very well, though, and I glued in more erasers to hold the LCD, PCB, and keypad in place. All of that added a noticeable amount of weight to everything. The front and back pieces also have erasers glued to them to help hold everything together.


There was not enough room to comfortably route the wires from the LCD and keypad to the PCB so I desoldered them and used Cat5 cable instead. The wires inside are much smaller and easier to work with. It is also possible to leave the individual wires inside the Cat5 cable to make routing neater and I did this for some of the keypad wires. After assembling everything it worked fairly well except the keypad buttons were hooked up upside down. This was easy to fix in software and I loaded the new version using the programming pins soldered to the PCB without having to take the PCB out of the case. There was another bug that caused the calculator to freeze after pressing escape. For some reason the program was going into sleep mode when I pressed escape. I must have added this during debugging but it does not make sense at this point.


The next step will be to add some sort of labels for the keys and then paint it if I decide to.

Saturday, May 10, 2014

New Project: 6502 Virtual Trainer

One project I have been interested in for a while is building a homebrew computer. Some of the projects I have followed like Veronica are really fascinating and I would like to do something similar. For my project I decided to use an M68000 but Mouser did not have any in DIP packages when I ordered from them last year so I settled on a W65C816S instead. This chip is compatible with the 6502 like Veronica uses but also has a 16-bit mode which is more powerful. Other homebrew computers like this one use that chip as well.

KIM-1 6502 trainer
Setting up RAM and ROM to work with the processor for a simple system is well-documented. My first idea was to hook up a microcontroller to the system once I had it running to monitor the bus and some of the control pins not usually used in simple systems. That way I could transfer information about the system to a PC over UART and even control the clock rate. Then I realized that it would be simpler to skip the RAM and ROM altogether and keep all of the memory on the PC. The microcontroller would relay data between the processor and the emulated memory and peripherals. This would not be a useful system by itself but it would let me learn a lot about how the processor works.

Simple systems like the KIM-1 were produced in the past along the same lines. These were called trainers and often had simple hardware that let people learn about how computers work. I decided to call my project a trainer also. My plan is to control the processor through an interface on the PC that will let me examine the memory as the program is running as well as set break points and single-step the processor. It will also show me the status of all the control pins and let me set the values of some of them. Peripherals like buttons, lights, and displays will all be virtual. Here are some of the ones I have working so far:

Wednesday, April 2, 2014

555 Entropy and Robotic Teddy Bears

Recently I have been keeping busy with a few electronics projects, although it doesn't look like either of them will turn into anything. The first would transmit text wirelessly from a PC to a microcontroller to be displayed on an LCD. For this I planned to hack toy walkie talkies. This is not an ideal way to transfer text but I thought it would be fun to try different ways of making them work to start understanding wireless communication. Unfortunately, in my whole town I could only find one set of walkie talkies and one of them turned out not to work. The data being sent would not be especially sensitive but I still did not want to send it as plain text. This got me wondering about encryption, which I also have no experience with. There are many algorithms but I would need one very easy to compute since the microcontrollers involved would not be very powerful but would have to decrypt and transfer quickly. One solution that intrigued me was using a one time pad. Each microcontroller would have the same list of random numbers that would simply be added or XOR'ed with the data to encrypt and decrypt it. One time pad schemes have the advantage of being truly unbreakable as long as the numbers used are random and never repeated. A bigger advantage for me is that the microcontrollers could simply fetch the numbers from an SD card without having to compute anything. To get truly random numbers, though, I would need a hardware random number generator. These are a common project for hobbysts but not always easy to build correctly. One method uses a transistor in reverse breakdown mode but I decided against this because it requires 15 volts or more. Apparently the transistor also changes with age (perhaps due to being continuously run in a way it was not designed to be) and the characteristics of the numbers generated change too. Another interesting way I found was to measure the output of a 555 timer with a microcontroller ADC as shown here. This made me wonder if I could just measure the length of 555 pulses compared to the oscillator in a microcontroller to use clock drift as an entropy source. I connected a 555 running at 480Hz to the hardware counter of an MSP430 running at 16MHz to measure how many clock cycles each 555 cycle took and dumped 1,000,000 samples out over UART.