Sound for model railroading scale 1/32

Status
Not open for further replies.
About the Python script :

1) Launch CopyFromSerial (Which also erases SPI Flash)
2) Wait for fix Led on Teensy 3.2
3) Unplug USB
:confused:
4) Plug USB
:confused:
5) Launch Python script with Command line : Python "rawfile-uploader.py" "COM4" "WHISTM1.TRW" - WHISTM1.TRW is in the same directory than "rawfile-uploader.py" )
:D
 
Thanks for the command procedure for CopyfromSerial.......but still cannot get it to work
Below is the errors from the CMD prompt window when I run the python bit...

...................................................................

C:\Python34>python "rawfile-uploader.py" "COM5" "LOCO201.RAW"
Traceback <most recent call last>:
File "rawfile-uploader.py", line 17, in <module>
import serial, sys, os, time
ImportError: No module named 'serial'

..........................................................

I have Python 3.4 installed in C:\Python34
I would probably need envionmental variables setup, but I havent done that co I copied the rawfile-uploader.py and the sound file LOCO201.RAW to c:\Python34 where python.exe is and opened a CMD prompt window and typed in the commands as you see. I first opened the CopyfromSerial sketch and uploaded it to teensy, LED flashed slow then faster them on solid, I then uplugged USB and plugged it in again, LEDs flashed again and went solid, then I typed in the CMD prompt, nothing seemed to happen except the errors on the CMD window

I see it is complaining about the first line in the script import serial etc etc.......do I need to setup anything....????
 
I am not familiar with Python........but on googling the error I this thats what I have to do......I have downloaded the pyserial-master....it mentions install with pip install pyserial but that doesnt work.....I probably need thinks in the right place etc paths etc or windows installer...??
 
I have not use PIP.
Manual installation
INSTALL PYSERIAL under WINDOWS
1) Check that windows knows the path of the executable python /
Open a command window (in "Accessories") and type "python".
If it appears a line with the python version, and the command prompt, everything is fine.
Otherwise it appears a message of the style "python is not recognized ....."
We must add the PATH to python: C: \ Python27 for example.
Find the command that launches python (for example, C: \ Python27 \ python)
Right click on "My Computer", "Advanced", "Environment Variables".
Choose, in system variables "Path" and "Modify"
Insert the Python folder (for example C: \ Python27)
Check that it works.

2) Download the pyserial-2.6.tar.gz archive on the pyserial website.
Uncompress it and copy the "pyserial-2.6" folder to the C: \ Python27 \ Lib \ site-packages folder.

3) Open a command window (in "Accessories"), and go to the folder that contains the
setup.py file. (using the cd command)
type:python setup.py install

Basic commands
(For more details consult the repository on the Net)
a) Open / close a port :
import serial # imports the serial module
ser = serial.Serial (0) # open the first serial port and create the object ser
print (ser) #displays port info
ser.close () # closes the port
Note
: when opening the port we can specify various parameters (baudrate (speed), timeout, ...)
Example :
ser = serial.Serial (0, baudrate = 9600, timeout = 0.1)

b) Read and write
It is convenient to place the write and read instructions in an infinite loop (with one condition
Release : break)

Example:
while 1: data = ser.read (8) # read data in packets of 8 bytes
print (data)
word = input ( 'Word to send ') # entering the word to send
if word = 'Q' : # type "Q" to leave
break
ser.write (mot.encode ( 'utf-8')) # send a string encoded in utf8
 
Thanks for reply......I would need to read up a bit on Python......and setup all the environment etc...
as a quick trial, at command prompt went to folder of setup.py and ran C:\python34\python setup.py install and it ran scrolling alot up the screen, tried the uploader again....It got past the import line....found alot of " frozen whatevers" but didn't copy any file......I can still use the SD copy.....but will probably reinstall python sometime and see If I can set it up correctly this time....thanks
 
Thanks for all the info.......
I decided I would uninstall the 3,4 and install the Python 2.7.....windows x86 exe version....there are an awful lot of versions to pick from
when I went looking for the pyserial....ther was a windows exe for x86 version so tried that and all seemed to work...seamlessly....no command line just click to install. .........and it added.....C:\Python27\;C:\Python27\Scripts; to my PATH.........
and its now working allowing import serial etc....
this is text from the python GUI screen........

Python 2.7.14 (v2.7.14:84471935ed, Sep 16 2017, 20:19:30) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import serial
>>> ser = serial.Serial(0)
>>> print ser
Serial<id=0x1353590, open=True>(port='COM1', baudrate=9600, bytesize=8, parity='N', stopbits=1, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False)

So tried Copyfrom serial.......all appeared to run OK this time.....and command window told me..I think....copying file or transferring file......and then immediately crashed my PC to restart......all restarted OK....Microsoft complained about recovering from a serious error.....send or not send etc......I didn't send.... Ran the Listfiles sketch....no files copied to spiflash....??????.
Question...What COM port should I put in the python CMD line.......I put in COM5 because that what teensy is using to run the sketch.....Does that cause a conflict of interests..?? ........should I put in a COM8 say or some other not used port for it to create....????.....
I will keep trying.....but at least I think Python is working now....Thanks

Edited...... I tried other port numbers...says it can't find them.....and tried COM5 again...same thing......CMD window said...Uploading 1 file.....then crashed PC and restarted.....but no file copied......
I tried in settings on IDE setting teensy as HID....compile and upload of sketch OK.....with Listfiles, but no message sent to com monitor to say no files on flash chip........it told me virtual serial online...???? on the com monitor window....??

Edited2....It says in the notes in the script that the script can be run as soon as teensy is plugged in as it will buffer and wait untill teensy starts to read the data from the USB serial...???....so I assume that means before the LED is steady on.......so tried CMD line while teensy flashing slow...and same thing right away while flashing slow.....cmd window shows "Uploading 1 files" and something else below it then in about 1 sec .... PC crash.... So I assume problem must be how the script is conflicting with USB serial when setting up buffers and waiting.....???...
 
Last edited:
If I run the CMD line putting in COM5 and teensy unplugged it says it cannot find it..OK
If I run the CDM line putting in COM1 which is a physical 9 pin rs232 port on PC that teensy is not connected to the script runs in the CMD window and says "Uploading 1 files..."
and the next line says " 1: LOCO201.RAW " .......so looks like it is finding the files OK and waiting on the port telling it what to do.....but I have nothing in COM1.
....so must be something to do with how virtual COM5 is using or conflicting with USB on my PC......?
 
I commented out the "ser.write" statement at the bottom of the script, and put in a print("b") for each byte read and a print("x") just before the f.close()
and all this worked....it printed out a long list of "b" ....... probably about 2 million of them and a "x" at the bottom and then <11.93 KB/s> then "All files uploaded" and returned to the C:\Python27> prompt.......so it is reading each byte in the file and going through the whole script.....but doesn't like writing to serial....???

This is the tailend of python script.............

#Binary data, with escaping
for byte in f.read():
if byte == BYTE_START or byte == BYTE_ESCAPE:
encoded.append(BYTE_ESCAPE)
encoded.append(chr(ord(byte) ^ 0x20))
else:
encoded.append(byte);
print("b.")

#Write end of data byte
encoded.append(BYTE_START)
#ser.write("".join(encoded))

finally:
print("x.")
f.close()

endTime = time.time();
print(" (" + str(round(fileLength / 1024 / (endTime - startTime), 2)) + " KB/s)");

print("All files uploaded")

..........................................................................
 
I installed Python2 (2.7), not Python 3.
Don't forget to just unplug and replug between CopyFromSerial and C:\Python34>python "rawfile-uploader.py" "COM5" "LOCO201.RAW"

COM1, COM5 ?
It is the same port than the port used to upload the CopyFromSerial in the Teensy (see in Windows tools, the port used by the Arduino IDE).
For me, it's COM4.
 
Last edited:
OK, but see earlier posts today, I have installed python2.7 this morning and all seem ok from Python point of view regards the previous 3.4 problems, but 2.7 is now crashing my PC when the Python script runs.....

I have tried various combination to see where the problen lies, and figure out that it is opening the port, finding the files, and reading them but when it actually attempts to do ser.write the PC crashes and no files copied....se earlier posts...

This is the CMD line I have been using for python 2.7
C:\Python27>python "rawfile-uploader.py" "COM5" "LOCO201.RAW"
 
I installed Python2 (2.7), not Python 3.
Don't forget to just unplug and replug between CopyFromSerial and C:\Python34>python "rawfile-uploader.py" "COM5" "LOCO201.RAW"

COM1, COM5 ?
It is the same port than the port used to upload the CopyFromSerial in the Teensy (see in Windows tools, the port used by the Arduino IDE).
For me, it's COM4.

I think you have also to install "Java".
 
I installed Python2 (2.7), not Python 3.
Don't forget to just unplug and replug between CopyFromSerial and C:\Python34>python "rawfile-uploader.py" "COM5" "LOCO201.RAW"
I have python2.t installed and pyserial from the website
This is the CMD line I have been using for python 2.7
C:\Python27>python "rawfile-uploader.py" "COM5" "LOCO201.RAW"


COM1, COM5 ? I only tried COM1 to see if script would run without crashing.....it is 9pin rs232 nothing connected....but the script ran from the CMD prompt. see earlier post
It is the same port than the port used to upload the CopyFromSerial in the Teensy (see in Windows tools, the port used by the Arduino IDE).
For me, it's COM4. ......... COM5 for me is the USB serial com port I use for Teensy and set up in tools settings and works for sketch uploads and monitor comms.

I think you have also to install "Java". ........Java version 8 is installed......somewhere in the background...????

I thought uninstalling 3.4 and installing 2.7 would have sorted out my problems but just give me different one.....

as per my earlier posts I think it is finding and reading the files ok.......but must be conflicts, interrupts etc when the ser.write() starts sending...if I comment this out all runs through but obviously no data sent....

Did you get your sound playing.....or are we both at the stage where it should works but doesn't......????
 
No, I don't get sound playing. It's a mystery !

Have test the dialog between Teensy and SPI Flash with "ReadBenchmark" (after launching "EraseEverything") ?
 
When I installed the python2.7 I used the windows installer and also a windows installer version of pyserial2.7.
Your post yesterday suggested the tar version pyserial2.6...
I have uninstalled the pyserial2.7 and unzipped the tar.gz version od 2.6 and installed it as per you instructions.......still the same...crashing and restarting my PC
The file I was trying to copy is 1.9 MB so I tried a small file the filesaw1.trw and it went through the full procedure and back to the command prompt without crashing the PC but still no file copied to flash.
Question after running the python script and hopfully the files copied and I want to list the files I have to upload the listfiles sketch to teensy and I need it plugged in...While I am compiling the listfiles script the leds on teensy are flashing....are they not then erasing the files again as they do on the first run...???
I did it by unplugging teensy board from the flash after the python script copy and loading the listfiles sketch to teensy unplugged....then plug in again to the flash board , power up via USB and list files....but still no files.....I dont know if the CopySerial erases as it flashes 2nd time or not...?
So it is still not working..... but not crashing with small files....I would need to try it on another computer....but will give up for now..except I get some idea of what is happening.....
 
About CopyFromSerial, hereafter the comments :
Code:
 * This is example code to 1) format an SPI Flash chip, and 2) copy raw 
 * audio files (mono channel, 16 bit signed, 44100Hz) to it using the 
 * SerialFlash library.  The audio can then be played back using the 
 * AudioPlaySerialflashRaw object in the Teensy Audio library.
 * 
 * To convert a .wav file to the proper .RAW format, use sox:
 * sox input.wav -r 44100 -b 16 --norm -e signed-integer -t raw OUTPUT.RAW remix 1,2
 * 
 * Note that the OUTPUT.RAW filename must be all caps and contain only the following
 * characters: A-Z, 0-9, comma, period, colon, dash, underscore.  (The SerialFlash
 * library converts filenames to caps, so to avoid confusion we just enforce it here).
 * 
 * It is a little difficult to see what is happening; aswe are using the Serial port
 * to upload files, we can't just throw out debug information.  Instead, we use the LED
 * (pin 13) to convey state.
 * 
 * While the chip is being formatted, the LED (pin 13) will toggle at 1Hz rate.  When 
 * the formatting is done, it flashes quickly (10Hz) for one second, then stays on 
 * solid.  When nothing has been received for 3 seconds, the upload is assumed to be 
 * completed, and the light goes off.
 * 
 * Use the 'rawfile-uploader.py' python script (included in the extras folder) to upload
 * the files.  You can start the script as soon as the Teensy is turned on, and the
 * USB serial upload will just buffer and wait until the flash is formatted.
 * 
 * This code was written by Wyatt Olson <wyatt@digitalcave.ca> (originally as part 
 * of Drum Master http://drummaster.digitalcave.ca and later modified into a 
 * standalone sample).
 
I have actually got it working......and the problem seem to be how the sketch is compiled and uploaded and how long I take to do it..???
The problem I had after Python2.7 and pyserial2.6 was all appeared to work but no files copied.
as described below if the lights are flashing the chip is being erased whether powered the first time or the second time
so if you copy files on you will erase them again compiling the next sketch, because the CopySerial sketch is still in Teensy until the next sketch is uploaded. You need to do it quickly.

While the chip is being formatted, the LED (pin 13) will toggle at 1Hz rate. When
* the formatting is done, it flashes quickly (10Hz) for one second, then stays on
* solid. When nothing has been received for 3 seconds, the upload is assumed to be
* completed, and the light goes off.


If you compile the next sketch with teensy USB unplugged and then plug it in again and immediately press the manual upload button on Teensy the new sketch will be loaded before the Copy fromSerial sketch has time to grt to the bit that starts erase.....and the copied files will still be there.

I normally power teensy with USB at compile time and let teensy automatically upload the next sketch...which in this case was Listfiles. By the time the sketch had compiled and uploaded the lights had started flashing and then went to solid on....and when I looked at the monitor there were no files...because they were deleted in the process.

I have added a 10 sec delay before the erase bit of the sketch to give more time to get things started,......also before as I started the python script maybe when the led were flashing that seemed to give error in the python command screen...not finding things etc......now if start python during the 10 sec...comms is doing nothing and it selects OK everytime. Also the LED is now going out at the end of the process. .....I also put in 2 parenthesis around the statement that adds the lastdatamillis + 3000....I will check these details out again tomorrow and try the larger files and see..... But its working OK now for small files anyway.....
 
Yes, now Copying files from Serial and Playing sound.......But............................................

The 10 second pause after the SerialFlashbegin helps to be more consistant when to start the Python script, at this point the serial flash is detected and teensy is waiting to start erase. I put in quick short LED flashing to indicate we are here.

Also, it depends on your setup......I have teensy plugged in a socket sitting on top of the audio board where the spiflash is so if after copying the files to spiFlash I unplug the USB teensy will power down and if I plug in later, the copyfromserial sketch is still there soas teensy boots up it will erase the files again if I dont get another say, listfiles or player sketch downloaded before the LEDs start flashing.
So after CopyFromSerial is run Do Not unplug USB but in the IDE load your next sketch....Listfiles or some Player etc after upload teensy will reboot and list files or play the files.

Another problem.....I get sound OK....but I thought only haphazzardly depending on something I was doing.?????......but discovered I need to open the monitor terminal and sound starts to play and continues to play even after I close the monitor.......also because of this sound will not play if powered from a USB power pack/bank.... So that is somesthing else to think about....

I can play both RAW and TRW files but only small ones..... only tried 15Kb approx......If I try to load a 700Kb or more file my PC crashes.........

I tried to load several files by just listing them on command line but it didnt like it.......comes up with cant find this and that and division by zeros....??

I think there must be something confilcting interrupts etc on my PC.....but it works otherwise...???
 
Ok, this process seems to be very touchy.

Can you send the soundfile from the SPI Flash to the DAC - A14 (without audioshield) ?
 
Yes, sending sound from the RAW and TRW files that are copied to spiFlash to DAC/A14 on teensy3.2 plugged into audio board just because the flash chip is solderd on it but the audio board is not enable. I have only a 22uf cap to a line jack and line in to PC so can hear it and see it in Audacity. Using the same sketch as I posted earlier, it may have different file names, also using my modified CopyFromSerial with the 10 sec delay added so give me more time to get teensy plugged in and run Python script. But now having fiddled with it......the best way is probably to plug in USB to teensy, upload the CopyFromSerial sketch, Teensy reboots LED start flashing then goes solid on, Do Not unplug USB, open CMD window, type in python script, message in CDM window files name etc and will say files copied and back to dos prompt, LED on Teensy goes off, Do not unplug USB from teensy, Load the player or Listfiles sketch in IDE and upload to teensy, teensy will reboot, open monitor if Listfiles and file should be listed with size, If player sketch was uploaded, teensy will reboot and you should hear sound.....thats the problem now.....I have to open the monitor window and sound starts to play.

The idea of the 10 second delay was also to allow more time, if teensy USB was unplugged after copying and the CopyFromSerial sketch was still in teensy, then when USB is plugged in again the next sketch needs to be loaded before the lights flash OR the copied files will be erased....??
attached below is the code of the 2 sketches....


This is CopyFromSerial.ino
Code:
/*
 * This is free and unencumbered software released into the public domain.
 * ARDUINO / Teensy Modified delays added.....
 * Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled
 * binary, for any purpose, commercial or non-commercial, and by any
 * means.
 * 
 * In jurisdictions that recognize copyright laws, the author or authors
 * of this software dedicate any and all copyright interest in the
 * software to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and
 * successors. We intend this dedication to be an overt act of
 * relinquishment in perpetuity of all present and future rights to this
 * software under copyright law.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * 
 * For more information, please refer to <http://unlicense.org>
 * -------------------------------------------------------------------------
 * 
 * This is example code to 1) format an SPI Flash chip, and 2) copy raw 
 * audio files (mono channel, 16 bit signed, 44100Hz) to it using the 
 * SerialFlash library.  The audio can then be played back using the 
 * AudioPlaySerialflashRaw object in the Teensy Audio library.
 * 
 * To convert a .wav file to the proper .RAW format, use sox:
 * sox input.wav -r 44100 -b 16 --norm -e signed-integer -t raw OUTPUT.RAW remix 1,2
 * 
 * Note that the OUTPUT.RAW filename must be all caps and contain only the following
 * characters: A-Z, 0-9, comma, period, colon, dash, underscore.  (The SerialFlash
 * library converts filenames to caps, so to avoid confusion we just enforce it here).
 * 
 * It is a little difficult to see what is happening; aswe are using the Serial port
 * to upload files, we can't just throw out debug information.  Instead, we use the LED
 * (pin 13) to convey state.
 * 
 * While the chip is being formatted, the LED (pin 13) will toggle at 1Hz rate.  When 
 * the formatting is done, it flashes quickly (10Hz) for one second, then stays on 
 * solid.  When nothing has been received for 3 seconds, the upload is assumed to be 
 * completed, and the light goes off.
 * 
 * Use the 'rawfile-uploader.py' python script (included in the extras folder) to upload
 * the files.  You can start the script as soon as the Teensy is turned on, and the
 * USB serial upload will just buffer and wait until the flash is formatted.
 * 
 * This code was written by Wyatt Olson <wyatt@digitalcave.ca> (originally as part 
 * of Drum Master http://drummaster.digitalcave.ca and later modified into a 
 * standalone sample).
 * 
 * Enjoy!
 * 
 *     // xxxx ... DELAY FOR 10 SECONDS ADDED ........Apr 2018.........
 *     // xxxx ... For more time to start up the Python script... Start command line to run the Python Script during this 10 second period 
 *     // xxxx ... when USB/serial commms is idle and waiting ......  
 *     // xxxx ... Also this delay allows more time for a next sketch to be loaded into Teensy. If this CopyfromSerial sketch is already loaded in Teensy 
 *     // xxxx ... and gets past this stage, while compiling the next sketch, the files just copied will be erased from spiFlash if the flash is still connected.
 *     // xxxx ... If the LEDs start double flashing ...then its too late.....you are about to start erasing the files that are already on the chip....xxxx
 *     // xxxx.... You need to be prepared, compiling and uploading the next new sketch needs to be done quickly or with verify and then manual upload control.
 *     // xxxx ... OR ... Do Not Uplug Teensy USB after coping files, then load the next sketch in IDE and Upload. 
 *     // xxxx ... That way Teensy will not reboot until after the next sketch is uploaded
 * 
 */

#include <SerialFlash.h>
#include <SPI.h>

const int FlashChipSelect = 6; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash
// I coul;dn't get #define CSPIN 6 to work so put in the FlashChipSelect = 6 line .....xxxxxxxxxxxxxxxxxxxx

//Buffer sizes
#define USB_BUFFER_SIZE      128
#define FLASH_BUFFER_SIZE    4096

//Max filename length (8.3 plus a null char terminator)
#define FILENAME_STRING_SIZE      13

//State machine
#define STATE_START      0
#define STATE_SIZE      1
#define STATE_CONTENT    2

//Special bytes in the communication protocol
#define BYTE_START      0x7e
#define BYTE_ESCAPE      0x7d
#define BYTE_SEPARATOR    0x7c


//SPI Pins (these are the values on the Audio board; change them if you have different ones)
//#define MOSI               7
//#define MISO              12
//#define SCK               14
// #define CSPIN              6
//#define CSPIN           21  // Arduino 101 built-in SPI Flash

void setup(){
  Serial.begin(9600);  //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored

  pinMode(13, OUTPUT);    // Teensy LED pin
  
  //Set up SPI
  SPI.setMOSI(7);  // uncomment these if using the alternate pins
  SPI.setMISO(12);  // these are the standard pins for the Teensy 3.2 & Audio Adaptor board conbination
  SPI.setSCK(14);
 

 if (!SerialFlash.begin(FlashChipSelect)) {
    while (1) {
      Serial.println("Unable to a access SPI Flash chip");
      delay(1000);
    }
  }
                  // xxxx .... DELAY FOR 10 SECONDS ADDED .................
                   // xxxx ... For more time to start up the Python script... Start command line to run the Python Script during this 10 second period
                    // xxxx ... when USB/serial commms is idle and waiting .......
  delay(10000);     // xxxx... Also this delay allows more time for a next sketch to be loaded into Teensy. If this CopyfromSerial sketch is already loaded in Teensy 
                   // xxxx... and gets past this stage, while compiling the next sketch, the files just copied will be erased from spiFlash if the flash is still connected.
                  // xxxx ... If the LEDs start double flashing ...then its too late.....you are about to start erasing the files that are already on the chip....xxxx
                 // xxxx.... You need to be prepared, compiling and uploading the next new sketch needs to be done quickly or with manual upload control.

// Double flash LED a few times to warn Erase is about to begin ..........
  for(uint8_t i = 0; i < 5; i++){
    delay(100);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
	delay(100);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(1000);
  }
                 
  //We start by formatting the flash...
  uint8_t id[5];
  SerialFlash.readID(id);
  SerialFlash.eraseAll();
  
  //Flash LED at 1Hz while formatting
  while (!SerialFlash.ready()) {
    delay(500);
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
  }

  //Quickly flash LED a few times when completed, then leave the light on solid
  for(uint8_t i = 0; i < 10; i++){
    delay(100);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
  }
  digitalWrite(13, HIGH);

   
  //We are now going to wait for the upload program
  while(!Serial.available());
  
  SerialFlashFile flashFile;
  
  uint8_t state = STATE_START;
  uint8_t escape = 0;
  uint8_t fileSizeIndex = 0;
  uint32_t fileSize = 0;
  char filename[FILENAME_STRING_SIZE];
  
  char usbBuffer[USB_BUFFER_SIZE];
  uint8_t flashBuffer[FLASH_BUFFER_SIZE];
  
  uint16_t flashBufferIndex = 0;
  uint8_t filenameIndex = 0;
  
  uint32_t lastReceiveTime = millis();
  
    // .... We assume the serial receive part is finished when we have not received something for 3 seconds
    // ..... parenthesis added around this bit on line below........... (lastReceiveTime + 3000) > millis()....reads better...
  
  while(Serial.available() || (lastReceiveTime + 3000) > millis()){
    uint16_t available = Serial.readBytes(usbBuffer, USB_BUFFER_SIZE);
    if (available){
      lastReceiveTime = millis();
    }

    for (uint16_t usbBufferIndex = 0; usbBufferIndex < available; usbBufferIndex++){
      uint8_t b = usbBuffer[usbBufferIndex];
      
      if (state == STATE_START){
        //Start byte.  Repeat start is fine.
        if (b == BYTE_START){
          for (uint8_t i = 0; i < FILENAME_STRING_SIZE; i++){
            filename[i] = 0x00;
          }
          filenameIndex = 0;
        }
        //Valid characters are A-Z, 0-9, comma, period, colon, dash, underscore
        else if ((b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') || b == '.' || b == ',' || b == ':' || b == '-' || b == '_'){
          filename[filenameIndex++] = b;
          if (filenameIndex >= FILENAME_STRING_SIZE){
            //Error name too long
            flushError();
            return;
          }
        }
        //Filename end character
        else if (b == BYTE_SEPARATOR){
          if (filenameIndex == 0){
            //Error empty filename
            flushError();
            return;
          }
          
          //Change state
          state = STATE_SIZE;
          fileSizeIndex = 0;
          fileSize = 0;
          
        }
        //Invalid character
        else {
          //Error bad filename
          flushError();
          return;
        }
      }
      //We read 4 bytes as a uint32_t for file size
      else if (state == STATE_SIZE){
        if (fileSizeIndex < 4){
          fileSize = (fileSize << 8) + b;
          fileSizeIndex++;
        }
        else if (b == BYTE_SEPARATOR){
          state = STATE_CONTENT;
          flashBufferIndex = 0;
          escape = 0;
          
          if (SerialFlash.exists(filename)){
            SerialFlash.remove(filename);  //It doesn't reclaim the space, but it does let you create a new file with the same name.
          }
          
          //Create a new file and open it for writing
          if (SerialFlash.create(filename, fileSize)) {
            flashFile = SerialFlash.open(filename);
            if (!flashFile) {
              //Error flash file open
              flushError();
              return;
            }
          }
          else {
            //Error flash create (no room left?)
            flushError();
            return;
          }
        }
        else {
          //Error invalid length requested
          flushError();
          return;
        }
      }
      else if (state == STATE_CONTENT){
        //Previous byte was escaped; unescape and add to buffer
        if (escape){
          escape = 0;
          flashBuffer[flashBufferIndex++] = b ^ 0x20;
        }
        //Escape the next byte
        else if (b == BYTE_ESCAPE){
          //Serial.println("esc");
          escape = 1;
        }
        //End of file
        else if (b == BYTE_START){
          //Serial.println("End of file");
          state = STATE_START;
          flashFile.write(flashBuffer, flashBufferIndex);
          flashFile.close();
          flashBufferIndex = 0;
        }
        //Normal byte; add to buffer
        else {
          flashBuffer[flashBufferIndex++] = b;
        }
        
        //The buffer is filled; write to SD card
        if (flashBufferIndex >= FLASH_BUFFER_SIZE){
          flashFile.write(flashBuffer, FLASH_BUFFER_SIZE);
          flashBufferIndex = 0;
        }
      }
    }
  }

  //Success!  Turn the light off.
  digitalWrite(13, LOW);
}

void loop(){
  //Do nothing.
}

void flushError(){
  uint32_t lastReceiveTime = millis();
  char usbBuffer[USB_BUFFER_SIZE];
  //We assume the serial receive part is finished when we have not received something for 3 seconds
  // ..... parenthesis added around this bit on line below........... (lastReceiveTime + 3000) > millis()....reads better...
  while(Serial.available() || (lastReceiveTime + 3000) > millis()){
    if (Serial.readBytes(usbBuffer, USB_BUFFER_SIZE)){
      lastReceiveTime = millis();
    }
  }
}


This is the FlashRawPlayer.ino
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#define FLASH_CHIP_SELECT 6
  
// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=228,273
AudioOutputAnalog        dac1;           //xy=751,337
AudioConnection          patchCord1(playFlashRaw1, 0, dac1, 0);
// GUItool: end automatically generated code

void setup() {
    Serial.begin(9600);
    while (!Serial) ;
    AudioMemory(20);
//  analogReference(EXTERNAL);
//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(7); //11
  SPI.setMISO(12);
  SPI.setSCK(14);
//************************************
    delay(2000);
    
    if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1){
            Serial.println ("Cannot access SPI Flash chip");
            delay (1000);
            }
   }
}
void playFile(const char *filename)
{
  SerialFlashFile ff = SerialFlash.open(filename);
  Serial.print("Playing file: ");
  Serial.println(ff);

  uint32_t sz = ff.size();
  uint32_t pos = ff.getFlashAddress();
  Serial.println(sz);
  Serial.println(pos);

  playFlashRaw1.play(filename);
  // Simply wait for the file to finish playing.
  while (playFlashRaw1.isPlaying()) {
   } 
       }    
void loop() {
  //playFile("AR2BR99.TRW");

   //playFile("CHAIN01.RAW");

   playFile("WHISTM1.TRW");
   
   // playFile("WHISTM2.RAW");
delay (1000);
  // playFile("FILESAW1.TRW");

  // playFile("FILETRW.TRW");
}
 
Last edited:
So, I don't understand why my sketch don't work.
Is there a difference between a Teensy without audioshield and a Teensy with a disable audioshield ?

I shall try on your solutions from your last post.
Thanks you.
 
It does not like " while(!Serial);" ......thats the problem of needing to open the monitor to get sound.

I tried various options but in the end just commented it out........it play for me now without opening the monitor.

I noticed ........ analogReference(EXTERNAL)........I changed it to analogReference(INTERNAL).....it will give lower output and less DC.....I assume you will be amplifying anyway......DAC is only rated at 1 mA.

Try thes changes and post how you get on....??


Code:
void setup() {
    Serial.begin(9600);
    delay(500);

  // while(!Serial){

      // wait for serial ready

   // }

    delay(500);
    AudioMemory(50);
  analogReference(INTERNAL);
  
//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(7); //11
  SPI.setMISO(12);
  SPI.setSCK(14);
//************************************
 
Yessssssssss, now, that works (without "while(!Serial)").;)

But why it doesn't work with "while(!Serial)"?:confused:
 
If USB connection not made then "while(!Serial)" will cause it to sit waiting until it is made.

I typically use something like :: while(!Serial && millis()<2000);

That will wait 2 seconds for Serial to connect then continue on through setup(). The time can be adjusted. Historically Teensy setup() was called with millis() at 400 after power up, with release of TD 1.42 that is expected to be set to drop to 350 millis. Depending on the SerialMonitor program used it - and if ready on upload/power up - Serial can generally be online at 400-500 ms.
 
Status
Not open for further replies.
Back
Top