Control of multiple OctoWS2811 with DMX input

discofock

New member
Hi all,

I'm working on the expansion of a project that I have coined disco jib which has been created for a private music festival and to bring some LED art to sailing trips. In its current configuration the disco sail utilizes two OctoWS2811 and FastLED library to control a total of 12 individual 5m RGB LED strips (1x 8 strips and 1x 4 strips). There is either a preprogrammed light show or the possibility to change effects via Serial interface and a Python script running on a laptop. Please find attached a picture of the installation during a recent sailing trip.

For the next version of the disco jib I want to implement DMX control of the entire installation.

Software used:
- The freeware QLC+ for DMX control and light shows (https://www.qlcplus.org/)
- TeensyDMX library (https://github.com/ssilverman/TeensyDMX)

Additional hardware for DMX upgrade:
- a USB to DMX RS485 adapter with FTDI chip for connection to the OctoWS2811's (https://www.amazon.de/dp/B07WV6P5W6?ref_=pe_27091401_487187591_302_E_DDE_dt_1)
- a UART TTL to RS485 adapter 485 Seriell 3.3V/5V (https://www.ebay.de/itm/153880466847)
- a female 3pin DMX socket

I ran into troubles making the DMX connection work and despite quite some time invested cannot find the problem.

This is the script I'm trying on the Teensy (from here: https://forum.pjrc.com/threads/66083-Receiving-DMX-with-a-RS-485-and-Teesny-4-1):
Code:
#include <TeensyDMX.h>
namespace teensydmx = ::qindesign::teensydmx;

teensydmx::Receiver dmxRx{Serial1};
uint8_t buf[7] {0};
uint32_t previousMillis = 0;
uint32_t currentMillis = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.println("Starting DMX receive");
  dmxRx.begin();
}

void loop() {
  currentMillis = millis();
  if (dmxRx.readPacket(buf, 1, 7) == 7) {
    digitalToggle(LED_BUILTIN);
    Serial.print(currentMillis - previousMillis); Serial.print("\t");
    previousMillis = currentMillis;
    Serial.printf("R G B A W D C: %03d %03d %03d %03d %03d %03d %03d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
  } else {
    Serial.printf("FramingErrors: %d | PacketTimeouts: %d | ShortPackets: %d | LongPackets: %d | Connected: %d\n", 
      dmxRx.errorStats().framingErrorCount,
      dmxRx.errorStats().packetTimeoutCount,
      dmxRx.errorStats().shortPacketCount,
      dmxRx.errorStats().longPacketCount,
      dmxRx.connected()
     );
  }
}

Attached you can find the wiring. The script does not seem to receive any DMX signals. dmxRx.connected() is returned with false and no errors are reported (see screenshot). The DMX input via QLC+ itself is confirmed to be working as it should with a separate DMX-controlled light. The RS485 board has been successfully used with an Arduino Uno and the DMXSerial library.

Anyone has an idea what might be wrong? I'm concerned the type of RS485 module I am using might be the problem as I cannot switch it manually to "receive" mode but it switches automatically (see here: https://electronics.stackexchange.com/questions/244425/how-is-this-rs485-module-working). It may be in the wrong mode for the TeensyDMX library to work properly?

Any help would be highly appreciated.

Thanks a lot!
 

Attachments

  • PXL_20221007_190105958s.jpg
    PXL_20221007_190105958s.jpg
    67.7 KB · Views: 32
  • schematics-01.jpg
    schematics-01.jpg
    101.8 KB · Views: 34
  • Screenshot 2022-11-19 at 16.47.13.jpg
    Screenshot 2022-11-19 at 16.47.13.jpg
    266.2 KB · Views: 28
Any help would be super appreciated. I struggle to understand why this doesn't work and have been stuck for some weeks no without any idea what to test next. I've also tested with another Teensy 3.2 (both installed on an OctoWS2811) so I think I can exclude malfunction of the Teensy's.

In case that's not easily seen on the pictures these are the connections I have now in place -

Teensy 3.2 <--> RS 485 board
Pin 0 (but also tested pin 1) <--> TXD
Pin 1 (but also tested pin 0)<--> RXD
5V <--> VCC
GND <--> GND

RS 485 <--> DMX 3-pin
A+ <--> Pin 3, Data +
B- <--> Pin 2, Data -
GND <--> Pin 1, GND

For the record: Naturally, also tested the BasicReceive example which also does not seem to receive data.

Code:
/*
 * A basic toy receive example, demonstrating single- and
 * multi-byte reads.
 *
 * This example is part of the TeensyDMX library.
 * (c) 2019-2020 Shawn Silverman
 */

#include <cstring>

#include <TeensyDMX.h>

namespace teensydmx = ::qindesign::teensydmx;

// Create the DMX receiver on Serial1.
teensydmx::Receiver dmxRx{Serial1};

// The last value on the channel, for knowing when to print a change
// (Example 1).
uint8_t lastValue = 0;

// Buffer in which to store packet data (Example 2).
uint8_t packetBuf[3]{0};

// The last values received on channels 2-4, initialized to zero.
uint8_t rgb[3]{0};

void setup() {
  // Serial initialization, for printing things
  Serial.begin(115200);
  while (!Serial && millis() < 4000) {
    // Wait for initialization to complete or a time limit
  }
  Serial.println("Starting BasicReceive.");

  // Turn on the LED, for indicating activity
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWriteFast(LED_BUILTIN, HIGH);

  // Start the receiver
  dmxRx.begin();

  // Print the first values
  lastValue = dmxRx.get(1);
  Serial.printf("Channel 1: %d\n", lastValue);

  // Note: If this reads < 3 bytes then the other values will stay at
  // zero (because 'rgb' was initialized to zero, above)
  dmxRx.readPacket(rgb, 10, 3);
  Serial.printf("RGB: %d %d %d\n", rgb[0], rgb[1], rgb[2]);
}

void loop() {
  // The following two examples print values when they change

  // Example 1. Get the current value of channel 1.
  // This will return zero for no data (and also for data that's zero)
  uint8_t v = dmxRx.get(1);
  if (v != lastValue) {
    lastValue = v;
    Serial.printf("Channel 1: %d\n", v);
  }

  // Example 2. Read channels 2-4.
  // A return of -1 means no data, and a value < 3 means that there
  // was data, but the received packet wasn't large enough to contain
  // channels 10-12
  int read = dmxRx.readPacket(packetBuf, 2, 3);
  if (read == 3) {
    if (memcmp(packetBuf, rgb, 3) != 0) {
      memcpy(rgb, packetBuf, 3);
      Serial.printf("RGB: %d %d %d\n", rgb[0], rgb[1], rgb[2]);
    }
  }
}
 
Back
Top