Skip to content

Commit

Permalink
SparkFunDMX: fix for issue Aircoookie#2928
Browse files Browse the repository at this point in the history
* make SparlFunDMX driver more robust:
- made variables static (so they don't overlap with other global variables)
- made sure all valriables are properly initialized
- do not apply pinMode and digitalRead to invalid pins (as this creates problems on -S3, -C3 and -S2)
* disable DMX sending code (unneeded code that may case troubles)
  • Loading branch information
softhack007 committed Dec 10, 2022
1 parent 8caeddd commit 9380b2b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
53 changes: 35 additions & 18 deletions wled00/src/dependencies/dmx/SparkFunDMX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Distributed as-is; no warranty is given.
******************************************************************************/

/* ----- LIBRARIES ----- */
#ifdef ESP32
#ifdef ARDUINO_ARCH_ESP32

#include <Arduino.h>

Expand All @@ -29,28 +29,36 @@ Distributed as-is; no warranty is given.
#define BREAKSPEED 83333
#define BREAKFORMAT SERIAL_8N1

int enablePin = -1; // disable the enable pin because it is not needed
int rxPin = -1; // disable the receiving pin because it is not needed
int txPin = 2; // transmit DMX data over this pin (default is pin 2)
static const int enablePin = -1; // disable the enable pin because it is not needed
static const int rxPin = -1; // disable the receiving pin because it is not needed - softhack007: Pin=-1 means "use default" not "disable"
static const int txPin = 2; // transmit DMX data over this pin (default is pin 2)

//DMX value array and size. Entry 0 will hold startbyte
uint8_t dmxData[dmxMaxChannel] = {};
int chanSize;
int currentChannel = 0;
static uint8_t dmxData[dmxMaxChannel] = { 0 };
static int chanSize = 0;
static int currentChannel = 0;

HardwareSerial DMXSerial(2);
// Some new MCUs (-S2, -C3) don't have HardwareSerial(2)
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 2, 0)
#if SOC_UART_NUM < 3
#error DMX output is not possible on your MCU, as it not have HardwareSerial(2)
#endif
#endif

static HardwareSerial DMXSerial(2);

/* Interrupt Timer for DMX Receive */
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
static hw_timer_t * timer = NULL;
static portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

volatile int _interruptCounter;
volatile bool _startCodeDetected = false;
static volatile int _interruptCounter = 0;
static volatile bool _startCodeDetected = false;


#if !defined(DMX_SEND_ONLY)
/* Start Code is detected by 21 low interrupts */
void IRAM_ATTR onTimer() {
if (digitalRead(rxPin) == 1)
if ((rxPin >= 0) && (digitalRead(rxPin) == 1))
{
_interruptCounter = 0; //If the RX Pin is high, we are not in an interrupt
}
Expand Down Expand Up @@ -80,10 +88,13 @@ void SparkFunDMX::initRead(int chanQuant) {
chanQuant = defaultMax;
}
chanSize = chanQuant;
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, LOW);
pinMode(rxPin, INPUT);
if (enablePin >= 0) {
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, LOW);
}
if (rxPin >= 0) pinMode(rxPin, INPUT);
}
#endif

// Set up the DMX-Protocol
void SparkFunDMX::initWrite (int chanQuant) {
Expand All @@ -96,15 +107,19 @@ void SparkFunDMX::initWrite (int chanQuant) {
chanSize = chanQuant + 1; //Add 1 for start code

DMXSerial.begin(DMXSPEED, DMXFORMAT, rxPin, txPin);
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, HIGH);
if (enablePin >= 0) {
pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, HIGH);
}
}

#if !defined(DMX_SEND_ONLY)
// Function to read DMX data
uint8_t SparkFunDMX::read(int Channel) {
if (Channel > chanSize) Channel = chanSize;
return(dmxData[Channel - 1]); //subtract one to account for start byte
}
#endif

// Function to send DMX data
void SparkFunDMX::write(int Channel, uint8_t value) {
Expand Down Expand Up @@ -133,6 +148,7 @@ void SparkFunDMX::update() {
DMXSerial.flush();
DMXSerial.end();//clear our DMX array, end the Hardware Serial port
}
#if !defined(DMX_SEND_ONLY)
else if (_READWRITE == _READ)//In a perfect world, this function ends serial communication upon packet completion and attaches RX to a CHANGE interrupt so the start code can be read again
{
if (_startCodeDetected == true)
Expand All @@ -153,6 +169,7 @@ void SparkFunDMX::update() {
}
}
}
#endif
}

// Function to update the DMX bus
Expand Down
12 changes: 8 additions & 4 deletions wled00/src/dependencies/dmx/SparkFunDMX.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,23 @@ Distributed as-is; no warranty is given.
#ifndef SparkFunDMX_h
#define SparkFunDMX_h

#define DMX_SEND_ONLY // this disables DMX sending features, and saves us two GPIO pins

// ---- Methods ----

class SparkFunDMX {
public:
void initRead(int maxChan);
void initWrite(int maxChan);
#if !defined(DMX_SEND_ONLY)
void initRead(int maxChan);
uint8_t read(int Channel);
#endif
void write(int channel, uint8_t value);
void update();
private:
uint8_t _startCodeValue = 0xFF;
bool _READ = true;
bool _WRITE = false;
const uint8_t _startCodeValue = 0xFF;
const bool _READ = true;
const bool _WRITE = false;
bool _READWRITE;
};

Expand Down

0 comments on commit 9380b2b

Please sign in to comment.