ok, I have this working well now. I used the lower level code posted here by tomk ness here - Arduino Playground - Max7219, there's an error in line 62+63, should be this:
byte max7219_reg_digit6 = 0x07;
byte max7219_reg_digit7 = 0x08;
Here's the code I'm happy with, it takes 8 bytes sent from Processing to generate the output for the LED matrix:
/*
code for max 7219 from maxim, controlling an 8x8 LED matrix
Orginal code by Nicholas Zambetti and Dave Mellis Interaction Design Institute Ivrea Dec 2004
First modification by Marcus Hannerstig K3, malmö högskola 2006
Second modification by tomekness FH-Potsdam Feb 2007
This version Tobie Kerridge ar Goldsmiths London March 2008
This version looks for incoming serial bytes to create the Matrix pattern
Processing is taking video input and sending the data as 8 bytes
*/
// define pins for the max7219
nt dataIn = 5;
int load = 6;
int clock = 7;
// define max7219 registers, these are in the Maxim datasheet
byte max7219_reg_noop = 0x00;
byte max7219_reg_digit0 = 0x01;
byte max7219_reg_digit1 = 0x02;
byte max7219_reg_digit2 = 0x03;
byte max7219_reg_digit3 = 0x04;
byte max7219_reg_digit4 = 0x05;
byte max7219_reg_digit5 = 0x06;
byte max7219_reg_digit6 = 0x07;
byte max7219_reg_digit7 = 0x08;
byte max7219_reg_decodeMode = 0x09;
byte max7219_reg_intensity = 0x0a;
byte max7219_reg_scanLimit = 0x0b;
byte max7219_reg_shutdown = 0x0c;
byte max7219_reg_displayTest = 0x0f;
// aditional pins and global variables
int debugPin = 13;
int byteHeadCount;
int byteDataCount;
int prevByteValue;
int matrixFrameCount;
char incomingByte;
byte byteData[8];
boolean byteDataFlag = false;
void setup()
{
// inintialise serial port:
Serial.begin(9600);
// set up I/O for the max7219
pinMode(dataIn, OUTPUT);
pinMode(clock, OUTPUT);
pinMode(load, OUTPUT);
//initialise the max 7219
maxSingle(max7219_reg_scanLimit, 0x07);
maxSingle(max7219_reg_decodeMode, 0x00);
maxSingle(max7219_reg_shutdown, 0x01);
maxSingle(max7219_reg_displayTest, 0x00);
// clear matrix
for (int e=1; e<=8; e++) {
maxSingle(e,0);
}
maxSingle(max7219_reg_intensity, 0x0f & 0x0f);
}
void loop()
{
// look for incoming serial data:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
if (byteDataFlag){
readSerData();
}
else{
readSerHeader();
}
prevByteValue = incomingByte;
}
}
// this function collects 8 bytes of useful data
void readSerData(){
byteData[byteDataCount] = incomingByte;
byteDataCount++;
if (byteDataCount == 8){
byteDataFlag = false;
serBytesToMatrix();
byteDataCount = 0;
}
}
// this function looks for 8 matching header bytes
void readSerHeader(){
// count header bytes
if (incomingByte == 85) {
if (prevByteValue == 85) {
byteHeadCount++;
}
if (byteHeadCount == 7) {
byteHeadCount = 0;
byteDataFlag = true;
}
}
else{
byteHeadCount = 0;
}
}
// this function writes data bytes to the LED Matrix
void serBytesToMatrix(){
blankMatrix();
maxSingle(1,byteData[0]);
maxSingle(2,byteData[1]);
maxSingle(3,byteData[2]);
maxSingle(4,byteData[3]);
maxSingle(5,byteData[4]);
maxSingle(6,byteData[5]);
maxSingle(7,byteData[6]);
maxSingle(8,byteData[7]);
}
// some clever bit shifting here to use the max7219
void putByte(byte data) {
byte i = 8;
byte mask;
while(i > 0) {
mask = 0x01 << (i - 1); // get bitmask
digitalWrite( clock, LOW); // tick
if (data & mask){ // choose bit
digitalWrite(dataIn, HIGH);// send 1
}
else{
digitalWrite(dataIn, LOW); // send 0
}
digitalWrite(clock, HIGH); // tock
--i; // move to lesser bit
}
}
// talks to the max7219
void maxSingle( byte reg, byte col) {
digitalWrite(load, LOW); // begin
putByte(reg); // specify register
putByte(col);//((data & 0x01) * 256) + data >> 1); // put data
digitalWrite(load, LOW); // and load da shit
digitalWrite(load,HIGH);
}
// uses the 2 functions above
void blankMatrix(){
// empty registers, turn all LEDs off
for (int e=1; e<=8; e++) {
maxSingle(e,0);
}
}
// something to check things are well
void initAnimation() {
blankMatrix();
delay(1000);
maxSingle(1,B00000001);
delay(100);
maxSingle(2,B00000010);
delay(100);
maxSingle(3,B00000100);
delay(100);
maxSingle(4,B00001000);
delay(100);
maxSingle(5,B00010000);
delay(100);
maxSingle(6,B00100000);
delay(100);
maxSingle(7,B01000000);
delay(100);
maxSingle(8,B10000000);
delay(100);
}