Advertisement
stb

DMX Transceiver Arduino Nano

stb
Dec 4th, 2018
541
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Based on Hendrik Hoelschers dmx code from http://www.hoelscher-hi.de/hendrik/
  2. // Optimized for Arduino Nano
  3.  
  4.  
  5.  
  6. #include <avr/io.h>
  7. #include <stdint.h>
  8. #include <avr/interrupt.h>
  9.  
  10.  
  11. // ********************* local definitions *********************
  12. #define DMX_CHANNELS    (6)            //Define the number of DMX values to store
  13.  
  14. enum {IDLE, BREAK, STARTB, STARTADR};      //DMX states
  15.  
  16. uint8_t  gDmxState;
  17. uint8_t  *gDmxPnt;
  18. uint16_t DmxCount;
  19.  
  20. int addr1dummy;
  21. int addr1;
  22. int addr2;
  23. int addr3;
  24. int addr4;
  25. int addr5;
  26. int addr6;
  27. int addr7;
  28. int addr8;
  29. int addr9;
  30.  
  31. bool bStartDone;
  32.  
  33. uint8_t  DmxField[DMX_CHANNELS];     //array of DMX vals (raw)
  34. uint16_t DmxAddress;                   //start address
  35.  
  36. int chOut1 = 3;
  37. int chOut2 = 5;
  38. int chOut3 = 6;
  39. int chOut4 = 9;
  40. int chOut5 = 10;
  41. int chOut6 = 11;
  42.  
  43. int addrPin1 = A0;
  44. int addrPin2 = A1;
  45. int addrPin3 = A2;
  46. int addrPin4 = A3;
  47. int addrPin5 = A4;
  48. int addrPin6 = A5;
  49. int addrPin7 = 7;
  50. int addrPin8 = 8;
  51. int addrPin9 = 12;
  52.  
  53. void setup()                           // run once, when the sketch starts
  54. {
  55.  
  56. // Die Pins 3, 5, 6, 9, 10 und 11 können PWM ausgeben, diese werden als Outputs verwendet.
  57.  pinMode(chOut1, OUTPUT);
  58.  pinMode(chOut2, OUTPUT);
  59.  pinMode(chOut3, OUTPUT);
  60.  pinMode(chOut4, OUTPUT);
  61.  pinMode(chOut5, OUTPUT);
  62.  pinMode(chOut6, OUTPUT);
  63.  
  64. // Nachfolgende Pins werden für die DIP-Switches verwendet.
  65.  
  66.  pinMode(A0, INPUT);
  67.  pinMode(A1, INPUT);
  68.  pinMode(A2, INPUT);
  69.  pinMode(A3, INPUT);
  70.  pinMode(A4, INPUT);
  71.  pinMode(A5, INPUT);
  72.  pinMode(7, INPUT);
  73.  pinMode(8, INPUT);
  74.  pinMode(12, INPUT);
  75.  
  76. // Pullups setzen auf den DIP-Switch-Inputs.
  77.  
  78.  digitalWrite(A0, HIGH);
  79.  digitalWrite(A1, HIGH);
  80.  digitalWrite(A2, HIGH);
  81.  digitalWrite(A3, HIGH);
  82.  digitalWrite(A4, HIGH);
  83.  digitalWrite(A5, HIGH);
  84.  digitalWrite(7, HIGH);
  85.  digitalWrite(8, HIGH);
  86.  digitalWrite(12, HIGH);
  87.  
  88.  
  89.  // Disable interrupts
  90.  cli();
  91.  
  92.  // 250kbps baud - only works for 16MHz clock frequency. See the ATMega8 datasheet if you are using a different clock speed
  93.  UBRR0H = 0;
  94.  UBRR0L = 3;
  95.  
  96.  // enable rx and interrupt on complete reception of a byte
  97.  UCSR0B = (1<<RXEN0)|(1<<RXCIE0);
  98.  UCSR0C = (1<<UMSEL01)|(3<<UCSZ00)|(1<<USBS0);
  99.  
  100.  // Enable interrupts
  101.  sei();
  102.  
  103.  gDmxState= IDLE;
  104.  
  105.  uint8_t i;
  106.  for (i=0; i<DMX_CHANNELS; i++)
  107.  {
  108.    DmxField[i]= 0;
  109.  }
  110.  
  111.  
  112.  delay(2000);
  113.  bStartDone = 1;
  114.  
  115.  
  116. }
  117.  
  118. void loop()                     // run over and over again
  119.  
  120. {
  121.  if (bStartDone == 1) // Programm erst nach 2 Sekunden ausführen (Delay in Setup-Routine vorgegeben), um Flicker beim Einschalten zu vermeiden
  122.   {
  123.  
  124.   if (digitalRead(addrPin1) == 0) {addr1 = 1;} else {addr1 = 0;}
  125.   if (digitalRead(addrPin2) == 0) {addr2 = 2;} else {addr2 = 0;}
  126.   if (digitalRead(addrPin3) == 0) {addr3 = 4;} else {addr3 = 0;}
  127.   if (digitalRead(addrPin4) == 0) {addr4 = 8;} else {addr4 = 0;}
  128.   if (digitalRead(addrPin5) == 0) {addr5 = 16;} else {addr5 = 0;}
  129.   if (digitalRead(addrPin6) == 0) {addr6 = 32;} else {addr6 = 0;}
  130.   if (digitalRead(addrPin7) == 0) {addr7 = 64;} else {addr7 = 0;}
  131.   if (digitalRead(addrPin8) == 0) {addr8 = 128;} else {addr8 = 0;}
  132.   if (digitalRead(addrPin9) == 0) {addr9 = 256;} else {addr9 = 0;}
  133.  
  134.  if ((addr1 + addr2 + addr3 + addr4 + addr5 + addr6 + addr7 + addr8 + addr9) == 0) {addr1dummy = 1;} else {addr1dummy = 0;} // Wenn kein DIP-Schalter auf ON steht, ist die Adresse 1.
  135.  
  136.   DmxAddress= (addr1dummy + addr1 + addr2 + addr3 + addr4 + addr5 + addr6 + addr7 + addr8 + addr9);  //DMX-Adresse setzen
  137.  
  138.   analogWrite(chOut1, DmxField[0]);
  139.   analogWrite(chOut2, DmxField[1]);
  140.   analogWrite(chOut3, DmxField[2]);
  141.   analogWrite(chOut4, DmxField[3]);
  142.   analogWrite(chOut5, DmxField[4]);
  143.   analogWrite(chOut6, DmxField[5]);
  144.      
  145.   }
  146. }
  147.  
  148. // *************** DMX Reception ISR ****************
  149. SIGNAL(USART_RX_vect)
  150. {
  151. uint8_t USARTstate= UCSR0A;                              //get state
  152. uint8_t DmxByte= UDR0;                                    //get data
  153. uint8_t DmxState= gDmxState;                              //just get once from SRAM!!!
  154.  
  155. if (USARTstate &(1<<FE0))                              //check for break
  156.      {
  157.      UCSR0A &= ~(1<<FE0);                              //reset flag
  158.      DmxCount= DmxAddress;                              //reset frame counter
  159.      gDmxState= BREAK;
  160.      }
  161.  
  162. else if (DmxState == BREAK)
  163.      {
  164.      if (DmxByte == 0)
  165.            {
  166.            gDmxState= STARTB;                        //normal start code detected
  167.            gDmxPnt= ((uint8_t*)DmxField +1);
  168.            }
  169.      else gDmxState= IDLE;
  170.      }
  171.  
  172. else if (DmxState == STARTB)
  173.      {
  174.      if (--DmxCount == 0)                              //start address reached?
  175.            {
  176.            gDmxState= STARTADR;
  177.            DmxField[0]= DmxByte;
  178.            }
  179.      }
  180.  
  181. else if (DmxState == STARTADR)
  182.      {
  183.      uint8_t *DmxPnt;
  184.      DmxPnt= gDmxPnt;
  185.      *DmxPnt= DmxByte;
  186.      if (++DmxPnt >= (DmxField +DMX_CHANNELS))             //all ch received?
  187.            {
  188.            gDmxState= IDLE;
  189.            }
  190.      else gDmxPnt= DmxPnt;
  191.      }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement