Controler un ruban Led en DMX avec un Arduino

Bonjour,

Pour un examen d'études, j'ai besoin de pouvoir contrôler un ruban Led Adressable W2812B depuis une console en DMX.

J'arrive à contrôler mon ruban via mon Arduino UNO pour faire des choses simples mais j'aurais besoin de pouvoir contrôler chaque Led en RGB (3 canaux par Led).

J'ai un DMX Shield à mettre sur mon Arduino mais j'aimerais trouver les lignes de commande à entrer dans l'Arduino pour lui dire que chaque Led est contrôlée par ma console.

Autre question, quelqu'un sait comment disposer les trucs jaunes sur le DMX Shield pour ce cas de figure ?

J'espère que ma demande était claire.
Merci à tous

Bonjour,

Pas vraiment.
On ne sait pas

  • ce que sont les choses simples que tu arrives à faire
  • quel shield DMX tu utilises donc difficile de t'aider sur son utilisation

Bonsoir m_a_l_o

Si ça peut t'aider :wink:

Cordialement
jpbbricole

Bonjour,

C'est vrai que je ne suis pas très précis.

J'arrive globalement à faire ce que je souhaite avec le ruban en fonction des lignes de code que je trouve un peu partout en les adaptant (chase, led/led, etc.)
Mais j'ai juste besoin du code pour dire à ma console "projecteur 10*RGB" par exemple. Pour que depuis ma console (GrandMA2) je puisse controler le RGB de chaque led indépendamment.

J'utilise le DMX Shield MAX485

Des choses à voir ici

L'une des difficultés liées à la transmission du signal WS2812 réside dans le fait que, sur une carte UNO, les interruptions doivent être désactivées pour obtenir une synchronisation correcte. Or, la détection de la rupture de réinitialisation de trame DMX nécessite l'utilisation des interruptions.

J'ai utilisé ce code pour la réception DMX.

#define PWM_LED_PIN 5
#define DMX_PING 13
#define MAX_DMX_CHANNELS 512

#define NUMBER_OF_CHANNELS 510

#define BAUDDMX 250000UL

#define RECEIVE_FORMAT 0x06 // 8N1 (could be 8N2 aswell.

#define UBDMX ((F_CPU / (8 * BAUDDMX)) - 1)



volatile uint16_t dmxaddress = 1;
volatile uint16_t i = 0;
volatile uint8_t dmxreceived = 0;
volatile uint16_t dmxcurrent = 0;
volatile uint8_t dmxvalue[NUMBER_OF_CHANNELS];

volatile uint8_t dmxnewvalue = 0;
volatile uint8_t zerocounter = 0;
volatile bool storeSerial = false;

void setup() {

  pinMode(PWM_LED_PIN, OUTPUT); // first dmxchannel LED value
  pinMode(DMX_PING, OUTPUT); //ping LED
  init_uart();
  SetupTimerRegisters();
}

void loop()  {
  ReceiveDMX();
  Processing();

}

void ReceiveDMX() {
  dmxnewvalue = 0;
  dmxcurrent = 0;
  zerocounter = 0;
  i = 0;
  UCSR0C = RECEIVE_FORMAT; //0x06; // 8N1
  bitSet(UCSR0B, RXCIE0);   // enable RX ISR
  bitSet(TIMSK2, OCIE2A);
  while (dmxnewvalue != 1);
}

void Processing() {  // main processing
  static bool pin = true;
  pin = !pin;
  analogWrite(5, dmxvalue[0]);
  digitalWrite(13, pin);
  if (dmxvalue[0] > 200) {
    digitalWrite(13, HIGH);
  }
  else {
    digitalWrite(13, LOW);
  }
}

void init_uart() {
  DDRD |=  (1 << PORTD1); // set TX pin  to output
  DDRD &= ~(1 << PORTD0); // set RX pin to input
  UCSR0A = 0x02; // 1<<U2X | 0<<MPCM;
  UCSR0B = 1 << RXCIE0 | 0 << TXCIE0 | 0 << UDRIE0 | 1 << RXEN0 | 1 << TXEN0 | 0 << UCSZ02; // Enable TX & RX, disable RX interrupt
  UCSR0C = RECEIVE_FORMAT; // 8N1
  UBRR0H = (UBDMX >> 8);  // set baud rate
  UBRR0L = (UBDMX & 0xFF); // HL register
}

void SetupTimerRegisters() {  // Sets up Timer2 to fire every 4us
  cli();
  bitClear(TCCR2A, COM2A1);
  bitClear(TCCR2A, COM2A0);
  bitClear(TCCR2A, COM2B1);
  bitClear(TCCR2A, COM2B0);
  bitSet(TCCR2A, WGM21);
  bitClear(TCCR2A, WGM20);
  bitClear(TCCR2B, FOC2A);
  bitClear(TCCR2B, FOC2B);
  bitClear(TCCR2B, WGM22);
  bitClear(TCCR2B, CS22);
  bitClear(TCCR2B, CS21);
  bitSet(TCCR2B, CS20);
  OCR2A = 64;
  bitClear(TIMSK2, OCIE2B);
  bitSet(TIMSK2, OCIE2A);
  bitClear(TIMSK2, TOIE2);
  sei();
}

ISR(TIMER2_COMPA_vect) {
  if (bitRead(PIND, PIND0)) {  // checks if the pin has gone HIGH
    zerocounter = 0;
  }
  else {
    zerocounter++;
    if (zerocounter == 20)  // if 80us have passed 'Break' has been detected
    {
      bitClear(TIMSK2, OCIE2A);  // disable Timer2 Interrupt
      storeSerial = true;

    }
  }
} //end Timer2 ISR

ISR(USART_RX_vect) {
  dmxreceived = UDR0;
  if (storeSerial) {
    dmxcurrent++;     //increment address counter starts at 0
    // this skips the start code
    if (dmxcurrent > dmxaddress) {        //check if the current address is the one we want.
      dmxvalue[i] = dmxreceived;
      i++;
      if ((i == NUMBER_OF_CHANNELS) || (dmxcurrent > MAX_DMX_CHANNELS - 2)) {
        bitClear(UCSR0B, RXCIE0);                   // disable RX ISR
        storeSerial = false;                      // set the flag to false
        dmxnewvalue = 1;                        //set newvalue, so that the main code can be executed.
      }
    }
  }
} // end ISR

Il s'agit d'une adaptation de ce que j'ai trouvé ici à l'origine (Méthode Max Pierson).