Skip to content

Commit

Permalink
Scenarios for demonstrating hang
Browse files Browse the repository at this point in the history
On line 44 of `adafruit_soundboard.py` is a variable `SCENARIO`.
Changing its value will demonstrate the different behaviors I've seen.
But first, make sure you've got an instance of the `Soundboard` class
already created. And to be safe, also set the `debug` and
`alt_get_files` flags.

For each scenario, do the following:

1. Set the value for `SCENARIO`
2. Run:
   ```
   mpy-cross adafruit_soundboard.py
   ```
3. Transfer `adafruit_soundboard.mpy` to the board
4. From the REPL, create an instance of `Soundboard`, in the examples
   the instance will be in the `sound` variable.
5. Follow the other instructions for the scenario

Also, on my soundboard, track 8 is a long track and track 0 is short.
It's totally normal for the driver to attempt to restart the board once
toward the beginning.

BTW reading `Soundboard.files` is a good debug command because it calls
lots of commands in sequence.

## Scenario 0

In scenario 0, no attempt is made to clear the input buffer between
commands. This results in the soundboard's output being interpreted
incorrectly. The `read()` method is used to read the soundboard's
output.

With `SCENARIO` set to 0, execute any of the following commands:

```
sound.vol
sound.vol_up()  # should work
sound.vol = 100
sound.files
```

This always gives me unpredictable results. Some commands work, others
don't.

## Scenario 1

In scenario 1, no attempt is made to clear the input buffer between
commands. This results in the soundboard's output being interpreted
incorrectly. The `readline()` method is used to read the soundboard's
output.

With `SCENARIO` set to 1, do the following:

1. Play a longer track, at least a few seconds to give yourself some
   time to enter the next command while it's still playing.
   ```sound.play(8)```
2. While the previous track is still playing, play another track
   immediately:
   ```sound.play_now(0)```
3. Play the long track again after the short track finishes
   ```sound.play(8)```
   (Actually, it doesn't matter which track you play at this point.)

At this point, you should be able to see in the debug output that the
feedback from the soundboard appears empty. It actually just processed a
single newline character, but it still interprets the result as being a
failure to play.

This can also be seen if you play a track multiple times in a row.

## Scenario 2

In scenario 2, the input buffer is cleared using the `UART.read()`
method. The `readline()` method is used to read the soundboard's output.

With `SCENARIO` set to 2, do the following:

1. Attempt to fetch the list of files from the board
   ```
   sound.files
   ```

The program should hang at this point. If you leave it for a minute,
such as I did to write the last few lines, it may begin to actually
interact with the soundboard properly, but very slowly. If you hit
Ctrl+C at one of the moments when it is paused, you'll see that things
are held up on line 125, where I'm trying to flush the input from the
board with a `UART.read()`.

## Scenario 3

In scenario 3, the input buffer is cleared using the `UART.read()`
method. The `read()` method is used to read the soundboard's output.

With `SCENARIO` set to 3, do the following:

1. Attempt to fetch the list of files from the board
   ```
   sound.files
   ```

This always gives me unpredictable results. Some commands work, others
don't.
  • Loading branch information
mmabey committed Aug 25, 2017
1 parent 826af8f commit 4a4add0
Showing 1 changed file with 13 additions and 6 deletions.
19 changes: 13 additions & 6 deletions adafruit_soundboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
CMD_DELAY = 0.010
DEBUG = False

SCENARIO = 0


class Soundboard:
"""Control an Adafruit Sound Board via UART.
Expand Down Expand Up @@ -117,11 +119,13 @@ def __init__(self, uart_tx, uart_rx, rst_pin=None, *, vol=None, alt_get_files=Fa

def _flush_uart_input(self):
"""Read any available data from the UART bus until none is left."""
return # TODO: adding this return statement prevented the hang, but made other commands do weird things
# m = self._uart.read()
# while m is not None:
# printif(m) # TODO: Remove this after debugging hanging issue
# m = self._uart.read()
if SCENARIO in (0, 1):
return # TODO: adding this return statement prevented the hang, but made other commands do weird things
elif SCENARIO in (2, 3):
m = self._uart.read()
while m is not None:
printif(m) # TODO: Remove this after debugging hanging issue
m = self._uart.read()

def _send_simple(self, cmd, check=None, strip=True):
"""Send the command, optionally do a check on the output.
Expand Down Expand Up @@ -162,7 +166,10 @@ def _send_simple(self, cmd, check=None, strip=True):
# We need to gobble the return when there's more than one character in the command
self._uart.readline()
try:
msg = self._uart.readline()
if SCENARIO in (1, 2):
msg = self._uart.readline()
elif SCENARIO in (0, 3):
msg = self._uart.read()
if strip:
msg = msg.strip()
assert isinstance(msg, bytes)
Expand Down

0 comments on commit 4a4add0

Please sign in to comment.