Hi all,
This is my first post here. Pleased to be apart of the forum.
I'm putting together a lighting project for my band (i'm the drummer) with an Arduino Mega and a DMX shield that has a number of Piezos on the drum kit which activate lights when triggered. The setup includes a foot switch to arm/disarm the process and a small LED screen and LED that indicates the status. This is inspired by this video, which is fairly old now:
There is no source code available for this, so I've decided to piece the code together myself. I have all the hardware wired correctly (i.e. it's all working) and I can trigger the lights via DMX with the Piezos. What I can't seem to do is find the best loop method to activate the lights. I want the code to send the DMX HIGH to the channel independently with a small delay to allow the lights to activate and then after n seconds set DMX channel to LOW (I hope that all makes sense...). If I want to trigger another light while the first light is activated, that should not interfere with the process. I have tinkered with IF, FOR, WHILE statements and can't quite seem to get this to function to do exactly what I want. Sometimes the DMX commands interfere with other DMX commands, sometimes the timer doesn't work, etc. This is my current set of code, I would appreciate some tips for writing the loop with the piezo trigger functions independent from one another and on a set timer if possible:
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DmxSimple.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
void lights_1();
void lights_2();
const int buttonPin = 3;
const int ledPin = 13;
const int ledPin2 = 8;
const int knockSensor = A10;
const int knockSensor1 = A11;
int threshold = 1023;
int threshold_1 = 1023;
bool threshold_met = false;
// variable to hold the value of the switchPin
int sensorReading = 0;
int sensorReading1 = 0;
volatile int switchState = LOW;
// Variables will change:
int lightState_1 = LOW;
int lightState_2 = LOW;
int lightState_3 = LOW;
// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis_1 = 0; // will store last time LED was updated
unsigned long previousMillis_2 = 0; // will store last time LED was updated
unsigned long previousMillis_3 = 0; // will store last time LED was updated
// constants won't change:
const long interval_1 = 1500; // interval at which to blink (milliseconds)
const long interval_2 = 1500; // interval at which to blink (milliseconds)
const long interval_3 = 2000; // interval at which to blink (milliseconds)
static const unsigned char PROGMEM logo_bmp[] =
{ B00000000, B11000000,
B00000001, B11000000,
B00000001, B11000000,
B00000011, B11100000,
B11110011, B11100000,
B11111110, B11111000,
B01111110, B11111111,
B00110011, B10011111,
B00011111, B11111100,
B00001101, B01110000,
B00011011, B10100000,
B00111111, B11100000,
B00111111, B11110000,
B01111100, B11110000,
B01110000, B01110000,
B00000000, B00110000
};
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
delay(1000);
// Clear the buffer
display.clearDisplay();
// Draw a single pixel in white
display.drawPixel(10, 10, SSD1306_WHITE);
// Show the display buffer on the screen. You MUST call display() after
// drawing commands to make them visible on screen!
display.display();
delay(2000);
//Button Confugration
pinMode(buttonPin, INPUT);
//Led Configuration
pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
DmxSimple.usePin(4);
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
DmxSimple.maxChannel(3);
attachInterrupt(1, buttonLow, CHANGE);
}
void loop() {
sensorReading = analogRead(knockSensor);
sensorReading1 = analogRead(knockSensor1);
unsigned long currentMillis_1 = millis();
unsigned long currentMillis_2 = millis();
//Serial.println(sensorReading1);
if (switchState == HIGH) {
update_display_armed();
if (sensorReading >= threshold) {
threshold_met = true;
if (currentMillis_1 - previousMillis_1 >= interval_1) {
//previousMillis_1 = currentMillis_1;
Serial.println(currentMillis_1);
DmxSimple.write(2, 255);
}
else {
DmxSimple.write(2, 0);
return;
}
}
if (sensorReading1 >= threshold_1) {
if (currentMillis_2 - previousMillis_2 >= interval_2) {
//previousMillis_2 = currentMillis_2;
Serial.println(currentMillis_2);
DmxSimple.write(3, 255);
}
else {
DmxSimple.write(3, 0);
return;
}
}
}
else {
update_display_disarmed();
}
}
void buttonLow() {
switchState = digitalRead(buttonPin);
digitalWrite(ledPin, switchState);
}
void update_display_armed() {
char msg[8] = "";
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 2);
display.print("ARMED");
snprintf(msg, sizeof msg, "");
display.print(msg);
display.display();
}
void update_display_disarmed() {
char msg[10] = "";
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE, BLACK);
display.setCursor(35, 2);
display.print("OFF");
snprintf(msg, sizeof msg, "");
display.print(msg);
display.display();
}
Many thanks.
Joe