Alternate SPI Pins / Audio Crackle

Status
Not open for further replies.

whholt

New member
My current project will use a Teensy 3.5, Audio Adaptor, the OctoWS2811 Adaptor circuity (74HCT245 buffer chip, 100 ohm matching resistors) as well as a few Pololu motor drivers and encoders, limit switches, I2C Expander, and what not. One of the early tasks of design was to develop a Pin Usage Table which favored the OctoWS2811 Library. This meant Audio Adaptor pin 6 (MEMCS), 7 (SD Card MOSI), and 14 (SD Card SCLK) would be assigned different pins. To do this, Adafruit stacking headers (#3366) were inserted through and soldered to the Teensy. Adafruit extra long headers (#400) were soldered to the Audio Adaptor. I could now cut off the header leads for pin 6, 7, and 14 then jumper these topside to the newly assigned pins.

So my debug platform is simply a second Teensy with the same stacking headers inserted into a breadboard that I can put the projects Audio Adaptor onto. I don't need the rest of the project circuitry until the audio is working. Also, I am using Arduino IDE 1.8.9 and Teensyduino 1.46 on a Windows XP box. My SD
Card is a Sandisk Ultra, 16GB formatted with https://www.sdcard.org/ formatter.

Now when it came to play audio, WavFilePlayer.ino produced silence. Bummer. So I decided to test the SD Card. I had already edited github Arduino ZModem code to transfer files via serial and it worked fine with the SD Card (I have since purchased a $10 USB SD Card adapter - MUCH nicer!). And SdCardInfo.ino worked fine. The SD Card was not the problem. I moved it to the Audio Adaptor. Still no audio from files on the SD Card. So I tried SampleDrum.ino and a modified version of SamplePlayer.ino (only plays 1 sound). Both had audio! Yet still
nothing from WavFilePlayer.

Eventually, I stumbled on SPI, found the SPI Library, page, and read about ALTERNATE SPI PINS! There was also some related information on the forum at: https://forum.pjrc.com/threads/50290-Teensy-3-2-SPI-pins. Yet these only said you could use 7 or 11 for MOSI. I can't use 7 because OctoWS281 uses it. And when I used 11, no audio was produced. That issue is discussed a little later. I finally dug into SPI.h and SPI.cpp and found other pins that could be used, according to the code. This is what code (for MK64FX512 (Teensy 3.5)) gave me:

  • MISO - 12, 8, 39, 255
  • MOSI - 11, 7, 28, 255
  • SCK - 13, 14, 27
  • CS - 10, 2, 9, 6, 20, 23, 21, 22, 15, 26, 45

I decided to use 13 for SCK but it didn't seem right to feed SCK to the Audio I2S-RX pin. So I cut the pad of pin 13 then added a topside jumper between pin 13 and 14 (as 14 has no Teensy connection - see above). Pin 28 would be used for MOSI. I made a 5-pin header (so it wouldn't fall out easily) and put it at the end of the Teensy stacking header. Then a jumper went from pin 5 of this header (28) to Audio Adaptor pin 7. So everything is easy to unplug and swap between breadboard or production Teensy.

So I updated my WavFilePlayer.ino test sketch and finally played audio from the SD Card! Yet, I was never able to play if the SD Card was in the Teensy SD Slot. That is a comment I have below. But as the audio played, crackle could easily be heard as well. I dug into code and finally found and edited AUDIO_BLOCK_SAMPLES in AudioSteam.h (Arduino IDE/teensy/avr/cores/teensy3). I changed to different values and 64 seemed to be best, though there still was some crackle. In the process, I also modified SD_t3.h and defined USE_TEENSY3_OPTIMIZED_CODE. That didn't really help the crackle, so I
took it back out.

I eventually wanted a simple, basic audio test file so I downloaded two 5 second WAV files from https://www.mediacollege.com/audio/tone/download/. The 1KHz Sine WAV file was a failure because the wife REALLY didn't like the 1KHz! So I used a 440Hz Sine WAV file for most of my subsequent testing. This was a Mono file. To shorten the story, code in "play_sd_wav.cpp" (e.g. the consume function) would take a mono signal and put the same data out both channels. For testing, I thought if I inverted one channel and summed them together, the audio should nullify itself and only the crackle would be left. I wrote a Python app that did this. It identifies the crackle and outputs the sample count and time between occurrences. However, I never
went very far into any analysis. Didn't have to!

One night I thought I had never really tested all the other pins. What if one didn't produce crackle! So I made a test sketch and modified the breadboard and began testing. The sketch basically moved WavFilePlayer.ino code into the main loop() then runs a state machine at 2 second intervals to begin playing a file, keeps running until isPlaying() report done (0), delays a short time, then plays the file again. It also outputs CPU and Memory diagnostics such as SamplePlayer or SampleDrum does.

This is the "no audio for pin 11" issue mentioned above. Since the 440Hz test file is 5 seconds long, the state machine sequence will report a few outputs of isPlaying() == 1 followed by an output of isPlaying == 0 before the file is played again. The pattern became quite familiar. That is how I found pin 11 does NOT produce audio but DOES report 1 and 0 from isPlaying(), as if audio IS playing. I have not spent time investigating this further but wanted to mention the issue.

Now back to testing the operation of the different pins. At one point, I had a thought.... So I grabbed a 6.2K ohm resistor and connected it from pin 13 to the 3.3v output of the Teensy. NO CRACKLE! I didn't believe it. I connected the resistor to GND. Crackle!!! I restored AUDIO_BLOCK_SAMPLES back to 128 and moved the resistor to 3.3V. NO CRACKLE!!! I tried other audio files. No crackle!! A 10K resistor did the same thing! So that is what I am using.

So, after more than a 2 week fight - I now get to see daylight!!!! Hooray!! Hopefully, someone else will benefit from this effort, which is part of why I am writing it.


Comments / Issues

Since a 10K pull down on pin 13 is causing crackle and a 10K pull up stops crackle, I conclude pin 13 trace is somehow inducing noise that is getting into audio signals (clock or inputs) or even into a pin used by the audio library. I would also expect a probe from an OScope would add sufficient pull up or capacitance as to hide the issue if someone was just casually instead of intently looking for it (Murphy wrote a law about this). If the cause is trace layout, it might be an area of concern for the new Teensy 4 layout.

Some sort of issue exists with using pin 11 for MOSI. It ends up looking like audio is playing, according to isPlaying(), but there is no audio output. On my breadboard, with the test sketch, I have moved MOSI to 7, 11, and 28 and only 11 does not produce audio.

I have double checked and still don't know why my test file will not play audio if the SD Card is inserted into the Teensy SD slot and BUILTIN_SDCARD is selected for SD.begin(chipSelect). There is nothing else on the breadboard except a Teensy 3.5 and an Audio Adaptor using a test sketch that works fine when the SD Card in in the Audio Adaptor SD slot. I have, of course, changed the chip select to BUILTIN_SDCARD and both kept SPI and removed SPI but no audio.
 

Attachments

  • DSCI2181.jpg
    DSCI2181.jpg
    113.2 KB · Views: 84
Status
Not open for further replies.
Back
Top