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

Thread: Cannot communicate between two Teensy 3.2 via UART

  1. #1

    Cannot communicate between two Teensy 3.2 via UART

    Hi, I'm having trouble sending and recieveing serial data using the UART.

    The setup is as follows:

    TEENSY 3.2 #1 - Sending on pin 1.
    CODE:

    void setup(){
    Serial1.begin(9600);
    }
    void loop(){
    for(int x = 0;x < 255;x++){
    Serial1.print(x);
    }
    }


    TEENSY 3.2 #2 - Recieving on pin 0.
    CODE:

    void setup(){
    Serial.begin(9600);
    Serial1.begin(9600);
    }
    void loop(){
    Serial.println(Serial1.read());
    }


    Produces these readings:

    138,154,130,138,154,138,138,154,146,138,154,154,13 8,154,162,138,154,170,138,154,178,138,154,186,138, 154,194,138,154,202,138,162,130,138
    etc. etc.

    Both Teensy's are sharing the same power and ground.

    What am I doing wrong?

  2. #2
    Member
    Join Date
    Aug 2013
    Location
    Ohio
    Posts
    88
    The transmitting program is experiencing buffer overrun: It is trying to send bytes without waiting for the characters to exit the sending UART.

    9600 bits/second produces output at 960 bytes per second. Assuming that each value takes at most 4 bytes to express (3 bytes of decimal and the comma), wait 5 milliseconds between sending each value in the for loop.

    The core teensyduino library has a delay function whose argument is a count of milliseconds to wait before proceeding.

    In the transmitter, try:

    Code:
    void loop(){
        for(int x = 0;x < 255;x++){
            Serial1.print(x);
            delay(5);
        }
    }
    5 milliseconds between sending each value should produce better results.

    That preserves the structure of your original program. There are several ways to improve it further. It's considered to be good form to limit the execution time of each entry to the loop() function.

    A far more effective treatment of the serial transmit rate would be to let the hardware UART driver inform your program when transmit buffer space is available, using the function Serial1.availableForWrite(): When that function returns a value of 4 (or 5 or whatever), then the program can transmit the next value without fear of buffer overrun.

    Code:
    void loop(){
        for(int x = 0;x < 255;x++){
            Serial1.print(x);
            while(Serial1.availableForWrite() < 4) {
                // it would be nice to yield() here...
            }
        }
    }
    Finally, the receiving program uses Serial1.println() to display whatever happens to the in the buffer at the time it is called, and it is called at a very high repeat rate. That is also unlikely to produce the results you expect.

    Disclaimer: I have not tested this code; this is a set of hints guiding further development.

  3. #3
    Thanks LenSamuelson for your reply,

    I tried your suggestion to lower the speed with which the transmitting Teenys sends values:

    int x;

    void setup() {
    Serial1.begin(9600);
    }

    void loop() {
    if(x > 255){
    x = 0;
    }else{
    x++;
    }
    Serial1.print(x);
    delay(1000);
    }


    and to have the recieving Teensy waiting for transmission with the available() function:

    int reading;

    void setup() {
    Serial.begin(9600);
    Serial1.begin(9600);
    }

    void loop(){
    if(Serial1.available() > 0){
    reading = Serial1.read();
    Serial.println(reading);
    }
    }


    The only difference is that the serial monitor now displays incorrect values (55,48,55,49,55,50,55,51,55,52,55,53,55,54,55 etc etc) at exactly 1 seconds apart.

    So I guess the transmitting speed is not the issue after all?
    I tried the availableForWrite but it did not improvement anything.

    Do you have any other suggestions?

  4. #4
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    You're printing the ASCII Values.
    Try Serial.write(reading) on the receiving Teensy (instead Serial.println(reading) )

  5. #5
    Thanks Frank B, as soon as I started treating the values as bytes I am able to run as fast as 38400 bauds without errors!

    I rewrote the code as follows:

    SENDER:

    int x;

    void setup() {
    Serial1.begin(38400);
    }

    void loop() {
    if(x > 255){
    x = 0;
    }else{
    x++;
    }
    Serial1.write(byte(x));
    }


    RECIEVER

    byte reading;

    void setup() {
    Serial.begin(38400);
    Serial1.begin(38400);
    }

    void loop(){
    if(Serial1.available() > 0){
    reading = Serial1.read();
    Serial.println(reading);
    }
    }


    Thanks!

    /Johan

  6. #6
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    5,679
    Great.
    You can try much more speed - with short wires, i use 4M Baud (4e6) Baud.

  7. #7
    Senior Member+ MichaelMeissner's Avatar
    Join Date
    Nov 2012
    Location
    Ayer Massachussetts
    Posts
    3,268

    Cool

    Quote Originally Posted by Frank B View Post
    Great.
    You can try much more speed - with short wires, i use 4M Baud (4e6) Baud.
    Though I suspect at higher speeds, you want to restrict yourself to using Serial1 or Serial2. These UARTs have FIFO queues that allow bytes to come in if the Teensy has interrupts blocked for a short period of time. Note, the Teensy LC does not have FIFO queues.

    In addition, you probably want to set up RTS/CTS flow control to prevent overflowing the buffers: http://www.pjrc.com/teensy/td_uart.html.

    Note, RTS can be any pin, but in the current library, CTS must be a fixed pin:
    • Serial1: pins 18 or 20;
    • Serial2: pin 23 (+ pin 60 on 3.6/3.5);
    • Serial3: pin 14;
    • Serial4 (on 3.5/3.6): No CTS support;
    • Serial5 (on 3.5/3.6): pin 24;
    • Serial6 (on 3.5/3.6): pin 56.

Posting Permissions

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