My plan when I originally started messing with DMX (and resulted in the code I posted quite some time ago) was to make a modular library that could be hooked up to various hardware devices. Here's sort of what I'm talking about, maybe it will be helpful to this discussion? Anybody want to join forces and build this into a library that will work with other DMX hardware?
(note, I just hacked this out, it hasn't been tested with the actual device and is just to illustrate my ideas for architecture)
ideas? thoughts?
Code:
void setup()
{
size(200,200);
DMXDevice foo = new ENTTECUsbPro(this, "COM1", 10);
foo.setChannelValue( byte(4), byte(10) );
}
void draw()
{
}
/* interface for all DMX devices */
public interface DMXDevice
{
public void setChannelValue( byte channel, byte value );
}
/* abstract implementation to handle simple caching of channel data to reduce work */
abstract class AbstractDMXDevice implements DMXDevice
{
protected byte[] channelValues;
protected int universeSize;
protected AbstractDMXDevice()
{
this(10);
}
protected AbstractDMXDevice( int universeSize )
{
this.universeSize = universeSize;
this.channelValues = new byte[universeSize];
}
public void setChannelValue( byte channel, byte value )
{
if(this.channelValues[channel] != value)
{
this.channelValues[channel] = value;
this.refreshDevice();
}
}
protected abstract void refreshDevice();
}
/* hardware-specific implementation, there would be one of
these for each type of DMX device. It only handles initialization and the specific logic needed to send the channel values to the hardware by implementing the "refreshDevice" method */
class ENTTECUsbPro extends AbstractDMXDevice
{
private byte[] message;
private Serial serial;
private final int SERIAL_RATE = 19200;
private final int HEADER_LENGTH = 5;
private final byte DMX_PRO_MESSAGE_START = byte(0x7E);
private final byte DMX_PRO_MESSAGE_END = byte(0xE7);
private final byte DMX_PRO_SEND_PACKET = byte(6);
public ENTTECUsbPro( PApplet parent, String port, int universeSize )
{
super(universeSize);
this.serial = new Serial(parent, port, this.SERIAL_RATE);
int dataSize = universeSize + this.HEADER_LENGTH + 1; // 5 byte header + 1 byte for "message end"
message = new byte[dataSize];
message[0] = DMX_PRO_MESSAGE_START;
message[1] = DMX_PRO_SEND_PACKET;
message[2] = byte(dataSize & 255);
message[3] = byte((dataSize >> 8) & 255);
message[4] = 0;
for (int i = 0; i < universeSize; i++)
{
message[i + HEADER_LENGTH] = byte(0);
}
message[dataSize - 1] = DMX_PRO_MESSAGE_END;
}
/* overrides AbstractDMXDevice */
void refreshDevice()
{
// just copy the new channel data into the current message array
System.arraycopy( this.channelValues, 0, this.message, HEADER_LENGTH, this.universeSize );
this.serial.write( message );
}
}