Skip to main content
Correct analysis
Source Link
the busybee
  • 2.5k
  • 10
  • 19

TL;DR: The statement that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially mess up SoftwareSerial's timing"interfere with SoftwareSerial" is correct.

YouIn your described case you will be fine, if you:

  • remove the usage ofgive up using tone(), assumedor accept that you use nothing else with interruptsthe sound might be distorted during serial communication.

  • use another (serial) communication method than SoftwareSerial for your own communication, and this must not use timely interrupts.

You might want to consider to write your own drivers. They must not use interrupts and should be resistant against other interrupts.

The transmission works with delay loops. During the transmission of a byte the interrupts are disabled.

AnyNo other interrupt servicecan be serviced during athis byte transmission will prolong the bit timing and most probably mess up the sent byte. ItThe duration depends on the time used by the interrupt service routine and the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs. Asynchronous serial communication works with a timing tolerance of about 10%, therefore angiving about 1ms interval without any interrupt service routine taking 10µs at maximum will by fine. However, the actual calculation is left as an exercise.

Any interrupt service during a byte receiving will prolong the bit timing and most probably mess upDuring the received byte receiving all interrupts are automatically disabled, see chapter 7. It7 of the data sheet. Again, the duration depends on the time used by the interrupt service routine and the baudrate. This happens ifIn your case this is about 1ms interval without any other interrupt has the same or higher priority than the pin change interruptservice.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA. If it is postponed during serial communication, the generated sound might not be what you expect.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

If you happen to begin() your own SoftwareSerial or start listen()ing after initializing the DFPlayMini library, you will effectively stop it listening of on its SoftwareSerial.

Otherwise, if you initialize the DFPlayMini library after your own communication, your own listening will be stopped. Of course, you could re-enable it, but see above.

TL;DR: The statement that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially mess up SoftwareSerial's timing" is correct.

You will be fine, if you:

  • remove the usage of tone(), assumed that you use nothing else with interrupts.

  • use another (serial) communication method than SoftwareSerial, and this must not use interrupts.

You might want to consider to write your own drivers. They must not use interrupts and should be resistant against other interrupts.

The transmission works with delay loops.

Any interrupt service during a byte transmission will prolong the bit timing and most probably mess up the sent byte. It depends on the time used by the interrupt service routine and the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs. Asynchronous serial communication works with a timing tolerance of about 10%, therefore an interrupt service routine taking 10µs at maximum will by fine. However, the actual calculation is left as an exercise.

Any interrupt service during a byte receiving will prolong the bit timing and most probably mess up the received byte. It depends on the time used by the interrupt service routine and the baudrate. This happens if this other interrupt has the same or higher priority than the pin change interrupt.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

TL;DR: The statement that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially interfere with SoftwareSerial" is correct.

In your described case you will be fine, if you:

  • give up using tone(), or accept that the sound might be distorted during serial communication.

  • use another (serial) communication method than SoftwareSerial for your own communication, and this must not use timely interrupts.

The transmission works with delay loops. During the transmission of a byte the interrupts are disabled.

No other interrupt can be serviced during this byte transmission. The duration depends on the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs, giving about 1ms interval without any interrupt service.

During the byte receiving all interrupts are automatically disabled, see chapter 7.7 of the data sheet. Again, the duration depends on the baudrate. In your case this is about 1ms interval without any other interrupt service.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA. If it is postponed during serial communication, the generated sound might not be what you expect.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

If you happen to begin() your own SoftwareSerial or start listen()ing after initializing the DFPlayMini library, you will effectively stop it listening of on its SoftwareSerial.

Otherwise, if you initialize the DFPlayMini library after your own communication, your own listening will be stopped. Of course, you could re-enable it, but see above.

deleted 1 character in body
Source Link
the busybee
  • 2.5k
  • 10
  • 19

TL;DR: The statementsstatement that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially mess up SoftwareSerial's timing" is correct.

You will be fine, if you:

  • remove the usage of tone(), assumed that you use nothing else with interrupts.

  • use another (serial) communication method than SoftwareSerial, and this must not use interrupts.

You might want to consider to write your own drivers. They must not use interrupts and should be resistant against other interrupts.


Analysis of SoftwareSerial

Unfortunately, the documentation does not show enough details, so we need to look into the source code.

The transmission works with delay loops.

Any interrupt service during a byte transmission will prolong the bit timing and most probably mess up the sent byte. It depends on the time used by the interrupt service routine and the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs. Asynchronous serial communication works with a timing tolerance of about 10%, therefore an interrupt service routine taking 10µs at maximum will by fine. However, the actual calculation is left as an exercise.

When you call listen(), the pin change interrupt is armed. With the falling edge of the start bit, the interrupt handler recv() starts to sample the RX line. The timing is realizesrealized with delay loops, again.

Please note that listen() is called during begin()!

Any interrupt service during a byte receiving will prolong the bit timing and most probably mess up the received byte. It depends on the time used by the interrupt service routine and the baudrate. This happens if this other interrupt has the same or higher priority than the pin change interrupt.

By the way, SoftwareSerial works only half-duplex, as it cannot receive while transmitting. This is perfect for RS485.

SoftwareSerial can listen to only one RX line. Starting to listen (via begin() or listen()) on one interface stops listening on any other interface controlled by SoftwareSerial.

So, we need to look up whether the other software uses interrupts or SoftwareSerial.

Analysis of the tone() function

The Arduino Nano uses a ATmega328 according to its technical details.

The Arduino documentation of tone() tells us nothing about the used timer or interrupts.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA.

Analysis of DFPlayer library

The library "DFPlayerMini" uses SoftwareSerial and according to its documentation uses no interrupts.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

Final note

Such research and checking the result is a common and necessary part of software development.

TL;DR: The statements that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially mess up SoftwareSerial's timing" is correct.

You will be fine, if you:

  • remove the usage of tone(), assumed that you use nothing else with interrupts.

  • use another (serial) communication method than SoftwareSerial, and this must not use interrupts.

You might want to consider to write your own drivers. They must not use interrupts and should be resistant against other interrupts.


Analysis of SoftwareSerial

Unfortunately, the documentation does not show enough details, so we need to look into the source code.

The transmission works with delay loops.

Any interrupt service during a byte transmission will prolong the bit timing and most probably mess up the sent byte. It depends on the time used by the interrupt service routine and the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs. Asynchronous serial communication works with a timing tolerance of about 10%, therefore an interrupt service routine taking 10µs at maximum will by fine. However, the actual calculation is left as an exercise.

When you call listen(), the pin change interrupt is armed. With the falling edge of the start bit, the interrupt handler recv() starts to sample the RX line. The timing is realizes with delay loops, again.

Please note that listen() is called during begin()!

Any interrupt service during a byte receiving will prolong the bit timing and most probably mess up the received byte. It depends on the time used by the interrupt service routine and the baudrate. This happens if this other interrupt has the same or higher priority than the pin change interrupt.

By the way, SoftwareSerial works only half-duplex, as it cannot receive while transmitting. This is perfect for RS485.

SoftwareSerial can listen to only one RX line. Starting to listen (via begin() or listen()) on one interface stops listening on any other interface controlled by SoftwareSerial.

So, we need to look up whether the other software uses interrupts or SoftwareSerial.

Analysis of the tone() function

The Arduino Nano uses a ATmega328 according to its technical details.

The Arduino documentation of tone() tells us nothing about the used timer or interrupts.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA.

Analysis of DFPlayer library

The library "DFPlayerMini" uses SoftwareSerial and according to its documentation uses no interrupts.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

Final note

Such research and checking the result is a common and necessary part of software development.

TL;DR: The statement that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially mess up SoftwareSerial's timing" is correct.

You will be fine, if you:

  • remove the usage of tone(), assumed that you use nothing else with interrupts.

  • use another (serial) communication method than SoftwareSerial, and this must not use interrupts.

You might want to consider to write your own drivers. They must not use interrupts and should be resistant against other interrupts.


Analysis of SoftwareSerial

Unfortunately, the documentation does not show enough details, so we need to look into the source code.

The transmission works with delay loops.

Any interrupt service during a byte transmission will prolong the bit timing and most probably mess up the sent byte. It depends on the time used by the interrupt service routine and the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs. Asynchronous serial communication works with a timing tolerance of about 10%, therefore an interrupt service routine taking 10µs at maximum will by fine. However, the actual calculation is left as an exercise.

When you call listen(), the pin change interrupt is armed. With the falling edge of the start bit, the interrupt handler recv() starts to sample the RX line. The timing is realized with delay loops, again.

Please note that listen() is called during begin()!

Any interrupt service during a byte receiving will prolong the bit timing and most probably mess up the received byte. It depends on the time used by the interrupt service routine and the baudrate. This happens if this other interrupt has the same or higher priority than the pin change interrupt.

By the way, SoftwareSerial works only half-duplex, as it cannot receive while transmitting. This is perfect for RS485.

SoftwareSerial can listen to only one RX line. Starting to listen (via begin() or listen()) on one interface stops listening on any other interface controlled by SoftwareSerial.

So, we need to look up whether the other software uses interrupts or SoftwareSerial.

Analysis of the tone() function

The Arduino Nano uses a ATmega328 according to its technical details.

The Arduino documentation of tone() tells us nothing about the used timer or interrupts.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA.

Analysis of DFPlayer library

The library "DFPlayerMini" uses SoftwareSerial and according to its documentation uses no interrupts.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

Final note

Such research and checking the result is a common and necessary part of software development.

Source Link
the busybee
  • 2.5k
  • 10
  • 19

TL;DR: The statements that "other libraries (and to extend, any other interrupt-driven software, for example your own) can potentially mess up SoftwareSerial's timing" is correct.

You will be fine, if you:

  • remove the usage of tone(), assumed that you use nothing else with interrupts.

  • use another (serial) communication method than SoftwareSerial, and this must not use interrupts.

You might want to consider to write your own drivers. They must not use interrupts and should be resistant against other interrupts.


Analysis of SoftwareSerial

Unfortunately, the documentation does not show enough details, so we need to look into the source code.

The transmission works with delay loops.

Any interrupt service during a byte transmission will prolong the bit timing and most probably mess up the sent byte. It depends on the time used by the interrupt service routine and the baudrate. In your case with 9600 baud, one bit time is 1 / (9600 1/s) = 104µs. Asynchronous serial communication works with a timing tolerance of about 10%, therefore an interrupt service routine taking 10µs at maximum will by fine. However, the actual calculation is left as an exercise.

When you call listen(), the pin change interrupt is armed. With the falling edge of the start bit, the interrupt handler recv() starts to sample the RX line. The timing is realizes with delay loops, again.

Please note that listen() is called during begin()!

Any interrupt service during a byte receiving will prolong the bit timing and most probably mess up the received byte. It depends on the time used by the interrupt service routine and the baudrate. This happens if this other interrupt has the same or higher priority than the pin change interrupt.

By the way, SoftwareSerial works only half-duplex, as it cannot receive while transmitting. This is perfect for RS485.

SoftwareSerial can listen to only one RX line. Starting to listen (via begin() or listen()) on one interface stops listening on any other interface controlled by SoftwareSerial.

So, we need to look up whether the other software uses interrupts or SoftwareSerial.

Analysis of the tone() function

The Arduino Nano uses a ATmega328 according to its technical details.

The Arduino documentation of tone() tells us nothing about the used timer or interrupts.

But the source code does. Apparently it uses timer 2 on a ATmega328. The tone is generated through the interrupt handler on TIMER2_COMPA.

Analysis of DFPlayer library

The library "DFPlayerMini" uses SoftwareSerial and according to its documentation uses no interrupts.

Unfortunately the library provides no methods to pause listening to the player. Otherwise you could use that to communicate on another interface controlled by SoftwareSerial.

Final note

Such research and checking the result is a common and necessary part of software development.