Bluetooth Serial between Teensy 4.1 and 3.6

Status
Not open for further replies.

gman3000

New member
Hi there. I am trying to communicate between a Teensy 4.1 and a Teensy 3.6 using Bluetooth serial devices. The Teensy 4.1 is attached to a BlueSmirf Silver and the Teensy 3.6 is a attached to a HC-05 BT serial device.

I have set up my code where the 4.1 sends a query via BT serial and then receives a string reply. I did it this way because in later projects I want the 4.1 to query when new info from the 3.6 is necessary. Currently the code is set up using elapsedMillis to query at 50 Hz. The problem is that the code works great at <2 Hz, but in higher values the message becomes chopped or erratic. The worst part is that the code works great when the UART is a hardwired connection between both devices and doesn't use the bluetooth serial devices.

I can reproduce the same issue using a BT terminal on a cellphone and quickly querying the Teensy 3.6. I'm thinking this is something simple I'm missing about buffers and the BT and I'd appreciate any advice. I'm not using CTS/RTS pins but that is an option with the bluetooth devices. The string buffer is set at 64 bytes on either end currently to facilitate longer strings in the future.

Here is a snippet of what incorrect output looks like:
Hold On To you Buttttssssssssssssss!!!!!
Hold On To you Buttttssssssssssssss!!!!!
Hold On To you Buttttssssssssssssss!!!!!
Hold On To you Buttttssssssssssssss!!!!!
Hold On To you Buttttssssssssssssss!!!!!
Hold On To you Buttttssssssssssssss!!!!!
Hold On To you ButtttsssssssssHold On To you B
Hold On To you Buttttssssssssssssss!!!!!

Here is the 4.1 code:
Code:
/*
Frame Module Code
Hardware consists of a Teensy 4.1 connected to a BlueSmirf silver
The code sends a query at a set sampling rate and receives data back
*/
#define HWSERIAL Serial1          //serial port for bluetooth module

const byte numChars = 64;         //incoming buffer size
char receivedChars[numChars];     //incoming buffer
boolean newData = false; //flag to determine when all queries have been received and put into one string
elapsedMillis newTimer;   //Time that sets the sampling rate 

int startMicros = 0;
int endMicros = 0;

void setup()
{
  Serial.begin(230400);  // Begin the serial monitor at 230400
  delay(100);


  HWSERIAL.begin(230400);  // The Bluetooth Mate definitions for connection
  delay(250);
  HWSERIAL.print("$$$");  // Print three times individually
  delay(250);  // Short delay, wait for the Mate to send back CMD
  HWSERIAL.println("C,98d351fdadf5");  //address and connect
  delay(100);
  HWSERIAL.println("---");                  //close command mode
  delay(100);

  delay(5000);
  Serial.println("Setup Complete");
}

void loop() {
  if (newTimer >= 20) {                   //using elapsedMillis to set a 50 Hz sampling rate
    HWSERIAL.print('?');                  //send query to wheel module
    recvWithStartEndMarkers();            //receive data back
    showNewData();                        //print new data monitor
    newTimer = 0;                         //reset timer
  }
}

/*
 * Function that finds the start and end characters of the received UART message
 */
void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = 'S';
  char endMarker = 'E';
  char rc;

  if (HWSERIAL.available() > 0) {
    while (HWSERIAL.available() > 0 && newData == false) {
      rc = HWSERIAL.read();


      if (recvInProgress == true) {
        if (rc != endMarker && rc != startMarker) {
          receivedChars[ndx] = rc;
          ndx++;
          if (ndx >= numChars) {
            ndx = numChars - 1;
          }
        }
        else if ( rc == endMarker) {
          receivedChars[ndx] = '\0'; // terminate the string
          recvInProgress = false;
          ndx = 0;
          newData = true;
        }
        else {           //rc is start marker
        }
      }

      else if (rc == startMarker) {
        recvInProgress = true;
      }
    }
  }
}

//function to print new data
void showNewData() {
  if (newData == true) {
    Serial.println(receivedChars);
    newData = false;
  }
}

And here is the 3.6 code:
Code:
//**** Communication Definitions ****//
// set this to the hardware serial port you wish to use
#define HWSERIAL Serial1

// Variables
char buffer[64];
char receivedChar; //buffer for message to send to roboteq
boolean newData = false; //flag to determine when all queries have been received and put into one string

void setup() {

  HWSERIAL.begin(230400);  // The Bluetooth Mate defaults to 115200bps
  delay(5000);  // Short delay, wait for the Mate to send back CMD
}


void loop() {
    recvOneChar();
    if(newData == true && receivedChar == '?'){         //if a query has been received
    newData = false;
      sprintf(buffer,"SHold On To you Buttttssssssssssssss!!!!!E");
      HWSERIAL.print(buffer);
    }
}



void recvOneChar() {
    if (HWSERIAL.available() > 0) {
        receivedChar = HWSERIAL.read();
        newData = true;
    }
}
 
Think about both buffer size and bandwidth, and the delay introduced, for every link in your chain of communications.

fill serial out buffer->transmit to BT modem-> BT transmision to receiver -> BT serial out to Teensy serial in -> Teensy read message and send response

I dont have the hardware setup to test but its clear that Round trip performance is just a fraction of raw BT baudrates.
 
Thanks. You are right. At this time I do not fully understand what the bluetooth modem is doing with the transmitted and/or received data.

Some more pointed googling describes similar issues with the HC-05 modules:
https://forum.arduino.cc/index.php?topic=694123.0

I won't have access to the system until Monday, but am going to start by progressively increasing buffer size from 1 to 64 bytes on the Teensy 3.6 side and see what happens.

Any other experience/advice is appreciated.
 
Well, the hardware was all fine. I was able to get it working by having the Teensy 3.6 loop and broadcast the message continuously rather than receiving a trigger and transmitting a message.

The Teensy 4.1 just looks at the received characters at a set interval made by elapsedMillis. I'm not entirely sure why it works now, but I think something was incorrect with the way I was receiving data at the 4.1.
 
Status
Not open for further replies.
Back
Top