@@ -104,15 +104,18 @@ int _dmxModePin; // pin used for I/O direction.
104
104
105
105
uint8_t _dmxRecvState; // Current State of receiving DMX Bytes
106
106
int _dmxChannel; // the next channel byte to be sent.
107
+ uint16_t _dmxRecvAddress = 0 ; // the address to which the devic should listen
108
+ uint16_t _dmxReceivePos = 0 ; // the DMX receiver channel count
107
109
108
- volatile int _dmxMaxChannel = 32 ; // the last channel used for sending (1..512).
110
+ volatile int _dmxMaxChannel = 0 ; // the last channel used for sending (1..512).
109
111
volatile unsigned long _dmxLastPacket = 0 ; // the last time (using the millis function) a packet was received.
110
112
111
113
bool _dmxUpdated = true ; // is set to true when new data arrived.
114
+ volatile unsigned long _dmxLastUpdate = 0 ; // the last time (using the millis function) a packet updated a channel.
112
115
113
116
// Array of DMX values (raw).
114
117
// Entry 0 will never be used for DMX data but will store the startbyte (0 for DMX mode).
115
- uint8_t _dmxData[DMXSERIAL_MAX + 1 ] ;
118
+ uint8_t * _dmxData;
116
119
117
120
// This pointer will point to the next byte in _dmxData;
118
121
uint8_t *_dmxDataPtr;
@@ -137,19 +140,26 @@ void DMXSerialClass::init(int mode)
137
140
void DMXSerialClass::init (int mode, int dmxModePin)
138
141
{
139
142
// initialize global variables
143
+
144
+ if (!_dmxRecvAddress) _dmxRecvAddress = 1 ;
145
+ if (!_dmxMaxChannel) _dmxMaxChannel = DMXSERIAL_MAX; // The default in Receiver mode is reading all possible 512 channels.
146
+
147
+ _dmxData = malloc ((min (_dmxMaxChannel, DMXSERIAL_MAX) + 1 ) * sizeof (uint8_t ));
148
+
140
149
_dmxMode = DMXNone;
141
150
_dmxModePin = dmxModePin;
142
151
_dmxRecvState = STARTUP; // initial state
143
152
_dmxChannel = 0 ;
144
153
_dmxDataPtr = _dmxData;
145
154
_dmxLastPacket = millis (); // remember current (relative) time in msecs.
155
+ _dmxLastUpdate = _dmxLastPacket;
156
+ _dmxReceivePos = 0 ;
146
157
147
- _dmxMaxChannel = DMXSERIAL_MAX; // The default in Receiver mode is reading all possible 512 channels.
148
158
_dmxDataLastPtr = _dmxData + _dmxMaxChannel;
149
159
150
160
// initialize the DMX buffer
151
161
// memset(_dmxData, 0, sizeof(_dmxData));
152
- for (int n = 0 ; n < DMXSERIAL_MAX + 1 ; n++)
162
+ for (int n = 0 ; n < _dmxMaxChannel + 1 ; n++)
153
163
_dmxData[n] = 0 ;
154
164
155
165
// now start
@@ -297,9 +307,30 @@ void DMXSerialClass::term(void)
297
307
{
298
308
// Disable all USART Features, including Interrupts
299
309
_DMX_setMode (DMXUARTMode::OFF);
310
+ free (_dmxData);
300
311
} // term()
301
312
302
313
314
+ // Calculate how long it has been since a channel was updated
315
+ unsigned long DMXSerialClass::noUpdateSince (void )
316
+ {
317
+ unsigned long now = millis ();
318
+ return (now - _dmxLastUpdate);
319
+ } // noUpdateSince()
320
+
321
+
322
+ // Set the DMX address of the listening device
323
+ void DMXSerialClass::setAddress (uint16_t address)
324
+ {
325
+ if (address < 1 ){
326
+ _dmxRecvAddress = 1 ;
327
+ } else if (address >= DMXSERIAL_MAX){
328
+ _dmxRecvAddress = DMXSERIAL_MAX;
329
+ } else {
330
+ _dmxRecvAddress = address;
331
+ }
332
+ }
333
+
303
334
// ----- internal functions and interrupt implementations -----
304
335
305
336
@@ -342,6 +373,7 @@ void _DMXReceived(uint8_t data, uint8_t frameerror)
342
373
// break condition detected.
343
374
_dmxRecvState = BREAK;
344
375
_dmxDataPtr = _dmxData;
376
+ _dmxReceivePos = 0 ;
345
377
346
378
} else if (DmxState == BREAK) {
347
379
// first byte after a break was read.
@@ -350,6 +382,7 @@ void _DMXReceived(uint8_t data, uint8_t frameerror)
350
382
_dmxRecvState = DATA;
351
383
_dmxLastPacket = millis (); // remember current (relative) time in msecs.
352
384
_dmxDataPtr++; // start saving data with channel # 1
385
+ _dmxReceivePos++;
353
386
354
387
} else {
355
388
// This might be a RDM or customer DMX command -> not implemented so wait for next BREAK !
@@ -358,12 +391,16 @@ void _DMXReceived(uint8_t data, uint8_t frameerror)
358
391
359
392
} else if (DmxState == DATA) {
360
393
// check for new data
361
- if (*_dmxDataPtr != data) {
362
- _dmxUpdated = true ;
363
- // store received data into dmx data buffer.
364
- *_dmxDataPtr = data;
365
- } // if
366
- _dmxDataPtr++;
394
+ if (_dmxReceivePos >= _dmxRecvAddress && _dmxReceivePos < (_dmxRecvAddress+_dmxMaxChannel)){
395
+ if (*_dmxDataPtr != data) {
396
+ _dmxUpdated = true ;
397
+ _dmxLastUpdate = millis ();
398
+ // store received data into dmx data buffer.
399
+ *_dmxDataPtr = data;
400
+ } // if
401
+ _dmxDataPtr++;
402
+ }
403
+ _dmxReceivePos++;
367
404
368
405
if (_dmxDataPtr > _dmxDataLastPtr) {
369
406
// all channels received.
0 commit comments