Arduino and the mechanical relay
// *** diychristmas.org free software so long as this line remains in sketch! // Vixen/xLights "generic" serial mechanical relay sketch // - Uses digitalWrite as this outputs LOW or HIGH no pwm values // - This is what is needed for a mechanical relay // Hookup the relay in order of channel definition // Define as many as you need // put channels (pins) in an array so we can use looping structures to control int channels[] = {2, 3, 4, 5, 6, 7, 8, 10}; // Vixen information // - CHANNEL_COUNT is number of channels it will listen for from Vixen const int CHANNEL_COUNT = 8; // speed for the com port for talking with vixen const long SERIAL_COM_SPEED = 115200L; // Generic Serial controller config - must be present, must match controller setup const int VIXEN_HEADER[3] = {33, 34, 35}; // This is character !"# (hard to replicate in Vixen sequence) // Relays // - most mechanical relays turn on when pin is low, off on high const int ON = LOW; const int OFF = HIGH; // these are program variables we need to use in multiple places const int SIZE_OF_HEADER = sizeof(VIXEN_HEADER) / sizeof(int); // no need to change int buffer[CHANNEL_COUNT]; // no need to change going to hold relay output values void setup() { Serial.begin(SERIAL_COM_SPEED); Serial.write("Setup"); // set the channel pins to output mode for (int channelIndex = 0; channelIndex < CHANNEL_COUNT; channelIndex++) { pinMode(channels[channelIndex], OUTPUT); } turnLightsOff(); powerOnSelfTest(); // watch your lights to make sure they are all going on in order } void loop() { waitForVixenHeader(VIXEN_HEADER); readFromVixen(); outputToLights(); } void turnLightsOff() { //turn them all off for (int channelIndex = 0; channelIndex < CHANNEL_COUNT; channelIndex++) { digitalWrite(channels[channelIndex], OFF); } } void outputToLights() { for (int channelIndex = 0; channelIndex < CHANNEL_COUNT; channelIndex++) { // we should only be seeing 255 and 0 but in case someone tried a fade // 48 is used for debug purposes. You can use the serial monitor to test // send this string !"#01010101 to turn on every other relay as 0 == dec(48) 1 == dec(49) if (buffer[channelIndex] > 48) { digitalWrite(channels[channelIndex], ON); } else { digitalWrite(channels[channelIndex], OFF); } } } void readFromVixen() { char buffer2[CHANNEL_COUNT]; int index = 0; while (Serial.available() < CHANNEL_COUNT) {} // We have enough data! for (int i = 0; i < CHANNEL_COUNT; i++) { int inByte = Serial.read(); buffer[i] = inByte; Serial.write(inByte); } } void waitForVixenHeader(int header[]) { for (int i = 0; i < SIZE_OF_HEADER; i++) { // wait for serial available while (!Serial.available()) {} // Check the byte until it matches the VIXEN_HEADER byte int inByte = Serial.read(); if (inByte != VIXEN_HEADER[i]) { i = -1; // wrong data set to "zero" } } // found the header! } // powerOnSelfTest - does a couple of checks to make sure everything turns on and off // - watch your lights, they should go on in order void powerOnSelfTest() { // This routines turns on and off each relay in order for (int channelIndex = 0; channelIndex < CHANNEL_COUNT; channelIndex++) { digitalWrite(channels[channelIndex], ON); // turn on one channel at a time delay(2000); digitalWrite(channels[channelIndex], OFF); } // This routines turns on each relay in order leaving them all on for .5 seconds for (int channelIndex = 0; channelIndex < CHANNEL_COUNT; channelIndex++) { digitalWrite(channels[channelIndex], ON); // all on test delay(500); // wait .5 seconds } delay(2000); // slight pause to check all on turnLightsOff(); }
Let's talk about the code... At the top of the sketch, you will find the definitions of how you are going to use the Arduino with Vixen, xLights or any other serial output. These things are self explanatory but for the "I've never seen an Arduino or Vixen setup" people, here is another try to explain them.
Things you might have to change
int channels[] = {2, 3, 4, 5, 6, 7, 8, 10};
This line assigns pins from the arduino to specific "channels" in order. In your software, you would assign channel one to Shrub1, channel two to Shrub2, etc. You will need to map these through the Arduino pins to the specific relay on your relay board and out to the lights. It might look like this:
Description | Channel | Pin | Relay |
---|---|---|---|
Shrub1Left | 1 | 2 | In1 |
Shrub2 | 2 | 3 | In2 |
Shrub3 | 3 | 4 | In3 |
Shrub4Right | 4 | 5 | In4 |
Post1Left | 5 | 6 | In5 |
Post2 | 6 | 7 | In6 |
Post3 | 7 | 8 | In7 |
Post4Right | 8 | 10 | In8 |
const int CHANNEL_COUNT = 8;
const long VIXEN_COM_SPEED = 115200L;
const int VIXEN_HEADER[3] = {33, 34, 35};
const int ON = LOW;
const int OFF = HIGH;