Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 5 of 5

Thread: Problems reading a bluetooth data stream

  1. #1
    Senior Member
    Join Date
    Sep 2019
    Posts
    241

    Problems reading a bluetooth data stream

    Hi all

    I have a simple app written in MIT App inventor 2. It's throwing out a text data stream once a second as a text file arranged as the following:

    Y
    ###
    ###
    ###
    \n

    The Y at the beginning lets me know the set of data that I am receiving (in this case, 3 sets of 3 digits). That appears to work fine.
    I am using the first letter to determine the following data's job.

    The following 9 digits are 3x sets of numerical data. If the Bluetooth module sends a 1 for instance, then it always sends the data as 3 digits (so it sends 001). The variable is always between 0-100.

    Maybe this is an odd way of sending the data, but I thought it would work.

    But, HC-06 is connected to my Teensy 3.2 and I am having difficulty reading this data effectively. Is once a second too often? I would have thought not.

    Excuse the scruffy code, it's prototyping time.

    Now there is a delay(30) in the serial reading loop which I know is a big no-no, but it actually works better like that.
    I will bin all the serial prints, once I know it is working.

    What is a better way to read the incoming BT data? Surely it need to decide that there is data, then loop putting that data into commandbuffer[btcount] until it reaches \n.

    Any assistance gratefully received.

    Code:
    #include <wavTrigger.h>                           //Wav trigger library for SFX and music
    
    wavTrigger wTrig;                                   //Initialise the wav trigger
    
    int led = 13;
    
    //------------------ Variables ----------------------
    
    int  gRateOffset = 0;                              // WAV Trigger sample-rate offset
    int  gNumTracks;                                   // Number of tracks on SD card
    
    char gWTrigVersion[VERSION_STRING_LEN];            // WAV Trigger version string
    
    char commandbuffer[50];
    int Size_of_Assembled_array;                       // The length of the assembled array, including empty spaces
    int btcount;
    
    long actualenginevolume;                           // The volume we are currently using
    long pitch = -32767;                                 // Current pitch of the engine sound effect
    
    byte enginevolumelevel;                            // Incoming data
    byte sfxvolumelevel;
    byte vehiclespeed;
    byte startsound;
    byte startgyro;
    byte stopsound;
    byte stopgyro;
    byte enginesound;
    byte sfx1;
    byte sfx2;
    byte sfx3;
    
    byte oldenginevolumelevel;
    byte oldsfxvolumelevel;
    byte oldvehiclespeed;
    //----------------------------------------------------------------------------------------------------------------------------------------------
    void setup() {
    
      pinMode(led, OUTPUT);
    
      Serial.begin(9600);                              // Debug serial
      Serial2.begin(9600);                             // Serial comms to the BT module
    
      delay(1000);
    
      //-------- Setup the Wav Trigger board -------------
    
      wTrig.start();                          // Setup the wav trigger
      delay(100);
      wTrig.stopAllTracks();                  // Stop all the tracks
      delay(100);
      wTrig.samplerateOffset(0);              // Set the sample rate to 0
      wTrig.setReporting(true);
      delay(100);
    
      wTrig.masterGain(-70);                  // Reset the master volume gain off the WAV trigger (-70 to +4)
    
      delay(500);
    
      if (wTrig.getVersion(gWTrigVersion, VERSION_STRING_LEN)) {
        Serial.print(gWTrigVersion);
        Serial.print("\n");
        gNumTracks = wTrig.getNumTracks();
        Serial.print("Number of WAV tracks = ");
        Serial.print(gNumTracks);
        Serial.print("\n");
      }
      else {
        Serial.print("WAV Trigger response not available");
      }
    
      //---------------- Set up the Bluetooth ----------------
    
      Serial.println("Setting up Bluetooth");
    
      delay(1000);
      Serial2.write("AT+NAMEBornSFX");                                                                                     // Set up the bluetooth
      delay(1000);
      Serial2.write("AT+PIN1234");
      delay(1000);
      Serial2.write("AT+BAUD4");
      Serial.println(F("Bluetooth configuration complete"));
    
      //------------------------------------------------------
    
    
      wTrig.trackPlayPoly(64);                               // Play track 64
      delay(1000);
    
      wTrig.samplerateOffset(-32767);                        // -32767 = one octave down.    +32767 = Up one octave
      wTrig.trackPlayPoly(90);                               // Play track 90
      wTrig.trackLoop(90, 1);                                // Turn looping of the track on
    
      delay(1500);
    
    }
    
    
    //==============================================================================================================================================
    void loop() {
    
      if (Serial2.available()) {                                                                                                 // If there is BT data, go and get it
    
        do {
          commandbuffer[btcount++] = Serial2.read();
          delay(30);
        } while ((Serial2.available()) && (btcount < 50));
        Size_of_Assembled_array = sizeof(commandbuffer);
    
          Serial.print("Incoming data: ");Serial.println(commandbuffer);
    
    
        if (btcount > 0) {                                                                                                      // If something has arrived, then check it
          Serial.println(" ");
          btcount = 0;
    
          if (commandbuffer[0] == 'X') {                                                                                        // Full data received (after leaving settings or at app boot)
            enginevolumelevel = (((commandbuffer[1] - 48) * 100) + ((commandbuffer[2] - 48) * 10) + (commandbuffer[3] - 48));
            Serial.print("Engine Volume: "); Serial.println(enginevolumelevel);
    
            sfxvolumelevel = (((commandbuffer[4] - 48) * 100) + ((commandbuffer[5] - 48) * 10) + (commandbuffer[6] - 48));
            Serial.print("SFX Volume: "); Serial.println(sfxvolumelevel);
    
            vehiclespeed = (((commandbuffer[7] - 48) * 100) + ((commandbuffer[8] - 48) * 10) + (commandbuffer[9] - 48));
            Serial.print("Vehicle speed: "); Serial.println(vehiclespeed);
    
            startsound = (((commandbuffer[10] - 48) * 100) + ((commandbuffer[11] - 48) * 10) + (commandbuffer[12] - 48));
            Serial.print("Start sound: "); Serial.println(startsound);
    
            startgyro = (((commandbuffer[13] - 48) * 100) + ((commandbuffer[14] - 48) * 10) + (commandbuffer[15] - 48));
            Serial.print("Start gyro: "); Serial.println(startgyro);
    
            stopsound = (((commandbuffer[16] - 48) * 100) + ((commandbuffer[17] - 48) * 10) + (commandbuffer[18] - 48));
            Serial.print("Stop sound: "); Serial.println(stopsound);
    
            stopgyro = (((commandbuffer[19] - 48) * 100) + ((commandbuffer[20] - 48) * 10) + (commandbuffer[21] - 48));
            Serial.print("Stop gyro: "); Serial.println(stopgyro);
    
            enginesound = (((commandbuffer[22] - 48) * 100) + ((commandbuffer[23] - 48) * 10) + (commandbuffer[24] - 48));
            Serial.print("Engine sound: "); Serial.println(enginesound);
    
            sfx1 = (((commandbuffer[25] - 48) * 100) + ((commandbuffer[26] - 48) * 10) + (commandbuffer[27] - 48));
            Serial.print("SFX 1: "); Serial.println(sfx1);
    
            sfx2 = (((commandbuffer[28] - 48) * 100) + ((commandbuffer[29] - 48) * 10) + (commandbuffer[30] - 48));
            Serial.print("SFX 2: "); Serial.println(sfx2);
    
            sfx3 = (((commandbuffer[31] - 48) * 100) + ((commandbuffer[32] - 48) * 10) + (commandbuffer[33] - 48));
            Serial.print("SFX 3: "); Serial.println(sfx3);
    
    
          }
    
          else if (commandbuffer[0] == 'Y') {                                                                                         // Partial data received
            enginevolumelevel = (((commandbuffer[1] - 48) * 100) + ((commandbuffer[2] - 48) * 10) + (commandbuffer[3] - 48));
            Serial.print("Engine Volume: "); Serial.println(enginevolumelevel);
    
            sfxvolumelevel = (((commandbuffer[4] - 48) * 100) + ((commandbuffer[5] - 48) * 10) + (commandbuffer[6] - 48));
            Serial.print("SFX Volume: "); Serial.println(sfxvolumelevel);
    
            vehiclespeed = (((commandbuffer[7] - 48) * 100) + ((commandbuffer[8] - 48) * 10) + (commandbuffer[9] - 48));
            Serial.print("vehiclespeed: "); Serial.println(vehiclespeed);
          }
    
          else if (commandbuffer[0] == 'T') {          // SFX 1
            Serial.println("Play SFX 1");
            wTrig.trackPlayPoly(110);
            wTrig.update();
          }
    
          else if (commandbuffer[0] == 'U') {          // SFX 2
            Serial.println("Play SFX 2");
            wTrig.trackPlayPoly(111);
            wTrig.update();
          }
    
          else if (commandbuffer[0] == 'V') {          // SFX 3
            Serial.println("Play SFX 3");
            wTrig.trackPlayPoly(112);
            wTrig.update();
          }
    
    
          wTrig.update();
          memset(commandbuffer, 0, sizeof(commandbuffer));
    
        }
      }
    
    
    
      if (enginevolumelevel != oldenginevolumelevel) {                               // Adjust the engine volume on the fly
        actualenginevolume = map(enginevolumelevel, 0, 100, -70, 10);
        wTrig.masterGain(actualenginevolume);
        wTrig.update();
        oldenginevolumelevel = enginevolumelevel;
      }
    
      if (sfxvolumelevel != oldsfxvolumelevel) {                                     // Adjust the SFX on the fly
        // Change SFX volume here
        oldsfxvolumelevel = sfxvolumelevel;
      }
      
    
      if (vehiclespeed != oldvehiclespeed) {                                         // Adjust the engine sound on the fly                                              // This may need fine tuning
        pitch = map(vehiclespeed, 0, 100, -32767, 32767);
        wTrig.samplerateOffset(pitch);
        wTrig.update();
        oldvehiclespeed = vehiclespeed;
      }
    
    
    }
    //==============================================================================================================================================

  2. #2
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,055
    A couple of questions come up, is the module paired ok? Oops, that's only one.

    If you are having problems communicating, I would set up a terminal program and see what is being sent.

    You could use a PC or write a quick terminal program using the Teensy to echo everything received from the serial port (Serial2) and write it to the screen (Serial).

    That way you will know where the problem lies, in the sending code or your decoding code.

    Have a look at this.

    EDIT:
    After looking at your code I am confused. I believe you are throwing a lot of data away.
    In your data gathering loop you wait for 50 characters, but you don't always use all those 50.
    You seem to use what you require for the command character and throw the rest away.

    You are also ignoring the CR/LF at the end of line.
    Last edited by BriComp; 11-27-2022 at 11:33 AM.

  3. #3
    Senior Member
    Join Date
    Sep 2019
    Posts
    241
    It suddenly started working fine. Bizarrely, if I throw the data at it quicker, it seems to work very well.

    Well, like I said. I know it isn't correct. I know it reads the whole 50 characters (which now could be less). I will adjust so that it looks for the CR/LF at the end (is the the \n?)

  4. #4
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    1,055
    Code:
    #include <wavTrigger.h>                           //Wav trigger library for SFX and music
    
    #define BlueTooth Serial2
    char commandChar;
    
    wavTrigger wTrig;                                   //Initialise the wav trigger
    
    int led = 13;
    
    //------------------ Variables ----------------------
    
    int  gRateOffset = 0;                              // WAV Trigger sample-rate offset
    int  gNumTracks;                                   // Number of tracks on SD card
    
    char gWTrigVersion[VERSION_STRING_LEN];            // WAV Trigger version string
    
    char commandbuffer[50];
    int Size_of_Assembled_array;                       // The length of the assembled array, including empty spaces
    int btcount;
    
    long actualenginevolume;                           // The volume we are currently using
    long pitch = -32767;                                 // Current pitch of the engine sound effect
    
    byte enginevolumelevel;                            // Incoming data
    byte sfxvolumelevel;
    byte vehiclespeed;
    byte startsound;
    byte startgyro;
    byte stopsound;
    byte stopgyro;
    byte enginesound;
    byte sfx1;
    byte sfx2;
    byte sfx3;
    
    byte oldenginevolumelevel;
    byte oldsfxvolumelevel;
    byte oldvehiclespeed;
    //----------------------------------------------------------------------------------------------------------------------------------------------
    void setup() {
    
        pinMode(led, OUTPUT);
    
        Serial.begin(9600);                              // Debug serial
        BlueTooth.begin(9600);                             // Serial comms to the BT module
    
        delay(1000);
    
        //-------- Setup the Wav Trigger board -------------
    
        wTrig.start();                          // Setup the wav trigger
        delay(100);
        wTrig.stopAllTracks();                  // Stop all the tracks
        delay(100);
        wTrig.samplerateOffset(0);              // Set the sample rate to 0
        wTrig.setReporting(true);
        delay(100);
    
        wTrig.masterGain(-70);                  // Reset the master volume gain off the WAV trigger (-70 to +4)
    
        delay(500);
    
        if (wTrig.getVersion(gWTrigVersion, VERSION_STRING_LEN)) {
            Serial.print(gWTrigVersion);
            Serial.print("\n");
            gNumTracks = wTrig.getNumTracks();
            Serial.print("Number of WAV tracks = ");
            Serial.print(gNumTracks);
            Serial.print("\n");
        }
        else {
            Serial.print("WAV Trigger response not available");
        }
    
        //---------------- Set up the Bluetooth ----------------
    
        Serial.println("Setting up Bluetooth");
    
        delay(1000);
        BlueTooth.write("AT+NAMEBornSFX");                                                                                     // Set up the bluetooth
        delay(1000);
        BlueTooth.write("AT+PIN1234");
        delay(1000);
        BlueTooth.write("AT+BAUD4");
        Serial.println(F("Bluetooth configuration complete"));
    
        //------------------------------------------------------
    
    
        wTrig.trackPlayPoly(64);                               // Play track 64
        delay(1000);
    
        wTrig.samplerateOffset(-32767);                        // -32767 = one octave down.    +32767 = Up one octave
        wTrig.trackPlayPoly(90);                               // Play track 90
        wTrig.trackLoop(90, 1);                                // Turn looping of the track on
    
        delay(1500);
    
    }
    #define lineBufferSize 10
    uint8_t lineBufCharCount = 0;
    char    lineBuffer[lineBufferSize];
    
    bool BlueToothReadLine() {
    
        char c;
    
        while (BlueTooth.available() && (lineBufCharCount < lineBufferSize)){
            c = BlueTooth.read();
            if (c != '\r' ) {
                if (c == '\n') {
                    lineBuffer[lineBufCharCount] = 0x0;
                    lineBufCharCount = 0;
                    return true;
                } else {
                    lineBuffer[lineBufCharCount] = c;
                    lineBufCharCount++;
                }
            }
            if (lineBufCharCount > lineBufferSize) {
                lineBufCharCount = 0;
                return false;
            }
        }
        return false;
    }
    uint8_t GetVauleFromLineBuffer() {
        return lineBuffer[0] * 100 + lineBuffer[1] * 10 + lineBuffer[2];
    }
    //==============================================================================================================================================
    void loop() {
    
        if (BlueToothReadLine()) {
    
            Serial.println("Incomming Data");
    
            switch (lineBuffer[0]) {
    
                case 'X':
                    while (!BlueToothReadLine());
                    enginevolumelevel = GetVauleFromLineBuffer(); Serial.print("Engine Volume: "); Serial.println(enginevolumelevel);
                    while (!BlueToothReadLine());
                    sfxvolumelevel = GetVauleFromLineBuffer(); Serial.print("SFX Volume: "); Serial.println(sfxvolumelevel);
                    while (!BlueToothReadLine());
                    vehiclespeed = GetVauleFromLineBuffer(); Serial.print("Vehicle speed: "); Serial.println(vehiclespeed);
                    while (!BlueToothReadLine());
                    startsound = GetVauleFromLineBuffer(); Serial.print("Start sound: "); Serial.println(startsound);
                    while (!BlueToothReadLine());
                    startgyro = GetVauleFromLineBuffer(); Serial.print("Start gyro: "); Serial.println(startgyro);
                    while (!BlueToothReadLine());
                    stopsound = GetVauleFromLineBuffer(); Serial.print("Stop sound: "); Serial.println(stopsound);
                    while (!BlueToothReadLine());
                    stopgyro = GetVauleFromLineBuffer(); Serial.print("Stop gyro: "); Serial.println(stopgyro);
                    while (!BlueToothReadLine());
                    enginesound = GetVauleFromLineBuffer(); Serial.print("Engine sound: "); Serial.println(enginesound);
                    while (!BlueToothReadLine());
                    sfx1 = GetVauleFromLineBuffer(); Serial.print("SFX 1: "); Serial.println(sfx1);
                    while (!BlueToothReadLine());
                    sfx2 = GetVauleFromLineBuffer(); Serial.print("SFX 2: "); Serial.println(sfx2);
                    while (!BlueToothReadLine());
                    sfx3 = GetVauleFromLineBuffer(); Serial.print("SFX 3: "); Serial.println(sfx3);
                case 'Y':
                    while (!BlueToothReadLine());
                    enginevolumelevel = GetVauleFromLineBuffer(); Serial.print("Engine Volume: "); Serial.println(enginevolumelevel);
                    while (!BlueToothReadLine());
                    sfxvolumelevel = GetVauleFromLineBuffer(); Serial.print("SFX Volume: "); Serial.println(sfxvolumelevel);
                    while (!BlueToothReadLine());
                    vehiclespeed = GetVauleFromLineBuffer(); Serial.print("Vehicle speed: "); Serial.println(vehiclespeed);
                case 'T':
                    Serial.println("Play SFX 1");
                    wTrig.trackPlayPoly(110);
                    wTrig.update();
                case 'U':
                    Serial.println("Play SFX 2");
                    wTrig.trackPlayPoly(111);
                    wTrig.update();
                case 'V':
                    Serial.println("Play SFX 3");
                    wTrig.trackPlayPoly(112);
                    wTrig.update();
                default:
                    Serial.print("Unknown Command Line : ");
                    Serial.println(lineBuffer);
            }
    
        }
    
        if (enginevolumelevel != oldenginevolumelevel) {                               // Adjust the engine volume on the fly
            actualenginevolume = map(enginevolumelevel, 0, 100, -70, 10);
            wTrig.masterGain(actualenginevolume);
            wTrig.update();
            oldenginevolumelevel = enginevolumelevel;
        }
    
        if (sfxvolumelevel != oldsfxvolumelevel) {                                     // Adjust the SFX on the fly
            // Change SFX volume here
            oldsfxvolumelevel = sfxvolumelevel;
        }
    
    
        if (vehiclespeed != oldvehiclespeed) {                                         // Adjust the engine sound on the fly                                              // This may need fine tuning
            pitch = map(vehiclespeed, 0, 100, -32767, 32767);
            wTrig.samplerateOffset(pitch);
            wTrig.update();
            oldvehiclespeed = vehiclespeed;
        }
    
    
    }
    //==============================================================================================================================================
    I just did a quick (??!) re-write to handle CR/LF. I can't say that I have tested it as I don't have the hardware, but it does compile ok.
    If it wasn't for the CR, you could just use Serial2.readStringUntil.

  5. #5
    Senior Member
    Join Date
    Sep 2019
    Posts
    241
    Thanks

    I will try that later this evening, once I have tracked down a very elusive ground hum on my Wav Trigger board

Posting Permissions

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