SparkFunDMX: fix for issue #2928

* 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)
This commit is contained in:
Frank 2022-12-10 17:55:14 +01:00
parent 8caeddde15
commit 9380b2b4e8
2 changed files with 43 additions and 22 deletions

View File

@ -14,7 +14,7 @@ Distributed as-is; no warranty is given.
******************************************************************************/ ******************************************************************************/
/* ----- LIBRARIES ----- */ /* ----- LIBRARIES ----- */
#ifdef ESP32 #ifdef ARDUINO_ARCH_ESP32
#include <Arduino.h> #include <Arduino.h>
@ -29,28 +29,36 @@ Distributed as-is; no warranty is given.
#define BREAKSPEED 83333 #define BREAKSPEED 83333
#define BREAKFORMAT SERIAL_8N1 #define BREAKFORMAT SERIAL_8N1
int enablePin = -1; // disable the enable pin because it is not needed static const int enablePin = -1; // disable the enable pin because it is not needed
int rxPin = -1; // disable the receiving 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"
int txPin = 2; // transmit DMX data over this pin (default is pin 2) 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 //DMX value array and size. Entry 0 will hold startbyte
uint8_t dmxData[dmxMaxChannel] = {}; static uint8_t dmxData[dmxMaxChannel] = { 0 };
int chanSize; static int chanSize = 0;
int currentChannel = 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 */ /* Interrupt Timer for DMX Receive */
hw_timer_t * timer = NULL; static hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
volatile int _interruptCounter; static volatile int _interruptCounter = 0;
volatile bool _startCodeDetected = false; static volatile bool _startCodeDetected = false;
#if !defined(DMX_SEND_ONLY)
/* Start Code is detected by 21 low interrupts */ /* Start Code is detected by 21 low interrupts */
void IRAM_ATTR onTimer() { 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 _interruptCounter = 0; //If the RX Pin is high, we are not in an interrupt
} }
@ -80,10 +88,13 @@ void SparkFunDMX::initRead(int chanQuant) {
chanQuant = defaultMax; chanQuant = defaultMax;
} }
chanSize = chanQuant; chanSize = chanQuant;
pinMode(enablePin, OUTPUT); if (enablePin >= 0) {
digitalWrite(enablePin, LOW); pinMode(enablePin, OUTPUT);
pinMode(rxPin, INPUT); digitalWrite(enablePin, LOW);
}
if (rxPin >= 0) pinMode(rxPin, INPUT);
} }
#endif
// Set up the DMX-Protocol // Set up the DMX-Protocol
void SparkFunDMX::initWrite (int chanQuant) { void SparkFunDMX::initWrite (int chanQuant) {
@ -96,15 +107,19 @@ void SparkFunDMX::initWrite (int chanQuant) {
chanSize = chanQuant + 1; //Add 1 for start code chanSize = chanQuant + 1; //Add 1 for start code
DMXSerial.begin(DMXSPEED, DMXFORMAT, rxPin, txPin); DMXSerial.begin(DMXSPEED, DMXFORMAT, rxPin, txPin);
pinMode(enablePin, OUTPUT); if (enablePin >= 0) {
digitalWrite(enablePin, HIGH); pinMode(enablePin, OUTPUT);
digitalWrite(enablePin, HIGH);
}
} }
#if !defined(DMX_SEND_ONLY)
// Function to read DMX data // Function to read DMX data
uint8_t SparkFunDMX::read(int Channel) { uint8_t SparkFunDMX::read(int Channel) {
if (Channel > chanSize) Channel = chanSize; if (Channel > chanSize) Channel = chanSize;
return(dmxData[Channel - 1]); //subtract one to account for start byte return(dmxData[Channel - 1]); //subtract one to account for start byte
} }
#endif
// Function to send DMX data // Function to send DMX data
void SparkFunDMX::write(int Channel, uint8_t value) { void SparkFunDMX::write(int Channel, uint8_t value) {
@ -133,6 +148,7 @@ void SparkFunDMX::update() {
DMXSerial.flush(); DMXSerial.flush();
DMXSerial.end();//clear our DMX array, end the Hardware Serial port 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 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) if (_startCodeDetected == true)
@ -153,6 +169,7 @@ void SparkFunDMX::update() {
} }
} }
} }
#endif
} }
// Function to update the DMX bus // Function to update the DMX bus

View File

@ -19,19 +19,23 @@ Distributed as-is; no warranty is given.
#ifndef SparkFunDMX_h #ifndef SparkFunDMX_h
#define SparkFunDMX_h #define SparkFunDMX_h
#define DMX_SEND_ONLY // this disables DMX sending features, and saves us two GPIO pins
// ---- Methods ---- // ---- Methods ----
class SparkFunDMX { class SparkFunDMX {
public: public:
void initRead(int maxChan);
void initWrite(int maxChan); void initWrite(int maxChan);
#if !defined(DMX_SEND_ONLY)
void initRead(int maxChan);
uint8_t read(int Channel); uint8_t read(int Channel);
#endif
void write(int channel, uint8_t value); void write(int channel, uint8_t value);
void update(); void update();
private: private:
uint8_t _startCodeValue = 0xFF; const uint8_t _startCodeValue = 0xFF;
bool _READ = true; const bool _READ = true;
bool _WRITE = false; const bool _WRITE = false;
bool _READWRITE; bool _READWRITE;
}; };