ESP32 Timer Interrupt (parallel)

Hallo zusammen,

Gibt es eine library für einen Timer der eine Funktion in vorgegebenen Intervallen durchführt?

Ich habe zwar diese Vorlage gefunden:

volatile int interruptCounter;
int totalInterruptCounter;
 
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
 
void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);
  interruptCounter++;
  portEXIT_CRITICAL_ISR(&timerMux);
 
}
 
void setup() {
 
  Serial.begin(115200);
 
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 100000, true);
  timerAlarmEnable(timer);
 
}
 
void loop() {
 
  if (interruptCounter > 0) {
 
    portENTER_CRITICAL(&timerMux);
    interruptCounter--;
    portEXIT_CRITICAL(&timerMux);
 
    totalInterruptCounter++;
 
    Serial.print("An interrupt as occurred. Total number: ");
    Serial.println(totalInterruptCounter);
 
  }
  //delay(10000);
  //timerAlarmDisable(timer);
  //timerDetachInterrupt(timer);
  //timerEnd(timer);
  //timer = NULL;
}

Aber diese fragt ja wieder im loop den aktuellen Status des Zählers ab.
Wenn ich also Funktionen im loop habe, die länger andauern als der Interrupt, funktioniert das nicht.

Ich könnte diese Funktion im 2. Kern des ESP32 ausführen, was aber auch nicht zielführend ist, wenn ich noch weitere Funktionen am 2. Kern laufen lassen möchte.

Ziel ist es, Datenpunkte in 10ms abständen ablegen zu können.
Es gibt dann noch einige Funktionen im Programm die in längeren Zeitabständen durchgeführt werden aber einige 10-100ms dauern.

Gibt es hierzu andere Lösungsansätze außer einen schnelleren Prozessor :slight_smile: ?

Danke!

patrick_bit4bit:
Ziel ist es, Datenpunkte in 10ms abständen ablegen zu können.

Wegen der bislang "enormen" Resonanz mal drei Ideen von mir:

  • Das schweizer Messer für Arduinos, die MobaTools, funktionieren auch für den ESP8266, leider aber nicht für den ESP32. "Mit der Klasse MoToTicker lassen sich Aktionen in regelmäßigen Abständen auslösen." Ich habe keinerlei Vorstellung, wie anspruchsvoll eine Erweiterung für den EDP32 ist, aber mit Hilfe des Autors könnte es eventuell machbar sein.
  • Interrupts werden benötigt, um kurze Ereignisse an einem Eingang nicht zu verpassen. Sonst werden sie hier im Forum meist nachgefragt, um eine schlechte, weil blockierende Programmierung zu übertünchen. Ich stelle mal die These auf, das ist bei Dir nicht anders. Da ich Dein Programm nicht kenne, ist das natürlich spekulativ. Mit einem kurzen Beispielprogramm kannst Du meine These gerne zerbröseln lassen.
  • Noch nicht benötigt habe ich ESP32TimerInterrupt

Zu deiner These:

Gut möglich, oder besser gesagt mit Sicherheit lässt mein Code optimierungen der Performance und Datenreduktion zu, jedoch sehe ich die Notwendigkeit von einem Interrupt nicht aufgrund der Code-Gestaltung.

Ablauf des Programms:
Der ESP nimmt alle 10ms Sensordaten auf und speichert diese in einem Buffervector zwischen.
Ist der Speicher voll, oder der ESP "hat gerade Zeit" werden die Daten gesammelt in die SQL an der SD abgelegt.
Das Ablegen dauert rund ca 200ms.
Parallel sollte noch ein Webserver incl Websocket Kommunikation laufen, der die Daten in der 2ten SQL Verbindung lest und an den Javascript Websocket weitergibt.

Da die Websocket connection auch noch einige ms beansprucht würde ich das Messen, buffern und eventuell noch den Websocket auf einem Kern ausführen. Das Schreiben und Lesen auf dem 2ten Kern.

Um die Werte alle 10ms Sekunden zu bekommen hätte ich an einen Interrupt gedacht.

Ich habe mal von Mutli-THreads gelesen, jedoch noch wenig Ahnung wie das Ganze funktioniert.
Wären meherere Threads eventuell eine bessere Lösung?

patrick_bit4bit:
... Das Ablegen dauert rund ca 200ms. ...
... Websocket Kommunikation ...

Mit ESP32TimerInterrupt könntest Du probieren, ob Interrupts während dieser Aktionen überhaupt zulässig sind.

Übrigens kann man, wenn sonst keine Lösung möglich ist, Aufgaben auch auf mehrere µCs aufteilen. Das habe ich schon mal mit einem ATtiny85 und einem UNO gemacht, Datenaustausch mittels I2C.