Taipan! on the Arduino. Part 3.

June 19th, 2012

Right, another update. I now have my display Arduino working nicely and my command structure worked out. I have started changing the serial print statement on the main game board into my special commands to send to the display unit to send to the LCD. It took a lot of fiddling to come up with a command structure that worked as well as some tricky balancing of resources to get things to work reliably. And I am still not sure I won’t run out of memory!

If you just want to see the films on YouTube of the progress so far you can go here (a test of the display module)  and here (the game running).

First the commands. Commands are sent from one Arduino to the other (one direction only – main board to display)  via the serial port. To improve the reliability somewhat I added in some flow control. The display unit sets a digital pin high when it is busy so the main unit knows not to send it more commands.

Commands are sent as strings between the two units. Each string can be up to 126 bytes long. Why 126? Well, that’s the maximum size of the serial receive buffer on the display unit. This is the maximum size I could have before running out of memory. Each command consists of a two letter identifier and then a value. The command/value pair is enclosed in braces and the whole command string is terminated by a special character. I use a ^ as the terminator.

The receiving side will fill it’s serial buffer until it receives a terminator (the ^ character) or the buffer is full. Once this happens it sets the busy flag to stop the other side sending data and processes what it has.

If the buffer was full and only a half command was received that partial command is dropped before the rest of the commands are processed.

A simple command to clear the screen sent from the main unit looks like this:

[cs 0]^

The receiving side sees the [ and knows the following two characters (cs – Clear Screen) are the command. It then takes the next characters as the value for the command. All commands need a value but those that don’t actually use the value will ignore it. I just use 0 as a place holder. Since it knows the command it will know how to process the value (i.e. as a number or as a string).

Commands can be sent chained in one command string such as:

[cs 0] [bx 0] [by 0] [bt 0]^

That command clears the screen, sets the bitmap x position to 0 and the bitmap y position to 0 then draws bitmap 0. The display unit knows bitmap 0 is the Taipan splash screen so it draws that.

Strings are sent as a simple command also:

[pr Taipan, do you wish me to go to\n]^

In the main game I have wrapper functions so I can pull a string direct from the flash memory via the table and send it to the display:

SendCommand(“[cx 0] [cy 50] [cp 0]^”);
SendCommand( GetStringFromTable(33) ); // Comprador’s Report

My GetStringFromTable function gets the strings from the flash memory and wraps them in the appropriate command structure to be sent to the display.

Interestingly calling that line uses less memory than calling Serial.print() with the same string.

Memory is my biggest problem.  The display unit code uses up 15,282 bytes of 32,256 but it only has 109 bytes of free SRAM. The main unit is using up 29,964 bytes of a 30,720 bytes. Now it is interesting that each board has a different amount of memory available and I only just realised this is the case.  The display is currently running on an Arduino Uno and the main board is a Duemilanove but I am not sure why there is that 2k or so difference in available memory. Something to do with the different bootloaders I think.

Something to investigate!

(5 minutes later…)

Well, I couldn’t leave that unexplored so I swapped the boards over. The Duemilanove  running the display works fine. However trying to upload the main code to the Uno results in the following error:

avrdude: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64
avrdude: stk500_cmd(): programmer is out of sync

Not sure why but there seems to be talk out there about it so I am sure I can get to the bottom of it eventually. Apparently there is some bootloader issue. That extra 2k of memory would be nice!

Often these weird errors can be very hard to track down. Another good example is the following:

Exception in thread “Thread-19358” java.lang.StackOverflowError
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
at java.util.regex.Pattern$Branch.match(Pattern.java:4114)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)
at java.util.regex.Pattern$Loop.match(Pattern.java:4295)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
(and on and on and on…)

That one isn’t even a compile error, that’s the compiler blowing up! And it turns out it is caused by this line:

prog_char string042[] PROGMEM = “Very well. Elder Brother Wu will””\n;

Note the double quotes at the end. Very hard to find without a useful error and when you have 255 lines of code similar to that without the error!

But progress is being made. I have made two small films using my phone (forgive the crappy quality) showing the progress so far. When I am eventually done I will release the code. Not that I expect anyone else to actually make this but just for the sake of interest.

Update: Turns out the Uno problem is a bug in it’s bootloader as explained here: http://forum.freetronics.com/viewtopic.php?t=338&p=1959

There is a zip file to download there. There is no documentation of course just the firmware, an exe and a batch file. Seems you might need to use another Arduino (not an Uno) to act as a programmer to reprogram the bootloader on the Uno apparently. I am not sure you can do it via the IDE directly. Is nothing simple!?

I think this explains it all better here: https://www.sparkfun.com/tutorials/247

Job for tomorrow.

I have added two little YouTube films of progress so far. The first is a test of the display module. The second show the game running to as far as I have got so far.

Update (tomorrow):  OK, today I worked out what you need to do to upload the working bootloader to the Uno. The easiest way by far, if you have two Arduinos, is to go here and download the files then follow the instructions to use one Arduino as a programmer to upload the fixed bootloader to the other. No PC is needed, just two Arduinos connected via 4 pins (well 6 including power). Using this method you don’t need a PC involved at all.

That did the trick and now my Eleven works and I have several kB more memory free.


Comments are closed.