24
Apr 10

Apple //t

twitter2In the summer of 1980 my family took a trip to the East Coast, and we flew American Airlines. It was my first time on an airplane and I remember being very excited. I had good cause to be excited – I was about to have the entire course of my life impacted, but didn’t know it yet.

I was reading the in-flight magazine and came across something that boggled my young mind. It was a full-page advertisement for a computer – a personal computer that you could buy and use yourself. I must have sat there and stared at that page for 15 minutes studying the picture of this thing called a “personal computer”. I tore the ad out and carried it around with me for the rest of the trip. It took about a year of bugging my parents but they eventually bought me an Apple II with 16K of RAM.

These were my formative years and I learned that machine inside and out, making indelible memories that last to this day. I met Steve Wozniak at a book signing recently and told him I was surprised to find that nobody had yet grabbed the license plate “LDA C030” for their vehicle. [Blank stare from Woz] “You know, L..D..A..” I repeated myself more slowly and loudly, the way you might to someone who doesn’t speak Engligh in the hopes of being understood and with similar results. He had no idea what the hell I was talking about. And why should he? The obscure 6502 machine language command to make the Apple II speaker click would never have anywhere near the meaning to him as it did me. To me it was my fundamental introduction to making electronic music, whereas to him it was simply a feature he stuck in a product he built decades ago. His brain was doing the sensible thing and had purged this knowledge sometime in the past 30 years. In my case, this information was carved in stone and I put it all to use last weekend.the-ad

Actually the story begins another week or two earlier at the Silicon Valley Electronics Flea Market. I came across a guy with a bunch of Apple II computers stacked up and ended up buying an Apple //e and a disk drive for $20. His prices were $10 for an Apple //e and $25 for an Apple II+. The Apple II+ is technically the lesser machine – an earlier model that lacked the features of the Apple //e but is more expensive due to scarcity. The computer my parents purchased for me was the original Apple II, an even older and more rare model. I asked him if he had any of that model and he said no, but if he did they’d run a few hundred dollars.

I loved that he said this, because when the Apple //e was released I recall thinking that it was an abomination. My original Apple II computer came with a full set of schematics and programming documentation. The Apple //e was the first computer Apple released that didn’t include instructions on how to program it. By that time there was enough commercially available software and, like today’s computers, it actually did useful things without the owner having to program it. At the age of 15 this felt like a change for the worse and made the Apple //e a lesser computer in my mind.

I brought my $20 worth of computer gear home and decided to turn it on. The sound of the beep and the noise the disk drive made instantly transported me back 30 years – it was a sound as familiar as any I’ve heard in my entire life. It was the 1980s and I was a teenager with all the 6502 opcodes memorized. Time to build something.

I have zero intention of becoming the Twitter Display Guy, but since I had just finished a Twitter Display project I thought it would be cool to do a Twitter/Apple II mash-up. So where to start…

Bootstrap

I had exactly zero software for the Apple //e I had just purchased, so I looked for a 6502 assembler that ran on the PC and was able to find several. But I needed a way to transfer the resulting binaries to the Apple and also would need a way to communicate with my PC to send the Twitter information.

I ended up implementing an SPI-like interface between the PC and Apple II using an FTDI USB cable in bit-bang mode. This essentially gives you 4 logic lines you can control from your PC. I hooked these up to the Apple II joystick connector to the button inputs and wrote software on the Apple II to listen to the virtual button presses being hammered out by the PC. I tested this software first by just driving some LEDs with the FTDI cable to get the switching software right.

bitbang-leds Once I could reliably toggle the logic lines on the FTDI cable, I hooked wires up to the Joystick button port as seen below. I call it the Track & Field protocol since it works by rapidly toggling the joystick buttons. Track & Field was an Apple II game where you had to mash the buttons as fast as you could to race, and was notorious for kids breaking their keyboards by pounding the buttons so hard. I was able to get this Rube Goldberg system working reliably at 3600 baud.

gameport-context gameport-closeup

ftdi-connectedBut of course the very first piece of software had to be entered by hand on the Apple II, so I wrote a tiny bootloader in about 50 bytes that will load a stream of my bit-banged data into RAM. I then used this bootloader to transfer the full program. Writing the bootloader was surprisingly easy – I did almost all of it from memory. The 6502 has 8-bit registers but 16-bit memory addresses so you can’t reference a byte of memory indirect through a register. So you either need to store the address pointer in the first 256 bytes of memory (Zero Page) or use a longer instruction with an absolute address. I dimly recalled there were limitations on which Zero Page addresses were available for your use so I wrote the program to be self-modifying with absolute addressing.

self-modifyingThis loop increments the variable PagePointer to store each successive byte received. Look closely and you’ll see that PagePointer actually points to program code. It’s pointing to where the address byte is for the STA $xxxx,Y instruction. So the code is modifying itself as it goes through the loop. Computers go out of their way to prevent you from making these kinds of “mistakes” today but back then we all did it and it was bad-ass.

Not So Fast

The Apple II has an 8-bit 6502 CPU running at 1 MHz, so it can literally execute thousands of instructions per second. In other words, it’s about a million times slower that the computer you are using right now. So I wasn’t about to write a networking stack or Twitter client on the Apple II itself. Just like the TweetWall the communication with Twitter would happen on a PC and the Apple is just used for display.

The Apple II has 2 graphics modes. Low-resolution mode, or LORES as the cool kids call it, supports 40×40 pixels with 16 fixed colors. The colors are bizarre – lots of blues but kind of short on reds. Two of the colors are the exact same shade of gray, but are shifted a half pixel from each other. The other mode is high-resolution mode (HIRES) which gives 280×192 pixels and 6 colors. But you can’t just put any color anywhere you want. You kinda lose half your horizontal resolution once you start using color and even then you can’t just put a green pixel next to an orange one. It’s unbelievably complicated (cue Amiga fans to retort with tales of Hold And Modify mode). This same set of constraints is what makes the text on the Apple II have those purple and green fringes around the edges.

I wrote software on the PC to turn Twitter avatars into both LORES and HIRES graphic representations. The result is a cool 8-bit vibe, and in many cases the graphics are distant abstractions that bear little resemblance to the original image. Here are a few examples:

IMG_2208  IMG_2245

IMG_2215 IMG_2241

IMG_2227 IMG_2217

The PC software does the conversion of images into the exact native memory-mapped graphics format needed for the Apple II. Then it uses the bit-bang joystick protocol to pump the graphics buffers over directly to the screen. There is some additional software on the Apple II that can scroll the bottom text or the LORES graphics for transition effects.

Fragile

Once I got it working it was nice but I didn’t have a good way to save it. If I turned off the Apple //e I would have to re-enter the bootloader by hand and then re-download the software. I tried using the tape-recorder save/load interface but it wasn’t reliable.

I managed to win an auction on eBay for some blank 5.25” floppies and was able to download an image of the DOS 3.3 system disk for the Apple II. I used my bootloader to load this disk into memory the first time and once I had that going I was able to use it to initialize one of my blank eBay floppies and then I was golden. The video below shows the end result – a bootable Twitter floppy that shows old-school tweets. I recommend playing Rush while watching this.


21
Apr 10

Pushing Pixels

sure-2416

I’ve gotten quite a few questions regarding how to hook up and drive the Sure Electronics LED matrices I use in some of my projects, so here’s a quick brain dump on what you need to do.

First off you’ll need to purchase some of the LED matrices. Sure Electronics has a storefront on eBay. There are 2 models of LED panel I’ve used: a 24×16 panel and a 32×8 panel. Prices are usually around $10-$12 each and depending on the day you check are available in various colors.

There are a variety of libraries that will drive these displays, so generally speaking you won’t need to know all the details on the interface protocol. But it’s useful to have the reference material available should you need it.

The Sure Electronics datasheet covers the cable pin connections and a high level overview of how to drive the display: http://www.sure-electronics.net/download/DE-DP017_Ver1.0_EN.pdf

Both of these displays use a Holtek HT1632 LED driver. The HT1632 datasheet goes into a bit more detail on how the chip works and the various modes, initialization procedure, etc.

Wiring Them Up

The displays come with a pair of ribbon cables which allows you to daisy-chain the displays together. So you only need the first display wired up to your microcontroller and the rest of them will chain off the first. Since they are all wired up to the same signals you need a way to identify the displays to address them from your code. This is handled with jumper switches on the front.

jumperThe jumpers are labeled CS1 through CS4. Each display should have one and only one of these switches flipped to the On position to set its ID. If two displays have the same ID, they will act as clones of each other and the same image will appear on both.

cable

The way I wire them up to my Arduino boards is as follows:

Signal LED Matrix Pin Arduino Pin Notes
+5V 16 5V Data sheet indicates this can pull 350mA of current max so make sure your regulator is up to the task.
GND 15 GND  
WR 5 Any Digital I/O Write clock
Data 7 Any Digital I/O Data to write
CS1..4 1..4 Any Digital I/O You’ll need to connect a CS pin to a discrete digital I/O pin for each display you are driving

Software & Support

You’re spoiled for choice here – there are numerous libraries floating around.

There’s an epic thread on the Arduino forums covering how to interface to these displays. Among the 17 pages of posts are a variety of demos and sample libraries to use.

Adam Lloyd has a library that he maintains at http://github.com/devdsp/HT1632-AVR that supports reading from the display’s backbuffer as well as writing to it. If you do this you’ll need to wire up pin 6 on the matrix as well.

My library is available as well: SureLEDMatrix.zip and here’s a quick example on how to use it:

#include <SureLEDMatrix.h>

// —- PIN Constants ———————————-
int PIN_CHIPSELECT_1 = 5;  // CS for LED matrix 1
int PIN_CHIPSELECT_2 = 6;  // CS for LED matrix 2
int PIN_WRITE = 7;
int PIN_DATA = 8;

// Instance of LED matrices
SureLEDMatrix matrix1(PIN_CHIPSELECT_1, PIN_WRITE, PIN_DATA, kMatrixType_24x16);
SureLEDMatrix matrix2(PIN_CHIPSELECT_2, PIN_WRITE, PIN_DATA, kMatrixType_24x16);

int scroll = 0;
int maxscroll = 200;

void setup()
{  
  // Initialize I/O pins
  pinMode(PIN_CHIPSELECT_1, OUTPUT);
  pinMode(PIN_CHIPSELECT_2, OUTPUT);
  pinMode(PIN_WRITE, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);

  // Initialize the LED matrices
  matrix1.Initialize(); 
  matrix1.SetBrightness(2);
  matrix2.Initialize(); 
  matrix2.SetBrightness(2); 
}

void loop()
{   
    // Draw the text on the right screen
    matrix1.DrawText("Hello Cleveland!", 7, scroll, false);
    // Draw the text on the left screen (24 pixels to the left)
    matrix2.DrawText("Hello Cleveland!", 7, scroll-24, false);
    // Scroll 1 pixel to the left
    scroll = scroll-1;
    if (scroll < -maxscroll)
    {
      scroll = 100;
    }
}


20
Apr 10

TweetWall

Also check out the Apple //e Twitter Display for another take on this idea.

tweetwallI’ve partitioned my social networking life into two fairly distinct pieces. Facebook is for friends and family, and Twitter is for my technology hobbies. Facebook is for vacation photos, and Twitter is for the latest news on robotics, CNC, Maker culture, etc. One consequence of this is that I usually only check Facebook once or twice a week to catch up on what people are doing and reject requests to join The Mafia/Vampire Clans/Farmville. However, I find myself checking Twitter multiple times a day, because there’s a constant stream of interesting technology tidbits coming in. Twitter is the cocktail party full of interesting sound-bites to Facebook’s Thanksgiving Dinner at Uncle Ralph’s house.

By its very design, Twitter doles out info in bite-sized nuggets of 140 characters. So the information is concise and easily digested, and likewise my Twitter sessions are short but frequent. Taken to the limit, it becomes essentially a broadcast of information trickling in constantly so why should I poll for it in my browser? Now there’s a million-dollar idea – I think I’ll call it Push Technology.

The Internet of Things is coming, and I’m convinced in the next 10 years the internet will be less about general-purpose computers like we use today and more about dozens of purpose-specific connected devices. In a future where applications will become physical objects, why not turn a web site into a piece of furniture like a Twitter Wall?

Raw Materials

led-pornThe ideal presentation of a tweet is the text of the tweet itself along with the sender’s name and avatar picture. So I grabbed some LED Matrices for some nice big text and a small OLED screen for the avatar picture. That covered the functional pieces, but for aesthetics (it is going to be hanging on the wall) I wanted some color LED backlighting so I threw some ShiftBrites into the design as well.

I decided to build an acrylic enclosure. I had some scraps of various colors laying around but only one large sheet, so the color was going to be transparent green. I laid out the design in vector art and cut the acrylic on an Epilog Laser Cutter at TechShop.

vector-art

 

Cutting & Bending

For the LED backlighting I wanted to do a Twitter logo with a diffuser to soften up the lighting. I had seen some folks use diffuser panels effectively with LEDs at Maker Faire last year but wasn’t sure what kind to use, so I picked up a sample acrylic diffuser panel at Tap Plastics and cut it out.

The results were quite good. The left picture below shows the diffuser panel cut out with a LED shining through it. The Twitter logo outline is cut from opaque white acrylic which was layered on top to give a clear white outline around the lit piece. The picture on the right shows the two layers of acrylic assembled and back-lit with a pair of LEDs.

twitter-acrylic backlit-logo

I designed the acrylic with tabs that would be bent backwards to create a box enclosure. TechShop recently got a thermoplastic bender and I tried it out for the first time on this project. It couldn’t be simpler – turn it on, lay your acrylic over the heating element for 5 minutes and then bend into place.

bend1 bend2

The Finished Product

I connected the LED Matrices, OLED screen and ShiftBrites up to a small Arduino-compatible board from adafruit and wrote software that controls them over a serial protocol from my PC. The PC calls the Twitter API to fetch a list of tweets and then sends the text and picture to the Arduino for display.

The serial connection to the Arduino is plenty fast to send the text quickly, but the images are 128×128 16-bit-per-pixel which means 32K of data and takes quite a while to transfer. Fortunately the OLED display has a micro-SD card slot and can store images locally. So my software keeps a directory of image URIs and their locations on the SD card. The first time an image is encountered it must be transferred to the card but subsequent times drawing the image simply means sending the Arduino the 3-byte card address to draw from.

The LED matrices were purchased cheaply on eBay from Sure Electronics. I wrote an Arduino library that abstracts them and provides a nice set of high-level text rendering APIs and 2 fonts. If you are planning to drive some LED matrices, I highly recommend these and you can download my library here.

front-off back-off

It can sit on my desk or sit on a shelf and deliver me a constant stream of Twitter wisdom.

weird-angle shelf

The bright LEDs and highly reflective acrylic make it hard to get a good picture of these when they’re turned on. The video below shows what it looks like in a completely darkened room and then with the lights on.

 

Software

A few folks have asked about where to get the LED matrix and how to connect them and drive them, so I posted some info and links here: http://www.atomsandelectrons.com/blog/post/Pushing-Pixels.aspx