Using bit-angle PWM to drive GPIO pins

Although yesterday's post was a reasonable introduction to bit-angle PWM, showing a pattern of characters on a console screen is hardly the most exciting or useful thing. So today I shall try to use the same code to drive something a bit more fun.

I still had the "flowing water light" lying around, which I had used to make a "knight rider" light with an Arduino. I connected it to GPIO pins 0-7 on the Raspberry Pi, If you don't have a convenient module like this, you can make your own with eight LEDs and eight resistors on a breadboard. I tweaked yesterday's PWM code to use WiringPi to switch the GPIO pins on and off instead of writing to the console. I also increased the PWM range to 6 bits (0-65) to give a bit more detail to the levels.

gpio-demo.c:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#include <wiringPi.h>

#define BITS 6
#define TICK_US 250

#define N_CHANNELS 8

extern int usleep(int usecs);

int levels[N_CHANNELS];
int state[N_CHANNELS];

void switch_on(int channel) {
  if (!state[channel]) {
    digitalWrite(channel, LOW);
    state[channel] = 1;
  }
}

void switch_off(int channel) {
  if (state[channel]) {
    digitalWrite(channel, HIGH);
    state[channel] = 0;
  }
}

void wait(int ticks) {
  usleep(ticks * TICK_US);
}

void emit() {
  int bit;
  int power;
  int channel;

  for (bit = 0; bit < BITS; ++bit) {
    power = 1 << bit;
    for (channel = 0; channel < N_CHANNELS; ++channel) {
      if ((levels[channel] & power) > 0) {
        switch_on(channel);
      } else {
        switch_off(channel);
      }
    }
    wait(power);
  }
}

void setup(int argc, char**argv, int* channels) {
  wiringPiSetup();
  for (int i = 0; i < N_CHANNELS; ++i) {
    pinMode(i, OUTPUT);
    digitalWrite(i, LOW);
    state[i] = 0;
		
    if (i < argc-1)
      channels[i] = atoi(argv[i+1]);
    else
      channels[i] = 0;
  }
}

int main(int argc, char**argv) {
  setup(argc, argv, levels);
  pinMode(0, OUTPUT);

  for (;;) {
    emit();
  }
}

To build this code, use: c99 -o gpio-demo gpio-demo.c -lwiringPi. To run it, use sudo ./gpio-demo with up to eight PWM proportions (in the range 0-63). Human perception of PWM LED light levels is not linear, and I found that sudo ./gpio-demo 62 61 60 59 58 57 56 55 gave a visible gradient. It happily drove 8 channels of independent PWM using less than 1% of the available CPU power.

SANYO DIGITAL CAMERA

While this does demonstrate the ability to generate PWM, it's not really very useful. The code enters into a loop in which it keeps checking whether it should change the status of the pins it is managing, but this prevents it from doing anything else (including from changing the PWM levels on the pins). A useful application would allow the "foreground" code to respond to inputs and make decisions, all while the PWM management is running in the "background". That's for another blog post, though.

SANYO DIGITAL CAMERA

I read somewhere that servos are usually controlled using PWM, so just to see if it would work, I connected the power and ground leads of a servo to the power and ground on the Raspberry Pi header, with a flying lead connected to the signal pin. I connected the signal pin of the servo to each of the outputs in turn and saw some servo-like behaviour, but most of the PWM levels that this code can generate are way outside the operating range for a servo, so that needs a bit more specialised software.

Efficient software PWM with bit-angle modulation

It is a few months now since I last had a play with pulse-width modulation (PWM). At the time I was concerned by the amount of processing power used by the simplistic approach I had implemented, so I abandoned the exercise.

Luckily, there are more efficient ways to do software PWM. One of the most popular is "bit-angle modulation" (BAM), also known as "binary code modulation" (BCM). The idea is deceptively simple, and is based on the premise that since the whole point of PWM is to switch an output on for a certain proportion of time, and off for a certain proportion of time, the system does not really need to check every single clock cycle just to see if any of the outputs should change. As long as the end result has the right proportions, the specific times at which the output is switched on and off are immaterial.

Following this thinking, we can get to a point where we can group some proportions together, allowing the system to sleep for longer periods, and thus use less processing power. For example, consider a system with 256 levels of PWM range. This can be represented as eight bits of data. We would expect value 255 (0xFF) to be fully on, and 0 to be fully off. We would also expect 128 (0x80) to be on for half the time, 64 (0x40) to be on for a quarter of the time and so on.

Any output with a PWM value of 128 or greater will be on for at least half the time, and any output with a value of less than 128 will be off for at least half the time. All outputs will be one or the other, which implies that by grouping outputs on this bit of the data we can allow the system to set the appropriate outputs on or off, then sleep for a whole half cycle! The process works similarly for the other bits of the PWM level.

To demonstrate this in action, I have written some C code to pretend that it is driving a PWM output but write the output to the console instead.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define BITS 4
#define STEP 1000

#define N_CHANNELS 16
#define N_CYCLES 5

extern int usleep(int usecs);

int levels[N_CHANNELS];
int nchannels = 0;
int state[N_CHANNELS];
char history[N_CHANNELS][(1 << BITS) * N_CYCLES + 1];
int hi;

int setup(int argc, char**argv, int* channels) {
  int ret = 0;
  for (ret = 0; ret < argc-1; ++ret) {
    channels[ret] = atoi(argv[ret+1]);
  }

  printf("running %d cycles of %d channels\n", N_CYCLES, ret);
  return ret;
}

void switch_on(int channel) {
  state[channel] = 1;
}

void switch_off(int channel) {
  state[channel] = 0;
}

void wait(int ticks) {
  int i;
  int channel;
  for (i = 0; i < ticks; ++i) {
    for (channel = 0; channel < nchannels; ++channel) {
      history[channel][hi] = state[channel] ? '^' : '_';
    }
    usleep(STEP);
    ++hi;
  }
}

void emit() {
  int bit;
  int power;
  int channel;

  for (bit = 0; bit < BITS; ++bit) {
    power = 1 << bit;
    for (channel = 0; channel < nchannels; ++channel) {
      if ((levels[channel] & power) > 0) {
        switch_on(channel);
      } else {
        switch_off(channel);
      }
    }
    wait(power);
  }
}

void describe() {
  int channel;
  for (channel = 0; channel < nchannels; ++channel) {
    history[channel][hi] = 0;
    puts(history[channel]);
  }
  putchar('\n');
}

int main(int argc, char**argv) {
  int cycle;

  nchannels = setup(argc, argv, levels);

  hi = 0;
  for (cycle = 0; cycle < N_CYCLES; ++cycle) {
    emit();
  }
  describe();
}

This code, together with a makefile so you can build it, can be found at the Raspberry Alpha Omega "pwm" project on github.

The example code runs five example cycles of as many PWM pins as you like. However, for simplicity they are limited to levels in the range 0-15. When you run the demo just give a sequence of numbers between 0 and 15, and it will show a graph of the output levels in glorious text-o-vision. For example, entering ./console-demo 0 1 2 3 4 5 6 7 8 9 10 11 12 13 13 15 gives the following output:

___________________________________________________________________________
^______________^______________^______________^______________^______________
_^^_____________^^_____________^^_____________^^_____________^^____________
^^^____________^^^____________^^^____________^^^____________^^^____________
___^^^^___________^^^^___________^^^^___________^^^^___________^^^^________
^__^^^^________^__^^^^________^__^^^^________^__^^^^________^__^^^^________
_^^^^^^_________^^^^^^_________^^^^^^_________^^^^^^_________^^^^^^________
^^^^^^^________^^^^^^^________^^^^^^^________^^^^^^^________^^^^^^^________
_______^^^^^^^^_______^^^^^^^^_______^^^^^^^^_______^^^^^^^^_______^^^^^^^^
^______^^^^^^^^^______^^^^^^^^^______^^^^^^^^^______^^^^^^^^^______^^^^^^^^
_^^____^^^^^^^^_^^____^^^^^^^^_^^____^^^^^^^^_^^____^^^^^^^^_^^____^^^^^^^^
^^^____^^^^^^^^^^^____^^^^^^^^^^^____^^^^^^^^^^^____^^^^^^^^^^^____^^^^^^^^
___^^^^^^^^^^^^___^^^^^^^^^^^^___^^^^^^^^^^^^___^^^^^^^^^^^^___^^^^^^^^^^^^
^__^^^^^^^^^^^^^__^^^^^^^^^^^^^__^^^^^^^^^^^^^__^^^^^^^^^^^^^__^^^^^^^^^^^^
^__^^^^^^^^^^^^^__^^^^^^^^^^^^^__^^^^^^^^^^^^^__^^^^^^^^^^^^^__^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

(The ^ characters show when the signal is "on".)

As I hope you can see, the number of ^ characters per cycle does indeed add up to the specified PWM level. What may seem odd is that they are not all adjacent, as was the case for the "obvious but inefficient" approach. If all we are concerned about is the proportion of time spent on or off per cycle, though, this is unimportant!

Next time I hope to connect this code to some actual GPIO pins and drive some real PWM.

Driving a 7219 LED matrix from a Raspberry Pi

Flushed with my success in getting data displayed on my cheap LED matrix using a Bus Pirate, I decided that the next step was to see if I could get it working with a Raspberry Pi. Looking around for useful resources to get me started I found:

Following the steps to install Wiring Pi, I began with

sudo apt-get update
sudo apt-get upgrade

This took at least a couple of hours (I gave up and left it running while I went to get something to eat). It seems a lot has changed since I last updated the Raspbian on this SD card!

Once this was complete, Gordon's installation page suggested installing the SPI driver using:

sudo modprobe spi_bcm2708
sudo chown `id -u`.`id -g` /dev/spidev0.*

Unfortunately, this didn't work, giving some fairly confusing errors:

pi@raspberrypi:~$ sudo modprobe spi_bcm2708
libkmod: ERROR ../libkmod/libkmod.c:554 kmod_search_moddep: could not open moddep file '/lib/modules/3.2.27+/modules.dep.bin'
pi@raspberrypi:~$ sudo chown `id -u`.`id -g` /dev/spidev0.*
chown: cannot access `/dev/spidev0.*': No such file or directory

So I gave up and went through the installation process for Wiring Pi and its tools:

git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

This worked with no errors. I then tried the suggested gpio load spi. This refused, but so much had changed on the system that I though it was probably due a reboot. After this it worked. Next step was to connect the LED matrix. I could probably have plugged this in with the raspberry Pi still running, but I played it safe and switched it off first.

Pi GPIO header LED board
MOSI / GPIO10 DIN
SCLK / GPIO11 CLK
3V3 Vcc
GND GND
and one of
CE0 CS
CE1 CS

In pictures, the SPI pins are sometimes marked as purple. I chose to connect the LED array CS line to CE0, so my code examples will use channel 0.

Once I had plugged it all in and restarted the Raspberry Pi, I quickly put together some code to use the "display test" register to switch all the LEDs on and off. This made sure that I could compile a simple C program using WiringPi and get it to talk to the appropriate SPI device:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <wiringPiSPI.h>

#define CHANNEL 0

void main(int argc, char** argv) {
	uint8_t on[] = { 0xFF, 0xFF };
	uint8_t off[] = { 0xFF, 0x00 };
	uint8_t buf[2];

	if (wiringPiSPISetup(CHANNEL, 1000000) < 0) {
		fprintf (stderr, "SPI Setup failed: %s\n", strerror(errno));
		exit(errno);
	}

	for (;;) {
		memcpy(buf, on, 2);
		wiringPiSPIDataRW(CHANNEL, buf, 2);
		sleep(1);
		memcpy(buf, off, 2);
		wiringPiSPIDataRW(CHANNEL, buf, 2);
		sleep(1);
	}
}

Most of the above code should be pretty straightforward. It's either boilerplate C or direct calls to Gordon's Wiring Pi SPI APIs. The only oddity is the three two-byte buffers. My first attempt passed the "on" and "off" patterns into the SPI API call directly, but the code did not quite work - it only displayed the full LED pattern once. The reason is that SPI is a bidirectional synchronous protocol and the returned values overwrite the outgoing ones during processing. Once I realised this I was able to fix the problem by re-initialising a single buffer before each SPI call. Still, it would have been nice for the API to also support a function with separate in and out buffers.

My next attempt was to try and write some stereotypical scrolling characters. I knew I would need the bitmap data for the characters, so I searched around for source code for an 8x8 bitmap font in a form that I could use. Eventually I found one in LISP which looked easy enough to reformat into C.

Rotated character on SPI LED Matrix

As I was working through the data making it look like C, I began to see patterns. For example, the last byte of a code is often 0, except on characters with "descenders", which led me to wonder if that might be the gap at the bottom of the character. After the reformatting exercise I hooked up the tidied character set data into some code to display characters. And found that they were rotated round 90 degrees! I had to tip my breadboard on its side to read the characters.

Undeterred, I pressed on and wrote some software to scroll any specified string. However, because of the orientation of the characters and the LED matrix, it was easier to scroll the text up/down rather than left/right. It's not quite what I planned, but it's still a cool effect.

You can find all the software for this demo, including the hand-formatted 8x8 character bitmap data, on the Raspberry Alpha Omega SPI project at GitHub

Testing a MAX7219 LED array with Bus Pirate

After thinking about how to drive the MAX7219 LED array I built yesterday, it occurred to me that maybe this is an ideal time to get to the bottom of how to use the Bus Pirate board that I failed to use with a MCP3002 ADC chip. This time I was determined to get it working.

To get started, I searched around and found the most important documents I need:

To get started I needed to make sure I could talk to the Bus Pirate, so I plugged it in to a nearby USB port on my Windows PC. It set itself up as a virtual COM port. I then opened a connection to the serial port in MobaXterm. Pressing "enter" a few times had no effect, so I went back to the Bus Pirate UI docs and found that the board expects an initial connection at 115200 baud. I changed the terminal speed and re-started the connection and got a nice Bus Pirate HiZ prompt.

Having verified that I could talk to the Bus Pirate from the PC, I disconnected it from the PC and started to wire it to the LED board. My initial plan was to connect wires straight form the Bus Pirate pins to the header on the LED board. However, both headers had pins rather than sockets, and I could not find any wires with a socket at both ends. I had, however, bought a bundle of wires with a socket at one end and a pin at another, so it was straightforward to run the wires from the Bus Pirate pins to a little breadboard, into which I also plugged the LED board. This turned out to be quite useful, as it provided a kind of stand for the display and kept everything neat.

I wired the pins as follows:

Bus Pirate LED board
3.3V Vcc
GND GND
MOSI DIN
CLK CLK
CS CS

I connected the Bus Pirate to the PC again and started to explore, with the help of the Bus Pirate UI guide. The obvious step was m to enter the menu, then 5 to select SPI mode. After that I tried sending some 0x00 and 0xFF values to the board which at least showed that the connection was working, as sometimes all the LEDs would light up and other times they would all go off. Hardly very useful, though. Time to hit the MAX7219 datasheet.

It took me a bit of time to get my head around this bit, as it seemed that the datasheet was filled with stuff I am not interested in (electrical and timing characteristics etc.), but very light on what data you need to send to the darned thing. Eventually through a combination of sending values to try things out, and going back and forth in the datasheet, I managed to work out what to do. So here's a summary.

First, note that the MA7219 expects 16-bit control words, which must be sent as two bytes using the Bus Pirate, so every command below is of the form [0xnn,0xnn]. The starting and ending brackets represent the setting of the CS line to tell the MAX7219 that there is data.

The MAX7219 is a register-based device. It has 16 addressable registers which serve both general purposes such as overall brightness, and a place to put the data for each column of the display. In every message to the MAX7219 chip, the low 4 bits of the first data byte indicate which register to write, and the second data byte indicates the data to write to it. Not all registers use all 8 bits of the data value, but you need to send it anyway. As an example sending [0x04,0xFF] places the value 0xFF into register 0x04. This could equivalently be sent as [0xF4,0xFF], as the high 4 bits of the register byte are ignored.

Once I worked out the register structure I could now see why my random set of 0x00 and 0xFF values had sometimes switched the whole display on and off. The chip has a "display test" register (0x0F). Setting data value 0xFF into this register switches all the LEDs on, and setting value 0x00 switches them all off. I could now repeatably send the two bytes [0xFF,0xFF] to switch all on, and [0xFF,0x00] to switch all off.

Getting to the next stage, where I could write my own data to the display turned out to be a bit more complicated. I don't know whether the chip always starts up with everything disabled, or whether it was just luck on my part, but I found that in order to get things fully working I needed to send:

  1. [0x09,0x00] to switch off character decoding
  2. [0x0B,0x07] to enable all columns (without this only the first column worked, which confused me for a bit)
  3. [0x0A,0xFF] to set intensity to maximum
  4. [0x0C,0x01] to enable the display

At this point the display showed what appeared to be a random pattern. This pattern went away when I wrote my own data to the column registers. If you don't like this appearing, then I guess you could write your initial data to each column before using [0x0C,0x01] to show what's there.

I decided to write data to columns to make a checkerboard pattern:

[0x01,0x55]
[0x02,0xAA]
[0x03,0x55]
[0x04,0xAA]
[0x05,0x55]
[0x06,0xAA]
[0x07,0x55]
[0x08,0xAA]


SANYO DIGITAL CAMERA

SANYO DIGITAL CAMERA


Now I know the sequence of bytes I need to write to the device to make it do stuff, the next step is to talk to it from a Raspberry Pi. I'll save that for another time, though.

Building a MAX7219 LED array

Time for a bit more soldering, I think. I couple of months ago I bought a little MAX7219 LED array kit from ebay for a couple of pounds. They are all over ebay and aliexpress.

SANYO DIGITAL CAMERA

As kits go it is very simple - a resistor, two capacitors, some sockets and some optional connectors. Soldering it was pretty easy. The only things I needed to be careful about were leaving enough "leg" showing on the electrolytic capacitor so that I could bend it down to avoid fouling the LED matrix module and making sure the sockets for the LED module were nice and straight. The "pins" on the module are really just bits of wire sticking out of some epoxy, so they need to be carefully aligned with the sockets to avoid bending.

SANYO DIGITAL CAMERA

SANYO DIGITAL CAMERA


As for what to do with it I'm not too sure. Although the pins are not labelled in the same terms, I'm pretty confident that the interface is SPI. I guess I'm going to have to work out how to drive SPI devices!

Building and testing a Raspi Robot board

I have had a kit of parts for a RaspiRobot board in my "to do pile" for a while now. Today I had a bit of spare time so I followed the construction instructions and put it together.

Step one was to check I had the right bits. I opened the packet and laid the components out just like the helpful picture on the website. Mine were different! The official picture shows four 4-way headers, whereas the set I got had two 4-way and two 2-way. A bit further down the page is a list of components, and that did agree with what I had received. Shame about the picture, though.

RaspiRobot Parts

RaspiRobot Parts


Once I had sorted that out I began assembling the board, with the help of my "third hand". Soldering it was very straigtforward, and all the components fitted nicely into their allotted places.

RaspiRobot

After construction, I was keen to test it. First of all I plugged it in without any motors or power supplies connected and followed the "Getting Started" tutorial

Once I had installed the various python stuff it requires, I was able to switch the two LEDs on and off. The instructions for switching the motors and open-collector outputs had no effect, of course.

Next, I tried to drive a motor. This is, after all, what the board is supposed to be for - if all I wanted was to switch two LEDs on and off I could have done it much more simply! This, however was where I hit problems. So far I have not been able to get the board to actually drive a motor. From reading the comments on the RaspiRobot sparkfun page it seems likely that the problem is one of power.

My first attempt was to try using USB power from the Pi. Nothing. But I half expected that - motors can take a lot of power, so the board provides a separate power input to drive the motors and (via a regulator) the Raspberry Pi. The web site says anything from 7-12V will do, so I tried a spare 12V power adaptor which I had lying around and happened to have the right kind of plug. It tested OK with a voltmeter, but did not seem to have enough juice to power up the Pi. Still, it only claimed an output of 400mA, so I tried a bigger one. 500mA was enough to half-start the Raspberry Pi, but not enough to boot the OS. I was sure a 1A adapter would be enough, but this didn't work either. All that happened was the regulator on the RaspiRobot board got very hot.

RaspiRobot

I know the motor works, because connecting it directly to the power adapter makes it spin happily. The problem definitely seems to be in the power handling on the RaspiRobot board.

I'll shelve this for now, and see if I can find anything else to power this board another day.

Altoids

Altoids are strange. A simple peppermint confectionery which has achieved an astonishing status among hobbyists of all kinds. The main reason, it seems, is the tin in which they are sold. The Altoids tin has become for many people the de-facto enclosure for hobby electronics projects. So much so that one of the questions in the official Raspberry Pi FAQ is "Will it fit in an Altoids tin?" (I'm afraid the answer is "no"). Naturally enough, this encouraged me to get some Altoids tins and build some stuff into them!

Some things about the Altoids phenomenon are a bit odd, though. Despite many of the tins proudly bearing the legend "Made in Great Britain", they are curiously hard to find in the UK, and surprisingly expensive when you can find them. After a bit of poking around, I eventually found some Altoids on Amazon for a more reasonable price, but the "downside" was that I had to order a dozen.

SANYO DIGITAL CAMERA

This should give me plenty of tins to build my projects into, and as a bonus my breath will be minty fresh for the next year or so ;)

Building and testing a “flowing water light”

I'm a bit of a sucker for cheap little electronics. After playing around with single LEDs and traffic lights for a while I wanted something a bit more interesting, so just over a pound for an "8 Channel Flowing Water Light LED DIY Kit" seemed too much fun to pass up.

SANYO DIGITAL CAMERA

The circuit is very simple indeed - a single-in-line resistor pack, eight standard LEDs, a board, and a connector. Slightly better than my own LED attempts, as it has a separate current-limiting resistor for each LED which helps prevent the inadvertent dimming I noticed when more than one light was on in my traffic lights. Assembly was also simple. The only even mildly tricky bit was keeping the LEDs neatly aligned to avoid too much of a "snaggle-toothed" look to the finished article.

To test the board I decided to start by using an Arduino. They have plenty of digital io pins and its easy to write code to drive them. To start with I decided not to bother with brightness control using PWM, but to stick with just switching the lights fully on or off. Even this needed a few false starts, though.

The first problem was that the Arduino I tried (a genuine Uno R3) would not connect to the PC. It started up when USB power was applied, but never appeared as a virtual COM port for programming. This was very odd, as only a few weeks ago I had this happily running my traffic lights. After half an hour of fiddling to no avail I gave up with that board and tried another (a Sainsmart Uno R3) which I had bought because of its optional 3.3V support and easy sensor connection area. This one connected with no problem, so I was able to write code and run it on the board.

SANYO DIGITAL CAMERA

The next problem was choosing which pins to use. I needed eight digital out pins and Vcc. Being an orderly sort of person I started by connecting the board to pins 0-7. It turns out that this was not a good idea. pins 0 and 1 are also used by an on-board serial port and gave me some strange output. I expect that with a bit of research I could work out how to disable the UART and use these two pins as regular digital outputs, but it was easier to just bump all the connections along a bit and use pins 3-10 instead.

The final problem (and this was one I should have guessed from the board connections) was that the LEDs are wired in a common-anode circuit, so to switch a light on I needed to pull the output pin low. Eventually I arrived at the following Arduino sketch

int first = 3;
int last = 10;
 
void setup() {
  for (int i = first; i <= last; ++i) {
    pinMode(i, OUTPUT);
  }
}

void showpin(int led) {
    digitalWrite(led, LOW);    // turn the LED on by making the voltage LOW
    delay(100);                // wait for 100ms
    digitalWrite(led, HIGH);   // turn the LED off
}  

// the loop routine runs over and over again forever:
void loop() {
  for (int led = first; led < last; ++led) {
    showpin(led);
  }
  for (int led = last; led > first; --led) {
    showpin(led);
  }
}

Which produced a pleasing "Knight Rider" effect (click to play, excuse the cheesy GIF!)

knight-rider

Think you know FORTH? then why not enter a competition?

It's nice to see old favourite programming languages getting a bit of love. "Circuit Cellar" magazine seems to be running a weekly "spot the bug" competition, and this week (week 2) it looks like a bit of FORTH. It doesn't say much about the program, but it is heavily commented (much more so than most FORTH code I have seen).

The Week 2 submission deadline is June 16, 12:00 pm EST, so why not have a go!

A pair of new goodies

I'm still struggling to find time to write here, but I really am pretty excited about two new arrivals I picked up today.

It's fair to say that the first has been getting a lot of press recently:

SANYO DIGITAL CAMERA

The second is more of a rarity. Following my comments a few months ago, and despite my failure to win a limited edition "Blue Pi" :(, I now have another one for the collection:

Chinese Red Pi