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

Thread: Serial Communication between two teensy 4.1

  1. #1
    Junior Member
    Join Date
    Aug 2022
    Posts
    3

    Serial Communication between two teensy 4.1

    Hi
    I'm new to Serial communication. I've been trying to send encoder and current information between two teensys using Serial 6 and 7. I test the code using one teensy and it worked at any speed. However when I use two teensys the packets of information that I send start to shift at frequencies higher than 100Hz. I've been using USB serial to monitor what is being sent. I have no idea why the info shifts at higher frequencies. I've attached the code. It is the same between two the two teensys, I just switch the channels used in my send and receive functions. read_test2.ino

  2. #2
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    868
    Code:
    #define CH2 Serial7
    #define CH1 Serial6
    
    /* Data Type to be sent received */
    struct dataType {
        float vPos, hPos, vCurrent, hCurrent;
    };
    
    dataType a, i;   // Variables to hold the data for Send/Receive
    
    //placeholder for information getting sent
    float ivpos = 0.10, ihpos = 0.20, ivcurrent = 0.0, ihcurrent = 0.0;
    float avpos = 0.50, ahpos = 0.70, avcurrent = 0.29, ahcurrent = 0.35;
    
    
    void setup() {
    
        // Initialize serial interface
        Serial.begin(9600);
        CH2.begin(115200);
        CH1.begin(115200);
    
        // Wait until the serial interfaces are active
        while (!Serial && millis()<5000);  // Wait for Serial (USB) to become active
    //    while (!CH2);
    //    while (!CH1);
        Serial.println("Serial ports active");
    
        //  InterfaceTime.begin(ReceivePacket, 5000);
        //  AvatarTime.begin(SendPacket, 5000);
    
    }
    
    
    
    void loop() {
       delay( 1000 ) ;   // Don't want to swamp the other Teensy
    
    // Put data into variable a for sending.
        a.vPos = avpos;
        a.hPos = ahpos;
        a.vCurrent = avcurrent;
        a.hCurrent = ahcurrent;
    
    /*  SendPacket */
        CH2.write((uint8_t*) &a, sizeof(a));    //Send the data
    
        if (CH1.available() >= sizeof(i)) {       // Wait for complete data received
    /*        ReceivePacket */
            CH1.readBytes((uint8_t*) &i, sizeof(i));   // Get the data from Serial Buffer
            delay(10);
            Serial.print(i.vPos);
            Serial.print(" , ");
            Serial.print(i.hPos);
            Serial.print(" , ");
            Serial.print(i.vCurrent);
            Serial.print(" , ");
            Serial.print(i.hCurrent);
            Serial.println("    <--- Read packet.");
            Serial.println();
        }
      }
    You could give the code above a try. It does compile, though I must admit that I have not tried it.

  3. #3
    Senior Member
    Join Date
    Nov 2012
    Posts
    1,885
    This might be the problem:
    Code:
      sprintf ( outgoingBytes , "s,%2.4f,%2.4f,%2.4f,%2.4f,e" , var1 , var2 , var3 , var4 ) ;
    The format specifiers aren't right. %2.4f means that the whole field is two characters long and there are four digits after the decimal point.
    If the integer part can be over 100, then the specifiers would each have to be at least %8.4f. If the integer can be in the thousands, it would have to be %9.4f.
    Either way, you'll have to make the character array larger:
    Code:
      char outgoingBytes[50] ;
    and the same in the receiving end:
    Code:
      char incomingBytes[50] ;
    Pete

  4. #4
    Senior Member
    Join Date
    May 2017
    Posts
    321
    I think you need to wait until all the characters have been received:

    Code:
    void ReceivePacket () {
    
      char incomingBytes[35] ;
    
      // Check if data is available
      if ( CH1.available() ) {              Will be true even if less than 35 characters received.  Perhaps CH1.available >= 35 would test if this is the issue
                                                  but really you should be checking the s, start characters and ,e end characters of the string for valid data.
    
        // Read bytes into char array
        for ( unsigned int i = 0 ; i < sizeof ( incomingBytes ) ; i++ ) {
          incomingBytes[i] = CH1.read() ;                                          returns -1 if character not available
          if ( DEBUG ) Serial.print ( incomingBytes[i] ) ;
        }

    Also you have a data buffer overrun on writing the string as sprintf terminates the string with a zero.


    edit: I now see the BriComp post also shows the need to wait for the complete string to be received.

  5. #5
    Junior Member
    Join Date
    Aug 2022
    Posts
    3
    Thanks for the code and help! I added some usb serial prints so I can see both what I'm sending and reading. I also am trying to have the data send super fast (around 10kHz) so I got rid of the delays, but for some reason one of the teensy still reads the packet incorrectly. This is the biggest problem I seem to be running into where, either one or both teensy seem to read the packets all shifted. Sometimes I'm able to unplug and replug the teensys at the same time and it fixes it but not all the time. So I'm worried that when I add in the other processes to the code, the messages will send all scrambled.

    This is with the new code.

    Click image for larger version. 

Name:	Teensy 1.jpg 
Views:	5 
Size:	87.9 KB 
ID:	29374Click image for larger version. 

Name:	teensy 2.jpg 
Views:	2 
Size:	84.6 KB 
ID:	29375


    and when I try editing my original code it seemed to make no difference and this is what happens.
    Click image for larger version. 

Name:	original teensy 1.jpg 
Views:	4 
Size:	164.9 KB 
ID:	29376Click image for larger version. 

Name:	original teensy 2.jpg 
Views:	6 
Size:	158.0 KB 
ID:	29377
    Last edited by ajc225; 09-15-2022 at 07:47 PM.

  6. #6
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    868
    Can you post your new code for the sending and the receiving Teensy.

  7. #7
    Junior Member
    Join Date
    Aug 2022
    Posts
    3
    This is the new code that you suggested. I just added in some prints to the usb and got rid of delays.

    Teensy_1.inoTeensy_2.ino

    My original code is the same because the two edits didn't really make a difference.

    Code:
    #define CH2 Serial7
    #define CH1 Serial6
    
    /* Data Type to be sent received */
    struct dataType {
      float vPos, hPos, vCurrent, hCurrent;
    };
    
    
    dataType a, i;   // Variables to hold the data for Send/Receive
    
    //placeholder for information getting sent
    float ivpos = 0.10, ihpos = 0.20, ivcurrent = 0.0, ihcurrent = 0.0;
    float avpos = 0.50, ahpos = 0.70, avcurrent = 0.29, ahcurrent = 0.35;
    
    
    void setup() {
    
      // Initialize serial interface
      Serial.begin(9600);
      CH2.begin(115200);
      CH1.begin(115200);
    
      // Wait until the serial interfaces are active
      while (!Serial && millis() < 5000); // Wait for Serial (USB) to become active
      //    while (!CH2);
      //    while (!CH1);
      Serial.println("Serial ports active");
    
      //  InterfaceTime.begin(ReceivePacket, 5000);
      //  AvatarTime.begin(SendPacket, 5000);
    
    }
    
    
    
    void loop() {
    //  delay( 10 ) ;   // Don't want to swamp the other Teensy
    
      // Put data into variable a for sending.
      i.vPos = ivpos;
      i.hPos = ihpos;
      i.vCurrent = ivcurrent;
      i.hCurrent = ihcurrent;
    
      /*  SendPacket */
      CH1.write((uint8_t*) &i, sizeof(i));    //Send the data
      Serial.print(i.vPos);
      Serial.print(" , ");
      Serial.print(i.hPos);
      Serial.print(" , ");
      Serial.print(i.vCurrent);
      Serial.print(" , ");
      Serial.print(i.hCurrent);
      Serial.println("    <--- Send packet through CH1.");
      Serial.println();
    
      if (CH2.available() >= sizeof(a)) {       // Wait for complete data received
        /*        ReceivePacket */
        CH2.readBytes((uint8_t*) &a, sizeof(a));   // Get the data from Serial Buffer
    //    delay(10);
        Serial.print(a.vPos);
        Serial.print(" , ");
        Serial.print(a.hPos);
        Serial.print(" , ");
        Serial.print(a.vCurrent);
        Serial.print(" , ");
        Serial.print(a.hCurrent);
        Serial.println("    <--- Read packet in CH2.");
        Serial.println();
      }
    }

    Code:
    #define CH2 Serial7
    #define CH1 Serial6
    
    /* Data Type to be sent received */
    struct dataType {
      float vPos, hPos, vCurrent, hCurrent;
    };
    
    
    
    dataType a, i;   // Variables to hold the data for Send/Receive
    
    //placeholder for information getting sent
    float ivpos = 0.10, ihpos = 0.20, ivcurrent = 0.0, ihcurrent = 0.0;
    float avpos = 0.50, ahpos = 0.70, avcurrent = 0.29, ahcurrent = 0.35;
    
    
    void setup() {
    
      // Initialize serial interface
      Serial.begin(9600);
      CH2.begin(115200);
      CH1.begin(115200);
    
      // Wait until the serial interfaces are active
      while (!Serial && millis() < 5000); // Wait for Serial (USB) to become active
      //    while (!CH2);
      //    while (!CH1);
      Serial.println("Serial ports active");
    
      //  InterfaceTime.begin(ReceivePacket, 5000);
      //  AvatarTime.begin(SendPacket, 5000);
    
    }
    
    
    
    void loop() {
      //   delay( 10 ) ;   // Don't want to swamp the other Teensy
    
      // Put data into variable a for sending.
      a.vPos = avpos;
      a.hPos = ahpos;
      a.vCurrent = avcurrent;
      a.hCurrent = ahcurrent;
    
      /*  SendPacket */
      CH2.write((uint8_t*) &a, sizeof(a));    //Send the data
      Serial.print(a.vPos);
      Serial.print(" , ");
      Serial.print(a.hPos);
      Serial.print(" , ");
      Serial.print(a.vCurrent);
      Serial.print(" , ");
      Serial.print(a.hCurrent);
      Serial.println("    <--- Send packet through CH2.");
      Serial.println();
    
      if (CH1.available() >= sizeof(i)) {       // Wait for complete data received
        /*        ReceivePacket */
        CH1.readBytes((uint8_t*) &i, sizeof(i));   // Get the data from Serial Buffer
    //    delay(10);
        Serial.print(i.vPos);
        Serial.print(" , ");
        Serial.print(i.hPos);
        Serial.print(" , ");
        Serial.print(i.vCurrent);
        Serial.print(" , ");
        Serial.print(i.hCurrent);
        Serial.println("    <--- Read packet in CH1.");
        Serial.println();
      }
    }
    Last edited by Paul; 09-15-2022 at 09:08 PM. Reason: added code to message

  8. #8
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    4,275
    I've never used it on Teensys, but I suspect you want to set up two additional pins to CTS (clear to send) and RTS (request to send) to use hardware flow control:


  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    26,800
    I believe you should try EasyTransfer. In Arduino, click File > Examples > EasyTransfer_TX_Example and also File > Examples > EasyTransfer_RX_Example.

    Edit those examples to use Serial6 or Serial7 as needed. They are written with just "Serial" so they can work on boards like Arduino Uno which don't have extra serial ports. Obviously on Teensy you would use Serial1 to Serial8, since "Serial" talks to your PC by USB.

  10. #10
    Senior Member BriComp's Avatar
    Join Date
    Apr 2014
    Location
    Cheltenham, UK
    Posts
    868
    Been Playing around with this on and off all day.
    Finally found my STUPID mistake and working fine now.
    Works at 230400 baud.
    Boy does it FLY!
    Code:
    /************************
         Send and Receive Code
    ************************/
    
    #define RxD Serial7
    #define TxD Serial6
    
    #define baud 230400 //115200
    
    #pragma pack(push,1)
    
    /* Data Type to be sent received */
    struct dataType {
        uint32_t dataIdx;
        float vPos, hPos, vCurrent, hCurrent;
    };
    
    dataType tx, rx;   // Variables to hold the data for Send/Receive
    #pragma pack(pop)
    
    //placeholder for information getting sent
    float ivpos = 0.10, ihpos = 0.20, ivcurrent = 0.0, ihcurrent = 0.0;
    float avpos = 0.50, ahpos = 0.70, avcurrent = 0.29, ahcurrent = 0.35;
    
    void ClearSerialBuffers() {
        TxD.flush();
        RxD.clear();
        delay(1000);
        TxD.flush();
        RxD.clear();
    }
    
    void setup() {
    
        // Initialize serial interface
        Serial.begin(9600);
        RxD.begin(baud);
        TxD.begin(baud);
    
        pinMode(LED_BUILTIN, OUTPUT);
        // Wait until the serial interfaces are active
        while (!Serial && millis() < 5000);  // Wait for Serial (USB) to become active
        Serial.println("Serial ports active:");
        Serial.println("     Sending on Serial6 Tx, Receiving on Serial 7 Rx");
    
        tx.dataIdx = 0;
        ClearSerialBuffers();
        delay(1000);    // Just to allow synch time between T4.1s
    }
    
    elapsedMillis timeout;
    #define waitTime 5000
    
    void loop() {
    
        tx.vPos = avpos;
        tx.hPos = ahpos;
        tx.vCurrent = avcurrent;
        tx.hCurrent = ahcurrent;
        tx.dataIdx++;
    
        /*  SendPacket */
        digitalWriteFast(LED_BUILTIN, HIGH);
        TxD.write((uint8_t*)&tx, sizeof(tx));    //Send the data
        TxD.flush();
    
        digitalWriteFast(LED_BUILTIN, LOW);
    
        Serial.print("Sent packet ---->  ");
        Serial.print(tx.dataIdx);
        Serial.print(" , ");
        Serial.print(tx.vPos);
        Serial.print(" , ");
        Serial.print(tx.hPos);
        Serial.print(" , ");
        Serial.print(tx.vCurrent);
        Serial.print(" , ");
        Serial.print(tx.hCurrent);
        Serial.println();
    
        timeout = 0;
    
        while ((RxD.available() < sizeof(rx)) && (timeout <= waitTime)) {}       // Wait for complete data received
        /*        ReceivePacket */
        if (timeout >= waitTime) {
            Serial.println("Timeout waiting for Rx Data");
            ClearSerialBuffers();
        }
        else {
            rx.dataIdx = 0;
            rx.hCurrent = 0;
            rx.hPos = 0;
            rx.vCurrent = 0;
            rx.vPos = 0;
    
            RxD.readBytes((uint8_t*)&rx, sizeof(rx));   // Get the data from Serial Buffer
            Serial.print("Read packet ---->  ");
            Serial.print(rx.dataIdx);
            Serial.print(" , ");
            Serial.print(rx.vPos);
            Serial.print(" , ");
            Serial.print(rx.hPos);
            Serial.print(" , ");
            Serial.print(rx.vCurrent);
            Serial.print(" , ");
            Serial.print(rx.hCurrent);
            Serial.println();
    
            if (rx.dataIdx != tx.dataIdx) {
                Serial.println("Lost Packet");
                ClearSerialBuffers();
            }
    
        }
    }
    Code:
    /*****************************
      Receive and Echo Back Code
    ******************************/
    
    #define RxD Serial7
    #define TxD Serial6
    #pragma pack(push,1)
    
    /* Data Type to be sent received */
    struct dataType {
        uint32_t dataIdx;
        float vPos, hPos, vCurrent, hCurrent;
    };
    
    dataType rx;   // Variables to hold the data for Send/Receive
    #pragma pack(pop)
    
    #define baud 230400  //115200
    
    void ClearSerialBuffers() {
        TxD.flush();
        RxD.clear();
        delay(1000);
        TxD.flush();
        RxD.clear();
    }
    
    void setup() {
    
        // Initialize serial interface
        Serial.begin(9600);
        RxD.begin(baud);
        TxD.begin(baud);
    
        pinMode(LED_BUILTIN, OUTPUT);
        // Wait until the serial interfaces are active
        while (!Serial && millis() < 5000);  // Wait for Serial (USB) to become active
        Serial.println("Serial ports active:");
        Serial.println("     Receiving on Serial7 Rx, Sending on Serial 6 Tx");
    
        ClearSerialBuffers();
    
    }
    void loop() {
    
        if (RxD.available() >= sizeof(rx)){
     
        /*        ReceivePacket */
            digitalWriteFast(LED_BUILTIN, HIGH);
            rx.dataIdx = 0;
            rx.hCurrent = 0;
            rx.hPos = 0;
            rx.vCurrent = 0;
            rx.vPos = 0;
            RxD.readBytes((uint8_t*)&rx, sizeof(rx));   // Get the data from Serial Buffer
            /*  SendPacket */
            TxD.write((uint8_t*)&rx, sizeof(rx));    //Send the data
            TxD.flush();
            digitalWriteFast(LED_BUILTIN, LOW);
    
        }
    }

Posting Permissions

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