Lab_interaccio/2009/CrossFading/CrossFading.pde

167 lines
4 KiB
Plaintext
Raw Normal View History

2025-02-25 21:21:58 +01:00
// 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);
}