// Cross Fading // This example uses channels 1,2 and 3 to drive an RGB lamp and make it fade from one color to another. #include "pins_arduino.h" int sig = 3; // signal int value = 0; int valueadd = 3; byte curr_rgb[3] = {0,0,0}; byte dmxChannel[64]; void setDmxChannel(byte channelID, byte value) { if (channelID < 64) dmxChannel[channelID] = value; } /* Sends a DMX byte out on a pin. Assumes a 16 MHz clock. * Disables interrupts, which will disrupt the millis() function if used * too frequently. */ void shiftDmxOut(int pin, int theByte) { int port_to_output[] = { NOT_A_PORT, NOT_A_PORT, _SFR_IO_ADDR(PORTB), _SFR_IO_ADDR(PORTC), _SFR_IO_ADDR(PORTD) }; int portNumber = port_to_output[digitalPinToPort(pin)]; int pinMask = digitalPinToBitMask(pin); // the first thing we do is to write te pin to high // it will be the mark between bytes. It may be also // high from before _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask; delayMicroseconds(10); // disable interrupts, otherwise the timer 0 overflow interrupt that // tracks milliseconds will make us delay longer than we want. cli(); // DMX starts with a start-bit that must always be zero _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask; // we need a delay of 4us (then one bit is transfered) // this seems more stable then using delayMicroseconds asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); for (int i = 0; i < 8; i++) { if (theByte & 01) { _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask; } else { _SFR_BYTE(_SFR_IO8(portNumber)) &= ~pinMask; } asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); asm("nop\n nop\n nop\n nop\n nop\n nop\n nop\n nop\n"); theByte >>= 1; } // the last thing we do is to write the pin to high // it will be the mark between bytes. (this break is have to be between 8 us and 1 sec) _SFR_BYTE(_SFR_IO8(portNumber)) |= pinMask; // reenable interrupts. sei(); } void processDmx() { /***** sending the dmx signal *****/ // sending the break (the break can be between 88us and 1sec) digitalWrite(sig, LOW); delay(10); dmxChannel[0] = 0; for (int count = 0; count <= 512; count++) { if (count < 64) shiftDmxOut(sig, dmxChannel[count]); else shiftDmxOut(sig,0); } /***** sending the dmx signal end *****/ } // fade from current colour to given rgb value // algorithm by David A. Mellis void fadeTo(byte r, byte g, byte b) { byte i; byte p_start[3]; byte p_end[3]; p_start[0] = curr_rgb[0]; p_start[1] = curr_rgb[1]; p_start[2] = curr_rgb[2]; p_end[0] = r; p_end[1] = g; p_end[2] = b; i = 0; while (i < 255) { curr_rgb[0] = (p_end[0] - p_start[0]) / 254 * i + p_start[0]; curr_rgb[1] = (p_end[1] - p_start[1]) / 254 * i + p_start[1]; curr_rgb[2] = (p_end[2] - p_start[2]) / 254 * i + p_start[2]; setDmxChannel(1, curr_rgb[0]); setDmxChannel(2, curr_rgb[1]); setDmxChannel(3, curr_rgb[2]); processDmx(); i++; } } void setup() { pinMode(sig, OUTPUT); } void loop() { fadeTo(255,0,0); delay(500); fadeTo(0,255,0); delay(500); fadeTo(0,0,255); delay(500); }