arkhipenko / TaskScheduler

Cooperative multitasking for Arduino, ESPx, STM32, nRF and other microcontrollers
http://playground.arduino.cc/Code/TaskScheduler
BSD 3-Clause "New" or "Revised" License
1.21k stars 221 forks source link

Least possible scheduling time #163

Open siddarth-murugesan opened 1 year ago

siddarth-murugesan commented 1 year ago

Hi, I am using this library to read IMU sensor data. I have a created task where the data is collected. It works fine when I run the task with a 1-second interval, but when I try to run it for 20ms or 50ms, it doesn't work well. I observed this using the millis() function in the task. If it is meant to be like that, what is the least possible scheduling time that a task can be assigned of ? Thanks

arkhipenko commented 1 year ago

The fastest scheduling is instant, and incrementally 1ms.

But I am sure the problem is elsewhere. Could you please send me your code at @.***? I'll have a look.

Sent from my mobile implant. Apologies for autocorrect.


From: Siddarth Chockalingam Murugesan @.> Sent: Wednesday, April 19, 2023 10:18:17 AM To: arkhipenko/TaskScheduler @.> Cc: Subscribed @.***> Subject: [arkhipenko/TaskScheduler] Least possible scheduling time (Issue #163)

Hi, I am using this library to read IMU sensor data. I have a created task where the data is collected. It works fine when I run the task with a 1-second interval, but when I try to run it for 20ms or 50ms, it doesn't work well. I observed this using the millis() function in the task. If it is meant to be like that, what is the least possible scheduling time that a task can be assigned of ? Thanks

— Reply to this email directly, view it on GitHubhttps://github.com/arkhipenko/TaskScheduler/issues/163, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AACMMTPRQQPQ56CZUFFGLCTXB7X2TANCNFSM6AAAAAAXEEWDAI. You are receiving this because you are subscribed to this thread.Message ID: @.***>

siddarth-murugesan commented 1 year ago

Thank you for your response. I have attached the code here and also have mailed you it. The created task is intended to collect IMU data for every 20 ms, running on Arduino on Xiao nrf52840 ble sense board, and send it via Bluetooth.

// Required libraries added (check readme file references for further info)

include

include "LSM6DS3.h"

include "MAX30105.h"

include "Wire.h"

include

//Create an instance of class LSM6DS3 IMU LSM6DS3 xIMU(I2C_MODE, 0x6A); //I2C device address 0x6A MAX30105 particleSensor; const int sensorPin = 0;

// UUid for Service const char* UUID_serv = "64cf715d-f89e-4ec0-b5c5-d10ad9b53bf2";

// UUid for IMU characteristics const char* UUID_imu = "64cf7161-f89e-4ec0-b5c5-d10ad9b53bf2";

// BLE Service BLEService IMUservice(UUID_serv);

// BLE Characteristics (1 time data + 6 IMU sensor data) BLECharacteristic IMUchar(UUID_imu, BLERead|BLENotify, 4*sizeof(float));

// millis return values in data type unsigned long type volatile unsigned long interrupt_time; // time inside the interrupt unsigned long main_time; // time in the main func (void loop) char interrupt_flag; // Interrupt flag float acc_x, acc_y, acc_z, gyro_x, gyro_y, gyro_z; // IMU sensor value variables unsigned int ppg_sensor; int sensorValue;

void imu_read_func(); Scheduler runner; Task imu_task(20, TASK_FOREVER, &imu_read_func);

void imu_read_func() { main_time = millis(); acc_x = xIMU.readFloatAccelX(); acc_y = xIMU.readFloatAccelY(); acc_z = xIMU.readFloatAccelZ(); float data[4] = {main_time, acc_x, acc_y, acc_z}; IMUchar.writeValue(data, sizeof(data)); }

void setup() { Serial.begin(115200); while (!Serial); Serial.println("Seeed XIAO BLE Sense IMU Data Logger"); bool err=false;

pinMode(LEDR, OUTPUT); // onboard led red pinMode(LEDB, OUTPUT); // onboard led blue digitalWrite(LEDR, HIGH); // led red off digitalWrite(LEDB, HIGH); // led blue off

// init IMU if (xIMU.begin() != 0) { Serial.println("Device error"); err = true; } else { Serial.println("IMU sensor OK!"); }

// Initialize ppg sensor

if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed { Serial.println("MAX30105 was not found. Please check wiring/power. "); err = true; } else { Serial.println("PPG sensor OK!"); }

pinMode(sensorPin, INPUT);

// init BLE

if (!BLE.begin()) { Serial.println("BLE: failed"); err=true; } else { Serial.println("BLE: ok"); }

// error: flash led forever if (err) { Serial.println("Init error. System halted"); while(1) { digitalWrite(LEDR, LOW); delay(500); digitalWrite(LEDR, HIGH); // led on delay(500);

}

}

//ppg sensor setup particleSensor.setup(); //Configure sensor with these settings

// Set BLE name BLE.setLocalName("IMU DataLogger"); BLE.setDeviceName("XIAO-BLE-Sense");

// Set advertised Service BLE.setAdvertisedService(IMUservice);

// Add characteristics to the Service IMUservice.addCharacteristic(IMUchar);

// add service to BLE BLE.addService(IMUservice);

// start advertising BLE.advertise(); Serial.println("Advertising started"); Serial.println("Bluetooth device active, waiting for connections...");

runner.addTask(imu_task); imu_task.enable(); }

void loop() { BLEDevice central = BLE.central();

// central device connected if (central) { digitalWrite(LEDB, LOW); // turn on the blue led Serial.print("Connected to central: "); Serial.println(central.address()); // central device MAC address

while (central.connected()) 
{
    runner.execute();
}

// central disconnected blue LED off
digitalWrite(LEDB, HIGH);
Serial.print("Disconnected from central: ");
Serial.println(central.address());

}

}

sseodate commented 1 year ago

you guys should check for this

define _TASK_MICRO_RES in my project of led increment light , split into micro second will make the led light goes up smoothly

liduwang0 commented 1 year ago

I am using nrf 52832. I also have this problem. i tested 80ms, I used mills(), no problems. i tested 50ms, the result is 40 ms. and I test 20 ms or other lower like 10ms, 5ms. the result is always 14ms.

liduwang0 commented 1 year ago

I tested example 13 Micros, the result is t1: 5006103 t1: 5007568 t1: 5009521 t1: 5012207 t1: 5016601 t1: 5024414 t1: 5039062 t1: 5067138 t1: 5122314 t1: 5231445 t1: 5448486 t1: 5881591 t1: 6746826 t1: 8476318 t2: 10004150 heartbeat

the first interval is also 14 ms,second is 20ms. it is weird.

arkhipenko commented 1 year ago

First, you should not do this in the loop:

while (central.connected()) 
{
    runner.execute();
}

this is blocking, and the framework does other things outside of the loop() which are now blocked.

Second:

void imu_read_func()
{
main_time = millis();
acc_x = xIMU.readFloatAccelX();
acc_y = xIMU.readFloatAccelY();
acc_z = xIMU.readFloatAccelZ();
float data[4] = {main_time, acc_x, acc_y, acc_z};
IMUchar.writeValue(data, sizeof(data));
}

This is a very expensive method - 3 reads of the Float value with I2C and a write to a BLE stack. How long does this method take standalone? It could very well be a few ms: I2C + you need to give BLE stack time to send your data.

Can you run this method 1000 times wrapped with two millis() calls before and after?

liduwang0 commented 1 year ago

I am using nrf 52832. I also have this problem. i tested 80ms, I used mills(), no problems. i tested 50ms, the result is 40 ms. and I test 20 ms or other lower like 10ms, 5ms. the result is always 14ms.

my problem is solved, UART costs so much time. when I remove all the print function. 1ms works well for me now.

RandoSY commented 1 year ago

Thanks you for posting this, helps me a tonne! :)

RandoSY commented 1 year ago

I am struggling to get this to wonderful BLE example to build, any advice on your setup? I am at latest Arduino IDE, and I've tried Platform.io as well. I think it might be very sensitive to exactly which version everything is?

Thank you!!!