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

Thread: How to set up sample rate 250Hz in teensy 3.6

  1. #1

    How to set up sample rate 250Hz in teensy 3.6

    I am using teensy 3.6 for the first time and I want to setup sample rate 250 Hz in teensy. Please help me with the sample code.

    int sensorPin = A0;
    int sensorValue = 0;
    float voltage = 0.0;
    char incomingByte;
    String stringSend = ' ';
    boolean STAT = false;
    boolean STAT1 = false;
    ADC adc;
    void setup() {
    Serial1.begin(9600);
    analogReadResolution(12);
    while (!Serial1) {
    ; // wait for serial port to connect. Needed for native USB port only
    }
    pinMode(sensorPin, INPUT);
    }

    void loop() {
    if (Serial1.available() > 0) { // if the data came
    incomingByte = Serial1.read();
    Serial.println(incomingByte);
    if(incomingByte == '0') {
    STAT = true;
    }
    else if(incomingByte == '1'){
    STAT = false;
    stringSend = '#';
    Serial1.print(stringSend);
    delay(100);
    }
    else{

    }
    }
    if(STAT)SendData();
    }
    void SendData(){
    sensorValue = analogRead(sensorPin);
    voltage = sensorValue * (5.0 / 4095.0);
    //Serial.println(voltage);
    stringSend = (String)voltage + ',';
    Serial1.print(stringSend);
    delay(100);
    }
    void SendLast(){
    stringSend = '#';
    Serial1.print(stringSend);
    delay(100);
    }
    This is my code

  2. #2
    Junior Member
    Join Date
    May 2018
    Location
    Brazil
    Posts
    7
    Hello.

    There are some things in your code I don't understand. Have you tried compiling it? When I do it returns an error because you are using and ADC object without including the corresponding library.
    Anyway, by looking at your code it seems you don't really use the ADC object, so you can simply delete the line "ADC adc;"

    The SendLast() function is also never used.

    But returning to your question. I think the easiest way to set a fixed sampling rate is to use a IntervalTimer object.

    An example:

    Create a global IntervalTimer object: IntervalTimer myTimer;
    Create a sampling function to be called 250 times per second (250 Hz): void sampleSensor() { sensorValue = analogRead(sensorPin); }
    In your setup, begin calling the function: myTimer.begin(sampleSensor, 4000); // sampleSensor will be called every 4000 microseconds (or, 250 times per second)

  3. #3
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,932
    You do not need the while statment at
    while (!Serial1) {
    just Serial.Begin

    You also have potential trouble with
    sensorValue * (5.0 / 4095.0)
    since the Teensy will be working with a 3.3V reference - depends on what the actual math you need but that looks like something from a classic 5V Arduino

    Also when posting code, if you use code tags it formats better, most easily done pressing the button with # on it in the edit box

    From the looks of it you will be capturing at 250hz, but the actual print 'senddata' block has a delay 100 in it so you will only get printed data at 10hz. If you want 250 prints a second better method would be to set a flag in sampleSensor, and print when that flag is set, then clear the flag. This will push the USB interface pretty hard and will probably cause missed mesaages and other problems, better solution would be to write into a buffer and send the buffer contents every second or so. More complex ways to do it, but having an even and odd buffer is probably the easiest way to avoid problems where the read out collides with the write.

    A lot depends on why you need values at 250hz - if you can preprocess them in sampleSensor a lot of data rate problems go away.

  4. #4
    Thanks for your response. If you kindly send me the sample code using buffer for 250Hz sample rate.

  5. #5
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,961
    Not sure why the prior post was deleted?

    ... based on this note in prior post
    A lot depends on why you need values at 250hz - if you can preprocess them in sampleSensor a lot of data rate problems go away.
    That suggests there isn't enough info to understand what the desired end solution would be.

    Members of the forum typically help solve the problem - not just provide a solution. That prior post offers some valuable suggestions - if they were to be followed a solution would be closer and posting that code would allow learning in the process.

  6. #6
    Quote Originally Posted by defragster View Post
    Not sure why the prior post was deleted?

    ... based on this note in prior post


    That suggests there isn't enough info to understand what the desired end solution would be.

    Members of the forum typically help solve the problem - not just provide a solution. That prior post offers some valuable suggestions - if they were to be followed a solution would be closer and posting that code would allow learning in the process.
    I am really sorry, I don't know how it got deleted. After Siridakis suggestion I wrote the below code:
    Code:
    int sensorPin = A0;
    int sensorValue = 0;
    float voltage = 0.0;
    char incomingByte;
    String stringSend = ' ';
    boolean STAT = false;
    boolean STAT1 = false;
    IntervalTimer myTimer;
    void setup() {
    Serial1.begin(9600);
    analogReadResolution(12);
    while (!Serial1) { 
    ; // wait for serial port to connect. Needed for native USB port only 
    }
    pinMode(sensorPin, INPUT);
    myTimer.begin(sampleSensor, 4000);
    }
    
    void loop() {
    if (Serial1.available() > 0) { // if the data came
    incomingByte = Serial1.read();
    Serial.println(incomingByte);
    if(incomingByte == '0') {
    STAT = true;
    }
    else if(incomingByte == '1'){
    STAT = false;
    stringSend = '#';
    Serial1.print(stringSend);
    delay(100);
    }
    else{
    
    }
    }
    if(STAT)SendData();
    }
    void SendData(){
    //sensorValue = analogRead(sensorPin);
    voltage = sensorValue * (5.0 / 4095.0);
    //Serial.println(voltage);
    stringSend = (String)voltage + ',';
    Serial1.print(stringSend);
    delay(100);
    }
    void sampleSensor() {
    	sensorValue = analogRead(sensorPin);
    }
    Then I got Gremlin's post and I made below modifications:
    Code:
    int sensorPin = A0;
    int sensorValue = 0;
    float voltage = 0.0;
    char incomingByte;
    String stringSend = ' ';
    boolean STAT = false;
    boolean STAT1 = false;
    boolean timer = false;
    IntervalTimer myTimer;
    void setup() {
    Serial1.begin(9600);
    analogReadResolution(12);
    pinMode(sensorPin, INPUT);
    myTimer.begin(sampleSensor, 4000);
    }
    
    void loop() {
    if (Serial1.available() > 0) { // if the data came
    incomingByte = Serial1.read();
    Serial.println(incomingByte);
    if(incomingByte == '0') {
    STAT = true;
    }
    else if(incomingByte == '1'){
    STAT = false;
    stringSend = '#';
    Serial1.print(stringSend);
    delay(100);
    }
    else{
    
    }
    }
    if(STAT && timer){
    	SendData();
    	timer = false;
    }
    void SendData(){
    //sensorValue = analogRead(sensorPin);
    voltage = sensorValue * (5.0 / 4095.0);
    //Serial.println(voltage);
    stringSend = (String)voltage + ',';
    Serial1.print(stringSend);
    delay(100);
    }
    void sampleSensor() {
    	sensorValue = analogRead(sensorPin);
    	timer = true;
    }
    I am using this code for Spirometry. For that reason I need to set up the sampling rate at 250 Hz. As part of spirometry differential pressure sensor output is coming in A0 pin of the Teensy.

    Please send me the buffer sample code for 250Hz.

  7. #7
    Senior Member
    Join Date
    Apr 2013
    Posts
    1,932
    You still have delay(100); in your send data block. If you get rid of that and maybe add a delay(1); at the end of void loop() to allow any background stuff to happen does this do what you need it to do?

    Buffering may not be required, depends if what you have is good enough.

  8. #8
    @Sudipto Trivedy
    Have a look to the following repo.
    https://github.com/BasicAirData/AirD.../AsgardADC.ino
    With this code, you can configure the sample rate and command your unit remotely (Protocol here https://github.com/BasicAirData/AirD...0Message%20Set).

  9. #9
    Senior Member
    Join Date
    Mar 2017
    Location
    Oakland, CA, USA
    Posts
    171
    Quote Originally Posted by GremlinWrangler View Post
    maybe add a delay(1); at the end of void loop() to allow any background stuff to happen
    Iím not sure delay(1) is needed on the Teensy. I believe the system does background things after each loop() call or in interrupts?

  10. #10
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,961
    On loop exit Teensy will 'only' check all Serial[#] devices for available and call out to serialAvailable[#]() functions with a call to yield() - that same yield() call is made from delay():
    Code:
     // from ...\hardware\teensy\avr\cores\teensy3\main.cpp
    	setup();
    	while (1) {
    		loop();
    		yield();
    	}

    So delay(100) may be extreme - delay(1) would just add some wait to prevent looping too fast if needed - that limits loop() to 1000/second - otherwise Teensy 3.6 will aim for a million or more if not doing anything.

  11. #11
    Quote Originally Posted by defragster View Post
    On loop exit Teensy will 'only' check all Serial[#] devices for available and call out to serialAvailable[#]() functions with a call to yield() - that same yield() call is made from delay():
    Code:
     // from ...\hardware\teensy\avr\cores\teensy3\main.cpp
    	setup();
    	while (1) {
    		loop();
    		yield();
    	}

    So delay(100) may be extreme - delay(1) would just add some wait to prevent looping too fast if needed - that limits loop() to 1000/second - otherwise Teensy 3.6 will aim for a million or more if not doing anything.
    Yes, a delay of 100 is pretty long.

    As the requirement is getting 250 Hz, fine-tuning is necessary. I mean it is advisable to check out what the software is doing. To do so you can add a sort of timestamp to your loop and send out a string to the USB. You need to define at least one variable to store the timestamp,for example, "unsigned long InitTime;". Then you assign to the variable the current value of timestamp in milliseconds, "InitTime = millis();" and send out the string to USB. Once you read the output you can select a more appropriate delay(delaytime). Ideally, you desire that your loop runs in 4 ms(1/250) . After your adjust the delaytime value recheck your loop time and iterate if necessary.
    "
    ...
    unsigned long InitTime;
    ..
    void loop() {

    ...
    InitTime = millis();
    ...
    -> Serial1 output to USB
    delay(delaytime);
    }
    "
    [You can also take two timestamps within the loop and send out the difference between the two values to the USB]

  12. #12
    @Sudipto Trivedy It will be interesting to know a little about the hardware, for example, the spirometer tube, used for your spirometry application. Your post disclosed to me that spirometry is a popular application (1,2) I fiddle around with an air data computer and seems fine for this application(it works! :-)). It is possible that in the future this application is added to Basic Air Data ADC.

    P.S. Interrupt based sensor reading is fine. However we moved to a simpler model to be easily integrated within third-party proejcts.

Posting Permissions

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