Forum Rule: Always post complete source code & details to reproduce any issue!
Page 5 of 6 FirstFirst ... 3 4 5 6 LastLast
Results 101 to 125 of 128

Thread: Sound for model railroading scale 1/32

  1. #101
    In order to know when starting Python script (and when it's too late), I propose to put the LED solid during this time.
    Code:
      ...............
     digitalWrite(13, HIGH);// Start Python script "Rawfile-uploader.py"
                      // 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.
      digitalWrite(13, LOW);// Too late to start Python "Rawfile-uploader.py"
      delay(1000);
    .............

  2. #102
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Yes, the CopyFomSerial you posted seems to be the same..... but I cannot get it to work with the #define CSPIN etc. The other programs for SerialFlash use.......
    const int FlashChipSelect = 6; // digital pin for flash chip CS pin ..... so thats what I did no the sketch I modified and posted earlier......the one I put the 10 sec delay in.
    The only other change I make is the pin numbers.....

    I see you have posted again regards keeping the LED on solid warning........that fair enough, go with that........but the real problem is that the sketch runs automatically as soon as plugged in and if not aware of the erase....your files will be erased fully, OR maybe if unplugged as a panic abort if you see the LED on.....I wonder could the files be corrupt and still list the names but not play.....????

    I had thought of adding a something like say.............
    char CopyRun = Serial.read();
    while(CopyRun <> 'c');
    So that Copy prog will not run until you open the monitor and type in a 'c' and send it.

    But I never got around to it.......

    ...............the CopyFromSerial, List files, ReadBenchmark,and PlayRawFlash work for me OKplaying out DAC, with python to send the actual files to spiflash and Audacity or SOX to convert them. The only problem I have is I cannot send large files with python on my XP machine.

  3. #103
    Have you a mean to read the data (byte) which are in the SPI Flash ?
    Thanks.

  4. #104
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Have you a mean to read the data (byte) which are in the SPI Flash ?......no not directly....except what can be de-ciphered from the examples.
    The data sheet will give op-codes for each operation......eg reading and writing bytes/ blocks from/to different addresses etc...???

    I thought from earlier post you had it working....what has changed....????
    I would copy the files again on to spiflash..or copy different ones....and play some sound from memory you know is working to make sure DAC itself is still OK

    I have attached a zip file containing a serial monitor controlled CopyFromSerial....you have to open Monitor and key in a "c" to start, guidence comes up on monitor, then run python script to copy files.....I had to put a serial.write("c") in the script so that it could start the teensy script
    Attached Files Attached Files

  5. #105
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    The last post maybe indicates you need to open the monitor in all cases......but only if you want to see the sketch running from the Arduino IDE as test etc.
    Normally if your Teensy has some sketch on it and you wanted to load CopyFromSerialMC to copy files to spiFlash........what you would do is open IDE upload the copy sketch to Teensy get the upload Boot OK message and Teensy would reboot but sit waiting on a "c" being typed.....there is no need to type "c" here......just let it wait and open python CMDline and run the rawfile-uploader-mc script.....It will send a "c" to start the teensy sketch copy the files to spiFlash. Then load Listfiles sketch or Player sketch as normal because when teensy is powered again with the CopyFromSerialMC sketch it will sit waiting for "c" and not erase the files when the delays time out as before.

  6. #106
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Regards a means to read Byte by Byte Data from the chip to see whatdata is there in byte format.....below is "a first cog" of the Reader part if the "RawHardwareTest" example in the SerialFlash library.......There are a few options for the print out to the monitor screen......

    Code:
    // RawHardwareTest - Check if a SPI Flash chip is compatible
    // with SerialFlash by performing many read and write tests
    // to its memory.
    //
    //  *** THIS IS RUNNING THE READER PART ONLY TO SEE DATA ON THE CHIP  ***
    //   ***  OUTPUT LOOKS SIMILAR TO READING A FILE IN A HEX EDITOR    ***
    //    ***    OUTPUT IS PRINTED READABLE TEXT TO MONITOR SCREEN    ***
    //     ***      IT IS IN HEX TEXT FORMAT NOT A BINARY FILE      ***
    //
    // The chip should be fully erased before running this test.
    // Use the EraseEverything to do a (slow) full chip erase.
    //
    // Normally you should NOT access the flash memory directly,
    // as this test program does.  You should create files and
    // read and write the files.  File creation allocates space
    // with program & erase boundaries within the chip, to allow
    // reading from any other files while a file is busy writing
    // or erasing (if created as erasable).
    //
    // If you discover an incompatible chip, please report it here:
    // https://github.com/PaulStoffregen/SerialFlash/issues
    // You MUST post the complete output of this program, and
    // the exact part number and manufacturer of the chip.
    
    
    #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
    
    SerialFlashFile file;
    
    const unsigned long testIncrement = 4096;
    
    void setup() {
    
      //uncomment these if using Teensy audio shield
      SPI.setSCK(14);  // Audio shield has SCK on pin 14
      SPI.setMOSI(7);  // Audio shield has MOSI on pin 7
    
      //uncomment these if you have other SPI chips connected
      //to keep them disabled while using only SerialFlash
      //pinMode(4, INPUT_PULLUP);
      //pinMode(10, INPUT_PULLUP);
    
      Serial.begin(9600);
    
      while (!Serial) ;
      delay(100);
    
      Serial.println("Raw SerialFlash Hardware Test");
      SerialFlash.begin(FlashChipSelect); // proceed even if begin() fails
    
      if (test()) {
        Serial.println();
        Serial.println("All Tests Passed  :-)");
        Serial.println("This message only applies for full test not when running Reader only");
        Serial.println("Test data was written to your chip.  You must run");
        Serial.println("EraseEverything before using this chip for files.");
      } else {
        Serial.println();
        Serial.println("Tests Failed  :{");
        Serial.println("This message only applies for full test not when running Reader only");
        Serial.println("The flash chip may be left in an improper state.");
        Serial.println("You might need to power cycle to return to normal.");
      }
    }
    
    
    bool test() {
      unsigned char buf[256], sig[256], buf2[8];
      unsigned long address, count, chipsize, blocksize;
      unsigned long usec;
      bool first;
    
      // Read the chip identification
      Serial.println();
      Serial.println("Read Chip Identification:");
      SerialFlash.readID(buf);
      Serial.print("  JEDEC ID:     ");
      Serial.print(buf[0], HEX);
      Serial.print(" ");
      Serial.print(buf[1], HEX);
      Serial.print(" ");
      Serial.println(buf[2], HEX);
      Serial.print("  Part Nummber: ");
      Serial.println(id2chip(buf));
      Serial.print("  Memory Size:  ");
      chipsize = SerialFlash.capacity(buf);
      Serial.print(chipsize);
      Serial.println(" bytes");
      if (chipsize == 0) return false;
      Serial.print("  Block Size:   ");
      blocksize = SerialFlash.blockSize();
      Serial.print(blocksize);
      Serial.println(" bytes");
    
    
      // Read the entire chip.  Every test location must be
      // erased, or have a previously tested signature
      Serial.println();
      Serial.println("Reading Chip...");
      memset(buf, 0, sizeof(buf));
      memset(sig, 0, sizeof(sig));
      memset(buf2, 0, sizeof(buf2));
      address = 0;
      count = 0;
      first = true;
      while (address < chipsize) {
        SerialFlash.read(address, buf, 8);
        //Serial.print("  addr = ");
        Serial.print(address, HEX);
       // Serial.print(", data = ");
        printbuf(buf, 8);
        
       
        if (first) {
          address = address + (testIncrement - 8);
          first = false;
        } else {
          address = address + 8;
          first = true;
        }
    
      }
    
    }
    
    
    void loop() {
      // do nothing after the test
    }
    
    const char * id2chip(const unsigned char *id)
    {
    	if (id[0] == 0xEF) {
    		// Winbond
    		if (id[1] == 0x40) {
    			if (id[2] == 0x14) return "W25Q80BV";
    			if (id[2] == 0x15) return "W25Q16DV";
    			if (id[2] == 0x17) return "W25Q64FV";
    			if (id[2] == 0x18) return "W25Q128FV";
    			if (id[2] == 0x19) return "W25Q256FV";
    		}
    	}
    	if (id[0] == 0x01) {
    		// Spansion
    		if (id[1] == 0x02) {
    			if (id[2] == 0x16) return "S25FL064A";
    			if (id[2] == 0x19) return "S25FL256S";
    			if (id[2] == 0x20) return "S25FL512S";
    		}
    		if (id[1] == 0x20) {
    			if (id[2] == 0x18) return "S25FL127S";
    		}
    	}
    	if (id[0] == 0xC2) {
    		// Macronix
    		if (id[1] == 0x20) {
    			if (id[2] == 0x18) return "MX25L12805D";
    		}
    	}
    	if (id[0] == 0x20) {
    		// Micron
    		if (id[1] == 0xBA) {
    			if (id[2] == 0x20) return "N25Q512A";
    			if (id[2] == 0x21) return "N25Q00AA";
    		}
    		if (id[1] == 0xBB) {
    			if (id[2] == 0x22) return "MT25QL02GC";
    		}
    	}
    	if (id[0] == 0xBF) {
    		// SST
    		if (id[1] == 0x25) {
    			if (id[2] == 0x02) return "SST25WF010";
    			if (id[2] == 0x03) return "SST25WF020";
    			if (id[2] == 0x04) return "SST25WF040";
    			if (id[2] == 0x41) return "SST25VF016B";
    			if (id[2] == 0x4A) return "SST25VF032";
    		}
    		if (id[1] == 0x25) {
    			if (id[2] == 0x01) return "SST26VF016";
    			if (id[2] == 0x02) return "SST26VF032";
    			if (id[2] == 0x43) return "SST26VF064";
    		}
    	}
    	return "(unknown chip)";
    }
    
    void printbuf(const void *buf, uint32_t len)
    {
      const uint8_t *p = (const uint8_t *)buf;
      do {
        unsigned char b = *p++;
        Serial.print(b >> 4, HEX);
        Serial.print(b & 15, HEX);
        //Serial.printf("%02X", *p++);
        Serial.print(" ");
      } while (--len > 0);
      Serial.println();
    }

  7. #107
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    In last post....change the order of printbuf........

    Put the line...... Serial.print(" "); ....as the first line......it makes more sense I think......gives a space between the offset and the actual data..........I couldn't find a smiley that smiles......?

  8. #108
    I tried on with CopyFromSerialMC and rawfile-uploader-mc.py.
    It works very well with "WHISTM1.TRW".
    Now, I will try to manage and to mix some soundfiles.
    Thank you very much.

  9. #109
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    This post is about making sense of the data copied into the chip rather than reading HEX numbers.......

    I have 2 short sound files on the chip...... a whistle of about 0.5 seconds and an engine sound 4 puffs lasting about 1.5 seconds.....using the player I play the engine sound looped so it plays repeatedly and blow the whistle on the push of a button on demand.

    To see the actual files on the chip, I run the RawHardwareReader and printed the data from the first 150000 adresses to the monitor screen, then selected and copied the data only and pasted into HxD hex editor and saved it as chipsnd1.raw......then imported this raw file into Audacity....16bit, Little Endian, 44100 ....and I cold see the waveform....it looks like the waveform of the orig 2 sound files that were copied.....then played the file in Audacity.....good quality of sound.
    So the sound files are being copied and extracted to/from the chip without any distortion. You will see/hear 2 glitches near the start of the file.....this is the 2 file names and what ever other format info is saved when the files are being copied.....you can read the names in the binary chipsnd1.raw file.
    Attached is Zip of the data extracted from the chip.........
    Attached Files Attached Files

  10. #110
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Hi Benoit92, I see you posted that the CopyFromSerialMC works.......So is your DAC sound out working again.....????
    My last post will let you see the raw data bytes that are copied to the chip as you mentioned earlier...

  11. #111
    I think that the soundfiles was not correctly loaded in Flash memory.
    But now, with your code modification, the sounfile is well loaded and the DAC works correctly?

    I tried to upload to SPI Flash :
    15 Ko ----------> Ok
    250 Ko --------> Ok
    1 Mo -----------> Ok
    2 Mo -----------> Ok
    4 Mo -----------> Ok

    5 Mo ----------------> Not Ok
    Windows Command :
    C:\Python27>python -c "import serial, sys; print(sys.platform, serial.VERSION)"
    ('win32', '3.4')

    C:\Python27>python -m serial.tools.list_ports
    COM4
    1 ports found

    C:\Python27>Python "rawfile-uploader-mc.py" "COM4" "A6BR99.TRW"
    Uploading 1 files...
    1: A6BR99.TRWTraceback (most recent call last):
    File "rawfile-uploader-mc.py", line 81, in <module>
    ser.write("".join(encoded))
    File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 323, in write
    raise writeTimeoutError
    serial.serialutil.SerialTimeoutException: Write timeout

  12. #112
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Thats good all is working...........I dont know python except readit and guess.....
    I have got errors like this before....basically I think it has timed out due to maybe connection interrupted or corruption.....did the lights flash and then go out or stay on.
    It looks like it has seen the COM4 port and found the file and is actually writing or attempting to write and something is delaying either data in from Serial or data going to spiflash.
    python displays on screen the message "uploading 1 files" and the filename before data has started....so if teensy didnt get the "c" the sketch would not start but COMMS would be made but teensy would not send data........You would know this if the LEDs did not flash...and then when data is complete LED goes out......Did you try it several times or with another copy of the file.
    I see you are able to send quite large files.......good....

  13. #113
    1) I tried to load some soundfiles together : 3758 Ko + 2441 Ko + 248 Ko ---> It works
    But when I want to load just a soundfile over 4000 Ko ---> It doesn't work ?

    2) When I try to load only a soundfile over 4000 Ko, the time-out message appears at the beginning (after unplug-plug-rawfileup-loader.py) when Led 13 goes like this :
    Code:
    // Double flash LED a few times to warn Erase is about to begin ..........
      for(uint8_t i = 0; i < 3; i++){
        delay(100);
        digitalWrite(13, HIGH);
        delay(100);
        digitalWrite(13, LOW);
      	delay(100);
        digitalWrite(13, HIGH);
        delay(100);
        digitalWrite(13, LOW);
        delay(1000);
      }

  14. #114
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Benoit92 wrote...............
    2) When I try to load only a soundfile over 4000 Ko, the time-out message appears at the beginning (after unplug-plug-rawfileup-loader.py) when Led 13 goes like this
    .................................................. .................
    Are you using my -mc version.......you dont need to unplug it.............Load the CopyFromSerialMC into Teensy...watch that you get RebootOK or what ever it says for successful upload.....Teensy will the be re-booted and will sit waiting on a " c " being keyed in.....but dont do it.......open python CMDline and run the rawfile-uploader-mc.py......it will send a " c " and start the teensy sketch, find the files and transfer them........ I can do several at one time OK......my problem is I cannot do large ones 500k etc my WinXP PC crashes and restarts.....small files OK.......large files work OK when I use a new windows10 laptop.

    I think the crash is caused by python talking to the serial port........I tried a mod to the python script...opened a file (g = open('sndbib.raw', 'wb') for writing the data to a file on PC instead of Serial out and sent the Large file 1.5MB to it.....it created the file and didnt crash PC.......dont know what to check why writing to serial crashes PD...???

    Just thinking about you timeout problem....If its timing out when the double flash ....that is before erase so mustnt be due to a long erase time if say alot of files were on chip.....I think it erases the whole chip each time anyway.......
    Last edited by Teenfor3; 04-24-2018 at 11:15 PM.

  15. #115
    I use a windows10 + laptop (ASUS 550).
    I followed your procedure and your codes (CopyFromSerialMC and rawfile-uploader-mc.py).
    It works well except for files over 4000 Ko (???) (about 45 seconds sound).
    I think I can do it with this limitation for my application.

    C:\Python27>python -c "import serial, sys; print(sys.platform, serial.VERSION)"
    ('win32', '3.4')

    C:\Python27>python -m serial.tools.list_ports
    COM4
    1 ports found

    C:\Python27>Python "rawfile-uploader-mc.py" "COM4" "A3BR99.TRW" "A4BR99.TRW" "A5BR99.TRW" "A9BR99.TRW" "A1BR99.TRW" "A6BR99.TRW"
    Uploading 6 files...
    1: A3BR99.TRW (13.42 KB/s) ----> 248 Ko
    2: A4BR99.TRW (198.41 KB/s)------>2441 Ko
    3: A5BR99.TRW (198.38 KB/s) ------> 3758 Ko
    4: A9BR99.TRW (649.18 KB/s) -------> 3937 Ko
    5: A1BR99.TRWTraceback (most recent call last): -------> 4135 Ko
    File "rawfile-uploader-mc.py", line 81, in <module>
    ser.write("".join(encoded))
    File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 323, in write
    raise writeTimeoutError
    serial.serialutil.SerialTimeoutException: Write timeout


    --> Led13 stays solid.
    Last soundfile "A6BR99.TRW" (5288 Ko) is lost.

    Is it a probem linked with Windows configuration (USB serial port driver)?

  16. #116
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    I didnt get time out errors but maybe not doing as long a list or not as large files so it probably is a genuine time out due to the size of transfer.
    I dont understand the size you list the files....is 3937Ko equal to 3937 Kbytes equal to 3.937 Mbytes.........I thought from previous posts you were using the W25Q64 flash
    Is that not 64 Mbit equal to 8 Mbytes

    There is an option ser.timeout() in setup for serial port in python.....I am not familiar with python so actually never used it......its in the pyserial docs.

    I have now surfaced another problem......I have 4 files on Flash about 100 Kbytes each that all play no problem but now I cannot get the EraseEverything sketch OR EraseAll in CopyFromSerial to erase them and so CopyFromSerial wont copy on any more files. Neither will CopyFromSD, It finds the files already there and only copies to blank Flash.
    All had been working but just stopped.....but still plays the files that are on........

    The RawHardwareTest sketch now gives me this..............
    JEDEC ID: EF 40 17
    Part Nummber: W25Q64FV
    Memory Size: 8388608 bytes
    Block Size: 65536 bytes

    Reading Chip...
    Previous data found at address 0
    You must fully erase the chip before this test
    found this: 4C 55 96 FA 58 02 F6 18
    correct: 00 00 00 00 15 F5 95 4B
    And tells me all tests failed......Yet all was working yesterday.......... Except maybe this is another XP only problem.......I will have to check out..???....any ideas...???

  17. #117
    I apologize because :
    Ko = Kilo octets = Kilo bytes
    So, W25Q64 = 64 Kilobits = 8 Kilobytes

    I try :
    Code:
    ser = serial.Serial(sys.argv[1], 9600, timeout=0, writeTimeout=None)
    But no effect !
    This breaks the thermometer but not the fever !

    any ideas...???
    Check the wires and connections and Write protect pin : https://www.pjrc.com/store/w25q64fv.pdf
    The Write Protect (/WP) pin can be used to prevent the Status Registersfrom being written.

    There are also some bits (status register) in W25Q64FV which deals with "write protection".

    3.12
    Write Protect (/WP)

    Used in conjunction with the Status Registerís Block Protect (CMP, SEC, TB,BP2, BP1 and BP0) bits and
    Status Register Protect (SRP) bits, a portion as small as a
    4KB sector or the entire memory array can be hardware protected.
    The /WP pin is active low. However, when the QE bit of Status Register-2 is set for Quad I/O, the /WP
    pin function is not available since this pin is used for IO2.
    See figure 1a, 1b and 1c for the pin configuration of Quad I/O operation.

    Try to erase :
    1) with setting /WP low
    2) then with /WP high
    in order to defreeze the write protection !!!
    -

    Try with another PC

  18. #118
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Thanks for reply.... I am still confused about the size of your files..... one of your files listed as 3937 Ko equals 3937 Kbytes equals 3.937 Mbytes ....... so adding up all your files transferred .....comes to over 14 MBytes........have you that much memory...?????.....maybe running out of memory...??
    Are these long files playing continuously......maybe better of SD card....??

    I dont know python well enough...but it looks a python error either due to setting or slow data

    Are you making the changes to the ser line in the script.......I found this in the pyserial docs..

    Possible values for the parameter timeout which controls the behavior of read():
    •timeout = None: wait forever / until requested number of bytes are received
    •timeout = 0: non-blocking mode, return immediately in any case, returning zero or more, up to
    the requested number of bytes
    •timeout = x: set timeout to x seconds (float allowed) returns immediately when the requested
    number of bytes are available, otherwise wait until the timeout expires and return all bytes that were
    received until then.
    write() is blocking by default, unless write_timeout is set. For possible values refer to the list for
    timeout above.

    There is also a 3 second time out if no data detected in the teensy sketch......maybe if that was lengthened...say 6 seconds and see what happens.

    Regards my copy and erase problem I put Arduino 185 and teensy 141 on the win10 laptop....no difference...still won't erase...No errors listed but says the usual "erase is Slow" but then says it does it in 0 , 1, or 2 seconds......but not actually done at all.

    Thanks for the info on the chip, I had the datasheet.....but would now need to read it........????
    Last edited by Teenfor3; 04-26-2018 at 12:22 AM. Reason: added a bit about Teensy timeout in sketch

  19. #119
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    I had previous problems with copyfromserial as per earlier posts and also copy large files on windows setup crashed my "old" XP PC.
    So I setup an old laptop with Ubuntu 16.04 with Arduino 1.8.5 and Teensy 1.4.1 and all runs well very fast.
    But a perculiar problem The CopyfromSerial that runs OK on windows PC with small files wouldnt copy at all on Linux setup, yet all compiled and ran no errors LEDs flashed but didn't go off at the end.
    It turned out The serial.read waiting for a "c" to be sent was being detected from the serial.println on the line before it and that was upsetting things......but did not cause a problem on windows......

    So maybe my statement for serial.read is wrong....?????...... but I took out all the serial.println statements and all works OK. I can now copy large files 2 MB plus on the Ubuntu laptop...no problem. Don't need to use monitor, just plug in teensy, upload copyfromserial sketch, then run python, then upload listfiles sketch to see files are there...no plugging and unplugging.

    Code:
    /*
     * This is free and unencumbered software released into the public domain.
     * 
     * ARDUINO / Teensy Modified CopyFromSerial direct using Python Script.....Apr2018....
     * ..
     * 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 ... MONITOR CONTROL ADDED ........Apr 2018.........
     * 
     */
    
    #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 couldn't get #define CSPIN 6 to work so put in ... FlashChipSelect = 6  .....xxxxxxxxxxxxxx
    
    //Buffer sizes
    #define USB_BUFFER_SIZE      128   // was 128
    #define FLASH_BUFFER_SIZE    4096  //was 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(){
      
       pinMode(13, OUTPUT);    // Teensy LED pin
       
      Serial.begin(9600);  //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored
          
       delay(1000);
       
      while(Serial.read() != 'c');  //wait on Python sending a c
    
      //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);
        }
      }
     
    // Double flash LED a few times to warn Erase is about to begin ..........
      for(uint8_t i = 0; i < 3; 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 1 second
      for(uint8_t i = 0; i < 10; i++){
        delay(100);
        digitalWrite(13, HIGH);
        delay(100);
        digitalWrite(13, LOW);
      }
      digitalWrite(13, HIGH);
      
      delay(1000);
     
      //We are now going to wait for the upload program
      while(!Serial.available());
      
      SerialFlashFile flashFile;
      //  Do some Flashing + 1 second off to indicate Copy is Starting
        delay(100);
        digitalWrite(13, LOW);
        delay(100);
        digitalWrite(13, HIGH);
        delay(100);
        digitalWrite(13, LOW);
        delay(100);
        digitalWrite(13, HIGH);
        delay(100);
        digitalWrite(13, LOW);
        delay(1000);
        digitalWrite(13, HIGH);
      
      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();
        }
      }
    }

  20. #120
    In short :
    You cancelled the "println" and "Serial.read" in order to avoid percussion between flux coming from Python script and flux coming from serial monitor.

    I tried to load 4,9 Mo, but it crashes.
    It's not really very important because, I can do with several soundfiles under 4 Mo.
    Perhaps a Windows limitation??!!

  21. #121
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    "It turned out The serial.read waiting for a "c" to be sent was being detected from the serial.println on the line before it and that was upsetting things......but did not cause a problem on windows......"

    What I meant was....The serial.Println( Enter a " c " to start Copy") ......has a " c " in it.......and this was being detected some how by the if (serial.read() != 'c') .......

    If I take the " c " out of the println sentence then all works OK...... OR if I change the serial.read to wait for " z " with a "c " in the println sentence all is OK...also change the python to send " z ".

    Even in the Arduino IDE opening the monitor when the " c " was in the Println started the sketch without entering a " c ".

    So I think the statement for getting serial.read() to detect a " c " or indeed any character is probably wrong....???.....but works in windows and not in Linux..?????
    I use the same python script statement to ser.write('c') in both windows and Linux...??

    Yes, the size of the files copied seems to be a different problem.......small files only work in windows....any size file works in Linux......??????....perculiar...??

  22. #122
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    I thought I would investigate your idea about "avoid percussion"....and I think that is actually the problem...
    I commented out the printlm("Enter a c to start Copy") and left in the other print lines and copy was not reliable......would copy on the windows machine OK, but not on Linux. On Linux it ran CopyFromSerial and the Python script ran OK but LED did not go out and files were not copied.
    Then commented out all the print lines, except the orig error prints which only print on error, and all works OK reliably. small files on windows and any size on Linux...

    On the Linux I copied, a 6MByte + a 700KByte + 2 of 100KByte each, to the spiflash in one batch and all copied OK and all played OK on both Linux and windows.
    I

  23. #123
    Hi, my "simply" code goes well.
    Now, I would like to mix two sounds together.
    Here is my "simply"code but without using "mixer".

    Code:
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
        //'*' Type on Serial Monitor
        //A0A8B14.TRW = 'a' Engine start - Pantograph up
        //A1AB814.TRW = 'z' Compressor + Air release
        //A2AB814.TRW = 'e' Horn
        //A3AB814.TRW = 'r' Start driving
        //A4AB814.TRW = 't' Driving
        //A5AB814.TRW = 'y' Brake
        //A6AB814.TRW = 'u' Compressor - Air release + Engine start
        //A7AB814.TRW = 'i' Uncoupling
        //A8AB814.TRW = 'o' Stop driving
        //A9AB814.TRW = 'p' Stand-by engine
    
    const int FLASH_CHIP_SELECT = 10;  
    #include <Audio.h>
    #include <Wire.h>
    #include <SPI.h>
    #include <SD.h>
    #include <SerialFlash.h>
    
    // 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
    
    int Data;     // Read serial data
    int PrevData;  // Read previous serial data
    
    void setup() {
        Serial.begin(9600); // Serial setup
        while (!Serial && millis()<500 );
        AudioMemory(50);//
        analogReference(EXTERNAL);// 3,3V Amplitude DAC
    
    //************************************
    //  Set up SPI Teensy without audio Card
      SPI.setMOSI(11); //7
      SPI.setMISO(12);
      SPI.setSCK(14);
    //************************************
        delay(2000);
        if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
            while (1){
                Serial.println ("Cannot access SPI Flash chip");
                delay (10000);
            }
        }
    }
        void playFile1(const char *filename)// Play audio file function
        {
          SerialFlashFile ff = SerialFlash.open(filename);
          Serial.print("Playing file1: ");
          Serial.println(ff);
          playFlashRaw1.play(filename);
         // Simply wait for the file to finish playing.
         while (playFlashRaw1.isPlaying()) {
         } 
        }
        
    void loop() {
    if ( Serial.available() ) {
        Data = Serial.read();
        Serial.println(Data);
      } 
      else {
        Serial.println("Nothing");
      }
    
    switch (Data) {
       case 'a':{  // Play Soundfile in loop 
         PrevData = 'a';    
         playFile1("A0AB814.TRW");
         break;
       }
       case 'z':{  // Play Soundfile in loop   
          PrevData = 'z';
          playFile1("A1AB814.TRW");
          break;
       }    
               case 'e':{   // Play Soundfile only once   
               playFile1("A2AB814.TRW");
               Data=PrevData; // Continue with previous soundfile 
               Serial.println(Data);
               break;
               } 
        case 't':{  // Play Soundfile in loop   
         PrevData = 't'; 
         playFile1("A4A814.TRW");
         break;
        }    
        case 'y':{  // Play Soundfile in loop   
         PrevData = 'y'; 
         playFile1("A5AB814.TRW");
          break;
        }    
        case 'u':{  // Play Soundfile in loop   
          PrevData = 'u';  
          playFile1("A6AB814.TRW");
         break; 
        }        
        case 'i':{  // Play Soundfile in loop    
          PrevData = 'i'; 
          playFile1("A7AB814.TRW");
          break;
        }    
        case 'o':{  // Play Soundfile in loop   
          PrevData = 'o';  
          playFile1("A8AB814.TRW");
          break;
        }  
        case 'p':{  // Play Soundfile in loop   
          PrevData = 'p';  
          playFile1("A9A814.TRW");
          break;
       }      
      }
    }

  24. #124
    Senior Member
    Join Date
    Apr 2014
    Posts
    327
    Depends on what sounds you want to mix...do you want to select 2 from the "case" list or is it a new sound played along with 1 of the select/case sounds
    In any case you need another playflash object if the new sound is on flash......connect both to mixer1 and output to dac1
    Depending on the logic of how you want them to play, copy the the playfile1 and call it playfile2 and change it to play the new object and call it as required.

    Code:
    AudioPlaySerialflashRaw  playFlashRaw1;  
    AudioPlaySerialflashRaw  playFlashRaw2; 
    AudioMixer4   mixer1;
    AudioOutputAnalog        dac1;           
    AudioConnection          patchCord1(playFlashRaw1, 0, mixer1, 0);
    AudioConnection          patchCord2(playFlashRaw2, 0, mixer1, 1);
    AudioConnection          patchCord3(mixer1, dac1);

  25. #125
    Ok, Thanks.
    I will define 2 functions : PlayFile1 and PlayFile2.
    And I will use for instance this type of mechanism :

    Setup
    mixer1 (0, 0.5)
    mixer1 (1, 0.5)
    void PlayFile1()
    void PlayFile2()
    Loop
    1) Readserial
    2) Switch ... Case 'a', 'z' ',e'
    3) PlayFile1

    4) Switch ... Case 'r', 't', 'y'
    5) PlayFile2

    So, I can play 'a' with 'r' together ?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •