openobject.org

Skills/knowledge needed to complete programming project research

From Physical Programming

What skills/ resources do I need: Peggy 2.0 interactive assignment

Whilst researching the use of Peggy boards and interesting things to use them for I also came across a number projects that may be of use for me to look at . Here are the projects:


-Boring old static LED sign. -LED clock with digits. BIG digits. -Scrolling readerboard. -Low-speed oscilloscope. -FFT sound grapher. -Mega MiniPOV -Add a temperature sensor in the prototyping area and make a giant display thermometer. -Add a EEPROM in the prototyping area to store data for a long animation. -Variable color LED panel, fading between different color LEDs in different areas. -14x14 RGB display, clumping three LED locations to form an RGB pixel. -Mega-emoticon display for use in car -Simulated animated neon sign. -Open/closed sign that states your hours, too. -True sprite animation -Simple video games -LED status board. -Blinkylight array for your sci-fi movie computer set.

Any of these would be great but i am still keen on using the peggy as a outboard display for a pc, if possible.

THE PEGGY BOARD:

The peggy board provides efficient power to a 25 x 25 array of LED locations. Peggy was designed to take some of the sting, complexity, and mess out of playing with LEDs. It's a versatile and powerful light-emitting pegboard that lets you efficiently drive hundreds of LEDs in whatever configuration you like, without so much as calculating a single load resistor. You can install anywhere from one to 625 LEDs, and Peggy will light them up for you.

Peggy can optionally be reprogrammed; however to do much more. The comes in two versions: peggy and peggy 2.0 which is the updated model. The biggest change is that the Peggy 2.0 hardware now supports simple animation capability with individually addressable LED locations, which is ideal for the projects we are looking at. Besides the microcontroller, there are now four support chips that help to drive the rows and columns of the display. Now, we're not talking live video feeds or long movies here (speed and memory considerations will spoil that party), but you might be surprised how much you can do with a little AVR microcontroller.

The second improvement has to do with the programming interfaces. As before, Peggy supports programming through a regular AVR ISP (in-system programming) connection, such as the USBtinyISP. However Peggy 2.0 can also be Arduino compatible: it supports programming via use with USB-TTL cable, using the popular Arduino software. (This is the same programming arrangement that you'll find on some of the popular Arduino-compatible boards such as the Boarduino and Bare Bones Boards.) depending on what program i decide to use,

Hardware Needed:

Peggy or Peggy 2.0, functioning, containing a minimum of 25 LED's. (standard structure.) The more the better.

USB-TTL cable or serial port adapter(depending on connection type)

To setup the hardware you must first put it together. It is apparently a simple process; however not followed correctly can destroy the Peggy or cause it not too function Here is the link:http://s3.amazonaws.com/evilmadscience/KitInstrux/peggy2.pdf

Software Needed:

As mentioned earlier depending on what program I decide to go with this will change; however i am leaning towards Arduino due its PC capabilities.

Find or borrow PC with Quartz composer program

Download the QC plugin code from here page.http://planetclegg.com/projects/VideoPeggyMisc.html Following these steps allows you to use the Peggy as a video out put

Download the AVR source code. Includes a sample Python script that sends an animated test pattern.( the basis to build on)

Download the Arduino Software - http://www.arduino.cc/en/Main/Software

Download the latest version of the Peggy2 library - http://code.google.com/p/peggy/

Here is a link to the skills I need for Arduino to be able to successfully use the software for a purpose.http://www.evilmadscientist.com/article.php/PeggyArdLib

evilmadscientist is useful for both Quartz and Arduino.

Programming Peggy 2.0

Here are notes on programming the Peggy 2.0. Your own contributions will be welcome too, of course!

The Big Idea (or, how it works). Peggy 2.0 is a multiplexed matrix display of 25x25 LEDs. That means that we turn on one row at a time, and write to that row which of its LEDs should be on. We then turn that row off, turn on selected LEDs in the next row and repeat, scanning through all 25 rows so quickly that there is no apparent flicker, just a continuous image.

This process is managed by the on-board microcontroller, an ATmega168, a type of AVR microcontroller. The row that is in use is picked by the PORTD I/O ports. Bits D0-D3 and D4-D7, respectively, are 4-bit output ports that go to two 74HC154 4-to-16 demultiplexers. Bits D0-D3 go to the first of these chips and the binary number that is sent, ranging from (decimal) 1 to 15 picks which of the rows 0-14 is powered on. A binary output of zero enables none of the rows. Similarly, bits D4-D7 pick which of rows 15-24 is powered on. Again, a binary output of zero on D4-D7 enables none of the rows.

An "enabled" row has power applied to the high side of each of the LEDs in that row. To determine which of the LEDs is turned on, we use two 16-bit LED driver chips (type STP16DP05) that are connected by a daisy-chained SPI output. Output four bytes on the SPI, of which the last 25 bits control the 25 columns of the LED display. To latch the SPI values in place, issue a brief pulse on pin PB1.

That's a bit of a mouthful, and fortunately, you don't have to do this all yourself, it's written for you. We have several sample applications that demonstrate different ways to run the display, in varying degrees of complexity. We will continue to add additional code examples in the near future.

Video Peggy using TWI (I²C) and Arduino : The no-mods version

Here is an instruction guide I found including the code needed:


"Stock" Peggy 2.0 with Arduino. The protoboard under the AVR was created to make it easy to swap with the serial version; it is a staight passthru and is NOT required. We can rebuild it, we have the technology... Once I had proven low-rez video workable with serial communication, I started looking at those mostly unused SDA/SCL pins on the stock Peggy board. On the Peggy PCB, SCL is unconnected, and SDA is used for the (optional) B5 button, but its a normally open, pull-to-ground button with a 5k or so pullup. So this means those pins can be used for I²C (aka I2C, 2-Wire or TWI) communication without otherwise modifying the board. We can then use some form of Serial-to-I2C translator to connect the Peggy to a PC/Mac, and an Arduino is perfect for this task.

So the basic setup would look something like this:


PC pushes data serially to the Arduino, which in turn pushes the same data to the Peggy via TWI/I2C. Software Theory of Operation (Peggy) The new Peggy firmware for TWI/I2C functions in a similar manner to the serial version. A timer interrupt refreshes the display by sequencing through the rows and sending SPI output to the chips that drive the LEDs. Meanwhile, the main program loop services the TWI registers in a "polled" manner as a TWI slave, receiving TWI data and stuffing it into a frame buffer.

The TWI code contains minimal error handling. It mainly just attempts to continue receiving regardless of any detected bus error conditions. There is no error correction, nor is it really necessary for processing video; it's better to keep moving and cover up any errors on the next frame than to have a complicated procedure for detecting and retransitting errors. In practice, the protocol is very robust and errors are extremely rare anyway.

In addition to replacing the input code, I worked on optimizing the display interrupt, and managed to cut down the amount of CPU time required to refresh the display considerably. At the default refresh rate of 70 frames per second, the display interrupt now only takes roughly 1/3rd of the CPU time, which is almost half as much as it was before. On the input side, 30 frames per second are easily handled, and the code is capable of processing data at almost twice that rate. The code is also a bit smaller; the compiled firmware weighs in at about 1024 bytes.

Software Theory of Operation (Arduino) The Arduino code works as a straightforward converter of serial data coming from the PC to TWI data going to the Peggy. Newer versions of the Arduino IDE (11 and up) come with a TWI library called "Wire". This made writing the conversion code almost trivial. It's simple enough that I'll post the main loop here:


void loop() {

 int count = Serial.available();
 
 if (count > 0)
 {
   // dont send more than 16 bytes at a time
   if (count > 16) count = 16;
 
   Wire.beginTransmission(PEGGY_ADDRESS); 
   while (count-- > 0 )
   {
     uint8_t c = Serial.read(); 
     Wire.send(c);
   }
   Wire.endTransmission();   
 }

} The code attempts to batch as many bytes as it can (up to 16), which is more efficient than writing one byte per transmission.

Some custom low-level code was used to the setup() method to work around some limitations in the Arduino library. Because of this, the Arduino sketch requires an Arduino Diecimila (Atmega168), although it can be made to work on a Atmega8 or '88 based boards with some minor modifications. The low level code reconfigures the clocks set for the Serial and the TWI libraries. The serial UART clock is changed so that it will be more reliable at 115k baud than the configuration that the Arduino library provides. Also, I override and increase the speed of the TWI clock, which is unfortunately hard coded to 100khz in the Wire library.

Quartz Composer -> Serial -> Arduino -> TWI ->Peggy 2.0. Hardware interfacing instructions IMPORTANT: You should install the firmware for both the Peggy and the Arduino before connecting the two devices. The two pins of each device will be wired directly together, and if one of these is set as an output on either of the devices, you'll have a short circuit, and you'll damage one or both of the AVRs. It might be prudent to use some inline 220 ohm resistors between the two, but I personally havent tried this.

The hardware hookup is simple. The Arduino analog 4 and 5 pins are wired to the SDA and SCL pins on the Peggy (i.e. SDA to SDA and SCL to SCL). A third wire is required to connect the ground between the two boards. Pullups enabled in the Peggy firmware and the Arduino code, so you shouldnt need any pullup resistors. The Arduino is connected to the PC/Mac via USB.


Peggy2 Arduino Library

This is a downloadable library of resources needed to be able to program Arduino to use with the peggy2 that may also be useful http://www.evilmadscientist.com/article.php/PeggyArdLib


Here is an instructional guide of how to do the same using QC:

In theory, the change is pretty simple: We want to free up the PD0 and PD1 pins (RxD/TxD), and use some other pins to do the job of driving the 74HC154 that PD0 and PD1 used to do. I chose PC4 and PC5, since one of those is unused by default on the Peggy board, and the other is used to read a button (b5) which I felt like I could live without.


Schematic changes to free up the serial ports. One of my goals was to not make any changes to the Peggy board that weren't easily reversible, so after some thought I came up with the idea to pull the AVR out of it's socket, and replace it with a daughter card. The daughter card has a socket for the AVR and maps all of the pins as before except for the ones I need to exchange. The card plugs into female headers that I soldered into the breakout pads on the Peggy board, along side the original AVR socket. I started to do this with a single sided PCB, when I realized I would need to solder headers from the top and the socket from the bottom (a head slapping moment). I dug around in my parts bin and found a protoboard called the SchmartBoard. Not only does this protoboard have thru-plated holes that can be soldered on either side, but it also has handy traces that run horizontally across the board on .05" centers. It makes soldering a little tricky (the pads are very small; it requires a fine-tipped iron), but it made rerouting the I/O quite simple.


The daughter card plugged into the Peggy2. (slightly incorrect wiring pictured) Bottom view.Software Theory of Operation (AVR) For the purposes of this explanation, the terms "LED" and "pixel" will be used interchangably. One LED on the Peggy board should be thought of as one pixel in a 25 x 25 pixel display.

The Peggy 2.0 allows for individual addressing of LEDs on each row, and by cycling through each row, all of the LEDs can be turned on or off. By using some high-speed strobing, it can be made to display 16 gray levels (actually brightness levels) for each LED. This requires fairly accurate timing to achieve good results.

So, again, the idea is to send data to the Peggy via a serial cable (or serial bluetooth), at a fast enough rate to support animation (or really really low resolution video). As described above, 115k baud serial is just fast enough.

The AVR code is broken into two parts: a serial reciever and a display refresh routine. Both sets of code share a "frame buffer" that is 325 bytes long.

For the serial reciever, the main method contains a loop that simply checks to see if there is a new byte of data from the serial UART, and if there is, it stores this in the frame buffer, and advances the pointer to the frame buffer to the next byte. Very simple.

The code looks for a "magic string" (0xdeadbeef) to mark the begining of a new frame of data. This gives the AVR something to re-sync a new frame with should communication get out of sync. The AVR watches for those four bytes, and when it sees them, it then proceeds to copy the next 325 bytes into a frame buffer. If erroneous data is recieved at the beginning of a frame, it is ignored until the start-of-frame marker is recieved.

The display refresh routine is handled by a high speed timer interrupt that reads data out of the frame buffer and updates a row of pixels on the display. By using a timer interrupt for display refresh, very accurate timing of when the pixels are turned on or off can be achieved.

The timer interrupt is called roughy 25000 times per second, and during each call one row is updated. This actually occurs 16 times per row to give the 16 brightness levels. Therefore at a rate of 25000 interrupts per second, you get 25000 / (25 rows * 13 levels) = 76 full frames per second. The interrupt needs to complete in the time it takes to recieve one byte, or else the serial UART buffer will be overrun. Also, there needs to be enough CPU time left over between interrupts for the serial loop to check the UART buffer for a new byte, and write it to the buffer. As it turns out, at 16mhz, an AVR can handle this with some CPU cycles to spare.

Note that the AVR doesn't care how many frames per second are transmitted, as long as each frame is transmitted at 115k baud. This code is therefore very general purpose, it can be used to update a static display at a much slower rate. If the serial transmission stops, it will simply display whatever was copied into the buffer last.

At slower transmission speeds, it would probably be necessary to double (or triple) buffer in order to avoid a "shearing effect". When the display routine starts drawing one frame, it will eventually catch up and pass the last received byte of serial data and start to display part of the previous frame. My prototype doesnt bother with this, at 115k baud, this effect is mostly unnoticable to the naked eye. (This is not the same as the strobing horizontal bar effect that you might notice in the video. That is caused by lack of synchronization with the camera I was using, a similar effect to what one would get trying to video tape a TV set.)

Take a break! Web Cam -> Quartz Composer -> Serial -> Peggy 2.0. Software Theory of Operation (transmitting computer) Since I've been using Mac's for the past year or so, my options were fairly wide open as far as how to transmit data to the AVR. For testing purposes, I created a quick Python app that used pySerial to send test pattern data to the AVR, just to test that everything was functioning properly.

I decided that the most flexible thing I could do for transmitting "video", and the like, was to create a Quartz Composer plugin. If you are not familar with Quartz Composer, it's a nifty application/framework for OS X that allows for graphics programming using a graphical nodal interface. QC "Patches" are wired together to make complex scenes. It's a very powerful tool, well integrated into the OS, but sort of hard to describe. You can get a better description from here or here. Windell has a great tutorial for it. But until you play around with it, it's hard to appreciate what can be done with it.

The QC plugin I wrote does little more than take and image as input and send a 25 x 25 pixel region to the serial port using the format described above. Writing this plugin turned out to be easier than I thought it would, Apple had sample code for both serial communications and QC plugins, and it was mainly an exercise in mashing the two samples together.

The only mildly difficult part, as an Objective-C neophyte, was figuring out how to access the image data at a pixel level. Quartz Composer uses opaque image types that can be cached in the video memory, which means that it must be transformed into another form in order to "read the individual pixels". Rendering the image into a CGContext allowed me to iterate through each pixel, converting it to 16 levels using something resembling the following pseudo code:

byte b = ( ((redEven + grnEven + blueEven) / 3) & 0xf0) |

          ((redOdd + grnOdd + blueOdd) / 3) >>4;

The red/grn/blue Even and Odd values represent pixels in either even or odd horizontal positions. A color average is a very poor way to convert to monochrome; it's a good idea to put a "Color Monochrome" patch in the QC pipeline for color sources.

Once I wrote the QC plugin, composing "scenes" in QC was rather easy. The screen grab below shows a composition that will play a movie file to both the Peggy and the Quartz Composer viewer.


A simple Quartz Composition to display a movie on the Peggy2. In the snippet above, you'll notice a Image crop and Image resize patch. Serial-to-Peggy patch only examines the top corner (25x25 pixels) an images, so these are used to crop and resize the input down to the appropriate size. By stringing these together, it's easy to send a movie, animated moving text, or even web cam input to the Peggy board. The demonstration videos show the results. All videos of the results can be reviewed here:

http://planetclegg.com/projects/QC-Peggy.html

the QC plugin code is available here:

http://planetclegg.com/projects/VideoPeggyMisc.html

An image of the simple QC video code can be found here

http://planetclegg.com/projects/VideoPeggyMisc.html

As it seems Arduino seems to be the logical choice because Peggy 2.0 supports theprogram with no modification required un like QC. For the beginner i think this is a wise choice; and with the added bonus of being able to use the program on PC for which i am more familiar with using it seems like a no brainer which path i may decide to take.