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

Thread: Teensy Hardware Serial delay

  1. #1
    Junior Member
    Join Date
    Sep 2015
    Location
    UK
    Posts
    5

    Teensy Hardware Serial delay

    Dear all,
    I am trying to transfer analog data from 72 photodiodes as quick as possible through BT (HC06 - HC05). It would be ideal to have a sampling frequency of 200Hz. Tested the code below with direct USB and had excellent sampling rates (about 1300 x 72 samples). But when I try to do the same using The Hardware Serial port 1 of Teensy 3.1 , there is a delay of nearly 300ms after every 80 x 72 samples (nearly 12000 bytes including the header and the footer). It will be great if someone can help me with this.
    Thanks!
    Code:
    #include <ADC.h>
    
    int sensVal;           // for raw sensor values 
    float filterVal;       // this determines smoothness  - .0001 is max  1 is off (no smoothing)
    float smoothedVal;     // this holds the last loop value just use a unique variable for every different sensor that needs smoothing
    
    uint8_t tP[150] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,  0,0,   0x00, 0x00, '\r', '\n' };
       
        int pinCount = 8;
        int k = 0;
     int digPins[] = { 9, 8, 7, 6, 5, 4, 3 , 2};// 8 digital pins
       //2, 3 , 4, 5, 6, 7, 8, 9 }; // 8 digital pins
    const int a0 = A0;
    const int a1 = A1;
    const int a2 = A2;
    const int a3 = A3;
    const int a4 = A4;
    const int a5 = A5;
    const int a6 = A6;
    const int a7 = A7;
    const int a8 = A8;// 9 analog pins
    
    int r[9] = {0,0,0,0,0,0,0,0,0}; 
            //    0,1,2,3,4,5,6,7,8
    elapsedMicros time;
    
    ADC *adc = new ADC(); // adc object
    
    void setup() {
      
      // put your setup code here, to run once:
      pinMode(a0, INPUT);
     pinMode(a1, INPUT);
     pinMode(a2, INPUT);
     pinMode(a3, INPUT);
     pinMode(a4, INPUT);
     pinMode(a5, INPUT);
     pinMode(a6, INPUT);
     pinMode(a7, INPUT);
     pinMode(a8, INPUT);
    
     pinMode(2, OUTPUT);
     pinMode(3, OUTPUT);
     pinMode(4, OUTPUT);
     pinMode(5, OUTPUT);
     pinMode(6, OUTPUT);
     pinMode(7, OUTPUT);
     pinMode(8, OUTPUT);
     pinMode(9, OUTPUT);
     Serial1.begin(115200);
           #if defined(ADC_TEENSY_3_1)
          //analogReference(EXTERNAL);
        adc->setAveraging(2, ADC_0); // set number of averages
        adc->setResolution(14, ADC_0); // set bits of resolution
        adc->setConversionSpeed(ADC_HIGH_SPEED, ADC_0); // change the conversion speed
        adc->setSamplingSpeed(ADC_HIGH_SPEED, ADC_0); // change the sampling speed
     adc->setAveraging(2, ADC_1); // set number of averages
        adc->setResolution(14, ADC_1); // set bits of resolution
        adc->setConversionSpeed(ADC_HIGH_SPEED, ADC_1); // change the conversion speed
        adc->setSamplingSpeed(ADC_HIGH_SPEED, ADC_1); // change the sampling speed
    
        // always call the compare functions after changing the resolution!
        //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_1), 0, ADC_1); // measurement will be ready if value < 1.0V
        //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [1.0,2.0] V
        #endif
    }
    
    void loop() {
    
      {
       for (int thisPin = 0; thisPin < pinCount; thisPin++) { 
        // turn the pin on:
        digitalWriteFast(digPins[thisPin], HIGH);   
       
      r[0] = adc->analogRead(a0); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    // Serial1.print("s1 ");
     tP[2+k*18] =(r[0]>> 8) & 0xff;
      tP[2+k*18+1] = r[0] & 0xff;
     r[1] = adc->analogRead(a1); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
      tP[2+k*18+2] =(r[1]>> 8) & 0xff;
      tP[2+k*18+3] = r[1] & 0xff;
     r[2] = adc->analogRead(a2); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
      tP[2+k*18+4] =(r[2]>> 8) & 0xff;
      tP[2+k*18+5] = r[2] & 0xff;
     r[3] = adc->analogRead(a3); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
      tP[2+k*18+6] =(r[3]>> 8) & 0xff;
      tP[2+k*18+7] = r[3] & 0xff;
     r[4] = adc->analogRead(a4); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
      tP[2+k*18+8] =(r[4]>> 8) & 0xff;
      tP[2+k*18+9] = r[4] & 0xff;
     r[5] = adc->analogRead(a5); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+10] =(r[5]>> 8) & 0xff;
      tP[2+k*18+11] = r[5] & 0xff;
     r[6] = adc->analogRead(a6); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
      tP[2+k*18+12] =(r[6]>> 8) & 0xff;
      tP[2+k*18+13] = r[6] & 0xff;
     r[7] = adc->analogRead(a7); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+14] =(r[7]>> 8) & 0xff;
      tP[2+k*18+15] = r[7] & 0xff;
     r[8] = adc->analogRead(a8); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
      tP[2+k*18+16] =(r[8]>> 8) & 0xff;
      tP[2+k*18+17] = r[8] & 0xff;
    
    
      
      k++;
    // delay(1);
     digitalWriteFast(digPins[thisPin], LOW); 
      
      if (thisPin == 8) {thisPin = 0;}
    if (k==8) {k=0; 
    
    
      Serial1.write(tP, 150);
      //};
                tP[147]++; // packetCount, loops at 0xFF on purpose
    
    }
     
     
    }
    }
     }
    Last edited by Bionicman; 09-11-2015 at 09:25 PM.

  2. #2
    Senior Member
    Join Date
    Aug 2013
    Location
    Gothenburg, Sweden
    Posts
    354
    Serial BAUD rate is 115200 that gives at most 11520 Bytes per second, with 150 bytes per sample of 72 photodiodes you can send at most 76 samples per second over that serial link.

    How do you measure the delay of 300mS ?

  3. #3
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    13,474
    What is limiting the Serial speed to 115k? I've had Teensy 3.1 to 3.1 work reliably at 921,600bps. USB is capable of much more which is why you are not seeing any trouble.
    When posting code wrap it like this for readability:Name:  code.PNG
Views: 247
Size:  1.7 KB

  4. #4
    Senior Member
    Join Date
    Aug 2013
    Location
    Gothenburg, Sweden
    Posts
    354
    True, but that was used in the OP sketch, and then there is the question of serial speed for the BT module.

  5. #5
    Junior Member
    Join Date
    Sep 2015
    Location
    UK
    Posts
    5
    Quote Originally Posted by mlu View Post
    Serial BAUD rate is 115200 that gives at most 11520 Bytes per second, with 150 bytes per sample of 72 photodiodes you can send at most 76 samples per second over that serial link.

    How do you measure the delay of 300mS ?
    Hi mlu,
    Thanks for the reply. The 300ms delay is after the 76 to 78 set of samples that get sent. After this delay the samples get done at about 28 mS intervals and the 300mS delay repeats itself. The baud rate is a limiting factor as you have rightly pointed out as the BT module is not doing more than 115200 maximum. Sorry about posting the code straight. Im reattaching it below:
    Code:
    #include <ADC.h>
    
    int sensVal; // for raw sensor values 
    float filterVal; // this determines smoothness - .0001 is max 1 is off (no smoothing)
    float smoothedVal; // this holds the last loop value just use a unique variable for every different sensor that needs smoothing
    
    uint8_t tP[150] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
    
    int pinCount = 8;
    int k = 0;
    int digPins[] = { 9, 8, 7, 6, 5, 4, 3 , 2};// 8 digital pins
    //2, 3 , 4, 5, 6, 7, 8, 9 }; // 8 digital pins
    const int a0 = A0;
    const int a1 = A1;
    const int a2 = A2;
    const int a3 = A3;
    const int a4 = A4;
    const int a5 = A5;
    const int a6 = A6;
    const int a7 = A7;
    const int a8 = A8;// 9 analog pins
    
    int r[9] = {0,0,0,0,0,0,0,0,0}; 
    // 0,1,2,3,4,5,6,7,8
    elapsedMicros time;
    
    ADC *adc = new ADC(); // adc object
    
    void setup() {
    
    // put your setup code here, to run once:
    pinMode(a0, INPUT);
    pinMode(a1, INPUT);
    pinMode(a2, INPUT);
    pinMode(a3, INPUT);
    pinMode(a4, INPUT);
    pinMode(a5, INPUT);
    pinMode(a6, INPUT);
    pinMode(a7, INPUT);
    pinMode(a8, INPUT);
    
    pinMode(2, OUTPUT);
    pinMode(3, OUTPUT);
    pinMode(4, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(6, OUTPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    Serial1.begin(115200);
    #if defined(ADC_TEENSY_3_1)
    //analogReference(EXTERNAL);
    adc->setAveraging(2, ADC_0); // set number of averages
    adc->setResolution(14, ADC_0); // set bits of resolution
    adc->setConversionSpeed(ADC_HIGH_SPEED, ADC_0); // change the conversion speed
    adc->setSamplingSpeed(ADC_HIGH_SPEED, ADC_0); // change the sampling speed
    adc->setAveraging(2, ADC_1); // set number of averages
    adc->setResolution(14, ADC_1); // set bits of resolution
    adc->setConversionSpeed(ADC_HIGH_SPEED, ADC_1); // change the conversion speed
    adc->setSamplingSpeed(ADC_HIGH_SPEED, ADC_1); // change the sampling speed
    
    // always call the compare functions after changing the resolution!
    //adc->enableCompare(1.0/3.3*adc->getMaxValue(ADC_1), 0, ADC_1); // measurement will be ready if value < 1.0V
    //adc->enableCompareRange(1.0*adc->getMaxValue(ADC_1)/3.3, 2.0*adc->getMaxValue(ADC_1)/3.3, 0, 1, ADC_1); // ready if value lies out of [1.0,2.0] V
    #endif
    }
    
    void loop() {
    
    {
    for (int thisPin = 0; thisPin < pinCount; thisPin++) { 
    // turn the pin on:
    digitalWriteFast(digPins[thisPin], HIGH); 
    
    r[0] = adc->analogRead(a0); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    // Serial1.print("s1 ");
    tP[2+k*18] =(r[0]>> 8) & 0xff;
    tP[2+k*18+1] = r[0] & 0xff;
    r[1] = adc->analogRead(a1); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+2] =(r[1]>> 8) & 0xff;
    tP[2+k*18+3] = r[1] & 0xff;
    r[2] = adc->analogRead(a2); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+4] =(r[2]>> 8) & 0xff;
    tP[2+k*18+5] = r[2] & 0xff;
    r[3] = adc->analogRead(a3); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+6] =(r[3]>> 8) & 0xff;
    tP[2+k*18+7] = r[3] & 0xff;
    r[4] = adc->analogRead(a4); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+8] =(r[4]>> 8) & 0xff;
    tP[2+k*18+9] = r[4] & 0xff;
    r[5] = adc->analogRead(a5); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+10] =(r[5]>> 8) & 0xff;
    tP[2+k*18+11] = r[5] & 0xff;
    r[6] = adc->analogRead(a6); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+12] =(r[6]>> 8) & 0xff;
    tP[2+k*18+13] = r[6] & 0xff;
    r[7] = adc->analogRead(a7); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+14] =(r[7]>> 8) & 0xff;
    tP[2+k*18+15] = r[7] & 0xff;
    r[8] = adc->analogRead(a8); // read a new value, will return ADC_ERROR_VALUE if the comparison is false.
    tP[2+k*18+16] =(r[8]>> 8) & 0xff;
    tP[2+k*18+17] = r[8] & 0xff;
    
    
    
    k++;
    // delay(1);
    digitalWriteFast(digPins[thisPin], LOW); 
    
    if (thisPin == 8) {thisPin = 0;}
    if (k==8) {k=0; 
    
    
    Serial1.write(tP, 150);
    //};
    tP[147]++; // packetCount, loops at 0xFF on purpose
    
    }
    
    
    }
    }
    }
    Last edited by Bionicman; 09-11-2015 at 08:44 PM.

  6. #6
    Junior Member
    Join Date
    Sep 2015
    Location
    UK
    Posts
    5
    I have tried increasing the serial transmit buffer size to 150. No gain. It will be a great help if some one can help with this issue. Im sure others with similar problem trying to multiplex sensors will find it useful.

  7. #7
    Junior Member
    Join Date
    Sep 2015
    Location
    UK
    Posts
    5
    Teensy LC arrived. Not having the same problem with LC. The code works perfect on LC. Not sure why. However I manage to solve the issue on teensy 3.1 with a 20mS delay in the program. Which also does reduce the sampling rate to 43 samples per second of 150 byte data.

Posting Permissions

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