diff --git a/IODevice.cpp b/IODevice.cpp index 98584ca..cf90efe 100644 --- a/IODevice.cpp +++ b/IODevice.cpp @@ -53,7 +53,9 @@ void IODevice::begin() { MCP23017::create(180, 16, 0x21); // Call the begin() methods of each configured device in turn + unsigned long currentMicros = micros(); for (IODevice *dev=_firstDevice; dev!=NULL; dev = dev->_nextDevice) { + dev->_nextEntryTime = currentMicros; dev->_begin(); } _initPhase = false; @@ -69,8 +71,14 @@ void IODevice::loop() { unsigned long currentMicros = micros(); // Call every device's loop function in turn, one per entry. if (!_nextLoopDevice) _nextLoopDevice = _firstDevice; - if (_nextLoopDevice) { + // Check if device exists, and is due to run + if (_nextLoopDevice /* && ((long)(currentMicros-_nextLoopDevice->_nextEntryTime) >= 0) */ ) { + // Move _nextEntryTime on, so that we can guarantee that the device will continue to + // be serviced if it doesn't update _nextEntryTime. + _nextLoopDevice->_nextEntryTime = currentMicros; + // Invoke device's _loop function _nextLoopDevice->_loop(currentMicros); + // Move to next device. _nextLoopDevice = _nextLoopDevice->_nextDevice; } @@ -157,12 +165,13 @@ void IODevice::writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t dur #endif } -// isBusy returns true if the device is currently in an animation of some sort, e.g. is changing -// the output over a period of time. +// isBusy, when called for a device pin is always a digital output or analogue output, +// returns input feedback state of the pin, i.e. whether the pin is busy performing +// an animation or fade over a period of time. bool IODevice::isBusy(VPIN vpin) { IODevice *dev = findDevice(vpin); if (dev) - return dev->_isBusy(vpin); + return dev->_read(vpin); else return false; } @@ -248,7 +257,7 @@ int IODevice::readAnalogue(VPIN vpin) { return dev->_readAnalogue(vpin); } #ifdef DIAG_IO - //DIAG(F("IODevice::readAnalogue(): Vpin %d not found!"), (int)vpin); + DIAG(F("IODevice::readAnalogue(): Vpin %d not found!"), (int)vpin); #endif return false; } diff --git a/IODevice.h b/IODevice.h index 58de64b..7e45816 100644 --- a/IODevice.h +++ b/IODevice.h @@ -129,7 +129,7 @@ public: static void write(VPIN vpin, int value); // write invokes the IODevice instance's _writeAnalogue method (not applicable for digital outputs) - static void writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration=0); + static void writeAnalogue(VPIN vpin, int value, uint8_t profile=0, uint16_t duration=0); // isBusy returns true if the device is currently in an animation of some sort, e.g. is changing // the output over a period of time. @@ -178,7 +178,7 @@ protected: }; // Method to write an 'analogue' value (optionally implemented within device class) - virtual void _writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) { + virtual void _writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) { (void)vpin; (void)value; (void) profile; (void)duration; }; @@ -203,13 +203,6 @@ protected: return 0; }; - // _isBusy returns true if the device is currently in an animation of some sort, e.g. is changing - // the output over a period of time. Returns false unless overridden in sub class. - virtual bool _isBusy(VPIN vpin) { - (void)vpin; - return false; - } - // Method to perform updates on an ongoing basis (optionally implemented within device class) virtual void _loop(unsigned long currentMicros) { (void)currentMicros; // Suppress compiler warning. @@ -220,6 +213,11 @@ protected: // Destructor virtual ~IODevice() {}; + + // Non-virtual function + void delayUntil(unsigned long futureMicrosCount) { + _nextEntryTime = futureMicrosCount; + } // Common object fields. VPIN _firstVpin; @@ -242,6 +240,7 @@ private: static IODevice *findDevice(VPIN vpin); IODevice *_nextDevice = 0; + unsigned long _nextEntryTime; static IODevice *_firstDevice; static IODevice *_nextLoopDevice; @@ -276,7 +275,7 @@ private: // Device-specific write functions. void _write(VPIN vpin, int value) override; void _writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t duration) override; - bool _isBusy(VPIN vpin) override; + int _read(VPIN vpin) override; // returns the busy status of the device void _loop(unsigned long currentMicros) override; void updatePosition(uint8_t pin); void writeDevice(uint8_t pin, int value); diff --git a/IO_DFPlayer.h b/IO_DFPlayer.h index 061cd3f..f7a1a9b 100644 --- a/IO_DFPlayer.h +++ b/IO_DFPlayer.h @@ -65,7 +65,7 @@ private: public: DFPlayer(VPIN firstVpin, int nPins, HardwareSerial &serial) { _firstVpin = firstVpin; - _nPins = min(nPins, 3); + _nPins = nPins; _serial = &serial; addDevice(this); } @@ -159,7 +159,8 @@ protected: } } - bool _isBusy(VPIN) override { + // A read on any pin indicates whether the player is still playing. + int _read(VPIN) override { return _playing; } diff --git a/IO_PCA9685.cpp b/IO_PCA9685.cpp index ddc45d8..d8c9795 100644 --- a/IO_PCA9685.cpp +++ b/IO_PCA9685.cpp @@ -169,9 +169,9 @@ void PCA9685::_writeAnalogue(VPIN vpin, int value, uint8_t profile, uint16_t dur s->fromPosition = s->currentPosition; } -// _isBusy returns true if the device is currently in executing an animation, +// _read returns true if the device is currently in executing an animation, // changing the output over a period of time. -bool PCA9685::_isBusy(VPIN vpin) { +int PCA9685::_read(VPIN vpin) { int pin = vpin - _firstVpin; struct ServoData *s = _servoData[pin]; if (s == NULL)