Bonjour à tous,
Je voudrais mesurer la période de 2 signaux provenant de capteurs RPM.
Signal d'entrée 3.3v 50%dty, varie entre 0 et 1khz en fonction de la vitesse.
J'utilise pour les simulation un générateur de fréquence.
Je voudrais ensuite générer un signal similaire mais avec une période différente (+20%) de manière à diminuer la fréquence.
Voici ci-dessous une ébauche de code: (Code simplifié pour 1 seul capteur)
// Define pins
const int sensorPin1 = 4; // GPIO pin for the first sensor
const int outputPin1 = 5; // Output GPIO pin for the first modified signal
// Timing variables for sensor 1
volatile unsigned long lastRise1 = 0;
volatile unsigned long lastFall1 = 0;
volatile unsigned long lastPeriod1 = 0;
volatile unsigned long modifiedPeriod1 = 0;
volatile unsigned long lastSignalTime1 = 0;
volatile bool updateRequired1 = false;
// Timing variables for sensor 2
volatile unsigned long lastRise2 = 0;
volatile unsigned long lastFall2 = 0;
volatile unsigned long lastPeriod2 = 0;
volatile unsigned long modifiedPeriod2 = 0;
volatile unsigned long lastSignalTime2 = 0;
volatile bool updateRequired2 = false;
// nterrupt Service Routines
// These routines only update timing info and debug counters.
void IRAM_ATTR onChange1() {
unsigned long currentTime = micros();
if (digitalRead(sensorPin1) == HIGH) {
if (lastFall1 != 0) {
lastPeriod1 = 2 * (currentTime - lastFall1);
lastSignalTime1 = millis();
updateRequired1 = true;
}
lastRise1 = currentTime;
} else {
lastFall1 = currentTime;
}
}
// Output Generation Function
void generateOutput(int pin, unsigned long period) {
if (period > 0) {
unsigned long halfPeriod = period / 2;
digitalWrite(pin, HIGH);
delayMicroseconds(halfPeriod);
digitalWrite(pin, LOW);
delayMicroseconds(halfPeriod);
} else {
digitalWrite(pin, LOW);
}
}
// Task to generate output signals
void outputTask(void *parameter) {
while (true) {
if (updateRequired1) {
modifiedPeriod1 = lastPeriod1 * 1.2; // adjust period as needed
updateRequired1 = false;
}
if (updateRequired2) {
modifiedPeriod2 = lastPeriod2 * 1.2;
updateRequired2 = false;
}
// If no signal has been detected recently, clear the modified period.
if (millis() - lastSignalTime1 > 2 * lastPeriod1 / 1000) {
modifiedPeriod1 = 0;
}
if (millis() - lastSignalTime2 > 2 * lastPeriod2 / 1000) {
modifiedPeriod2 = 0;
}
generateOutput(outputPin1, modifiedPeriod1);
}
}
//Setup
void setup() {
// Initialize Serial for debug output
Serial.begin(115200);
// (Optional) Wait for Serial to connect (useful on some boards)
while (!Serial) {
; // wait for serial port to connect.
}
pinMode(sensorPin1, INPUT);
pinMode(outputPin1, OUTPUT);
// Attach interrupts for both rising and falling edges.
attachInterrupt(digitalPinToInterrupt(sensorPin1), onChange1, CHANGE);
// Create tasks:
// outputTask runs on core 0 to generate the output signal.
xTaskCreatePinnedToCore(outputTask, "OutputTask", 1000, NULL, 1, NULL, 0);
// debugTask runs on core 1 to print debug information.
}
// Main loop
void loop() {
}
Le problème est que:
Le code fonctionne, mais redémarre toutes les 5 secondes. (pendant un court instant, le signal passe à l'état bas et est faussé).
09:16:23.888 -> E (10109) task_wdt: Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:
09:16:23.921 -> E (10109) task_wdt: - IDLE0 (CPU 0)
09:16:23.921 -> E (10109) task_wdt: Tasks currently running:
09:16:23.921 -> E (10109) task_wdt: CPU 0: OutputTask
09:16:23.921 -> E (10109) task_wdt: CPU 1: loopTask
09:16:23.921 -> E (10109) task_wdt: Aborting.
09:16:23.921 -> E (10109) task_wdt: Print CPU 0 (current core) backtrace
Si j'ajoute la ligne ci-dessous dans la fonction "outputtask", le programme ne redémarre plus, mais mon signal est forcément faux. je n'ai plus un pwm de 50%
Donc dans mon cas, cette solution n'est pas bonne. J'ai besoin du temps réel.
vTaskDelay(1); // Delay of 1 tick (usually 1 ms)
Il s'agit de mon premier programme sur ESP32, avec FREETOS et utilisation de plusieurs coeurs.
D'avance, merci pour votre aide.