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 ----- */
#ifdef ESP32
#ifdef ARDUINO_ARCH_ESP32
#include <Arduino.h>
@ -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
}
@ -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) {
@ -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) {
@ -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)
@ -153,6 +169,7 @@ void SparkFunDMX::update() {
}
}
}
#endif
}
// Function to update the DMX bus

View File

@ -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;
};