Teensy Hardware Serial delay

Status
Not open for further replies.

Bionicman

Member
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:
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 ?
 
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: code.PNG
 
True, but that was used in the OP sketch, and then there is the question of serial speed for the BT module.
 
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:
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.
 
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.
 
Status
Not open for further replies.
Back
Top