DMXSimple Issues

Status
Not open for further replies.
Hi everyone

I just started to make a new project to send DMX with my teensy LC.
I opened the first example of DMXSimple, but I'ts not working
There's my code :

Code:
#include <DmxSimple.h>

void setup() 
  {
  DmxSimple.usePin(2);
  Serial.begin(115200);
  // DmxSimple.maxChannel(4);
}

void loop() 
  {
  int brightness;
  for (brightness = 0; brightness <= 255; brightness++) 
    {
    Serial.println(brightness);
    // DmxSimple.write(1, brightness);
    delay(10);
    }
  }

These lines works fine, but when I add the
Code:
DmxSimple.write(1, brightness);
to the program, windows tells me that the USB material haven't worked correctly.

anybody has an idea ?

Thanks !
 
DmxSimple doesn't work on Teensy-LC.

Here's some code that can send DMX on Serial1. It hasn't been tested on LC, but should work. It's a little more hands-on than DmxSimple...

Code:
uint8_t buffer[513];

void xmit() {
  digitalWriteFast(12, HIGH);
  Serial1.begin(83333, SERIAL_8N1);
  Serial1.write(0);
  Serial1.flush();
  Serial1.begin(250000, SERIAL_8N2);
  digitalWriteFast(12, LOW);
  // first byte of buffer must be zero
  // to comply with DMX protocol
  Serial1.write(buffer, sizeof(buffer));
  Serial1.flush();
}

#define RED    0xFF0000
#define GREEN  0x00FF00
#define BLUE   0x0000FF
#define YELLOW 0xFFFF00
#define PINK   0xFF1088
#define ORANGE 0xE05800
#define WHITE  0xFFFFFF

void setup() {
  Serial1.begin(250000);
  pinMode(12, OUTPUT);
}

void loop() {
  colorWipe(RED);
  colorWipe(GREEN);
  colorWipe(BLUE);
  colorWipe(YELLOW);
  colorWipe(PINK);
  colorWipe(ORANGE);
  colorWipe(WHITE);
}

void colorWipe(int color)
{
  for (int i=0; i < 48; i++) {
    buffer[0] = 0;
    buffer[i*3 + 1] = color >> 16;
    buffer[i*3 + 2] = color >> 8;
    buffer[i*3 + 3] = color >> 0;
    buffer[i*3 + 1 + 144] = color >> 16;
    buffer[i*3 + 2 + 144] = color >> 8;
    buffer[i*3 + 3 + 144] = color >> 0;
    buffer[i*3 + 1 + 288] = color >> 16;
    buffer[i*3 + 2 + 288] = color >> 8;
    buffer[i*3 + 3 + 288] = color >> 0;
    buffer[25] = 0x5A;
    xmit();
    buffer[25] = 0xA5;
    xmit();
  }
}
 
Yes thank you !

I'll try that ! But I don't really understand what colorWipe does and why is the : buffer[25] = 0x5A; is here
Does the buffer represents all the values for the channels ? and xmit() sends the frame ?
 
And it works perfectely !
Thank you a lot Paul !

there's a sample of code I use now :
Code:
uint8_t buffer[513];
const int delaiDmxSend = 22;
unsigned long lastDmxSend = 0;

void dmxEmit() 
  {
  Serial3.begin(83333, SERIAL_8N1);
  Serial3.write(0);
  Serial3.flush();
  Serial3.begin(250000, SERIAL_8N2);
  // first byte of buffer must be zero
  // to comply with DMX protocol
  Serial3.write(buffer, sizeof(buffer));
  Serial3.flush();
  lastDmxSend = millis();
  }

void dmxInit()
  {
  Serial3.begin(250000);
  for (int i = 0; i < 513; i++)
    {
    buffer[i] = 0;
    }
  }

void dmxUpdate()
  {
  if (lastDmxSend + delaiDmxSend < millis())
    {
    dmxEmit();
    }
  }

void dmxSetChannel(int channel, byte value)
  {
  if (channel > 0 && channel < 513)
    {
    buffer[channel] = value;
    }
  }

the function dmxInit have to be called in setup()
the function dmxUpdate in loop()
then, you just have to call dmxSetChannel() to set a channel to his value

Thanks a lot again !
 
I know this is kind of an old thread but potentially useful for a variety of projects. Here's some code that allows the DMX packets to be mostly buffered and free up the processor for other tasks. It also allows a refresh time of 1.2 milliseconds if only 24 channels are sent. There's still a little pause in the beginning of each transmission, but the data and majority of the transmissions are buffered. If you're sending all 512 channels, it might be nice to have that 22 milliseconds free to do other things.

Serial3.availableForWrite() returns a value that is 1 less than the serial3 buffer size. I'm not sure why it does this, but the code does work.

Code:
// Buffered DMX library with low channel counts for fast refresh rate, or high channel count without tying up the processor for a long period of time.

byte buffer[25]; // Minimum size = number of channels + 1.  Add more channels if the last light flickers.  This seems reliable: size = number of channels + 4.
// Send at at least 24 channels (25 bytes) to keep time between breaks above 1.2 milliseconds.  Some DMX hardware may not be able to handle faster refresh times.

int serial3TXbuffersizeminus1;

void setup()
{
  Serial3.begin(250000);
  delay(100);
  serial3TXbuffersizeminus1 = Serial3.availableForWrite();

  Serial.begin(9600);
  Serial.print("serial3 buffer size: ");
  Serial.print((serial3TXbuffersizeminus1 + 1)); // See how large buffer size is using Teensyduino serial monitor.
  // Increase serial3 buffer size to send more channels.
  // open file: hardware/teensy/avr/cores/teensy3/serial3.c
  // edit line: #define TX_BUFFER_SIZE 40

  DMXset(1, 255); // Usually red on an RGB light with start address 1.
  DMXupdate();
  delay(500);

  DMXset(1, 0);
  DMXupdate();
  delay(500);

  DMXset(2, 255); // Usually green on an RGB light with start address 1.
  DMXupdate();
  delay(500);

  DMXset(2, 0);
  DMXupdate();
  delay(500);

  DMXset(3, 255); // Usually blue on an RGB light with start address 1.
  DMXupdate();
  delay(500);

  DMXset(3, 0);
  DMXupdate();
  delay(500);

}


void loop()
{
  while (1) // Probably won't matter for this application.  For faster time-critical sketches, loop function may have jitter on Arduino, possibly not Teensy?
  {
    // Code can run here while DMX data is buffered.
    // Examples: FFT, read SD card, MIDI in, ultrasound sensor, digitalRead() tactile button, analogRead() dial, light sensor, accelerometer.
    
    /*
    DMXset(channel, brightness);
    DMXset(channel, brightness);
    DMXset(channel, brightness);
    etc...
    DMXupdate();
    */
    
  }
}


void DMXupdate() // Will only transmit if previous packet has finished.
{
  if (Serial3.availableForWrite() == serial3TXbuffersizeminus1) // Is serial3 buffer empty?
  {
    Serial3.begin(83333, SERIAL_8N1);
    Serial3.write(0);
    Serial3.flush();
    Serial3.begin(250000, SERIAL_8N2);
    Serial3.write(buffer, sizeof(buffer));
    // Avoid 2nd Serial3.flush() to free up processor for other operations.
  }
}


void DMXset(unsigned int channel, byte value)
{
  if (channel > 0 && channel < sizeof(buffer))
  {
    buffer[channel] = value;
  }
}
 
Thread revival from the dead !
I have ended up here in my searches to see why DMXsimple locks up my Teensy LC.

My quest is to have a Midi floor controller using the Teensy 4 x USB Midi ports/pipes up stream to control video projection software, FreestylerDMX, midi softsynth, and control external equipment (those sorted), and use the USB Serial down stream for DMX from FreeStylerDMX software to a RS-485 DMX interface + wireless DMX.
So I basically want to pass through DMX from USB serial to an output pin.
I guess there is no simple way to do this without buffering the whole 512 byte frame.
Going to try out the above example with some DMX Receive code and see what happens, thanks for sharing :)

EDIT: The code above works great on the Teensy LC, but unfortunately hogs all the CPU time in my project for the other stuff to work properly, so I will go with plan B and use a USB Hub inside my project and a separate USB to DMX.
 
Last edited:
Curious, when you say USB to DMX, do you mean USB Pro Widget emulation or raw bytes over USB-serial?

The TeensyDMX library works with Teensy LC and can send packets having less than 512 bytes. There’s also a way to do USB Pro emulation and framed USB-serial relaying.
 
The intention was to use it to relay USB serial (DMX) to a serial out pin to a RS485 IC,
but there is too much time used by other functions, such as 14 button scanning, 2 x rotary encoders, I2C LCD display, 10 Neopixel leds, and 4 x Midi to USB.

My resolve was to add a 4 port USB hub and a FTDI USB to RS422 module and have the DMX bypass the Teensy LC all together.
All working fine now.

Did have some success trying use of interrupts on received USB serial, but it messed everything else up.
 
And it works perfectely !
Thank you a lot Paul !

there's a sample of code I use now :
Code:
uint8_t buffer[513];
const int delaiDmxSend = 22;
unsigned long lastDmxSend = 0;

void dmxEmit() 
  {
  Serial3.begin(83333, SERIAL_8N1);
  Serial3.write(0);
  Serial3.flush();
  Serial3.begin(250000, SERIAL_8N2);
  // first byte of buffer must be zero
  // to comply with DMX protocol
  Serial3.write(buffer, sizeof(buffer));
  Serial3.flush();
  lastDmxSend = millis();
  }

void dmxInit()
  {
  Serial3.begin(250000);
  for (int i = 0; i < 513; i++)
    {
    buffer[i] = 0;
    }
  }

void dmxUpdate()
  {
  if (lastDmxSend + delaiDmxSend < millis())
    {
    dmxEmit();
    }
  }

void dmxSetChannel(int channel, byte value)
  {
  if (channel > 0 && channel < 513)
    {
    buffer[channel] = value;
    }
  }

the function dmxInit have to be called in setup()
the function dmxUpdate in loop()
then, you just have to call dmxSetChannel() to set a channel to his value

Thanks a lot again !

Hi everyone.. I know this is an old thread...but I have a question:

Is this code compatible with Teensy 4?
when i use it, the colour chosen in my RGB led stays for half second and then goes to black (it doesn't remain). And when i send a blackout: channels 1,2,3 to 0 it lights up at around 1-5% for half a second and then goes black...
Does it happens with other teensy models?
Thanks
 
Status
Not open for further replies.
Back
Top