IT WORKS! YAY!!!
I turns out that I wasn't setting the baud rate correctly. Anyway, heres the working code :
// ********************* local definitions *********************
#define DMX_CHANNELS (32) //Define the number of DMX values to store
enum {IDLE, BREAK, STARTB, STARTADR}; //DMX states
uint8_t gDmxState;
uint8_t *gDmxPnt;
uint16_t DmxCount;
uint8_t DmxField[DMX_CHANNELS]; //array of DMX vals (raw)
uint16_t DmxAddress; //start address
int ledPin = 13; // LED connected to digital pin 13
void setup() // run once, when the sketch starts
{
// sets the digital pin as output
pinMode(ledPin, OUTPUT);
// Disable interrupts
cli();
// 250kbps baud - only works for 16MHz clock frequency. See the ATMega8 datasheet if you are using a different clock speed
UBRRH = 0;
UBRRL = 3;
// enable rx and interrupt on complete reception of a byte
UCSRB = (1<<RXEN)|(1<<RXCIE);
UCSRC = (1<<URSEL)|(3<<UCSZ0)|(1<<USBS);
// Enable interrupts
sei();
gDmxState= IDLE;
uint8_t i;
for (i=0; i<DMX_CHANNELS; i++)
{
DmxField[i]= 0;
}
DmxAddress= 10; //Set the base DMX address. Could use DIP switches for this.
}
void loop() // run over and over again
{
if(DmxField[0] >=127)
{
digitalWrite(ledPin, HIGH); // sets the LED on
}
else
{
digitalWrite(ledPin, LOW); // sets the LED off
}
}
// *************** DMX Reception ISR ****************
SIGNAL(SIG_UART_RECV)
{
uint8_t USARTstate= UCSRA; //get state
uint8_t DmxByte= UDR; //get data
uint8_t DmxState= gDmxState; //just get once from SRAM!!!
if (USARTstate &(1<<FE)) //check for break
{
UCSRA &= ~(1<<FE); //reset flag
DmxCount= DmxAddress; //reset frame counter
gDmxState= BREAK;
}
else if (DmxState == BREAK)
{
if (DmxByte == 0)
{
gDmxState= STARTB; //normal start code detected
gDmxPnt= ((uint8_t*)DmxField +1);
}
else gDmxState= IDLE;
}
else if (DmxState == STARTB)
{
if (--DmxCount == 0) //start address reached?
{
gDmxState= STARTADR;
DmxField[0]= DmxByte;
}
}
else if (DmxState == STARTADR)
{
uint8_t *DmxPnt;
DmxPnt= gDmxPnt;
*DmxPnt= DmxByte;
if (++DmxPnt >= (DmxField +DMX_CHANNELS)) //all ch received?
{
gDmxState= IDLE;
}
else gDmxPnt= DmxPnt;
}
}
Many thanks to Hendrik Hoelscher for the original code, and to those who've helped me on this forum.
At the moment, this code only works on the ATMega8 CPU, not the ATMega168 as the register names are different. I don't have a 168-based Arduino to play with so if anyone wants to add to the code to make it work with the 168, be my guest. Also I think this might be worth putting into a separate library once it is made to work with the 168-based boards.