Hi, I'm using A Arduino Library for sending and receiving DMX to implement a simple DMX receiver that turns an LED on or off depending on the value of a given DMX channel. The problem is that if the DMX cable is disconnected the LED stays in the state it was last in however if DMX comms is lost (cable disconnected etc.) I want the LED to go off if DMX comms is lost regardless of the last received value does anyone know if this is possible?
How do you define "DMX comms is lost"? Is it that there is no new data within some period of time? If so, then, you can just turn the LED off if no new data arrives within that period of time.
PaulS:
How do you define "DMX comms is lost"? Is it that there is no new data within some period of time? If so, then, you can just turn the LED off if no new data arrives within that period of time.
Yes but how do I know if there is no more data? it looks like if you do a DMXserial.read it returns the last value received even if no cable is connected ideally it should return an error.
t looks like if you do a DMXserial.read it returns the last value received even if no cable is connected ideally it should return an error.
You are right. The data read is not removed from the buffer, so there is no way to tell if the data is new or two weeks old. You might need to contact the author(s) to get that addressed.
You might work around the issue by noting whether the data is the same for any period of time, and assuming that the data is old if no change is detected for that period of time.
t looks like if you do a DMXserial.read it returns the last value received even if no cable is connected ideally it should return an error.
You are right. The data read is not removed from the buffer, so there is no way to tell if the data is new or two weeks old. You might need to contact the author(s) to get that addressed.
You might work around the issue by noting whether the data is the same for any period of time, and assuming that the data is old if no change is detected for that period of time.
Thanks I tried to modify the library myself to clear a channel value to 0 once read (not a perfect solution but suits my needs) :
Original code :-
// Read the current value of a channel.
uint8_t DMXSerialClass::read(int channel)
{
// adjust parameter
if (channel < 1) channel = 1;
if (channel > DMXSERIAL_MAX) channel = DMXSERIAL_MAX;
// read value from buffer
return(_dmxData[channel]);
}
My attempt
// Read the current value of a channel.
uint8_t DMXSerialClass::read(int channel)
{
// adjust parameter
if (channel < 1) channel = 1;
if (channel > DMXSERIAL_MAX) channel = DMXSERIAL_MAX;
// read value from buffer
int channeltemp=_dmxData[channel]; // copy value to temp variable
_dmxData[channel]=0; //set the read channel to 0
channel=channeltemp; // restore from temp variable
return(channel); // return it
}
But now the LED doesn't light at all when I'm sending the correct DMX values.
PaulS:
You might work around the issue by noting whether the data is the same for any period of time, and assuming that the data is old if no change is detected for that period of time.
No good it could be at the same value intentionally for a very long time.
Thanks I tried to modify the library myself to clear a channel value to 0 once read (not a perfect solution but suits my needs)
Hmmm...
uint8_t DMXSerialClass::read(int channel)
{
// adjust parameter
if (channel < 1) channel = 1;
if (channel > DMXSERIAL_MAX) channel = DMXSERIAL_MAX;
// read value from buffer
int channeltemp=_dmxData[channel]; // copy value to temp variable
_dmxData[channel]=0; //set the read channel to 0
channel=channeltemp; // restore from temp variable
return(channel); // return it
}
Setting channel to the value for the channel is probably not a good idea. If channeltemp were the right type, you could just return it.
uint8_t DMXSerialClass::read(int channel)
{
// adjust parameter
if (channel < 1) channel = 1;
if (channel > DMXSERIAL_MAX) channel = DMXSERIAL_MAX;
// read value from buffer
uint8_t value =_dmxData[channel]; // copy value to temp variable
_dmxData[channel]=0; //set the read channel to 0
return(value); // return it
}
Thanks I tried to modify the library myself to clear a channel value to 0 once read (not a perfect solution but suits my needs)
Hmmm...
uint8_t DMXSerialClass::read(int channel)
{
// adjust parameter
if (channel < 1) channel = 1;
if (channel > DMXSERIAL_MAX) channel = DMXSERIAL_MAX;
// read value from buffer
int channeltemp=_dmxData[channel]; // copy value to temp variable
_dmxData[channel]=0; //set the read channel to 0
channel=channeltemp; // restore from temp variable
return(channel); // return it
}
Setting channel to the value for the channel is probably not a good idea. If channeltemp were the right type, you could just return it.
uint8_t DMXSerialClass::read(int channel)
{
// adjust parameter
if (channel < 1) channel = 1;
if (channel > DMXSERIAL_MAX) channel = DMXSERIAL_MAX;
// read value from buffer
uint8_t value =_dmxData[channel]; // copy value to temp variable
_dmxData[channel]=0; //set the read channel to 0
return(value); // return it
}
Thanks I originally tried something similar (although I think I got the type wrong) but I thought maybe the returned variable had to be the same name as the one at the top of the function. Either way the version you posted didn't work either, the led stays off.
After reading the data, you could disable interrupts, clear the data, and re-enable interrupts. That would stop the interrupt from firing in the middle of the reset.
Disabling the interrupt didn't seem to work for some reason. What I actually ended up doing to avoid using the delay was :-
Read value for DMX channel of interest.
Set value for that channel to zero.
Keep checking the channels value and if zero then do nothing, otherwise get new value.
The author has now included a call where you can check the time since the last DMX start frame and use that to timeout if you haven't seen one in a while.