Wednesday, January 5, 2011

AVRphrase


When I started playing around with embedded systems, I wanted to do something more interesting than just flashing an LED, and I spent a lot of time trying to come up with project ideas that would be useful (or at least fun) when they were done. One of the first ideas I had was to make my own version of catchphrase. Most of my extended family enjoys the game, but one problem with it is that some of the younger nephews can't understand most of the words. I thought it would be fun to create a version that they could play, and then the project grew from there.

 I made the first version right after getting an Arduino for Christmas 2009, so it was a fun project to get familiar with the Arduino and pretty easy to get up and running with the libraries and examples on the web. I spent about a week of evenings playing around before I got something I was happy with.  My first version was really simple, with all of the words stored in the AVR's flash using PROGMEM (I was able to fit around 700 words in 5 categories--any more words would give me problems, even though the flash wasn't even close to full). The problem with this was that the way I input the words was very, very tedious and was not something I could see any of my relatives understanding if I wanted to give it to them as something they could customize in the future.  The prototype was basically a 16x2 LCD, 5 push buttons, an ATmega328 mcu, a 16 MHz crystal, a piezo buzzer, and a 5V linear regulator.  I used a socket for the microcontroller so that I could pull it out and place it in my Arduino to program it.  I soldered it together on a protoboard, but didn't have a good enclosure or any power management.  It ran off of a 9V battery, and to turn it off you had to unplug the battery.  It was fun to work on, and a good proof-of-concept, but I got sidetracked for a while after I finished it.


I started thinking that it would be a fun project to take further.....maybe get a pcb printed and make enough to give as Christmas presents next year. Then I saw a post on Hackaday of someone who had done a similar project, but with a price tag over $200.  That was one of the things that made me decide I could definitely put this together, and for way less.  Christmas 2010 was the goal.  As I started thinking it through, I came up with more features that I could add, and other ways it could be used. The original used a 16x2 LCD display, and I would probably keep that on the next one. I also think the layout of a 5 pushbutton interface works well.  I had two buttons for keeping score, one for changing categories, one for starting/stopping the game, and one to advance to the next word.  It's a little different than the real Catchphrase, but the interface seems a little cleaner to me.  I definitely needed to add an on/off capability, as the last version was always on when the battery was connected. I also wanted  it to run off of a couple of AA batteries instead of a 9V.  The major change that I wanted to make was to remove the wordlist from the flash memory of the micro. By using an external EEPROM chip (SPI or I2C),  I could store the wordlist there and have a minimal code footprint on the micro. I could also add a mode where you could connect the microcontroller to a computer and use it as a UART to SPI bridge to program the wordlist into the EEPROM.  I needed USB capability if I wanted anyone else to be able to upload new word lists, as well as a simple way to upload new words.  With these ideas in mind, I set out to begin my design.

I decided right away that I wanted to move away from the Arduino development environment and switch to straight avr-gcc if I stuck with an AVR, or potentially use this as an opportunity to gain experience with another micro like PIC or MSP430.  The requirements I initially laid out for the microcontroller are listed below:
  • SPI/I2C - For interfacing with external EEPROM
  • UART/USB - For connecting to computer to program EEPROM
  • 5 GPIOs - Buttons
  • 7-11 GPIOs - LCD, Piezo buzzer 
  • 4-8 kB program space (rough estimate)
The list is pretty basic, and I knew that the ATmegaXX8 series would be up to the task and I already had a simple AVR ISP programmer, although at school I had access to a Dragon as well. I had a few PICs with built in USB that met the requirements, but I would be leaving college in a few months and thereby losing access to a PIC programmer. I also have a TI ez430 kit,  but I'm not sure that the series of 430 that comes with that kit would have worked.  In the end, I decided to stick with an AVR because of familiarity and the tools I already had, but I plan on using a different family of micro on my next project to try and expand my capabilities.  I had ATmega48, ATmega168, and ATmega328 chips in DIP packages, which were perfect for prototyping, and I could figure out how much code space I actually needed before actually selecting a chip because of the simplicity of switching between them.  I programmed the chips in AVR-GCC within AVR Studio.  I got pretty used to using the debugWire feature of the Dragon on school projects, and ended up picking one up after I graduated, which was very helpful for this project.

I had a pretty good idea in my head of what I wanted to do, so I started breadboarding another prototype.  I worked slowly and tried to get each functional piece working and simple "driver/interface" code written before moving on.  I pretty much always had the freeware CadSoft Eagle schematic editor up while I was working and kept the schematic consistent with what I had breadboarded.  The schematic definitely evolved as I went, but you can see the final version below.


At the top left of the schematic is the power regulator.  It's an MCP1259 inductorless charge pump DC-DC converter from Microchip that provides a regulated 3.3V from a 1.8-3.6V supply.  My V+ is coming from 2 AA batteries, and this chip also has a bypass feature that I'm using when I enter the power down state.  I used this chip, along with a couple others from Microchip because I was able to obtain some samples of them to test as a student and they worked well for my application. At the top middle is the LCD, which is a standard 16x2 character LCD.  I was able to find these pretty cheaply from  Xenon-Tech.  The LCD needs 5V power, so I stepped up the 3.3v using a voltage quadrupler and a 5.1V zener diode (see lower left of schematic) as described in this application note.  At the top right is an MCP2200 USB-UART converter, which is used to communicate with a PC to upload a new word list.  I used this instead of an FTDI232 chip because it was about half the price (although it did require an external 12 MHz crystal), but it doesn't work on Mac (or at least didn't at the time I was working with it), which is a downside.  At the bottom right is a chain of buttons configured as a voltage divider and connected to an ADC pin on the microcontroller.  This allowed me to use only one pin to read all 5 buttons, and I handled the debouncing in software.  At the bottom is the EEPROM chip.  I'm using a 25AA512 SPI EEPROM, which has 512Kbit and 1,000,000 erase/write cycles.  This series of memory chips goes all the way from 1Kbit to 1Mbit, and I'm using this one because it was a good balance of cost and storage.  Because my LCD is a 16 character display, I store each word/phrase as 16 characters regardless of the actual size, which simplified addressing and knowing where the words would be stored in memory, and allowed me to have ~4000 words/phrases.  I think the actual Hasbro Catcphrase has ~10,000 phrases, but 4000 is plenty for my homemade version, and it would be a simple change to move to the larger chip if I needed to.  I had a piezo buzzer and programming header, but pretty much everything else on the schematic is just supporting components.

I wanted my final design to be surface mount, and some of the chips I selected were only available in surface mount packages, so I had to use breakout boards for those in my prototype.  I got the breakout boards from Sparkfun and Proto-Advantage, and they were perfect for what I needed.  I kept my breadboarded prototype up to date even after I moved on to the PCB and was making minor adjustments there, just so I would always have an easy to modify prototype.  You can see the breadboarded version below.


Once I had the hardware finalized (or at least I thought it was finalized) and test code written for each portion, I decided it would be best to lay out a pcb and get the actual hardware in hand, as that was the longest lead time item, and I could worry about finalizing the software later.  I used Eagle to lay out the pcb, and had them fabricated through Gold Phoenix PCB using their 2 layer 155 sq. in. panel service, which I was very pleased with.  The physical constraints on my board came from the case I'd selected, and I was able to fit 15 boards on their panel.  The holes in the four corners are used to mount the board to the case.


Even though I had 15 pcb's, I hadn't really planned on making that many.  I bought enough components to populate 10 of them (10 was the cut-off for a price break on a lot of the components), thinking I'd make some mistakes and have 8 or 9 in the end (I ended up with 9 working units, and the one that's broken just needs an new MCP2200 chip and then it's good to go).  The "bottom side" of the pcb is actually the top of the game, but only has the screen and 5 buttons, which were all through-hole components.


The top of the pcb (bottom of the game) is where everything else is.  There were a couple of mistakes on the board, but I was able to fix them by hand.  At the bottom left is a pull-up resistor that was accidentally inline with the voltage divider-to-ADC path.  Luckily, it was over a 3.3v pour, and I was able to scrape away a small patch of solder mask and make a new "pad" for the resistor and jumper the old pad with solder.  The other mistake came from not reading the datasheet for my USB-UART converter closely enough.  It has a pin called Vusb, which I thought needed to be connected to the 5V USB pin.  It actually has it's own internal regulator, and I just needed a capacitor there.  I was able to cut the trace and add the capacitor after the fact.  Another mistake I didn't fix was that I forgot to connect a GPIO from the mcu to the reset pin on the USB-UART converter.  This is a pain, because sometimes the chip gets messed up and needs to be reset, but I have to do that by disconnecting the batteries rather than in software.  Otherwise, I was very pleased with how it turned out.


Once I had the hardware complete, I moved on to finishing the software.  I'd written most of the functions I needed already, I just had to write my main routine and make any fixes that came up.  When the mcu initializes, it checks the first page of EEPROM, which lets it know how many categories there are, and then reads in the name and starting/stopping memory locations for that category.  It only stores this information for the current category, and has to go back and read out the information for the next category when you change categories.  I have a few timers running, but the main process occurs once every 50 ms.  This is where button presses are registered and actions are taken.  The duration of the game round is randomly selected to be between 45 and 75 seconds at the beginning of each round.  Random words are selected by taking the value of a 16 bit timer at the time of the button press modulus by the size of the current category.  The timer gets progressively faster as the round goes on, and lets out a long beep to signal the end of the round.  In between rounds, the players can add points to either team, and the game will announce when a team has won.  After three minutes without any button presses, the game enters a power-down sleep mode and sets up a pin change interrupt on the ADC pin connected to the buttons.  Pressing any of the buttons (except for team 2 score) will wake up the device and re-initialize everything.  I ended up using the ATmega48, and when I was done it was 99.7% full on program space, which limited me from implementing a few other features I'd thought up later, but I still got the basic functionality in there.

The PC software to load words is written in Processing.  I tried to make it as simple as possible so that the user just has to click "play" and everything works once their lists are set up.  I have a data folder set up where the user adds all of their category names to a file called "CategoryNames.txt".  They then have to create a text file with the same name and fill it with their word list.  The processing sketch would run on Windows, Linux, or Mac, but the USB-UART chip doesn't support Mac, and I'm the only one I know who uses Linux, so I just gave everyone directions for Windows.  There's some simple error checking that takes care of common problems, but I fully expect to have to do some more troubleshooting once others start using it.  I gave everyone a CD with a user manual, USB drivers, sample word lists, and the wordloader program, so they should have everything they need to customize their AVRphrase.  The default category list was ~2800 words, which left them with plenty of room to add more, and they can always remove the defaults.

I cut the cases using a Dremel drill press, and they're pretty rough, but they work.  The last few I did definitely look better than the first couple.

The game plays pretty much exactly the same as the original Catchphrase, and is a lot of fun for groups of 4-10 people.  The fact that you can create custom categories also adds another fun element (my nephews love the Star Wars category).  I also think it has value as an educational tool, and could be marketed to teachers as something they could put their vocabulary words on and have students play for a fun learning/review game.  Below you can see a brief video of how the game works.  The end product ended up costing ~$30 each.  There are a few things I would have done differently if I were to do this again, but I had a lot of fun with the project and was able to get it finished up by Christmas Eve.

8 comments:

  1. Zach this project turned out great! Its crazy to see how much It changed since school. I assume you already submitted to hackaday, they will love your documentation. Hope you are doing well and your knee is healing up. I am getting pretty close to working prototype for my project and I will let you know when it is working.

    ReplyDelete
  2. Are you willing to share your schematic and board files?

    ReplyDelete
  3. @Scott Gibson -- Sure. I need to fix a couple of mistakes so that you won't have to cut traces and add components like I did. I'll post the schematic/board files sometime next week.

    ReplyDelete
  4. And what about the firmware/source code?

    ReplyDelete
  5. Awesome! I would absolutely love if you could share the whole shebang of data. I've been recently looking into building my own Catchphrase clone, and the guy who did the Arduino-based one has been AWOL since February 2010.

    This is so cool.

    ReplyDelete
  6. I'm definitely willing to share all my design files. I'll go through and clean things up (add comments) first, but keep an eye out for another post next week if you're interested.

    ReplyDelete
  7. Good to see your project on HaD! Looks like you have put together a really polished version of what I saw last spring. Keep it up!

    ReplyDelete
  8. Zach, I like the changes you have made. I am interested in an educational use for AVRphrase because of the freedoms you incorporated. Is there a way to discuss one of your latest designs to test?

    ReplyDelete