DMX hardware rec for Teensy 3.2?

Status
Not open for further replies.
(Note: you need an “end code” when wrapping code — [/CODE].)

Code:
data[7] = 0;
data[8] = 128;
data[9] = 128;
Etc…

It works in the setup section because that’s one of several syntaxes for “creating an array of length 7 and then initializing it with some values.” You’re trying to do an assignment and C++ doesn’t have “assign several things to an array at once, starting from a specific index.”
 
Excellent Shawn! Thanks... I was sucessfull at applying that technique but it seemed unweildly so I tried to get fancy. Thanks again.

The light show is simple but there are a lot of mechanics and sound that is taking a ton of time too. I don't work this hard at work!

Photos soon
 
Opening Night... Tonight!

Thanks for everybody's help with this! I got everything working except addressing individual lights (Case 8 in the DMX Function section shows one of many attempts). Other than that, the show is exactly what I hoped for and is going to be fun for a lot of kids who will hopefully turn to STEM in education. For me? I learned a ton about coding the Teensy and balancing coding, mechanics and soldering under a time constraint. I am literally writing this while my thumb is bleeding.

Anyway, here is my 2021 Halloween Show "Paper Moon". I'll send video soon; the music really makes it...

Jeff


Code:
/***************************************************
  Holiday Show Control - v1.1 10/15/21
  by Jeff W. Parisse - 09/09/2021
  jparisse@me.com
  TeensyDMX library (c) 2019-2020 Shawn Silverman
  Adafruit Servo Driver Library Written by Limor Fried/Ladyada for Adafruit Industries.
  Thanks to Shawn and Paul S. for their help on the PJRC Forums.

  This program acts as a show controller for holiday show projects. It runs on a Teesy 3.2 and controls servos via
  a I2C servo controller, addressable LEDs via an external processor, sound via an 16Mb Sound F/C Controller and
  DMX via a CTC-DRA-10-R2 Arduino Shield.

  Processor: Teensy 3.2
  PIR Sensor: 5V In, 3.3V Logic HIGH on Detect
  DMX Shield: Generic using TeensyDMX Library
  NEO Processor; Adafruit Itsy Bitsy M4 Express, LOW to trigger
  Sound F/X Board: LOW to trigger
  Servo Driver: I2C Address A1 (despite hardware A0 selected)
  AC Relays: HIGH to turn ON

  Pin Outs:
    Pin 0   RX    Serial In
    Pin 1   TX    Serial Out
    Pin 2   DMX   DOUT
    Pin 3   PIR   DIN
    Pin 4   AUX   DIN
    Pin 5   NEO   DOUT
    Pin 6   AC1   DOUT
    Pin 7   AC2   DOUT
    Pin 8   SFX0  DOUT
    Pin 9   SFX1  DOUT
    Pin 10  SFX2  DOUT
    Pin 11  SFX3  DOUT
    Pin 12  SFX4  DOUT
    Pin 13  LED   DOUT
    Pin 14  SFX5  DOUT
    Pin 15  SFX6  DOUT
    Pin 16  SFX7  DOUT
    Pin 17  SFX8  DOUT
    Pin 18  SDA   I2C
    Pin 19  SCL   I2C
    Pin 22  VOL+  DOUT (v1.1 not used)
    Pin 23  VOL-  DOUT (v1.1 not used)
 ****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <TeensyDMX.h>

#define dmxPin 2
#define pirPin 3
#define auxPin 4
#define neoPin 5
#define ac1Pin 6
#define ac2Pin 7
#define sfx0Pin 8
#define sfx1Pin 9
#define sfx2Pin 10
#define sfx3Pin 11
#define sfx4Pin 12
#define ledPin 13
#define sfx5Pin 14
#define sfx6Pin 15
#define sfx7Pin 16
#define sfx8Pin 17
#define volupPin 22
#define voldnPin 23
#define servoFreq 50                 // ~50 Hz servo updates

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
namespace teensydmx = ::qindesign::teensydmx;
teensydmx::Sender dmxTx{Serial1};

// DMX Variables
uint8_t data[7] = {255, 0, 0, 0, 0, 0, 0};          // Default: OFF
unsigned long dmxInterval = 1000;                   // 1sec
unsigned long previousDmxMillis = 0;
uint8_t dmxPick = 1;                                // Default
uint8_t x = 0;                                      // For Loop Counter

// Servo Variables
uint8_t servo1 = 0;
uint8_t servo2 = 1;
uint8_t servo3 = 2;
uint8_t servo4 = 3;
uint8_t servo5 = 4;
uint8_t servo6 = 5;
uint8_t servo7 = 6;
uint8_t servo8 = 7;
uint8_t servo9 = 8;
uint8_t servo10 = 9;
uint8_t servo11 = 10;
uint8_t servo12 = 11;
uint8_t servo13 = 12;
uint8_t servo14 = 13;
uint8_t servo15 = 14;
uint8_t servo16 = 15;

// Servo Timer
boolean servoDirection = LOW;
uint16_t servoMin = 167;                       // 900ms This is the 'minimum' pulse length count (out of 4096)
uint16_t servoCenter = 279;                    // 900ms This is the 'minimum' pulse length count (out of 4096)
uint16_t servoMax = 390;                       // 2100ms This is the 'maximum' pulse length count (out of 4096)
unsigned long servoInterval = 500;             // Default
unsigned long previousServoMillis = 0;

// Moon Timer (Blocking)
boolean moonState = LOW;
uint16_t moonUp = 167;                        // 900ms This is the 'minimum' pulse length count (out of 4096)
uint16_t moonDown = 390;                      // 2100ms This is the 'maximum' pulse length count (out of 4096)
unsigned long moonSongInterval = 30000;       // Length of Song #1 - Paper Moon

// Show Timer
boolean showState = LOW;
int showMin = 120000;                         // 120,000 ms = 00:02:00 (two minutes)
int showMax = 180000;                         // 180,000 ms = 00:03:00 (three minutes)
unsigned long showInterval = 120000;          // Default: 120,000 ms = 00:02:00
unsigned long previousShowMillis = 0;

// Delay Timer
boolean delayState = LOW;
int delayMin = 60000;                        // 60,000 ms = 00:01:00 (one minute)
int delayMax = 120000;                       // 120,000 ms = 00:02:00 (two minutes)
unsigned long delayInterval = 30000;         // Default: 30,000 ms = 00:00:30
unsigned long previousDelayMillis = 0;

int songPick = 1;                            // Start with Song #1
int intervalPick = 2;                        // Default
int danceStep = 250;                         // Default

void setup() {
  // Serial.begin(115200);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(servoFreq);                 // Analog servos run at ~50 Hz updates
  pinMode(pirPin, INPUT);
  pinMode(auxPin, INPUT_PULLUP);
  pinMode(dmxPin, OUTPUT);
  pinMode(neoPin, OUTPUT);
  pinMode(ac1Pin, OUTPUT);
  pinMode(ac2Pin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(sfx0Pin, OUTPUT);
  pinMode(sfx1Pin, OUTPUT);
  pinMode(sfx2Pin, OUTPUT);
  pinMode(sfx3Pin, OUTPUT);
  pinMode(sfx4Pin, OUTPUT);
  pinMode(sfx5Pin, OUTPUT);
  pinMode(sfx6Pin, OUTPUT);
  pinMode(sfx7Pin, OUTPUT);
  pinMode(sfx8Pin, OUTPUT);
  pinMode(volupPin, OUTPUT);
  pinMode(voldnPin, OUTPUT);
  // Turn everything OFF
  pwm.setPWM(servo9, 0, moonDown);          // Moon Servo
  digitalWrite(dmxPin, HIGH);               // Set DMX TX Pin to HIGH
  for (x = 1; x <= 23; x = x + 7) {         // Set DMX Lights to OFF
    dmxTx.set(x, data, 7);
  }
  dmxTx.begin();                            // Start DMX
  digitalWrite(neoPin, LOW);                // LEDs OFF
  digitalWrite(ac1Pin, LOW);                // Black Light OFF
  digitalWrite(ac2Pin, LOW);                // Mirrored Ball & Spotlight OFF
  digitalWrite(ledPin, LOW);                // Trigger Indicator OFF
  soundOff();                               // All sounds OFF
  delay(3000);                              // Wait 3 seconds for PIR Module to go LOW
  digitalWrite(sfx0Pin, LOW);               // Ambient Sound ON
}

void loop() {
  unsigned long currentMillis = millis();                                       // Check Time
  boolean pirState = digitalRead(pirPin);                                       // Check PIR Trigger
  if (pirState == HIGH) {                                                       // If PIR triggered, change showState to HIGH
    showState = HIGH;
    digitalWrite(ledPin, HIGH);
  }
  else {
    digitalWrite(ledPin, LOW);
  }
  if (currentMillis - previousDelayMillis >= delayInterval) {
    previousDelayMillis = currentMillis;
    delayState = HIGH;
  }
  if (showState == HIGH && delayState == HIGH) {
    digitalWrite(sfx0Pin, HIGH);                                               // Ambient Sound OFF
    if (moonState == LOW) {                                                    // Check if Moon Show has run
      digitalWrite(ac1Pin, HIGH);                                              // Black Lights ON
      digitalWrite(sfx1Pin, LOW);                                              // Play Paper Moon
      for (uint16_t moonPos = moonDown; moonPos >= moonUp; --moonPos) {        // Moon UP
        pwm.setPWM(servo9, 0, moonPos);
        delay(10);
      }
      delay(moonSongInterval);
      for (uint16_t moonPos = moonUp; moonPos <= moonDown; ++moonPos) {        // Moon DOWN
        pwm.setPWM(servo9, 0, moonPos);
        delay(10);
      }
      digitalWrite(ac1Pin, LOW);                                               // Black Lights OFF
      soundOff();                                                              // All sound OFF
      moonState = HIGH;                                                        // Moon Show has run
    }
    // Dance Show Starts Here
    digitalWrite(ac2Pin, HIGH);                                                // Mirror Ball ON
    digitalWrite(neoPin, HIGH);                                                // Neopixels ON
    playSong();                                                                // Start Music
    if (currentMillis - previousDmxMillis >= dmxInterval) {
      previousDmxMillis = currentMillis;
      playDmx();
    }
    if (servoDirection == LOW) {
      uint16_t pulseLengthLow1 = random(servoMin, servoCenter);
      uint16_t pulseLengthLow2 = random(servoMin, servoCenter);
      pwm.setPWM(servo1, 0, pulseLengthLow1);
      pwm.setPWM(servo2, 0, pulseLengthLow2);
      servoInterval = getDanceStep();
      servoDirection = HIGH;
    }
    else {
      uint16_t pulseLengthHigh1 = random(servoCenter, servoMax);
      uint16_t pulseLengthHigh2 = random(servoCenter, servoMax);
      pwm.setPWM(servo1, 0, pulseLengthHigh1);
      pwm.setPWM(servo2, 0, pulseLengthHigh2);
      servoInterval = getDanceStep();
      servoDirection = LOW;
    }
    if (currentMillis - previousShowMillis >= showInterval) {       // Check for End of Show
      previousShowMillis = currentMillis;
      previousDelayMillis = currentMillis;
      showState = LOW;
      delayState = LOW;
      moonState = LOW;
      pwm.setPWM(servo1, 0, servoCenter);                           // Center Servo1
      pwm.setPWM(servo2, 0, servoCenter);                           // Center Servo2
      pwm.setPWM(servo9, 0, moonDown);                              // Moon DOWN
      digitalWrite(neoPin, LOW);                                    // Turn NeoPixels Off
      digitalWrite(ac2Pin, LOW);                                    // AC 2 OFF - Mirrored Ball & Pin Spot
      soundOff();                                                   // Turn Sound OFF
      dmxOff();                                                     // Turn DMX OFF
      digitalWrite(sfx0Pin, LOW);                                   // Sound #0 ON - Scene 0
      ++songPick;                                                   // Advance Song List by 1
      if (songPick >= 8) {                                          // If >7, Rollover Song List
        songPick = 1;
      }
      showInterval = random(showMin, showMax);                      // Pick new show interval.
      delayInterval = random(delayMin, delayMax);                   // Pick new delay interval.
    }
  }
}

// Functions
void soundOff() {
  digitalWrite(sfx0Pin, HIGH);
  digitalWrite(sfx1Pin, HIGH);
  digitalWrite(sfx2Pin, HIGH);
  digitalWrite(sfx3Pin, HIGH);
  digitalWrite(sfx4Pin, HIGH);
  digitalWrite(sfx5Pin, HIGH);
  digitalWrite(sfx6Pin, HIGH);
  digitalWrite(sfx7Pin, HIGH);
  digitalWrite(sfx8Pin, HIGH);
  digitalWrite(volupPin, HIGH);
  digitalWrite(voldnPin, HIGH);
}

void dmxOff() {
  data[0] = 255;
  data[1] = 0;
  data[2] = 0;
  data[3] = 0;
  data[4] = 0;
  data[5] = 0;
  data[6] = 0;
  for (x = 1; x <= 23; x = x + 7) {
    dmxTx.set(x, data, 7);
  }
}

void playSong() {
  switch (songPick) {
    case 1:
      digitalWrite(sfx2Pin, LOW);
      break;
    case 2:
      digitalWrite(sfx3Pin, LOW);
      break;
    case 3:
      digitalWrite(sfx4Pin, LOW);
      break;
    case 4:
      digitalWrite(sfx5Pin, LOW);
      break;
    case 5:
      digitalWrite(sfx6Pin, LOW);
      break;
    case 6:
      digitalWrite(sfx7Pin, LOW);
      break;
    case 7:
      digitalWrite(sfx8Pin, LOW);
      break;
  }
}

void playDmx() {
  dmxPick = random(1, 11);
  switch (dmxPick) {
    case 1: // Red
      data[0] = 255;
      data[1] = 255;
      data[2] = 0;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 2: // Green
      data[0] = 255;
      data[1] = 0;
      data[2] = 255;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 3: // Blue
      data[0] = 255;
      data[1] = 0;
      data[2] = 0;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 4: // White
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 5: // Yellow
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 6: // Purple
      data[0] = 255;
      data[1] = 255;
      data[2] = 0;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 7: // Cyan
      data[0] = 255;
      data[1] = 0;
      data[2] = 255;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 8: // Spotlight Dancer #1
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 16; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 9: // Spotlight Dancer #2
      //
    case 10: // Red Spot Dancer #2
      //
      break;
  }
}

int getDanceStep() {
  intervalPick = random(1, 5);
  switch (intervalPick) {
    case 1:
      danceStep = 125;
      break;
    case 2:
      danceStep = 250;
      break;
    case 3:
      danceStep = 375;
      break;
    case 4:
      danceStep = 500;
      break;
  }
  return danceStep;
}
 
I revised the code to clean up timing events and remove a dance code bug:

Code:
/***************************************************
  Holiday Show Control - v1.1 10/15/21
  by Jeff W. Parisse - 09/09/2021
  jparisse@me.com
  TeensyDMX library (c) 2019-2020 Shawn Silverman
  Adafruit Servo Driver Library Written by Limor Fried/Ladyada for Adafruit Industries.
  Thanks to Shawn and Paul S. for their help on the PJRC Forums.

  This program acts as a show controller for holiday show projects. It runs on a Teesy 3.2 and controls servos via
  a I2C servo controller, addressable LEDs via an external processor, sound via an 16Mb Sound F/C Controller and
  DMX via a CTC-DRA-10-R2 Arduino Shield.

  Processor: Teensy 3.2
  PIR Sensor: 5V In, 3.3V Logic HIGH on Detect
  DMX Shield: Generic using TeensyDMX Library
  NEO Processor; Adafruit Itsy Bitsy M4 Express, LOW to trigger
  Sound F/X Board: LOW to trigger
  Servo Driver: I2C Address A1 (despite hardware A0 selected)
  AC Relays: HIGH to turn ON

  Pin Outs:
    Pin 0   RX    Serial In
    Pin 1   TX    Serial Out
    Pin 2   DMX   DOUT
    Pin 3   PIR   DIN
    Pin 4   AUX   DIN
    Pin 5   NEO   DOUT
    Pin 6   AC1   DOUT
    Pin 7   AC2   DOUT
    Pin 8   SFX0  DOUT
    Pin 9   SFX1  DOUT
    Pin 10  SFX2  DOUT
    Pin 11  SFX3  DOUT
    Pin 12  SFX4  DOUT
    Pin 13  LED   DOUT
    Pin 14  SFX5  DOUT
    Pin 15  SFX6  DOUT
    Pin 16  SFX7  DOUT
    Pin 17  SFX8  DOUT
    Pin 18  SDA   I2C
    Pin 19  SCL   I2C
    Pin 22  VOL+  DOUT (v1.1 not used)
    Pin 23  VOL-  DOUT (v1.1 not used)
 ****************************************************/

#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <TeensyDMX.h>

#define dmxPin 2
#define pirPin 3
#define auxPin 4
#define neoPin 5
#define ac1Pin 6
#define ac2Pin 7
#define sfx0Pin 8
#define sfx1Pin 9
#define sfx2Pin 10
#define sfx3Pin 11
#define sfx4Pin 12
#define ledPin 13
#define sfx5Pin 14
#define sfx6Pin 15
#define sfx7Pin 16
#define sfx8Pin 17
#define volupPin 22
#define voldnPin 23
#define servoFreq 50                 // ~50 Hz servo updates

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
namespace teensydmx = ::qindesign::teensydmx;
teensydmx::Sender dmxTx{Serial1};

// DMX Variables
boolean dmxToggle = HIGH;
uint8_t data[7] = {255, 0, 0, 0, 0, 0, 0};          // Default: OFF
uint8_t dmxPick = 1;                                // Default
uint8_t x = 0;                                      // For Loop Counter

// Servo Variables
uint8_t servo1 = 0;
uint8_t servo2 = 1;
uint8_t servo3 = 2;
uint8_t servo4 = 3;
uint8_t servo5 = 4;
uint8_t servo6 = 5;
uint8_t servo7 = 6;
uint8_t servo8 = 7;
uint8_t servo9 = 8;
uint8_t servo10 = 9;
uint8_t servo11 = 10;
uint8_t servo12 = 11;
uint8_t servo13 = 12;
uint8_t servo14 = 13;
uint8_t servo15 = 14;
uint8_t servo16 = 15;

// Servo Timer
boolean servoDirection = LOW;
uint16_t servoMin = 167;                       // 900ms This is the 'minimum' pulse length count (out of 4096)
uint16_t servoCenter = 279;                    // 900ms This is the 'minimum' pulse length count (out of 4096)
uint16_t servoMax = 390;                       // 2100ms This is the 'maximum' pulse length count (out of 4096)
unsigned long servoInterval = 500;             // Default
unsigned long previousServoMillis = 0;

// Moon Timer (Blocking)
boolean moonState = LOW;
uint16_t moonUp = 167;                        // 900ms This is the 'minimum' pulse length count (out of 4096)
uint16_t moonDown = 390;                      // 2100ms This is the 'maximum' pulse length count (out of 4096)
unsigned long moonSongInterval = 30000;       // Length of Song #1 - Paper Moon

// Show Timer
boolean showState = LOW;
int showMin = 120000;                         // 120,000 ms = 00:02:00 (two minutes)
int showMax = 180000;                         // 180,000 ms = 00:03:00 (three minutes)
unsigned long showInterval = 120000;          // Default: 120,000 ms = 00:02:00
unsigned long previousShowMillis = 0;

// Delay Timer (Blocking)
boolean delayState = LOW;
int delayMin = 15000;                        // 15,000 ms = 00:00:15 (fifteen seconds)
int delayMax = 60000;                        // 60,000 ms = 00:01:00 (one minute)
int randomDelay = 0;                         // Default

// Show Default Variables
int songPick = 1;                            // Start with Song #1
int intervalPick = 2;                        // Default
int danceStep = 250;                         // Default

void setup() {
  // Serial.begin(115200);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(servoFreq);                 // Analog servos run at ~50 Hz updates
  pinMode(pirPin, INPUT);
  pinMode(auxPin, INPUT_PULLUP);
  pinMode(dmxPin, OUTPUT);
  pinMode(neoPin, OUTPUT);
  pinMode(ac1Pin, OUTPUT);
  pinMode(ac2Pin, OUTPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(sfx0Pin, OUTPUT);
  pinMode(sfx1Pin, OUTPUT);
  pinMode(sfx2Pin, OUTPUT);
  pinMode(sfx3Pin, OUTPUT);
  pinMode(sfx4Pin, OUTPUT);
  pinMode(sfx5Pin, OUTPUT);
  pinMode(sfx6Pin, OUTPUT);
  pinMode(sfx7Pin, OUTPUT);
  pinMode(sfx8Pin, OUTPUT);
  pinMode(volupPin, OUTPUT);
  pinMode(voldnPin, OUTPUT);

  // Turn everything OFF
  pwm.setPWM(servo9, 0, moonDown);          // Moon Servo
  digitalWrite(dmxPin, HIGH);               // Set DMX TX Pin to HIGH
  for (x = 1; x <= 23; x = x + 7) {         // Set DMX Lights to OFF
    dmxTx.set(x, data, 7);
  }
  dmxTx.begin();                            // Start DMX
  digitalWrite(neoPin, LOW);                // LEDs OFF
  digitalWrite(ac1Pin, LOW);                // Black Light OFF
  digitalWrite(ac2Pin, LOW);                // Mirrored Ball & Spotlight OFF (Not Used)
  digitalWrite(ledPin, LOW);                // Trigger Indicator OFF
  soundOff();                               // All sounds OFF
  delay(3000);                              // Wait 3 seconds for PIR Module to go LOW
  digitalWrite(sfx0Pin, LOW);               // Ambient Sound ON
}

void loop() {
  unsigned long currentMillis = millis();                                       // Check Time
  boolean pirState = digitalRead(pirPin);                                       // Check PIR Trigger
  if (pirState == HIGH) {                                                       // If PIR triggered, change showState to HIGH
    digitalWrite(ledPin, HIGH);
    showState = HIGH;
  }
  else {
    digitalWrite(ledPin, LOW);
  }
  if (delayState == HIGH) {
    delay(randomDelay);
    delayState = LOW;
  }
  if (showState == HIGH) {
    digitalWrite(sfx0Pin, HIGH);                                               // Ambient Sound OFF
    if (moonState == LOW) {                                                    // Check if Moon Show has run
      digitalWrite(ac1Pin, HIGH);                                              // Black Lights ON
      digitalWrite(sfx1Pin, LOW);                                              // Play Paper Moon
      for (uint16_t moonPos = moonDown; moonPos >= moonUp; --moonPos) {        // Moon UP
        pwm.setPWM(servo9, 0, moonPos);
        delay(10);
      }
      delay(moonSongInterval);                                                 // Wait for Song
      for (uint16_t moonPos = moonUp; moonPos <= moonDown; ++moonPos) {        // Moon DOWN
        pwm.setPWM(servo9, 0, moonPos);
        delay(10);
      }
      digitalWrite(ac1Pin, LOW);                                     // Black Lights OFF
      soundOff();                                                    // All sound OFF
      moonState = HIGH;                                              // Moon Show has run
    }
    digitalWrite(ac2Pin, HIGH);                                      // Mirror Ball ON
    digitalWrite(neoPin, HIGH);                                      // Neopixels ON
    playSong();                                                      // Start Music

    // Dance Show Starts Here
    if (currentMillis - previousServoMillis >= servoInterval) {      //
      previousServoMillis = currentMillis;
      playServo();
      if (dmxToggle == HIGH); {
      playDmx();
      }
      dmxToggle = !dmxToggle;
    }

    if (currentMillis - previousShowMillis >= showInterval) {       // Check for End of Show
      previousShowMillis = currentMillis;
      showState = LOW;
      moonState = LOW;
      delayState = HIGH;
      pwm.setPWM(servo1, 0, servoCenter);                           // Center Servo1
      pwm.setPWM(servo2, 0, servoCenter);                           // Center Servo2
      pwm.setPWM(servo9, 0, moonDown);                              // Moon DOWN
      digitalWrite(neoPin, LOW);                                    // Turn NeoPixels Off
      digitalWrite(ac2Pin, LOW);                                    // AC 2 OFF - Mirrored Ball & Pin Spot
      soundOff();                                                   // Turn Sound OFF
      dmxOff();                                                     // Turn DMX OFF
      digitalWrite(sfx0Pin, LOW);                                   // Sound #0 ON - Scene 0
      ++songPick;                                                   // Advance Song List by 1
      if (songPick >= 8) {                                          // If >7, Rollover Song List
        songPick = 1;
      }
      showInterval = random(showMin, showMax);                      // Pick new show interval.
      randomDelay = random(delayMin, delayMax);                     // Pick new delay interval.
    }
  }
}

// Functions
void soundOff() {
  digitalWrite(sfx0Pin, HIGH);
  digitalWrite(sfx1Pin, HIGH);
  digitalWrite(sfx2Pin, HIGH);
  digitalWrite(sfx3Pin, HIGH);
  digitalWrite(sfx4Pin, HIGH);
  digitalWrite(sfx5Pin, HIGH);
  digitalWrite(sfx6Pin, HIGH);
  digitalWrite(sfx7Pin, HIGH);
  digitalWrite(sfx8Pin, HIGH);
  digitalWrite(volupPin, HIGH);
  digitalWrite(voldnPin, HIGH);
}

void dmxOff() {
  data[0] = 255;
  data[1] = 0;
  data[2] = 0;
  data[3] = 0;
  data[4] = 0;
  data[5] = 0;
  data[6] = 0;
  for (x = 1; x <= 23; x = x + 7) {
    dmxTx.set(x, data, 7);
  }
}

void playSong() {
  switch (songPick) {
    case 1:
      digitalWrite(sfx2Pin, LOW);
      break;
    case 2:
      digitalWrite(sfx3Pin, LOW);
      break;
    case 3:
      digitalWrite(sfx4Pin, LOW);
      break;
    case 4:
      digitalWrite(sfx5Pin, LOW);
      break;
    case 5:
      digitalWrite(sfx6Pin, LOW);
      break;
    case 6:
      digitalWrite(sfx7Pin, LOW);
      break;
    case 7:
      digitalWrite(sfx8Pin, LOW);
      break;
  }
}

void playServo() {
  if (servoDirection == LOW) {
    uint16_t pulseLengthLow1 = random(servoMin, servoCenter);
    uint16_t pulseLengthLow2 = random(servoMin, servoCenter);
    pwm.setPWM(servo1, 0, pulseLengthLow1);
    pwm.setPWM(servo2, 0, pulseLengthLow2);
    servoInterval = getDanceStep();
    servoDirection = HIGH;
  }
  else {
    uint16_t pulseLengthHigh1 = random(servoCenter, servoMax);
    uint16_t pulseLengthHigh2 = random(servoCenter, servoMax);
    pwm.setPWM(servo1, 0, pulseLengthHigh1);
    pwm.setPWM(servo2, 0, pulseLengthHigh2);
    servoInterval = getDanceStep();
    servoDirection = LOW;
  }
}

int getDanceStep() {
  intervalPick = random(1, 5);
  switch (intervalPick) {
    case 1:
      danceStep = 125;
      break;
    case 2:
      danceStep = 250;
      break;
    case 3:
      danceStep = 375;
      break;
    case 4:
      danceStep = 500;
      break;
  }
  return danceStep;
}

void playDmx() {
  dmxPick = random(1, 11);
  switch (dmxPick) {
    case 1: // Red
      data[0] = 255;
      data[1] = 255;
      data[2] = 0;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 2: // Green
      data[0] = 255;
      data[1] = 0;
      data[2] = 255;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 3: // Blue
      data[0] = 255;
      data[1] = 0;
      data[2] = 0;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 4: // White
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 5: // Yellow
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 6: // Purple
      data[0] = 255;
      data[1] = 255;
      data[2] = 0;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 7: // Cyan
      data[0] = 255;
      data[1] = 0;
      data[2] = 255;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 8: // White
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 255;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 9: // Yellow
      data[0] = 255;
      data[1] = 255;
      data[2] = 255;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
    case 10: // Red
      data[0] = 255;
      data[1] = 255;
      data[2] = 0;
      data[3] = 0;
      data[4] = 0;
      data[5] = 0;
      data[6] = 0;
      for (x = 1; x <= 23; x = x + 7) {
        dmxTx.set(x, data, 7);
      }
      break;
  }
}
 
2021 Halloween Show - Teensy 3.2

The song selection, show length and intermission length are randomized so the show is slightly different each time. There is a dance party of 5 year olds that show up every evening. The show is a big hit in the neighborhood. Thanks for everyone’s help.

Note to Shawn: I wasn’t able to individually address the fixtures. When I used a “for” loop to set less than all four fixtures, I just got black from all. I’d love to discuss if you have time.

Jeff

https://youtu.be/F-0MqxYrnBw
 
It looks like you have an extra semicolon here:

Code:
if (dmxToggle == HIGH); {
playDmx();
}
 
It looks like you have an extra semicolon here:

Code:
if (dmxToggle == HIGH); {
playDmx();
}


Oh wow! I wonder why the compiler didn’t flag it. The code snippet makes the lights change at half time (of the skeleton tempo) and I can confirm that it works. I’ll change it out immediately however. Thanks for looking it over! The show is a big hit and the lighting changes make it. I will use my controller for every holiday so I intend to learn more about DMX and programming in general…
 
You need a style-checking tool like lint for catching this sort of mistake - there's nothing wrong with the C code as it stands,
you are allowed to use empty statements and redundant block statements however you want, they are part of the language.

Why is the bool variable dmxToggle set to HIGH rather than true BTW? Its not a pin state as far as I can tell, just a bool.
I'd reserve HIGH and LOW names for digital pin input and output where it makes sense.

Or in short:
Code:
  if (dmxToggle)
    playDmx();
 
Mark,
Thanks for the explanation! As to the question, I noticed when referencing Boolean that “true” and “false” are expected but panicked because I was too close to opening night to make the change especially when I read that HIGH and LOW will work as substitutes. Even though the show is on until Halloween, I still wish to improve my code and make changes especially the last two suggested since they will help me conform to generally accepted practices. I want to use this controller every holiday to entertain the neighbors but also as a opportunity to learn more about coding. Thanks for the help, I will rework the Boolean variables to the true/false nomenclature.

Jeff
 
Status
Not open for further replies.
Back
Top