mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +01:00
Update IO_DFPlayer.h
Rework delay between command: instead of sending null characters, which doesn't work on some chip sets, send commands from the _loop() function with a 100ms delay between consecutive commands.
This commit is contained in:
parent
881463ada9
commit
325d4bce73
|
@ -75,20 +75,9 @@ private:
|
||||||
bool _playing = false;
|
bool _playing = false;
|
||||||
uint8_t _inputIndex = 0;
|
uint8_t _inputIndex = 0;
|
||||||
unsigned long _commandSendTime; // Allows timeout processing
|
unsigned long _commandSendTime; // Allows timeout processing
|
||||||
uint8_t _lastVolumeLevel = MAXVOLUME;
|
uint8_t _requestedVolumeLevel = MAXVOLUME;
|
||||||
|
uint8_t _currentVolume = MAXVOLUME;
|
||||||
// When two commands are sent in quick succession, the device sometimes
|
int _requestedSong = -1; // -1=none, 0=stop, >0=file number
|
||||||
// fails to execute one. A delay is required between successive commands.
|
|
||||||
// This could be implemented by buffering commands and outputting them
|
|
||||||
// from the loop() function, but it would somewhat complicate the
|
|
||||||
// driver. A simpler solution is to output a number of NUL pad characters
|
|
||||||
// between successive command strings if there isn't sufficient elapsed time
|
|
||||||
// between them. At 9600 baud, each pad character takes approximately
|
|
||||||
// 1ms to complete. Experiments indicate that the minimum number of pads
|
|
||||||
// for reliable operation is 17. This gives 17.7ms between the end of one
|
|
||||||
// command and the beginning of the next, or 28ms between successive commands
|
|
||||||
// being completed. I've allowed 20 characters, which is almost 21ms.
|
|
||||||
const int numPadCharacters = 20; // Number of pad characters between commands
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -148,11 +137,39 @@ protected:
|
||||||
} else
|
} else
|
||||||
_inputIndex = 0; // Unrecognised character sequence, start again!
|
_inputIndex = 0; // Unrecognised character sequence, start again!
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the initial prompt to device has timed out. Allow 5 seconds
|
// Check if the initial prompt to device has timed out. Allow 5 seconds
|
||||||
if (_deviceState == DEVSTATE_INITIALISING && currentMicros - _commandSendTime > 5000000UL) {
|
if (_deviceState == DEVSTATE_INITIALISING && currentMicros - _commandSendTime > 5000000UL) {
|
||||||
DIAG(F("DFPlayer device not responding on serial port"));
|
DIAG(F("DFPlayer device not responding on serial port"));
|
||||||
_deviceState = DEVSTATE_FAILED;
|
_deviceState = DEVSTATE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When two commands are sent in quick succession, the device will often fail to
|
||||||
|
// execute one. Testing has indicated that a delay of 100ms or more is required
|
||||||
|
// between successive commands to get reliable operation.
|
||||||
|
// If 100ms has elapsed since the last thing sent, then check if there's some output to do.
|
||||||
|
if (currentMicros - _commandSendTime > 100000UL) {
|
||||||
|
if (_currentVolume > _requestedVolumeLevel) {
|
||||||
|
// Change volume before changing song if volume is reducing.
|
||||||
|
_currentVolume = _requestedVolumeLevel;
|
||||||
|
sendPacket(0x06, _currentVolume);
|
||||||
|
_commandSendTime = currentMicros;
|
||||||
|
} else if (_requestedSong > 0) {
|
||||||
|
// Change song
|
||||||
|
sendPacket(0x03, _requestedSong);
|
||||||
|
_requestedSong = -1;
|
||||||
|
_commandSendTime = currentMicros;
|
||||||
|
} else if (_requestedSong == 0) {
|
||||||
|
sendPacket(0x16); // Stop playing
|
||||||
|
_requestedSong = -1;
|
||||||
|
_commandSendTime = currentMicros;
|
||||||
|
} else if (_currentVolume < _requestedVolumeLevel) {
|
||||||
|
// Change volume after changing song if volume is increasing.
|
||||||
|
_currentVolume = _requestedVolumeLevel;
|
||||||
|
sendPacket(0x06, _currentVolume);
|
||||||
|
_commandSendTime = currentMicros;
|
||||||
|
}
|
||||||
|
}
|
||||||
delayUntil(currentMicros + 10000); // Only enter every 10ms
|
delayUntil(currentMicros + 10000); // Only enter every 10ms
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,14 +182,14 @@ protected:
|
||||||
#ifdef DIAG_IO
|
#ifdef DIAG_IO
|
||||||
DIAG(F("DFPlayer: Play %d"), pin+1);
|
DIAG(F("DFPlayer: Play %d"), pin+1);
|
||||||
#endif
|
#endif
|
||||||
sendPacket(0x03, pin+1);
|
_requestedSong = pin+1;
|
||||||
_playing = true;
|
_playing = true;
|
||||||
} else {
|
} else {
|
||||||
// Value 0, stop playing
|
// Value 0, stop playing
|
||||||
#ifdef DIAG_IO
|
#ifdef DIAG_IO
|
||||||
DIAG(F("DFPlayer: Stop"));
|
DIAG(F("DFPlayer: Stop"));
|
||||||
#endif
|
#endif
|
||||||
sendPacket(0x16);
|
_requestedSong = 0; // No song
|
||||||
_playing = false;
|
_playing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,10 +198,6 @@ protected:
|
||||||
// Volume may be specified as second parameter to writeAnalogue.
|
// Volume may be specified as second parameter to writeAnalogue.
|
||||||
// If value is zero, the player stops playing.
|
// If value is zero, the player stops playing.
|
||||||
// WriteAnalogue on second pin sets the output volume.
|
// WriteAnalogue on second pin sets the output volume.
|
||||||
// If starting a new file and setting volume, then avoid a short burst of loud noise by
|
|
||||||
// the following strategy:
|
|
||||||
// - If the volume is increasing, start playing the song before setting the volume,
|
|
||||||
// - If the volume is decreasing, decrease it and then start playing.
|
|
||||||
//
|
//
|
||||||
void _writeAnalogue(VPIN vpin, int value, uint8_t volume=0, uint16_t=0) override {
|
void _writeAnalogue(VPIN vpin, int value, uint8_t volume=0, uint16_t=0) override {
|
||||||
uint8_t pin = vpin - _firstVpin;
|
uint8_t pin = vpin - _firstVpin;
|
||||||
|
@ -198,28 +211,18 @@ protected:
|
||||||
|
|
||||||
if (pin == 0) {
|
if (pin == 0) {
|
||||||
// Play track
|
// Play track
|
||||||
if (value > 0) {
|
if (value > 0 && volume != 0) {
|
||||||
if (volume != 0) {
|
if (volume != 0)
|
||||||
if (volume <= _lastVolumeLevel)
|
_requestedVolumeLevel = volume;
|
||||||
sendPacket(0x06, volume); // Set volume before starting
|
_requestedSong = value;
|
||||||
sendPacket(0x03, value); // Play track
|
|
||||||
_playing = true;
|
_playing = true;
|
||||||
if (volume > _lastVolumeLevel)
|
|
||||||
sendPacket(0x06, volume); // Set volume after starting
|
|
||||||
_lastVolumeLevel = volume;
|
|
||||||
} else {
|
} else {
|
||||||
// Volume not changed, just play
|
_requestedSong = 0; // stop playing
|
||||||
sendPacket(0x03, value);
|
|
||||||
_playing = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sendPacket(0x16); // Stop play
|
|
||||||
_playing = false;
|
_playing = false;
|
||||||
}
|
}
|
||||||
} else if (pin == 1) {
|
} else if (pin == 1) {
|
||||||
// Set volume (0-30)
|
// Set volume (0-30)
|
||||||
sendPacket(0x06, value);
|
_requestedVolumeLevel = volume;
|
||||||
_lastVolumeLevel = volume;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +249,6 @@ private:
|
||||||
|
|
||||||
void sendPacket(uint8_t command, uint16_t arg = 0)
|
void sendPacket(uint8_t command, uint16_t arg = 0)
|
||||||
{
|
{
|
||||||
unsigned long currentMillis = millis();
|
|
||||||
uint8_t out[] = { 0x7E,
|
uint8_t out[] = { 0x7E,
|
||||||
0xFF,
|
0xFF,
|
||||||
06,
|
06,
|
||||||
|
@ -260,19 +262,8 @@ private:
|
||||||
|
|
||||||
setChecksum(out);
|
setChecksum(out);
|
||||||
|
|
||||||
// Check how long since the last command was sent.
|
// Output the command
|
||||||
// Each character takes approx 1ms at 9600 baud
|
|
||||||
unsigned long minimumGap = numPadCharacters + sizeof(out);
|
|
||||||
if (currentMillis - _commandSendTime < minimumGap) {
|
|
||||||
// Output some pad characters to add an
|
|
||||||
// artificial delay between commands
|
|
||||||
for (int i=0; i<numPadCharacters; i++)
|
|
||||||
_serial->write((uint8_t)0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now output the command
|
|
||||||
_serial->write(out, sizeof(out));
|
_serial->write(out, sizeof(out));
|
||||||
_commandSendTime = currentMillis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t calcChecksum(uint8_t* packet)
|
uint16_t calcChecksum(uint8_t* packet)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user