Hi everyone, I recently wanted to understand more about programming on the Arduino IDE and was wondering if there is an extra method or module I can add to my esp32 to make "stable" loops at the same frequency between loops? I realize that if I set a loop specifying whether to run it at 10 or 100hz on the serial print I see that the time interval between one print and the next is never precise, sometimes it even slows down a bit. my professor advised me to use better devices such as programming an stm32 directly, but I don't think this is the problem. advice and opinions?
What is 'precise' for you? This is a very vague term.
Without seeing your intention and attempts to fullfill them no one can tell you what the problem is.
How about posting your code so we can see what you were doing
ESP32 has both(FreeRTOS) software timers and hardware timers available.
if I talk about creating cycles without delays I think it's quite clear. I would like to understand why on Arduino ESP or similar products very often the programmed loops are not perfectly synchronous but have delays or advances. as an ignorant I wonder if there is a way to guarantee that the loop is constant.
there is no specific code, I note that when printing data on serial in general the codes are never with a constant frequency.
so it's a programming problem right? are there commands using this FreeRTOS to develop constant frequency loops?
Nothing is clear. You refuse to answer our questions. What is precise for you? 1µs? 1ms? 1s? Absolutely precise is impossible - its always a matter how close you look.
And of course the programming has a great influence. So give an example or you will never get a reasonable answer.
Never will be constant. Serial communications are asynchronous (meanaing NOT fixed in frequency)
Why do you need exact intervals in the Serial?
For accurate pulse generation, use hardware timers. But this has nothing to do with RTOS
On regular microcontrollers, interrupts (e.g. I2C, timers) get priority and delay other code execution. On more advanced platforms like ESP32, there's an actual operating system that can do the same, prioritizing other tasks.
Sounds like what you may be interested in is 'real time computing'. As said by @gfvalvo on an ESP platform you could use timers or RTOS scheduled tasks. On smaller microcontrollers, you can use general purpose timers for much the same thing.
on my loop
// Creazione della stringa con i dati dei sensori
sensorData = "&, ";
sensorData += String(roll) + "," + String(pitch) + "," + String(yaw) + ",";
sensorData += String(roll_d) + "," + String(pitch_d) + "," + String(yaw_d) + ",";
sensorData += String(temperature) + "," + String(pressure) + "," + String(humidity) + "," + String(altitude) + ",";
sensorData += String(year) + "," + String(month) + "," + String(day) + "," + String(hour) + "," + String(minute) + "," + String(second) + ",";
sensorData += String(lat) + "," + String(lng) + "," + String(alt) + "," + String(speed) + ",";
sensorData += String(busvoltage) + "," + String(shuntvoltage) + "," + String(loadvoltage) + "," + String(current_mA) + "," + String(power_mW) + ", §";
// Stampa dei dati dei sensori
Serial.println(sensorData);
File log = SD.open("/datalog.txt", FILE_APPEND);
log.println(sensorData);
log.close();
on serial monitor:
17:29:37.885 -> &, 0.00,-179.31,188.81,0.25,-0.13,-0.06,28.16,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
17:29:37.932 -> &, 0.00,-179.31,188.81,0.06,0.06,0.00,28.16,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
17:29:37.977 -> &, 0.00,-179.31,188.81,-0.06,-0.06,0.06,28.16,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
17:29:38.018 -> &, 0.00,-179.31,188.81,-0.06,-0.19,0.06,28.11,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
17:29:38.018 -> &, 0.00,-179.31,188.81,0.13,0.06,-0.06,28.11,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
17:29:38.101 -> &, 0.00,-179.31,188.81,0.06,0.06,-0.06,28.11,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
17:29:38.147 -> &, 0.00,-179.31,188.81,-0.13,-0.13,0.19,28.11,1006.62,38.61,55.18,2000,0,0,0,0,0,0.00,0.00,0.00,0.00,5.19,0.00,5.19,-0.10,0.00, §
See post #9
I don't see any loop here. And I don't see any attempt to do anything at regular intervals.
is that the timer reported by the serial monitor or the actual time on the esp32?
how long does it take to send a print? 1 msec/char at 9600 bps
can you do everything needed within 100 msec (10Hz) or 10 msec (100 Hz)?
something like this should be precise
const unsigned long MsecPeriod = 100;
unsigned long msecLst;
void
loop (void)
{
unsigned long msec = millis ();
if (msec - msecLst >= MsecPeriod) {
msecLst += MsecPeriod;
Serial.println (msec);
}
}
void
setup (void)
{
Serial.begin (115200);
}
Good question. One normally wants to do "something" of value on a periodic basis ... even if it's just blinking an LED. Printing to serial periodically doesn't seem to provide much value.
It depends on the precision / accuracy required. FreeRTOS provides easy to use software timers to call registered callback functions from a high-priority task. It will probably provide better control than a vTaskdelay()
statement, but not as good as a hardware timer (which might be more difficult to use). Like everything in engineering ... you must consider the requirements and the tradeoffs. @andreaarcarisi's pseudo-requirement of "stable" is useless, it provides zero information.
What @andreaarcarisi is obviously not willing to tell us...
Looks like a symptom of serial buffering, as per #9. Especially with there being zero ms between these two lines:
131*7=917 chars in 38.147-37.885=0.262s is 3500 char/sec.
Everybody is trying to solve a problem that isn't a problem. It's just the way async communications work