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

Thread: High Speed Serial comms between 2 Teensy 3.1

  1. #1
    Senior Member
    Join Date
    Mar 2013
    Posts
    643

    High Speed Serial comms between 2 Teensy 3.1

    I have to say it sounds easy enough unless your like me and just play with C on the weekend

    Needless to say after pulling my hair this afternoon I have managed to get 2 Teensy 3.1's talking to each other at 4.8Mhz.
    My large scale plan is to send data from a motor controller on my EGoCart to a touch screen mounted on the steering wheel and I needed a little more then the standard Serial Baud rates could do, I will be using RS485 to make up for the cable lengths. Adding RS485 to the testing will come soon.

    Below is the Transmit(motor controller) portion stripped down and the Receiving side(ILI9341 LCD w/touch) in its current WIP glory. Right now I am only transmitting 2 bytes, which will be 1 of several analog values im reading and sending in the final build along with a dozen or so other pieces of data.

    I think the Serial can go faster but I will leave it for another day.... Like tomorrow.


    Questions, comments, "hey this is lame do this instead". all welcome.


    Transmit
    Code:
    /////////Donziboy2/////////
    
    #define SERIAL_BAUD_RATE 4800000
    
    
    void setup() {
    
    
      Serial.begin(9600);
      Serial1.begin( SERIAL_BAUD_RATE, SERIAL_8N1 );
    
      delay(200);
    }
    
    elapsedMillis serialtesting; //
    int batterySOC = 1234;     //serialtestvalue
    byte buffer[1] = {0};
    
    void loop() {
      int i;
    
     if(serialtesting > 200) {    //10s
    buffer[1] = (byte) (batterySOC & 0xFF);
    buffer[0] = (byte) ((batterySOC >> 8) & 0xFF);
    
     Serial1.write(buffer[0]);
     Serial1.write(buffer[1]);
       serialtesting = 0;
       batterySOC = batterySOC + 1;
       if(batterySOC > 9999){
        batterySOC = 0; 
       }
     }
    }
    Receive

    Code:
    /***************************************************
    Adafruit graphicstest used as a base.
     ****************************************************/
    //////////////////////////////////////////////////////
    //Modified by Donziboy2
    //////////////////////////////////////////////////////
    
    
    #include "SPI.h"
    #include "ILI9341_t3.h"
    
    // For the Adafruit shield, these are the default.
    #define TFT_DC  9
    #define TFT_CS 10
    #define TFT_RST 8
    ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC, TFT_RST);
    
    
    #define SERIAL_BAUD_RATE 4800000
    
    //Test perams
    int frequency2 = 259;
    float BatterySOC = 0;     // percentage of charge (assumed)
    float BatterySOCold = 0;
    volatile int32_t executiontime = 0;
    byte boxset = 0;
    byte drivestate = 1;
    byte drivestateold = 0;
    byte  Redfull = 0;
    byte  Yellowfull = 0;
    byte  Greenfull = 0;
      int a = 0;
      int b = 0;
    float xold = 0;
    float yold = 0;
    float zold = 0;
    float aold = 10;
    float bold = 10;
    float cold = 10;
    float dold = 9;
    int h = 0;
    int i = 0;
    byte buffer[1] = {0};
    
    
    void setup() {
    
      tft.begin();
      tft.fillScreen(ILI9341_BLACK);
      tft.setRotation(3);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setTextSize(3);
      tft.println("Initializing.....");
      delay(1000);
      tft.fillScreen(ILI9341_BLACK);
      tft.fillRect(5, 5, 20, 230, ILI9341_WHITE);     //blank battery bar once
      mainScreen();
     
      Serial.begin( 9600 );
      Serial1.begin( SERIAL_BAUD_RATE );
     
    }
    
    
    void loop() {
    
        
      
      if (Serial1.available() > 1){
     
      buffer[0] = Serial1.read(); 
      buffer[1] = Serial1.read();
        
        int a = buffer[0] << 8;
        a = a + buffer[1];
        BatterySOC = a;
      }
    
      
        refreshtime();
        
        mainScreen();
        
    
     //   delay(50);
     // frequency2++;
        h++;
     //   i++;
        if(h == 30){
        if(frequency2 >= 999){
          a = 1;
        }
        if(frequency2 <= 0){
         a = 0; 
        }
        if(a == 0){
          frequency2 = frequency2 + 1;   
        }
        else
            {
                 frequency2 = frequency2 - 1; 
            }
        h = 0;
        }
      /*  
        if(i == 2){
        if(BatterySOC >= 9999){
          b = 1;
        }
        if(BatterySOC <= 0){
         b = 0; 
        }
        if(b == 0){
          BatterySOC = BatterySOC + 1;   
        }
        else
            {
                 BatterySOC = BatterySOC - 1; 
            }  
      i = 0;
        }*/
    }
    
    unsigned long refreshtime(){
    
      
      tft.fillRect(35, 110, 75, 15, ILI9341_BLACK);
      tft.setCursor(35, 110);
      tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(2);
      tft.print(executiontime);
      tft.setCursor(35, 130);
      tft.print("Microseconds");
    
    }
    
    
    unsigned long mainScreen() {
      elapsedMicros elapsedtesttime;
      
      if(boxset < 1){                                 //removes redraw for no reason
      tft.drawRect(145, 5, 170, 30, ILI9341_GREEN);   //drive status box 
      tft.drawRect(35, 185, 65, 50, ILI9341_WHITE);
      tft.drawRect(105, 185, 65, 50, ILI9341_WHITE);
      tft.drawRect(175, 185, 65, 50, ILI9341_WHITE);
      tft.drawRect(245, 185, 65, 50, ILI9341_WHITE);
      tft.drawRect(5, 5, 20, 230, ILI9341_WHITE);     //battery bar outline
     
      tft.setTextColor(ILI9341_WHITE);   tft.setTextSize(2);
      tft.setCursor(74, 5);   
      tft.print(".");
      tft.setCursor(110, 5);
      tft.print("%");
      
      tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(2);
      tft.setCursor(50, 22);
      tft.print("Charge");
      tft.setTextColor(ILI9341_BLUE);    tft.setTextSize(4);  
      tft.setCursor(240, 150);  
      tft.println("MPH"); 
      tft.setTextColor(ILI9341_YELLOW);   tft.setTextSize(5);
      tft.setCursor(255, 110);   
      tft.print("."); 
     
      boxset = 1;
    }  
      
      
      
      
      if(BatterySOCold > BatterySOC){
        float w = (1 - (BatterySOC / 10000)) * 228; 
      tft.fillRect(6, 6, 18, w, ILI9341_WHITE);     //blank battery bar
      Redfull = 0;
      Yellowfull = 0;
      }
     
     
     
     
     
      if(BatterySOC <= 3333 && BatterySOC != 0){      //red battery bar only
        float x;
        float y;
        x = BatterySOC / 3333;
        y = x * 76;                  //rectangle size
        x = 235 - y;                 //rectangle starting position
      tft.fillRect(6, x, 18, y, ILI9341_RED);
      Redfull = 0;
      Yellowfull = 0;
      }
      
      if(BatterySOC <= 6666 && BatterySOC > 3333){      //red and yellow battery bars only
        float x;
        float y;
        x = BatterySOC - 3333;    //remove red region
        x = x / 3333;
        y = x * 76;                 //rectangle size
        x = 159 - y;                //rectangle starting postion
        if(Redfull == 0){
      tft.fillRect(6, 158, 18, 76, ILI9341_RED);
      Redfull = 1;
        }
      tft.fillRect(6, x, 18, y, ILI9341_YELLOW);
      Yellowfull = 0;
      }
      
      if(BatterySOC <= 10000 && BatterySOC > 6666){      //red, yellow and green battery bars only
        float x;
        float y;
        x = BatterySOC - 6666;    //remove red and yellow region
        x = x / 3333;
        y = x * 76;                 //rectangle size
        x = 83 - y;                //rectangle starting postion
      if(Redfull == 0){
      tft.fillRect(6, 158, 18, 76, ILI9341_RED);
      Redfull = 1;
      }
      if(Yellowfull == 0){
      tft.fillRect(6, 82, 18, 76, ILI9341_YELLOW);
      Yellowfull = 1;
      }
      tft.fillRect(6, x, 18, y, ILI9341_GREEN);
      }
      
      
    //  tft.fillRect(50, 5, 59, 14, ILI9341_BLACK);     //clears % value
      
     // tft.setTextColor(ILI9341_BLACK); tft.setTextSize(2);
     // tft.setCursor(50, 5);
     // tft.print((float)BatterySOCold * 100,2);     tft.print("%");
      
                                                                    //1234 as example
      float a = BatterySOC / 1000;                                  //1.234
      float b = BatterySOC / 100;                                   //12.34  
      float c = BatterySOC / 10;                                    //123.4
      int aa = a;                                                   //1
      int bb = b;                                                   //12
      int cc = c;                                                   //123
      float aaa = aa;                                                //1
      float bbb = bb;                                                //12
      float ccc = cc;                                                //123
      a = aaa;                                                       //1
      b = bbb - (aaa * 10);                                          //2
      c = ccc - (bbb * 10);                                          //3
      float d = BatterySOC - (ccc * 10);                             //4
      
      
    
      tft.setTextSize(2);
      if(a != aold){
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(50, 5);
      tft.print(aold, 0);
      tft.setTextColor(ILI9341_WHITE);
      tft.setCursor(50, 5);  
      tft.print(a, 0);
      aold = a; 
      }
    
      if(b != bold){
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(62, 5);
      tft.print(bold, 0);
      tft.setTextColor(ILI9341_WHITE);
      tft.setCursor(62, 5);  
      tft.print(b, 0);
      bold = b;
      }
    
    ////decimal is printed once with rest of boxes
      if(c != cold){ 
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(86, 5);
      tft.print(cold, 0);
      tft.setTextColor(ILI9341_WHITE);
      tft.setCursor(86, 5);  
      tft.print(c, 0);
      cold = c;
      }
    
      if(d != dold){
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(98, 5);
      tft.print(dold, 0);
      tft.setTextColor(ILI9341_WHITE);
      tft.setCursor(98, 5);  
      tft.print(d, 0);
      dold = d; 
      }
    
      BatterySOCold = BatterySOC;
      
      
      
     // tft.setCursor(50, 5);
     // tft.setTextColor(ILI9341_WHITE);  tft.setTextSize(2);
     // tft.print((float)BatterySOC * 100,2);    tft.print("%");
     // tft.fillRect(195, 110, 115, 35, ILI9341_BLACK);   //clears MPH Value
      
      
     
      
                                                     //239 as example
    float x = frequency2 / 100;                      //2.39
    float y = (frequency2 / 10);                     //23.9
    int xx = x;                                      //2
    int yy = y;                                      //23
    float xxx = xx;                                  //2
    float yyy = yy;                                  //23
    x = xxx;                                         //2
    y = yyy - (x * 10);                              //3
    float z = frequency2 - (yyy * 10);               //9
    
      
      
      tft.setTextSize(5);
      if(x != xold){
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(195, 110);
      tft.print(xold, 0);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setCursor(195, 110);  
      tft.print(x, 0);
      xold = x; 
      }
    
      if(y != yold){
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(225, 110);
      tft.print(yold, 0);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setCursor(225, 110);  
      tft.print(y, 0);
      yold = y;
      }
    
    ////decimal is printed once with rest of boxes
      if(z != zold){ 
      tft.setTextColor(ILI9341_BLACK);    
      tft.setCursor(285, 110);
      tft.print(zold, 0);
      tft.setTextColor(ILI9341_YELLOW);
      tft.setCursor(285, 110);  
      tft.print(z, 0);
      zold = z;
      }
    
    
      
      
      //tft.print((float)frequency2, 1);  // this rounds 25.98765 to 26.0  :(
    
      
      
      if(drivestateold != drivestate){   //only change is drivestate changes
      tft.setTextColor(ILI9341_RED);    tft.setTextSize(2);
      tft.setCursor(170, 12);
      tft.println("DriveStatus");
      drivestateold = 1;
      }
      
      executiontime = elapsedtesttime;
    
    }
    P.S. not sure if this would be better in Tech Support

  2. #2
    Senior Member johnnyfp's Avatar
    Join Date
    Jan 2014
    Location
    New Zealand
    Posts
    260
    Why not use SPI instead. That can be clocked much faster.

  3. #3
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    I'm logging data on the receiving micro that will tie up SPI, I'm also refreshing the screen that will tie the SPI up some. I also have to deal with a 12'+ cable from the motor micro to the display micro. Add to that I would need to limit the SPI clock over that distance, which would mean slower screen and NVflash writes. Serial transfers between micros is hardly documented as it is and SPI is practically an urban legend compared to Serial.

    Also i'm not even sure if i'm using Serial correctly atm....

  4. #4
    Senior Member
    Join Date
    Aug 2013
    Location
    Gothenburg, Sweden
    Posts
    292
    Do you ever increase 'serialtesting' in the transitter loop ?

    Sending handful of values ever second or ten seconds, do you really need to push the serial speed between your twop boards?

    Top serial speeds is needed for fast command/response exchanges, with not trivial data lengths, and for big data volumes, neither seems to be these case here.

  5. #5
    Senior Member
    Join Date
    Nov 2012
    Location
    Boston, MA, USA
    Posts
    1,103
    Quote Originally Posted by Donziboy2 View Post
    Add to that I would need to limit the SPI clock over that distance, which would mean slower screen and NVflash writes.
    The devices on an SPI bus do not all have to use the same speeds.

  6. #6
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    Quote Originally Posted by mlu View Post
    Do you ever increase 'serialtesting' in the transitter loop ?

    Sending handful of values ever second or ten seconds, do you really need to push the serial speed between your twop boards?

    Top serial speeds is needed for fast command/response exchanges, with not trivial data lengths, and for big data volumes, neither seems to be these case here.
    My plan is to send up to 64 bytes between ADC reads of my motor controller, I plan to read the ADC's at 2KHz. I plan to send periodically to the screen micro after completing an ADC reads and doing any processing that is needed before sending all the ADC averages and any drive state info I think is needed.

  7. #7
    Senior Member
    Join Date
    Aug 2013
    Location
    Gothenburg, Sweden
    Posts
    292
    Yeah, for control loops 2kHz can be important, for display anything above 10Hz total overkill. The user cannot process information faster than this.

  8. #8
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    Got Serial1 going at 6Mhz @96Mhz. Seems to be sending the 16 byte data pretty well (6x 0-4095adc values and 1x 32bit timing value). Looking at Frank B's CRC library to determine if im seeing errors, I just have to figure out how to use the library......

    Another thing worth mentioning...... Checking Serial1.available() > 1 and sending lots of bytes is a bad idea, at 4.8Mhz I was only getting the first 2 bytes before the data got processed and the others got read as a new transmission. It took me hours to find this simple mistake along with several others I made.

    Code:
    if (Serial1.available() > 1)
    This works much better.
    Code:
    if (Serial1.available() >= (n of bytes - 1))  //if using 16 bytes set this to 15
    edit 2....
    Just found another interesting thing.

    I have the serial byte buffer set to 1, on both my transmit test and the current sketch im running 16 bytes on and somehow its working.....

    Pieces from my 16byte sketch..

    Declared before setup in my 16 byte transmit and after setup in my receive sketch.
    Code:
    byte buffer[1] = {0};
    receiving chunk
    Code:
      if (Serial1.available() >= 15){
     
        
        for(i = 0; i < 16; i++){
      buffer[i] = Serial1.read(); 
    //  buffer[1] = Serial1.read();
        }
        
    int a = 0;
    uint32_t b = 0;
    
        a = buffer[0] << 8;
        a = a + buffer[1];
        newaverages[0] = a;    //throttleaverage
        a = 0;
        a = buffer[2] << 8;
        a = a + buffer[3];
        newaverages[1] = a;    //currentaverage
        a = 0;
        a = buffer[4] << 8;
        a = a + buffer[5];
        newaverages[2] = a;    //busvaverage
        a = 0;
        a = buffer[6] << 8;
        a = a + buffer[7];
        newaverages[3] = a;    //battvaverage   
        a = 0;
        a = buffer[8] << 8;
        a = a + buffer[9];
        newaverages[4] = a;    //motortaverage 
        a = 0;
        a = buffer[10] << 8;
        a = a + buffer[11];
        newaverages[5] = a;    //hstaverage
    
        b = buffer[12] << 8 + b;
        b = buffer[13] << 8 + b;
        b = buffer[14] << 8 + b;
        b = buffer[15] + b;
        frequency1 = b;    //frequency1    
     
          newdata = 1;
      }
    transmit chunk

    Code:
     if(serialcounter > 2000) {   
      buffer[0] = (byte) ((throttleaverage >> 8) & 0xFF); 
      buffer[1] = (byte) (throttleaverage & 0xFF);
      buffer[2] = (byte) ((currentaverage >> 8) & 0xFF); 
      buffer[3] = (byte) (currentaverage & 0xFF);
      buffer[4] = (byte) ((busvaverage >> 8) & 0xFF); 
      buffer[5] = (byte) (busvaverage & 0xFF);
      buffer[6] = (byte) ((battvaverage >> 8) & 0xFF); 
      buffer[7] = (byte) (battvaverage & 0xFF);
      buffer[8] = (byte) ((motortaverage >> 8) & 0xFF); 
      buffer[9] = (byte) (motortaverage & 0xFF);
      buffer[10] = (byte) ((hstaverage >> 8) & 0xFF); 
      buffer[11] = (byte) (hstaverage & 0xFF);
      buffer[12] = (byte) ((frequency1 >> 24) & 0xFF); 
      buffer[13] = (byte) ((frequency1 >> 16) & 0xFF);
      buffer[14] = (byte) ((frequency1 >> 8) & 0xFF); 
      buffer[15] = (byte) (frequency1 & 0xFF);
    
      
     Serial1.write(buffer[0]);
     Serial1.write(buffer[1]);
     Serial1.write(buffer[2]);
     Serial1.write(buffer[3]);
     Serial1.write(buffer[4]);
     Serial1.write(buffer[5]);
     Serial1.write(buffer[6]);
     Serial1.write(buffer[7]);
     Serial1.write(buffer[8]);
     Serial1.write(buffer[9]);
     Serial1.write(buffer[10]);
     Serial1.write(buffer[11]);
     Serial1.write(buffer[12]);
     Serial1.write(buffer[13]);
     Serial1.write(buffer[14]);
     Serial1.write(buffer[15]);
     
     
     serialcounter = 0;
     }
    Not sure if its idiot proof or a bug lol.

    edit 3...
    and i found more mistakes, really missing those debug tools now :/
    Last edited by Donziboy2; 03-28-2015 at 02:40 AM.

  9. #9
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    Just an update im running Serial @ 6Mhz over RS485 and I have implemented CRC thanks to Frank B and his Fast CRC library.

    I will leave my project running overnight to see how many CRC fails I can get.

  10. #10
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    18,183
    Wow, I think 6 Mbits/sec is probably the fastest anyone's ever reported running hardware serial.

    I know I've only tested up to 1 Mbit/sec.

  11. #11
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    I am using 16' of Cat5 and MAX3087 transceivers.

    I had not expected to be able to send data this fast, the biggest hurdle for me is timing. The higher speed lets me do more other things like adding extra ADC inputs, even increasing the frequency at which I read my A/D inputs.

    I did run the test setup all night.
    In order.
    6x 12bit analog values, 1 motor speed value in microseconds/pulse(external interrupt), a crc fail count, the current crc value and lastly the running time in seconds.
    As you can see it ran 10hours overnight with no crc fails, 10 transmits per second.

    As you can tell from the ghosting on the MPH value, it is updating pretty fast, the microseconds counter says 12. That is the amount of time the last screen update took.



    So far i'm pleased with the results, i'm doing everything on solder-less breadboards and have had very little in the way of noise issues on both the ADC channels and the serial. I am tearing the current setup apart and have started building everything up the way I have in my motor controller schematics. With any luck I will be running a small test motor (200W) by the end of the weekend.

  12. #12
    Member mixania's Avatar
    Join Date
    Oct 2014
    Location
    New York, NY
    Posts
    20
    Quote Originally Posted by Donziboy2 View Post
    I am using 16' of Cat5 and MAX3087 transceivers.
    As you can tell from the ghosting on the MPH value, it is updating pretty fast, the microseconds counter says 12. That is the amount of time the last screen update took.
    Are you saying you are able to drive that screen at 83FPS (1000/12)?? Wow, that is pretty damn fast. I bet you will get only get like 7FPS by using the Ada-fruit library.

  13. #13
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    Quote Originally Posted by mixania View Post
    Are you saying you are able to drive that screen at 83FPS (1000/12)?? Wow, that is pretty damn fast. I bet you will get only get like 7FPS by using the Ada-fruit library.
    Its in microseconds not milliseconds. It ranges from around 10uS to about 15-20mS depending on what is getting updated. Had a few discussions on the Highly-optimized-ILI9341 thread about optimizing redraws on the screen.

    It boils down to only updating what has to be updated. Blacking just the text is far faster then making a large black rectangle then redrawing the text.

  14. #14
    Member mixania's Avatar
    Join Date
    Oct 2014
    Location
    New York, NY
    Posts
    20
    Quote Originally Posted by Donziboy2 View Post
    Its in microseconds not milliseconds. It ranges from around 10uS to about 15-20mS depending on what is getting updated. Had a few discussions on the Highly-optimized-ILI9341 thread about optimizing redraws on the screen.
    Thanks for the info, it is definitely intriguing.

  15. #15
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    Quote Originally Posted by PaulStoffregen View Post
    Wow, I think 6 Mbits/sec is probably the fastest anyone's ever reported running hardware serial.

    I know I've only tested up to 1 Mbit/sec.
    I have found one issue so far and that is a pause between transmitting bytes that is roughly 2.4uS(longer then it takes to actually transmit the byte). Is there a way to reduce this dead time?

    edit....
    Yay it gets stranger, I went ahead and took it down to 3Mhz and now its transmitting without pauses and its taking less time then 6Mhz...
    Went from 63uS for 17 Bytes @ 6Mhz to 49uS to transmit the same 17 Bytes at 3Mhz.
    Last edited by Donziboy2; 04-22-2015 at 11:02 AM.

  16. #16
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    6,784
    Post below that may relate to post #15 dead time - where KurtE observed and got a fix in 1.29 for T_2 - the T_3 code seems to do the same::

    Teensy 2 - Hardware Serial: Serial1.write() not as fast as Arduino code base...

    Quote Originally Posted by KurtE View Post
    ...
    So I took a look at: size_t HardwareSerial::write(uint8_t c)
    in HardwareSerial.cpp and noticed the speed hack added to arduino in about 1.5.3 was not added here. The hack was when you call this function, if the queue is empty and the data register is empty, simply stuff it into the data register without adding it to queue and relying on interrupt handler. I found that this helped a lot at fast baud rates.

  17. #17
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany NRW
    Posts
    4,466
    Perhaps interesting to see how fast it is possible with F_BUS overclocking.. maybe more than 6MBIT..

  18. #18
    Senior Member
    Join Date
    Mar 2013
    Posts
    643
    Just an update to anyone who comes across this thread. To fix the Slower then expected 6Mhz transmits is to replace the Serial1.write(buffer[0]); with Serial1.write(buffer, n);, where n is the number of bytes in the buffer.

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    3,638
    FYI - as this was mentioned in other thread: https://forum.pjrc.com/threads/46696...895#post154895

    Thought I would mention, that I verified your speedup (on T3.2) using same program (slightly modified for 3rd case of output one byte at a time using Serial.write)...

    Code:
    void setup() {
      while (!Serial && (millis() < 2000)) ;
      Serial.println("Test Start");
      Serial1.begin(6000000);
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
    }
    
    void loop() {
      uint32_t start_time = millis();
      uint8_t data[32];
    
      for (uint8_t i = 0; i < 32; i++) {
        data[i] = i;
      }
      // We wish to output 1600 characters. 
      digitalWriteFast(2, HIGH);
      for (int i = 0; i < 50; i++) {
        digitalWriteFast(3, HIGH);
    #if 1
        // This code assumes that the serial registers are setup and TX and RX are enabled but the interrupt is not... 
        for (int j = 0; j < 32; j++) {
    #if 1
            Serial1.write(data[j]);
    #else        
            while  (!(UART0_S1 & UART_S1_TDRE)) ;   // Wait for uart1 to say it has room to put
            UART0_D = data[j];
    #endif
        }
     
    #else    
        Serial1.write(data, 32);
    #endif
        digitalWriteFast(3, LOW);
      }
      digitalWriteFast(2, LOW);
      // quick and dirty..
      delay(500-(millis()-start_time));
    }
    The time to output the 1600 characters was the same using Serial1.write(buf, cnt) and using hardware registers: 2.667ms
    The time doing one write at a time was: 6.8ms... At that speed you can not queue up enough characters to be able to fill the queue...

Posting Permissions

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