Big LED Screen

From Noisebridge
(Difference between revisions)
Jump to: navigation, search
(Daughterboards)
m (nburl)
 
(22 intermediate revisions by 11 users not shown)
Line 4: Line 4:
  
 
* Dimensions (in pixels) are 128 by 48
 
* Dimensions (in pixels) are 128 by 48
* Originally controlled by a 386; mobo is shot.
 
* The 386 connects via ISA to a "buffer board" which looks to be a memory buffer and power conditioner.
 
 
* The buffer board stores data into a couple memory chips, which are then accessible to the daughterboards which drive the actual LEDs.
 
* The buffer board stores data into a couple memory chips, which are then accessible to the daughterboards which drive the actual LEDs.
 
* There are four daughterboards, in two chains of length two.  Each of these daughterboards is connected to a single "section" of LEDs (ie: there are four big "sections" of LEDs).  Each daughterboard runs a section of 32 by 48 pixels.
 
* There are four daughterboards, in two chains of length two.  Each of these daughterboards is connected to a single "section" of LEDs (ie: there are four big "sections" of LEDs).  Each daughterboard runs a section of 32 by 48 pixels.
  
As of 2009-01-28 I am potentially leaving things connected inside it as I work on it.  If you want to work on it, please make sure you either check with me or disconnect the things I added before turning it on.  Thanks!  --[[User:Shkoo|Shkoo]] 10:04, 28 January 2009 (PST)
+
=== History ===
  
=== Motherboard ===
+
* Originally controlled by a 386; mobo is shot.
 
+
* The 386 connects via ISA to a "buffer board" which looks to be a memory buffer and power conditioner.
BoringBroken.  Did I mention boring?
+
* The "buffer board" has most traces terminating to a socket with a missing chip, so we don't know what happened here.
 
+
   
=== Buffer board ===
+
==== Buffer board ====
  
Tonight (2008-12-30) I worked from the backend up a bit, but eventually gave up.  I then moved to the ISA frontside and worked down, which was far more productive.
+
Tonight (2008-12-30) Josh worked from the backend up a bit, but eventually gave up.  He then moved to the ISA frontside and worked down, which was far more productive.
  
The device appears to sit at ISA IO ports 0x180 through 0x183.  The addresses are decoded by U51 (74688 comparator), which then hits the OE2 on U52-19 (74541 driver iirc).  This is then used to feed U53 and U54 (both 74574 D-flip-flops).  These appear to be there to combat fan-out.  I'm not entirely certain where these go, but it seemed like they were going into the RAMs.
+
The device appears to sit at ISA IO ports 0x180 through 0x183.  The addresses are decoded by U51 (74688 comparator), which then hits the OE2 on U52-19 (74541 driver iirc).  This is then used to feed U53 and U54 (both 74574 D-flip-flops).  These appear to be there to combat fan-out.  He's not entirely certain where these go, but it seemed like they were going into the RAMs.
  
 
The low bits of the ISA address selection sit on the rightmost two pins on the top row of the header, SA1 and SA0, in that order (Just hook the connector up and use the multimeter if that's nonsensical).  I haven't traced them through yet; I was in the middle of it when my time ran out.  They look to run over to the empty chip socket on the right side of the board.  Most traces tend to terminate at this chip socket, so most likely we won't be able to use the display logic on the buffer board.
 
The low bits of the ISA address selection sit on the rightmost two pins on the top row of the header, SA1 and SA0, in that order (Just hook the connector up and use the multimeter if that's nonsensical).  I haven't traced them through yet; I was in the middle of it when my time ran out.  They look to run over to the empty chip socket on the right side of the board.  Most traces tend to terminate at this chip socket, so most likely we won't be able to use the display logic on the buffer board.
  
=== Daughterboards ===
+
==== Daughterboards ====
 +
 
 +
[http://www.flickr.com/photos/31848713@N00/3430719610/ Picture of a daughterboard]
  
 
The daughterboards each have qty 3 UCN5832A ([[Image:Ucn5832.pdf]]) 32-bit shift registers (for a total of 96 bits) which drive an array of 32 by 48 pixels (for a total of 1536).  The theory is the other end of the LEDs are connected to 16 different power sources, making all the LEDs addressable (96 * 16 = 1536).  (The shift register does a current sink)
 
The daughterboards each have qty 3 UCN5832A ([[Image:Ucn5832.pdf]]) 32-bit shift registers (for a total of 96 bits) which drive an array of 32 by 48 pixels (for a total of 1536).  The theory is the other end of the LEDs are connected to 16 different power sources, making all the LEDs addressable (96 * 16 = 1536).  (The shift register does a current sink)
Line 43: Line 43:
  
 
Per Josh, the grounds do not need to be connected for now.
 
Per Josh, the grounds do not need to be connected for now.
 
If anyone can make additional cables and pcb-mountable headers show up that are compatible with the daughterboard cables, that would be useful.
 
  
 
The serial is daisy chained together.  There are two sets of two daughterboards (four daughterboards total) with 3 shift registers on each daughterboard.  So, each chain of shift registers includes 6 shift registers for a total of 192 bits per chain.
 
The serial is daisy chained together.  There are two sets of two daughterboards (four daughterboards total) with 3 shift registers on each daughterboard.  So, each chain of shift registers includes 6 shift registers for a total of 192 bits per chain.
 +
 +
* The 10-pin ports between the daughterboards (J3 and J2) are wired differently.  J3 is:
 +
  1 -
 +
  2 -
 +
  3 -
 +
  4 -
 +
  5 - ground
 +
  6 -
 +
  7 - clock
 +
  8 -
 +
  9 - serial out (j2) / serial in (j3)
 +
  10 -
  
 
(The existing logic shifts out 200 bits instead of 192; we don't know why).
 
(The existing logic shifts out 200 bits instead of 192; we don't know why).
Line 56: Line 66:
 
The shift register is rated for 3.3Mhz, so we could conceivably drive it faster than the 1.5Mhz that it's currently running.
 
The shift register is rated for 3.3Mhz, so we could conceivably drive it faster than the 1.5Mhz that it's currently running.
  
== Plan of Nils ==
+
== Current Operation ==
 +
 
 +
=== Overview ===
 +
 
 +
[http://www.flickr.com/photos/31848713@N00/3430728760/in/photostream/ Overview of the inside of the screen (picture)]
 +
 
 +
[http://www.flickr.com/photos/31848713@N00/3429916211/in/photostream/ Detail of our breadboard (picture)]
 +
 
 +
==== LED Hardware ====
 +
 
 +
The sign is currently driven by two boarduinos on a solderless breadboard.  One controls the left half of the sign, and the other controls the right half.
 +
 
 +
The old hardware buffer board has 16 power sources that it cycles through in sequence.  It goes through each cycle of 16 power sources at about 500 Hz.  (So it changes power sources every 1/8000th of a second).
 +
 
 +
Each boarduino shifts bits out along a serial line controlling 192 shift registers.  These shift registers act as controllable current-limited drains.
 +
 
 +
The LEDs on the display have their anodes connected to the power sources.  Each anode is shared by 192 LEDs.
 +
 
 +
The LEDs on the display have their cathodes connected to the shift registers.  Each shift register pin is shared by 16 LEDs.
 +
 
 +
This gives us 3072 LEDs per half of the display, which are arranged into an array 64 LEDs wide by 48 LEDs tall.
 +
 
 +
The boarduinos have connections to the preexisting circuitry to tell which power source is in use at any time, and send the respective data to the shift registers for display.
 +
 
 +
We also have an xbee series 1 (802.15.4) wireless chip onboard so we don't have to open up the sign to talk to it.
 +
 
 +
==== Software ====
 +
 
 +
Though we are using arduino compatible hardware, we are using AVR-GCC to compile native code directly for the atmel mega168 chip on the boarduino.  The arduino framework does not perform well enough nor allow us good access to the atmega168 integrated chip features such as SPI and TWI.
 +
 
 +
We are using lady ada's arduino bootloader.  This acts like an atmel stk500 programmer, and allows us to upload software over the wireless connection.
 +
 
 +
The XBEE wireless chip has virtual transparenet pins configured so we can control the reset pins of the two boarduinos independently, and upload new code to each half of the sign at a time.
 +
 
 +
The two halves talk to each other using the TWI interface on the atmega168.
 +
 
 +
=== Pin connections ===
 +
 
 +
[[Image:ledscreen-schematic.png|500px]]
 +
 
 +
Here are the pins that need to be connected other than power and ground:
 +
 
 +
* MOSI (PB3) - this sends serial data to the daughterboard
 +
* SCK (PB5) - this sends lcock signal to the daughterboard
 +
* PB1 - this should be connected to the latch/strobe signal from the old buffer board
 +
* PB0 - this should be connected to the latch/strobe signal going to the daughterboard
 +
* PD7 - this should be hooked up to the left side of one of the power sources on the buffer board through a voltage divider (and small capacitor to stabilize the signal) to bring the 15 volts down to 5 volts.  Do not use the output of the power source, since it's not nearly as stable.
 +
 
 +
It uses the existing STROBE (latch) signal from the buffer board for timing, and reads the state of one of the buffer board's output powers to synchronize where in the sequence of 16 power sources.  It captures the latch signal and re-emits it to the daughterboard.
 +
 
 +
It ignores the serial clock and serial data from the buffer board.
 +
 
 +
Unfortunately this has very little processor time to spare since it's spending all its time clocking out the serial data.  We're probably limited to very basic patterns on here.
 +
 
 +
== Usage ==
 +
 
 +
=== Getting the source ===
 +
 
 +
The source is in a mercurial repository on [[pony]].  Point your mercurial client at http://pony.local/d3/nils/bigledscreen to pull down a copy of it.
 +
 
 +
=== Programming the xbee ===
 +
 
 +
To control the sign wirelessly, you will want to program an xbee chip to interface with it.  I recommend the "xbee explorer" from sparkfun.  To program your new xbee, you will need to make sure your xbee has a recent enough firmware (10A5 is recommended).  Unfortunately firmware upgrade must be done using Digi/MaxStream's "X-CTU" application which runs under windows.  This can be performed with wine and linux.  See [http://paparazzi.enac.fr/wiki/XBee_configuration paparazzi's]xbee config page and [http://www.libelium.com/squidbee/upload/3/31/Data-sheet-max-stream.pdf digi's xbee AT command set] for information about using x-ctu or minicom with your xbee.
 +
 
 +
The Xbee on the computer side needs to have a small hardware modification to work: pins AD0 and AD1 need to be shorted, and pins AD2 and AD3 need to be shorted.  This is because the xbee connected to your computer toggles pins 0 and 2 to control the state of pins 1 and 3, and pins 1 and 3 are mirrored by the xbee connected to the sign.  If you use a stock xbee, you'll still be able to talk to the sign with it but you won't be able to flash new firmware.
 +
 
 +
Once you have your xbee connected to your computer, you can use xbee-pgm.pl to set it up to talk to the sign such as the following:
 +
 
 +
  ./xbee-pgm.pl /dev/cu.usbserial.A12345 program-computer-side
 +
 
 +
where /dev/cu.usbserial.A12345 is the serial port for your xbee.
 +
 
 +
If your xbee was configured to use the original 9600 baud rate, you will need to run this twice to actually write the new baud rate to flash.  Your xbee will now talk at 19200 baud, and is now configured to talk to the sign.
 +
 
 +
=== Uploading new sign code ===
 +
 
 +
To compile new sign code, simply "make" in the bigledscreen directory.  This will produce a "ledlife.hex" file that you can upload to the sign.  If you are unfamiliar with AVR programming and avrdude, you should go through one of the tutorials on the internet first.  This is not a good first project.
 +
 
 +
To upload new sign code, you must upload to each half of the sign separately.  First, activate the reset pins on both halves of the sign:
 +
 
 +
  ./xbee-pgm.pl /dev/cu.usbserial.A12345 all-high
 +
 
 +
Now, release the reset pin on half of the sign.  This allows the left half of the sign to boot up:
 +
 
 +
  ./xbee-pgm.pl /dev/cu.usbserial.A12345 3-high
 +
 
 +
The atmega168 will now start the Lady Ada's bootloader, which acts just like a stk500.
 +
 
 +
Immediately, start your "avrdude" to upload code.  If you do not do this fast enough, you will need to toggle the reset pin again.
 +
 
 +
  avrdude -F -b 19200 -c stk500v1 -p m168 -P /dev/cu.usbserial-A12345 -e -U flash:w:ledlife.hex
 +
 
 +
Sometimes this will fail.  If it fails repeatedly, reposition your xbee closer to the sign, or reorient it, and try again.
 +
 
 +
Once this half is done, you can upload the right half:
 +
 
 +
  ./xbee-pgm.pl /dev/cu.usbserial.A12345 1-high
 +
  avrdude -F -b 19200 -c stk500v1 -p m168 -P /dev/cu.usbserial-A12345 -e -U flash:w:ledlife.hex
 +
 
 +
Then you can release the reset pin on the left half so it can boot up, and both halves can run:
 +
 
 +
  ./xbee-pgm.pl /dev/cu.usbserial.A12345 all-low
 +
 
 +
=== Controlling a running sign ===
  
=== Short Term ===
+
You can use the "sendcmd.pl" script to send bytes to the sign.  The usage is similar to xbee-pgm.pl:
  
Hook up arduino to drive one of the chains (two daughterboards, half of the sign).
+
  ./sendcmd.pl <serial port> <byte code>
  
Use existing STROBE (latch) signal from the buffer board for timing.  I'm assuming the STROBE signal indicates when the power shifts to the next of the 16 power drivers.
+
<byte code> is the decimal value of the byte to send.  You should not send bytes too fast, and sometimes bytes get missed.  Hopefully this will change in the future.
  
Ignore serial clock and serial data from buffer board; instead, generate it directly from the arduino.  This is possible using the USART on the atmega168 chip.  I'll use avrgcc instead of the arduino framework, since the arduino framework won't work fast enough to do this.
+
You can address one or both of the halves by sending one of the following values:
  
The USART on the atmega168 will run in SPI mode, generating both a serial clock and unframed serial data.
+
  0 - address left
 +
  1 - address right
 +
  2 - address both
  
Possibly we can connect another pin on the arduino to one of the 16 power driving wires, and run it in input mode.  This will allow us to synchronize to the power driving sequence.
+
If you want to send a data value from 0 to 3 (inclusive) and don't want to address a screen, you can first send a "3", which indicates that the next byte should be treated as a data byte instead of an address byte.
  
Then we can drive a test pattern of some sort to try to figure out how the shift registers and power driving channels map to LEDs, assuming they actually do. :)
+
Immediately after you address a screen, you send a command:
  
=== Long Term ===
+
  64 - Turn on life, and randomly occasionally reset
 +
  65 - Turn on life without the periodic random reset
 +
  66 - Run test pattern
 +
  67 - Act as single-buffered framebuffer
 +
  68 - Act as double-buffered framebuffer
 +
 
 +
  70 - clear framebuffer, home cursor
 +
  71 - set x coordinate of cursor
 +
  72 - set y coordinate of cursor
 +
  73 - for double-buffered framebuffer, swap front and back buffers
 +
  74 - for double-buffered framebuffer, do a single round of life and swap front and back buffers
  
Get an atmel xmega based solutionIt has 4 UARTs that we can use 3 of as following:
+
When setting an x or y coordinate of the cursor, follow the command with the cursor position added to 128The cursor is 8 pixels wide horozontally and 1 pixel tall.  Valid values for setting the X cursor coordinate are 128 through 135.  Valid values for setting the Y cursor coordinate are 128 through 175.
  
* Drive daughter board 1
+
After you have issued attention and a command, any further bytes you send will be placed on the screen at the cursor, and then the cursor will go to the next 8 pixels.  It scans in the standard left-to-right, top-to-bottom order.
* Drive daughter board 2
+
* Drive XBEE wireless chip for communication with the outside world so we don't have to deal with running wires through the case
+
  
The xmega does DMA to its UARTs so we don't have to waste quite so much CPU time copying bytes out.
+
An example script, "gliders.sh", will place a bunch of gliders on the display.  (You may need to change the "port" variable to match your local serial port).  Note that it has several times where it stops and asks you if everything is ok; use ctrl-c to abort if any bytes got missed in transit, and then start over.
  
Unfortunately none of the atmel xmega series have DIP packages, so it's a bit tougher to breadboard them.  TQFP 100 seems like the way to go.
+
For further information, UTSL.
  
If anyone wants to mess around with etching a pcb to support this solution (assuming tests on the short term solution go well), let me know.  Otherwise I'll send it off to batchpcb, but that takes a few weeks.  -[[User:Shkoo|nils]]
+
[[Category:Pages with a Noisebridge Tiny URL]]

Latest revision as of 04:05, 7 August 2012

Contents

[edit] The Big LED Screen

[edit] Overview

  • Dimensions (in pixels) are 128 by 48
  • The buffer board stores data into a couple memory chips, which are then accessible to the daughterboards which drive the actual LEDs.
  • There are four daughterboards, in two chains of length two. Each of these daughterboards is connected to a single "section" of LEDs (ie: there are four big "sections" of LEDs). Each daughterboard runs a section of 32 by 48 pixels.

[edit] History

  • Originally controlled by a 386; mobo is shot.
  • The 386 connects via ISA to a "buffer board" which looks to be a memory buffer and power conditioner.
  • The "buffer board" has most traces terminating to a socket with a missing chip, so we don't know what happened here.

[edit] Buffer board

Tonight (2008-12-30) Josh worked from the backend up a bit, but eventually gave up. He then moved to the ISA frontside and worked down, which was far more productive.

The device appears to sit at ISA IO ports 0x180 through 0x183. The addresses are decoded by U51 (74688 comparator), which then hits the OE2 on U52-19 (74541 driver iirc). This is then used to feed U53 and U54 (both 74574 D-flip-flops). These appear to be there to combat fan-out. He's not entirely certain where these go, but it seemed like they were going into the RAMs.

The low bits of the ISA address selection sit on the rightmost two pins on the top row of the header, SA1 and SA0, in that order (Just hook the connector up and use the multimeter if that's nonsensical). I haven't traced them through yet; I was in the middle of it when my time ran out. They look to run over to the empty chip socket on the right side of the board. Most traces tend to terminate at this chip socket, so most likely we won't be able to use the display logic on the buffer board.

[edit] Daughterboards

Picture of a daughterboard

The daughterboards each have qty 3 UCN5832A (File:Ucn5832.pdf) 32-bit shift registers (for a total of 96 bits) which drive an array of 32 by 48 pixels (for a total of 1536). The theory is the other end of the LEDs are connected to 16 different power sources, making all the LEDs addressable (96 * 16 = 1536). (The shift register does a current sink)

The daughterboards receive serial based on the following:

  • The long 10-pin pigtails are as follows:
 1 - UCN-40   CLK (serial clock)
 2 - GND
 3 - UCN-4    STROBE (latch driver)
 4 - GND
 5 - UCN-2    SIN (serial in)
 6 - GND
 7 - UCN-3    GND
 8 - GND
 9 - GND

Pin 1 is marked red. When looking into the end of the connector, when the red-marked wire is on the left, odd pins are on top. The keyed edge of the connector is also on top. The top left pin is pin 1.

Per Josh, the grounds do not need to be connected for now.

The serial is daisy chained together. There are two sets of two daughterboards (four daughterboards total) with 3 shift registers on each daughterboard. So, each chain of shift registers includes 6 shift registers for a total of 192 bits per chain.

  • The 10-pin ports between the daughterboards (J3 and J2) are wired differently. J3 is:
 1 -
 2 -
 3 -
 4 -
 5 - ground
 6 -
 7 - clock
 8 -
 9 - serial out (j2) / serial in (j3)
 10 -

(The existing logic shifts out 200 bits instead of 192; we don't know why).

Looking at the sign doing STROBE: sequences 130us apart, within each sequence, 5 peaks @+5V, 4us each high, otherwise the signal is low.

Looking at CLK: We do a bunch of lcokign, the strobe, etc. 8 CLKs in 5us, entire process takes 125us, appx 200CLKs. This gives an input rate of 1.6MHz(!)

The shift register is rated for 3.3Mhz, so we could conceivably drive it faster than the 1.5Mhz that it's currently running.

[edit] Current Operation

[edit] Overview

Overview of the inside of the screen (picture)

Detail of our breadboard (picture)

[edit] LED Hardware

The sign is currently driven by two boarduinos on a solderless breadboard. One controls the left half of the sign, and the other controls the right half.

The old hardware buffer board has 16 power sources that it cycles through in sequence. It goes through each cycle of 16 power sources at about 500 Hz. (So it changes power sources every 1/8000th of a second).

Each boarduino shifts bits out along a serial line controlling 192 shift registers. These shift registers act as controllable current-limited drains.

The LEDs on the display have their anodes connected to the power sources. Each anode is shared by 192 LEDs.

The LEDs on the display have their cathodes connected to the shift registers. Each shift register pin is shared by 16 LEDs.

This gives us 3072 LEDs per half of the display, which are arranged into an array 64 LEDs wide by 48 LEDs tall.

The boarduinos have connections to the preexisting circuitry to tell which power source is in use at any time, and send the respective data to the shift registers for display.

We also have an xbee series 1 (802.15.4) wireless chip onboard so we don't have to open up the sign to talk to it.

[edit] Software

Though we are using arduino compatible hardware, we are using AVR-GCC to compile native code directly for the atmel mega168 chip on the boarduino. The arduino framework does not perform well enough nor allow us good access to the atmega168 integrated chip features such as SPI and TWI.

We are using lady ada's arduino bootloader. This acts like an atmel stk500 programmer, and allows us to upload software over the wireless connection.

The XBEE wireless chip has virtual transparenet pins configured so we can control the reset pins of the two boarduinos independently, and upload new code to each half of the sign at a time.

The two halves talk to each other using the TWI interface on the atmega168.

[edit] Pin connections

Ledscreen-schematic.png

Here are the pins that need to be connected other than power and ground:

  • MOSI (PB3) - this sends serial data to the daughterboard
  • SCK (PB5) - this sends lcock signal to the daughterboard
  • PB1 - this should be connected to the latch/strobe signal from the old buffer board
  • PB0 - this should be connected to the latch/strobe signal going to the daughterboard
  • PD7 - this should be hooked up to the left side of one of the power sources on the buffer board through a voltage divider (and small capacitor to stabilize the signal) to bring the 15 volts down to 5 volts. Do not use the output of the power source, since it's not nearly as stable.

It uses the existing STROBE (latch) signal from the buffer board for timing, and reads the state of one of the buffer board's output powers to synchronize where in the sequence of 16 power sources. It captures the latch signal and re-emits it to the daughterboard.

It ignores the serial clock and serial data from the buffer board.

Unfortunately this has very little processor time to spare since it's spending all its time clocking out the serial data. We're probably limited to very basic patterns on here.

[edit] Usage

[edit] Getting the source

The source is in a mercurial repository on pony. Point your mercurial client at http://pony.local/d3/nils/bigledscreen to pull down a copy of it.

[edit] Programming the xbee

To control the sign wirelessly, you will want to program an xbee chip to interface with it. I recommend the "xbee explorer" from sparkfun. To program your new xbee, you will need to make sure your xbee has a recent enough firmware (10A5 is recommended). Unfortunately firmware upgrade must be done using Digi/MaxStream's "X-CTU" application which runs under windows. This can be performed with wine and linux. See paparazzi'sxbee config page and digi's xbee AT command set for information about using x-ctu or minicom with your xbee.

The Xbee on the computer side needs to have a small hardware modification to work: pins AD0 and AD1 need to be shorted, and pins AD2 and AD3 need to be shorted. This is because the xbee connected to your computer toggles pins 0 and 2 to control the state of pins 1 and 3, and pins 1 and 3 are mirrored by the xbee connected to the sign. If you use a stock xbee, you'll still be able to talk to the sign with it but you won't be able to flash new firmware.

Once you have your xbee connected to your computer, you can use xbee-pgm.pl to set it up to talk to the sign such as the following:

 ./xbee-pgm.pl /dev/cu.usbserial.A12345 program-computer-side

where /dev/cu.usbserial.A12345 is the serial port for your xbee.

If your xbee was configured to use the original 9600 baud rate, you will need to run this twice to actually write the new baud rate to flash. Your xbee will now talk at 19200 baud, and is now configured to talk to the sign.

[edit] Uploading new sign code

To compile new sign code, simply "make" in the bigledscreen directory. This will produce a "ledlife.hex" file that you can upload to the sign. If you are unfamiliar with AVR programming and avrdude, you should go through one of the tutorials on the internet first. This is not a good first project.

To upload new sign code, you must upload to each half of the sign separately. First, activate the reset pins on both halves of the sign:

 ./xbee-pgm.pl /dev/cu.usbserial.A12345 all-high

Now, release the reset pin on half of the sign. This allows the left half of the sign to boot up:

 ./xbee-pgm.pl /dev/cu.usbserial.A12345 3-high

The atmega168 will now start the Lady Ada's bootloader, which acts just like a stk500.

Immediately, start your "avrdude" to upload code. If you do not do this fast enough, you will need to toggle the reset pin again.

 avrdude -F -b 19200 -c stk500v1 -p m168 -P /dev/cu.usbserial-A12345 -e -U flash:w:ledlife.hex

Sometimes this will fail. If it fails repeatedly, reposition your xbee closer to the sign, or reorient it, and try again.

Once this half is done, you can upload the right half:

 ./xbee-pgm.pl /dev/cu.usbserial.A12345 1-high
 avrdude -F -b 19200 -c stk500v1 -p m168 -P /dev/cu.usbserial-A12345 -e -U flash:w:ledlife.hex

Then you can release the reset pin on the left half so it can boot up, and both halves can run:

 ./xbee-pgm.pl /dev/cu.usbserial.A12345 all-low

[edit] Controlling a running sign

You can use the "sendcmd.pl" script to send bytes to the sign. The usage is similar to xbee-pgm.pl:

 ./sendcmd.pl <serial port> <byte code>

<byte code> is the decimal value of the byte to send. You should not send bytes too fast, and sometimes bytes get missed. Hopefully this will change in the future.

You can address one or both of the halves by sending one of the following values:

 0 - address left
 1 - address right
 2 - address both

If you want to send a data value from 0 to 3 (inclusive) and don't want to address a screen, you can first send a "3", which indicates that the next byte should be treated as a data byte instead of an address byte.

Immediately after you address a screen, you send a command:

 64 - Turn on life, and randomly occasionally reset
 65 - Turn on life without the periodic random reset
 66 - Run test pattern
 67 - Act as single-buffered framebuffer
 68 - Act as double-buffered framebuffer
 
 70 - clear framebuffer, home cursor
 71 - set x coordinate of cursor
 72 - set y coordinate of cursor
 73 - for double-buffered framebuffer, swap front and back buffers
 74 - for double-buffered framebuffer, do a single round of life and swap front and back buffers

When setting an x or y coordinate of the cursor, follow the command with the cursor position added to 128. The cursor is 8 pixels wide horozontally and 1 pixel tall. Valid values for setting the X cursor coordinate are 128 through 135. Valid values for setting the Y cursor coordinate are 128 through 175.

After you have issued attention and a command, any further bytes you send will be placed on the screen at the cursor, and then the cursor will go to the next 8 pixels. It scans in the standard left-to-right, top-to-bottom order.

An example script, "gliders.sh", will place a bunch of gliders on the display. (You may need to change the "port" variable to match your local serial port). Note that it has several times where it stops and asks you if everything is ok; use ctrl-c to abort if any bytes got missed in transit, and then start over.

For further information, UTSL.

Personal tools