Monday, November 24, 2014

Driving a RGB LED with Arduino Uno


Here's a simple way to drive a RGB LED with Arduino Uno. The microcontroller generates a multiplexed PWM signal in software. The PWM is generated in an interrupt routine so the main program and LED update frequency are completely independent. The only requirements is that main program does not use hardware timer 1.

Components required: one common cathode RGB LED, one 330 ohm resistor.



Saturday, January 18, 2014

VIC-20 Flash Memory Programmer Part 1/2

My first computer was the Commodore VIC-20 which my dad bought me when I was something like 7 years old (thanks dad!). VIC-20 is the predecessor to the mighty Commodore 64, the most popular microcomputer ever. VIC has much the same feel as the C64 and both machines share the same basic design centered around the timings of the video signal generation. Unlike the C64 though, which had great graphics and sound capabilities for making games, the VIC-20 system is very bare bones. Most notably, the VIC does not have sprites and has only 5 kilobytes of RAM, of which less than 4KB can be used for programming. Compared to C64's 64 kilobytes, making games or basically anything at all moderately complex is a much more challenging exercise. However, the VIC has a charm of its own, mainly because of its simplicity. For example, the chip which handles both graphics and sound has only fifteen 8-bit hardware registers, so it's easy to master everything there is about it.

Another nice thing about these computers is that it's possible to see how they are built and understand how they work by simply looking at the schematic. The schematic of the VIC-20 even fits on three sheets of paper! So it naturally follows that these computers are a tinkerer's dream: it's easy make all sorts of interesting hacks and expansions for them. And that's precisely why I recently bought a VIC-20 (unfortunately I sold my old VIC when I upgraded to the C64 back in the days).

After getting my dirty fingers on my shiny new computer I immediately began to think about various projects I could do with it. Thus the idea for the VIC-20 Flash Memory Programmer cartridge was born! The basic idea is to make a device with a flash memory that would plug into the expansion port of the VIC. Programs would be cross-compiled on a much more powerful host computer and transferred to programmer's flash memory over a serial connection.

Prototype #1


To get started I bought a couple of game cartridges and disassembled them. I found out that the hardware inside these cartridges is really simple: they just contain a single 8K x 8 ROM chip and a 0.1uF decoupling cap. The ROM is wired directly to the address and data busses of the VIC-20 through the expansion port. In the hope of achieving greater good I sacrificed one of the cartridges and desoldered its ROM chip and soldered ribbons cables in its place. I then connected the ribbon cable to a breadboard.

Desoldered ROM chip of a cartridge game, ribbon cable soldered in its place.


Next I bought a few 256K x 8 flash memory chips (yeah, I know, overkill for VIC's 16-bit address space but smaller flash chips aren't available). I wired a flash chip to my Arduino Uno which I use for prototyping new projects and wrote a simple sketch for flashing the chip. It turned out flash chips are buggers to work with! Well, at least they are trickier than other memory chips I have worked with before, but my experience is quite limited... Writing has to be done per 128-byte page, and there is a clever protection scheme which prevents accidental writing to the memory. A certain bit pattern has to be written to special addresses in correct sequence before the chip goes into flash programming mode.

Arduino Uno has only 20 general purpose I/O pins and two are typically reserved for serial debugging. For flashing the chip, I needed 16 pins for addressing and 8 pins for the data so I used a few 74HC595 shift registers to expand the pin count. So no problem, I built this flash programmer on a breadboard. But the damn thing refused to work! I checked the wirings for at least three times and read the code until it burned my eyes, but no, the flash refused all attempts at programming!

Even after a long debugging session I could not find anything wrong with my code or the wirings. Everything seemed right. Then I had an idea that the implementation must be correct and the problem must be caused by a failure in the design. So at this point I went back to reading the datasheets. And then I noticed a crucial detail I had missed: the flash memory is really picky about timings. If the delay between consequent byte writes is longer than 200us, the chip drops out of page writing mode. I timed my code and because I was using shift registers and standard Arduino library calls (which are known to be slow), it took about 250us to write a byte. I quickly replaced standard lib code with direct port manipulation, and the code ran much, much quicker. And more importantly the flash chip began working like a charm!

At this point I unplugged the flash chip with some random data I had written to it and moved it on another breadboard which was connected to the hacked cartridge game. After carefully checking the connections at least twice I nervously powered on my VIC. The familiar CBM Basic V2 welcome screen appeared. Good, the computer was at least working and not crashing and burning because of short circuits on the breadboard. I then typed in a few peeks to checks values in the cartridge address space… and the data I had written to the flash appeared on the screen. SUCCESS!

Flash programmer with ATMega328P, 256Kx8 flash memory and
two '595 shift registers. Powered by "BreadPower" (more about that
in a future blog post, perhaps).


Prototype #2


It was time to combine the separated flash programmer breadboard and the flash chip breadboard together into one working device. After all, the goal was to be able to reprogram the flash when VIC was powered. For this I quickly whipped up the following simple design (see block diagram below): the flash memory would be connected to the expansion port through tri-state buffers. By disabling the buffer the flash chip is detached from the VIC while the MCU is reprogramming it. This is important so that signals don't leak out to the address and data bus, most likely clashing with other signals there, maybe even harming the components inside the computer. In normal operation the buffer is enable and the VIC can access the memory. In this state the MCU needs to tristate its I/O pins so that the VIC is not intefered by the MCU sitting on its lane.

Block diagram of the VIC-20 Flash Memory Programmer showing
the tri-state buffers, flash memory and the microcontroller.

The 74HC541, a 8-bit tri-state buffer with two output enable pins, turned out to be just the right chip for my needs. For VIC's 13 address bits (covering 8 kilos of ROM) and 8 data bits, I would need three of chips. With three '541s, the flash chip, MCU and shift registers that's a lot of chips to breadboard! So I began to look for another microcontroller than the ATMega328 for this project. I really like to work with AVRs so I looked what else they have in store, and I quickly found the ATMega32A, which has almost the same features as the '328, 32KB flash and 2KB SRAM. But the ATMega32A has 32 general purpose I/O pins compared to ATMega328's 20 pins, so with it I wouldn't need any shift registers. It also comes in the breadboard friendly DIL40 package, although those 40 pins make it one phat chip!

After a looong wait, a delivery of five ATMega32As finally arrived from China and I built the second prototype whose schematic is shown below.

Schematic of the final version drawn with Eagle which I'm really starting to like!

So does it actually work? To test this I wrote a very simple program in assembly language, the language understood by the 6502 CPU in charge of the VIC-20 system:


A000  INC 900F
           JMP A000

(sorry about the formatting of the code, I need to figure out how to do proper code formatting with Blogger)

What does the program do? Well, A000 (40960 in decimal) is the starting address of the cartridge memory space. The first instruction just increments a video chip register at address $900F which controls the colors of the screen. Then the next instruction jumps back to the start of the program forming an infinite loop. Basically the program just cycles through the colors as fast as it can. I translated the assembly program to machine code by hand and got the following byte sequence: EE 0F 90 4C 00 A0.

At this point I was ready to test the real deal. I plugged in the breadboard to VIC's expansion port, fired up the VIC and connected my laptop to the serial port of the flash programmer. And here's what happened:



At the start of the video I have already typed in a short basic program which prints the first ten bytes from the cartridge memory to the screen. I run the program with the flash memory disconnected (i.e. 74HC541s disabled) which returns some bogus values. I then type in the serial commands on my laptop to load the machine code of my test program. After uploading I verify that the bytes have indeed changed by running the VIC basic program again. Finally I execute the program with "SYS 40960" (A000 in hex) which jumps to my machine routine.

All this trouble for some random stripes of colors you may wonder? Basically yes, but now it's possible to develop some more complex programs, like my own cartridge games! That would be cool indeed! But first I need a more robust solution than that ugly mess on the breadboard...

Three tri-state buffers nearest to the VIC, flash memory in the middle and ATMega32A
in the back. Those ribbon cables with male pin headers soldered to them are very
handy when building complex circuits on a breadboard. It took some time to make them
but it was definitely worth it!



Friday, December 27, 2013

Speed Tester v2.0


Back in April I made an ATmega328P based speed and reaction time tester. Since then the game has been tested numerous times on our friends and relatives and it has also been a huge hit at a certain kindergarden! Last summer I was given orders to make a new device for a family of relatives. The game would be a christmas present for the whole family so utmost secrecy had to be maintained while building it. Also, the new device would have to be vandal proof because they have three kids :)

Instead of building an exact copy, which would have been boring, I decided to make a completely new revision. In this blog post I'll lay out the major changes and discuss some challenges I met.

But first a video!


From wall wart to battery powered


The old device was powered by a wall wart which was a little cumbersome to use and limited the usability somewhat. I decided early on that the new version would be battery powered. As this was my first real battery powered project, I had to do some research about battery efficiency. The old device uses a 7805 voltage regulator to convert a voltage between 7-15 volts down to 5 volts, a voltage more suitable for microcontrollers. The problem with 7805 is that it turns the extra voltage to heat and thus wastes a great amount of energy. Also the 7805 requires that the input voltage is about 2 volts higher than the output voltage. With batteries this would mean that once battery level would drop below the threshold voltage, the regulator would shut down, and thus even more battery capacity would be wasted.

I looked into another options like using low dropout regulators and even diodes to drop the voltage (the voltage drop of a typical diode is about 0.7 volts) but this was a dead end. Then I discovered the wonderful world of switching regulators. These tiny devices turn the voltage on and off very radiply and after suitable filtering this produces the desired output voltage. The amazing thing about switching regulators is that when the regulator switches off no current flows. This means that switching regulators are very efficient and only minimal amount of energy is lost. 

There are many kinds of switching regulators. Step Down voltage regulators work like the 7805, they take a higher voltage and drop it to desired output voltage. Step Up regulators work in the opposite direction. The issue with batteries is that battery voltage varies a lot during the lifetime of a battery as battery capacity is drained. Therefore a Step Down voltage regulator is not a good option for us; a Step Down regulator shuts down like the 7805 when input voltage drops below target voltage. Using a Step Up regulator to set up from 3 volts (two AA batteries) to 5 volts would probably be an acceptable solution, but I figured I would need the extra juice of 4x AA batteries.

Luckily I found a perfect match for my usecase: the Pololu S7V8F5. It is a combined Step Down/Step Up regulator. This little beast, about the size of a 7805, is capable of taking any voltage between 2.7 and 11.8 volts and turn it into steady 5 volts with typical efficiency over 90%. This is just what I needed to powered the device with four AA batteries.

Left: 7805 voltage regulator
Right: My new best friend, the S7V7F5 Step-up/step-down regulator


I also made some optimizations to reduce the power consumption of the hardware. First I lowered the MCU clock frequency from 16 Mhz to 2 Mhz by setting the 1/8 prescaler fuse bit. This reduced power consumption quite a bit (about 10mA less current drawn) and the clock rate is still fast enough to update the display hundreds of times per second and generate the necessary bleeps accurately in 300-600hz range. I also simplified the design by removing the 74HC595 shift register that was wired between the led display and the MCU. The MCU now drives the seven segment displays directly.

It is pretty easy to forget to turn off the game after playing, so I added an attract mode thingy which flashes the leds and makes some noise if the game sits too long in the main menu. As a last touch I added a reverse voltage protection circuit to protect the electonics in case the batteries are inserted the wrong way around. Typically reverse voltage protection is implemented using a diode in series with the battery, but diodes have a pretty big forward voltage drop, so this would have lowered battery efficiency. A better solution is to use a MOSFET or transistor. After some reach I decided to use a PNP transistor for this task. It was actually quite hard to find a suitable transistor: the required transistor needs to be PNP, have a high beta value, low saturation voltage and max collector emitter voltage of at least 6 volts. After a long search I found the ZXTP2012ASTZ which is just perfect for this task.

To protect the electronics I needed a sturdy enclosure. I have the privilege of knowing Antti Sirén, a master craftsman, who made the enclosure from wood and painted it bright christmasy red. Thanks Antti!

Yay! My first schematic done with Eagle


Inside the box are four AA batteries, main PCB and four arcade buttons with microswitches and LEDs. The 3x 7-segment display is on a separate PCB which is mounted on the lid.

New software revision


I also wanted to improve the software side to make the game more enjoyable. The old version is pretty harsh because the time window when the button needs to be pressed is very short. If you weren't fast enough to press the button before the next led lit up, it was game over. This resulted in unnecessary frustration and it was not sometimes clear what had happened. Sometimes the players felt it was the game's fault, not their own that the game had ended. To fix this, I changed the logic so that as long as you pressed the correct button in sequence, no matter when, it would be ok. So the player could be behind the led sequence as long as he kept pressing the buttons in the correct order. This improves the game a lot. Now the game can only end when the player presses the wrong button and there is no doubt whose fault it was.

Another aspect which has a big influence on gameplay is the speed up curve which makes the game gradually faster as you play. If this curve is wrong the game either speeds up too slow and feels boring, or too fast and it feels too difficult. Also abrupt changes to the speed are easily noticed and distrupt player's flow. Surprisingly a linear speed up curve does not feel natural at all. After many iterations I ended with a piecewise linear curve with 4 parts.

As a result of these changes the game is now a tad easier and a game last a little longer. The game should now be more rewarding to the player. As icing on the cake I added a totally new game mode, the memory game. Check it out in the video below!


Saturday, November 23, 2013

Toorum's Quest II - Retro video game and console

Okay, this project was a lot bigger and time consuming than I initially thought. The project started last summer and I planned to finish it by end of summer holidays. It took actually a few month longer and I'm glad it's finally done! Watch the following video to see what this is all about:



What did you just see? Simply put I made a retro 8-bit video game console, called The Box, and a 2D platformer game for it. Here is the feature list:

  • Based on ATmega328P running at 16 Mhz (same as Arduino Uno).
  • The game has a display resolution of 104x80 with 256 colors.
  • Video mode is tile based and supports up to 3 sprites per scan line.
  • Sprites are multiplexed so there can be unlimited number of sprites vertically on the screen.
  • 4 audio channels with triangle, pulse, sawtooth and noise waveforms.
  • Chiptune music playroutine and sound effects.
  • NES controller support.

Read on to learn more!

Source code in github

Top-left: 128x80 untiled titlescreen, Top-right: game screen, 104x80 tiled with sprites
Bottom-left: Final console hardware, Bottom-right: Prototype based on Arduino Uno


The Box hardware


The design is based on ATmega328P microcontroller (MCU) which has only 2 kilobytes of RAM and 32 kilobytes of program memory. The MCU is clocked at 16 Mhz, which makes the specs exactly the same as in Arduino Uno (intentional choice btw., because the initial prototype was built on Arduino Uno). Everything, the NTSC video signal generation, sound synthesis, music playroutine and game logic is running on the MCU, so many things had to be hand-optimized in assembler language. Only a single additional IC, the AD725 is needed in addition to the ATmega328P.

The most interesting part of the hardware is video signal generation. Here's the basic idea, inspired by Uzebox (which uses a more powerful MCU running at almost doubled clock rate btw.). The MCU outputs 8-bit colors in R3G3B2 format every sixth clock cycle and the bits are turned into analog voltages using resistor DAC. The R,G,B analog signals are fed to AD725, which is RGB to NTSC/PAL encoder. The AD725 outputs composite video signal. The AD725 requires a 14.31818Mhz clock signal for NTSC color modulation, so I have a DIP14 packaged crystal oscillator on board for this. The hardware design of the video stage is mostly based on the reference design in the AD725 datasheet. The AD725 is a surface mount part so I bought a SOIC28-DIP adapter for it and modded it to a SIOC16-DIP adapter to take less space the PCB.

The image quality is actually very good, the best we can get with composite video I would say. The picture is rock solid, only slight jittering can be seen between highly saturated colors problem inherent with composite video. If you going to build the console on breadboard expect lower visual quality -- only by building this on a PCB can you get rock solid picture. The breadboard version is actually not that bad, but after seeing the quality of PCB version you can't go back :)

Schematic (click to enlarge)


Parts list

Apart from standard value resistors and capacitors you need the following parts:
  • ATmega328P (easily found anywhere)
  • 16Mhz crystal
  • AD725 (I ordered 5 from China)
  • 14.31818Mhz crystal oscillator in DIP8 or DIP14 package (RS components has the DIP14 version)
  • SOIC28-DIP adapter for AD725 (I got it from Sparkfun)
  • The 10uF filtering caps on the power supply lines should be tantalum (recommened by AD725 datasheet)
  • 3.18k, 1.58k and 806 resistors (1% tolerance) for DAC
  • NES controller
  • NES controller socket (these can be bought online, e.g. from www.parallax.com)
You can also build this on a breadboard and connect it to Arduino Uno board. The compiled code fits into program memory with the standard Uno bootloader. It's much easier and faster to build the console like this but of course the end result won't be as pretty.

Tiled graphics mode with sprites


Video generation is written in AVR assembler. I don't know if anybody else has written a tile based color graphics mode with sprites on an 16Mhz Arduino compatible setup before. The MCU has only 2 kilobytes of RAM, so it's not enough to hold a frame buffer. The game uses a display resolution of 104x80 so with 8-bit colors 8320 bytes would be needed for the frame buffer alone, clearly out of our reach. So, first I had to do a tiled graphics mode.

The game screen is made of 13x10 tiles, each 8x8 pixels. A tile, therefore, consumes 64 bytes of program memory. I have a tile buffer of 13x10 pointers that point into tile graphics in program memory. On each scanline, I fetch the tile pointer from RAM, and pull 8 pixels from the tile and output the pixels exactly every 6 cycles. With pixel width of 6 cycles and with doubled scanlines the pixels are approximately square on screen. Pulling a pixel from program memory takes 3 cycles and outputting a pixel takes 1 cycle, so there are only 2 cycles remaining to fetch the tile addresses. With careful ordering of instructions and unrolling the loop it can be done. Overall, it was fairly easy to get the basic tiling setup working.

However, things started to get much more complicated because I also wanted to have sprites on top of the tiles. The ATmega328P running at 16Mhz is not fast enough to do the tiles and mask sprites on tiles during the time period of a scanline. It took me a while to figure out how do the sprites. Then it hit me. Because I have doubled the scanlines, I have actually two scanlines of time to process a single row of 104 pixels. In order to pull this off I had to use double buffering, so that while I was computing the next row of pixels, I was pulling in the previously computed scanline and still outputting pixels every 6th cycle. So on even scanlines, I do as many tiles as possible (which turned out to be 9 tiles), write the pixels to a scanline buffer WHILE reading the pixels of the previous scanline and outputting them to screen. On odd scanlines, I do the remaining 4 tiles, write the resulting pixels to memory, mask sprites on top of the tiles, and again while pulling pixels from previously computed scanline and outputting them to screen. A buffer holds a single row of 104 pixels. After two scanlines the buffers are swapped. Doing everything while outputting a pixel every 6 cycles meant that every cycle had to be counted.

There is actually three seperate "threads" running in the code and the threads are manually interleaved. This was very painful to code but eventually I managed to do it. The result is a video mode where I can have 3 sprites on each scanline. The game has actually more sprites because I can reuse the hardware sprites vertically on the screen by using multiplexing. I have a buffer in RAM which stores the sprite locations and image pointers for three sprites on each scanline. Multiplexing the sprites is as simple as writing the sprite data to the buffer in the correct place.


Multichannel music and sound effects


I also wanted to have multichannel music in the spirit of C64's SID and Rob Hubbard (the best chiptune musician ever, just listen to the music of Commando, International Karate or Monty on the Run if you don't believe me). Unfortunately there is not enough time left on the scanlines to do any sound synthesis. So sound had to be generated in the vertical blank period when the MCU is not busy doing the tiles and sprites. There are max 263 scanlines on a NTSC screen, so I fill a buffer of 263 bytes of 8-bit audio samples during the vblank. The video generation reads the samples and sends them out of the chip using pulse width modulation (PWM). Since we are constantly sending out samples while generating new samples, the sound needs to be double buffered. Otherwise clips and pops can be heard.

The audio system supports 4 channels, with triangle, pulse with varying pulse width, sawtooth and noise waveforms. Volume is controlled using ADSR envelopes. Oscillators and mixing is coded in assembler. The music playroutine is pretty much a standard four channel tracker with support for pulse width animation, volume slides, arpeggios, vibrato and portamento effects. Music data is compressed in memory so that each track row uses only 1 byte. The catchy tune was composed by Antti Tiihonen aka jpeeba using a custom textmode tracker I wrote just for this project.

Other tidbits


Rooms are stored compressed in program memory using a simple RLE compression. I had very limited RAM left because all the sound buffers, scanline buffers, tile pointers and sprite buffers use up almost every byte of available RAM. I could not have the game state of every room simultaneously in memory. So when the player moves to a new rooms I store only collected hearts, gold and opened doors as compressed bitfields in RAM. This way each inactive room consumes only 1 byte of memory as long as there are only 8 things per room to be stored.

Some of the tiles are animated on the screen: gold pieces, hearts and the princess are technically background tiles. I only swap their tile pointers every few frames. To make this really fast I scan only a single row of tiles per frame, so that the whole screen is updated every 10 frames.

There are actually three different video modes in the game: the main game mode with tiles and sprites (13x10 tiles), untiled titlescreen mode with 128x80 resolution and intro text mode with 14x10 tiles with no sprites. I did not need sprites for the titlescreen and there was space left in program memory so I could afford a slightly bigger resolution for the titlescreen. I couldn't fit the intro text beautifully into only 13x10 tiles, so I had to do a custom graphics mode with one more tile horizontally for the intro ;-)

In the end, there are only a few bytes of RAM and about 200 bytes of program memory left. I know by optimizing and with better compression techniques (and removing one of two of the extra video modes) I could fit even more into memory but luckily the game does not really need more stuff.

Thanks for reading!

Etched circuit board (excuse the hand drawn lines)

Media coverage:

Legend of Grimrock Co-Creator Builds 8-Bit Game On DIY Console
8-Bit Video Game is Best of Retro Gaming on a Shoestring Budget
8-bit gaming with Atmel’s ATmega328P
The True 8-Bit Video Game Toorum’s Quest II And The Console Made To Play It

Saturday, April 20, 2013

First Project: Arduino Spede

Here's my take on a reaction time tester entitled Arduino Spede. The device is similar to the one seen in Speden Spelit TV show that ran in Finnish television in the 90s. The idea is to push buttons that lit up in a random sequence. The sequence gets faster and faster until eventually you are too slow or push the wrong button and it's game over. Each LED also plays a different note (C#, D#, F# and G#), so if you are really hardcore you can play with your eyes closed! My musically talented girlfriend Saara gets a score of about 30 with her eyes closed, where I can do only about 4 or 5 if I'm very lucky :)

If you're interested in knowing how it works or even building one yourself, read on!

Schematic


Parts list

  • 1 Arduino UNO R3 (or equivalent)
  • 1 CC56-21SRWA common cathode four digit 7-segment display (or similar)
  • 1 74HC595 shift register chip
  • 4 push buttons
  • 4 LEDs
  • 4 BC548B transistors (almost any NPN transistor with similar specs should work)
  • 1 1uF capacitor
  • 4 1 kohm resistors
  • 4 390 ohm resistors
  • 1 470 ohm resistor
  • 7 560 ohm resistors
  • 1 small speaker
  • 14-pin ribbon cable
  • 2 14-pin ribbon cable connectors (female)
  • 2 14-pin PCB connectors (male)
  • Pin headers and Harwin connectors for LEDs, buttons and speaker
  • Wires, etc.

How does it work?

Buttons: The buttons are connected to digital pins 14-17, which are set up to use the internal pull up resistors inside Arduino. When no buttons are pressed the internal resistors pull up the pins to high state. When a button is pressed the corresponding pin does low. Without the pull up resistors the state of the input pins would be undetermined.

LEDs: The four LEDs are connected to digital pins 3-6 in series with 390 ohm current limiting resistors. Without the resistors the LEDs or digital pins of the Arduino could burn out.

Speaker: The speaker is connected to digital pin 2 via a resistor. In hindsight I should have also used a capacitor in series to filter out the DC and pass only the audible AC frequencies. I'm using the Arduino tone library to generate the tones. I've chosen frequencies 277, 311, 370 and 415 Hz which produce exotic Asian sounding notes C#, D#, F# and G#.

The score display: This is by far the most complicated part of the schematic. I've chosen a 4 digit seven segment display so you shouldn't run out of digits no matter how good you are! The display is a so called common cathode display, meaning that the cathodes (negative terminals of the LEDs) of a digit are tied together. The display has a pin for each segment A-G but the pins are shared for all digits. So, for example, if the anode (positive terminal of a LED) for segments B and C are set high and the common cathode of digit 1 is pulled to ground, number 1 would be displayed in the first digit.

Because a single anode pin is connected to all digits, it's impossible to display different numbers in different digit positions at the same time. Instead, we can turn on a digit one by one very rapidly in succession. So, for example, to display the number 1234, first we would set the anodes to display number 1 and enable only the first digit by pulling the cathode of digit 1 to ground. Then we would turn off the digit, set the anodes to display number 2 and turn on digit 2. And so on for 3 and 4. If this is done fast enough, the eye cannot see the LEDs blinking on and off and it appears as if the digits are all lit.

The job of NPN transistors T1-T4 is precisely to pull the digits to ground. Normally the transistors are off, meaning there is no current flowing through them. Digital pins 10-13 are connected to the base of the transistors, so setting a pin high turns on the corresponding transistor and enables a digit.

In order to cut down the number of Arduino pins I've used a 74HC595 shift register between the Arduino and the display. The shift register is a serial in, parallel out device and also acts as a 8 bit buffer. It has eight outputs which "latch" to a state, meaning that the outputs remember their state until the state changes again. The Arduino sends the state of eight outputs one bit at a time (serial transmission). For seven segments we need only seven bits so the eighth bit is unused. There is a great tutorial about using the 74HC595 chip with Arduino here.

This may sound a little tricky. Check out the datasheets of parts CC56-21SRWA and 74HC595 for more details. You should be able to substitute the display with another part but it has to have common cathodes. The pin ordering is also likely different from the one I used.

Putting it together

The final version consists of three circuit boards which I made myself (I could write about the process in a separate blog post). One of the boards contains only the display and it is connected using a 14 pin ribbon cable to the main board. The main board contains the 74HC595 chip, transistors, resistors and the capacitor.

After building these and making sure everything worked, I realized that I didn't want to allocate my Arduino permanently to the project. So I made a third circuit board, a standalone Arduino board following the instructions here.

You can use normal pushbuttons and LEDs, or you can order some fancy arcade buttons with built-in LEDs from Ebay like I did. I soldered wires to the terminals of buttons and LEDs and connected them using Harwin connectors and headers to the main board.

Source code

Download source code

The code itself should be self explanatory so just a few comments. The game can be in one of three states each of which is implemented in a separate function: startMenu(), playGame() and gameOver().

Start menu flicks between previous score and high score. High score is stored in EPPROM which retains its value even when the device is turned off. When a button is pressed, a new game begins. Holding all four buttons while in start menu causes the high score to be cleared.

Playing the game is handled by playGame() function. Here one of the four LEDs is turned on randomly and a timer starts counting down. If the player presses a wrong button or the timer reaches zero, the game is over. If the player pressed the correct button, the procedure starts again with a new randomly selected LED. This time the timer starts from a little bit smaller value. This repeats until the game is over.

In game over state, the score is blinked a few times and a tone is played. The game enters the menu state automatically after a short delay.

Display and main circuit boards, hand drawn, before dipping into acid bath
The wiring for LEDs. Buttons not connected yet.

Harwin connectors for connecting LEDs and buttons to circuit board
Standalone Arduino board (left) and main board (right)


Testing the outputs

Wednesday, February 6, 2013

Fixing a C64

A couple of weeks ago someone broke into our apartment building's storage cellar. When I was cleaning up the mess the damned thieves had left behind, I found a bag with some electronics junk stuffed into it that I had completely forgotten. Amid the junk was a rare jewel, the motherboard of a Commodore 64 from 1987! I have no idea what had happened to the case and accessories, maybe the thieves got them, those bastards!

The Commodore 64 was a pretty nifty piece of hardware and very popular in Finland in the 80s. It had 64 KB of memory and most importantly thousands of games. The graphics hardware supported up to 8 sprites (with multiplexing many more could be produced) and the SID sound chip is still used by musicians today to get that oldschool sound.

Anyway, the motherboard was in a pretty bad shape and the fusebox of the transformer was missing. That wouldn't do! So I visited Bebek, a famous electronics shop in Helsinki to get some parts. The owner of the shop, Mr. Bebek is a very nice chap who has had the shop for 40 years. Although he is retired he can be spotted in his shop every now and then. I bought a new fusebox and a 160mA fuse, and as an added bonus a male DIN-8 connector, some speaker cable, and a couple of RCA plugs (more about these in a bit). 

Fixing the transformer was a matter of minutes with a soldering iron (the wires were rather thick so I needed to heat them pretty long with my 15W iron). The next problem was to hook up the C64 to a display to see if it still worked. Now, the way C64 were hooked up to a display in the old days was to use a RF adapter which transformed the output signal to a RF signal for a TV. I didn't have a RF adapter so I had earlier googled up "commodore 64 tv out." Luckily the C64 was advanced in its time and it could also produce component video signal through the video port. Among the google hits was a page describing the pin outs of the C64 video port

Using the instructions it was pretty easy to make a cable with a DIN-8 connector in one end to plug into the video port and two RCA males in the other end with component video and mono audio. I quickly assembled and attached the cable between the C64 and a monitor and nervously turned on power. Two seconds later to my amazement an old childhood friend of mine, the classic light blue, deep blue welcome screen of the C64 basic appeared on my Dell. 

I have no games or a floppy/tape storage drive for the C64 and the motherboard is in dire need of a case to protect against the elements. I'll probably come back to this project later. My part shipment including the Arduino arrived soon after this, so I had already other projects in my mind... but more about those later!

Ideas for future projects:
  • Wooden case for C64
  • 1541 emulator using Arduino
(oops this post got a lot longer than "the brief intro" that I promised to myself, better fix this for the next post before it becomes a habit!)


Welcome!

This blog is about my endeavors into the world of electronics and microcontrollers. I have always wanted to learn electronics but it wasn't until recently when I got an Arduino microcontroller board that things started to really click. I figured soon that I need to write things down or otherwise I start forgetting what I have learned. Hence this blog.

The blog serves two purposes. It is intended as a notebook for myself so I expect most posts to be quite brief. But if you're an Arduino beginner like me these ramblings might as well be interesting to you too!