part 2
/******************************* MAX485 variable declarations *****************************/
int receiveroutputenable = 2;
/* receiver output enable (pin2) on the max485.
* will be left low to set the max485 to receive data. */
int driveroutputenable = 3;
/* driver output enable (pin3) on the max485.
* will left low to disable driver output. */
int rxpin = 0; // serial receive pin, which takes the incoming data from the MAX485.
int txpin = 1; // serial transmission pin
/******************************* DMX variable declarations ********************************/
volatile byte i = 0; //dummy variable for dmxvalue[]
volatile byte dmxreceived = 0; //the latest received value
volatile unsigned int dmxcurrent = 0; //counter variable that is incremented every time we receive a value.
volatile byte dmxvalue[4] = {1, 0, 0, 0}; //stores the DMX values we're interested in using.
volatile byte dmxstream[512]={ 0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0}; /* the dmx stream 32 by 16 rows */
volatile boolean dmxvaluesend = 0; //when dmx is recieved and modified so it's ready to sendready to send
/******************************* Timer2 variable declarations *****************************/
volatile byte zerocounter = 0;
/* a counter to hold the number of zeros received in sequence on the serial receive pin.
* When we've received a minimum of 11 zeros in a row, we must be in a break. As written,
* the timer2 ISR actually checks for 22 zeros in a row, for the full 88uS break. */
void setup() {
/***************************** dmx out ******************************* */
pinMode(sig, OUTPUT);
digitalWrite(13, HIGH);
/******************************* Max485 configuration ***********************************/
pinMode(receiveroutputenable, OUTPUT);
pinMode(driveroutputenable, OUTPUT);
digitalWrite(receiveroutputenable, LOW);
digitalWrite(driveroutputenable, LOW); //sets pins 3 and 4 to low to enable reciever mode on the MAX485.
pinMode(rxpin, INPUT); //sets serial pin to receive data
/******************************* Addressing subroutine *********************************/
digitalWrite(pinadd1, HIGH);
digitalWrite(pinadd2, HIGH);
digitalWrite(pinadd4, HIGH);
digitalWrite(pinadd8, HIGH);
digitalWrite(pinadd16, HIGH);
digitalWrite(pinadd32, HIGH);
digitalWrite(pinadd64, HIGH);
digitalWrite(pinadd128, HIGH); //turns on the internal pull-up resistor for adress pins 2 through 9
pinMode(pinadd1, INPUT);
pinMode(pinadd2, INPUT);
pinMode(pinadd4, INPUT);
pinMode(pinadd8, INPUT);
pinMode(pinadd16, INPUT);
pinMode(pinadd32, INPUT);
pinMode(pinadd64, INPUT);
pinMode(pinadd128, INPUT); //sets address pins to input
add1 = digitalRead(pinadd1);
add2 = digitalRead(pinadd2) *2;
add4 = digitalRead(pinadd4) *4;
add8 = digitalRead(pinadd8) *8;
add16 = digitalRead(pinadd16) *16;
add32= digitalRead(pinadd32) *32;
add64 = digitalRead(pinadd64) *64;
add128 = digitalRead(pinadd128) *128;
dmxaddress = (add1 + add2 + add4 + add8 + add16 + add32 + add64 + add128);
dmxaddress = dmxaddress + 3; // not sure about this
/* this will allow the USART receive interrupt to fire an additional 3 times for every dmx frame.
* Here's why:
* Once to account for the fact that DMX addresses run from 0-511, whereas channel numbers
* start numbering at 1.
* Once for the Mark After Break (MAB), which will be detected by the USART as a valid character
* (a zero, eight more zeros, followed by a one)
* Once for the START code that precedes the 512 DMX values (used for RDM). */
/******************************* USART configuration ************************************/
Serial.begin(250000);
/* Each bit is 4uS long, hence 250Kbps baud rate */
cli(); //disable interrupts while we're setting bits in registers
bitClear(UCSR0B, RXCIE0); //disable USART reception interrupt
/******************************* Timer2 configuration ***********************************/
//NOTE: this will disable PWM on pins 3 and 11.
bitClear(TCCR2A, COM2A1);
bitClear(TCCR2A, COM2A0); //disable compare match output A mode
bitClear(TCCR2A, COM2B1);
bitClear(TCCR2A, COM2B0); //disable compare match output B mode
bitSet(TCCR2A, WGM21);
bitClear(TCCR2A, WGM20); //set mode 2, CTC. TOP will be set by OCRA.
bitClear(TCCR2B, FOC2A);
bitClear(TCCR2B, FOC2B); //disable Force Output Compare A and B.
bitClear(TCCR2B, WGM22); //set mode 2, CTC. TOP will be set by OCRA.
bitClear(TCCR2B, CS22);
bitClear(TCCR2B, CS21);
bitSet(TCCR2B, CS20); // no prescaler means the clock will increment every 62.5ns (assuming 16Mhz clock speed).
OCR2A = 64;
/* Set output compare register to 64, so that the Output Compare Interrupt will fire
* every 4uS. */
bitClear(TIMSK2, OCIE2B); //Disable Timer/Counter2 Output Compare Match B Interrupt
bitSet(TIMSK2, OCIE2A); //Enable Timer/Counter2 Output Compare Match A Interrupt
bitClear(TIMSK2, TOIE2); //Disable Timer/Counter2 Overflow Interrupt Enable
sei(); //reenable interrupts now that timer2 has been configured.
} //end setup()
void loop() {
// the processor gets parked here while the ISRs are doing their thing.
if (dmxvaluesend == 1) { //when all dmx is read switch to send
///////////////////////////////////////////////////////////sending the dmx signal
// sending the break (the break can be between 88us and 1sec)
digitalWrite(sig, LOW);
delay(10);
//sending the start byte
shiftDmxOut(sig,0);
// send out the dmx
for (count = 1; count<=512; count++){
if (count <=4)
{
shiftDmxOut(sig, dmxvalue[count]);
} // send dmx 1 thru 4
else{
shiftDmxOut(sig, dmxstream[count]); //send normal dmx
}
}
dmxvaluesend = 0;
dmxcurrent = 0;
zerocounter = 0; //and then when finished reset variables and enable timer2 interrupt
i = 0;
bitSet(TIMSK2, OCIE2A); //Enable Timer/Counter2 Output Compare Match A Interrupt
}
} //end loop()
//Timer2 compare match interrupt vector handler
ISR(TIMER2_COMPA_vect) {
if (bitRead(PIND, PIND0)) { // if a one is detected, we're not in a break, reset zerocounter.
zerocounter = 0;
}
else {
zerocounter++; // increment zerocounter if a zero is received.
if (zerocounter == 22)
{
bitClear(TIMSK2, OCIE2A); //disable this interrupt and enable reception interrupt now that we're in a break.
bitSet(UCSR0B, RXCIE0);
}
}
} //end Timer2 ISR
ISR(USART_RX_vect){
dmxreceived = UDR0;
/* The receive buffer (UDR0) must be read during the reception ISR, or the ISR will just
* execute again immediately upon exiting. */
dmxcurrent++; //increment address counter
dmxstream[dmxcurrent]=dmxreceived;
if(dmxcurrent == dmxaddress) { //check if the current address is the one we want.
dmxvalue[i] = dmxreceived; // stores the levels we want
i++;
if(i == 4) {
bitClear(UCSR0B, RXCIE0);
}
}
if (dmxcurrent >= 512) //***************************** if all values have been read ******//
{
dmxvaluesend = 1; //set tells the program to send dmx
}
} // end ISR
any and all advice greatfully acepted.