Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Least possible scheduling time #163

Open
siddarth-murugesan opened this issue Apr 19, 2023 · 9 comments
Open

Least possible scheduling time #163

siddarth-murugesan opened this issue Apr 19, 2023 · 9 comments

Comments

@siddarth-murugesan
Copy link

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
Copy link
Owner

arkhipenko commented Apr 19, 2023 via email

@siddarth-murugesan
Copy link
Author

siddarth-murugesan commented Apr 20, 2023

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 <ArduinoBLE.h>
#include "LSM6DS3.h"
#include "MAX30105.h"
#include "Wire.h"
#include <TaskScheduler.h>

//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
Copy link

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
Copy link

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
Copy link

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
Copy link
Owner

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
Copy link

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
Copy link

RandoSY commented Jun 26, 2023

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

@RandoSY
Copy link

RandoSY commented Jun 26, 2023

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!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants