Follow along with the video below to see how to install our site as a web app on your home screen.
Huomio: This feature may not be available in some browsers.
// ... existing code ...
// RPM Calculation variables - volatile for interrupt safety
volatile unsigned long lastFallTime = 0; // Time of last falling edge
volatile unsigned long period = 0; // Pulse period in microseconds
// ... existing setup ...
void setup() {
// ... existing setup code ...
// RPM Pin with pull-up and PCI enabled
pinMode(rpmPin, INPUT_PULLUP);
PCICR |= (1 << PCIE2); // Enable PCINT2 group
PCMSK2 |= (1 << PCINT21); // Enable interrupt for PCINT21 (pin 5)
// ... rest of setup ...
}
// Pin Change Interrupt for RPM sensor (pin 5)
ISR(PCINT2_vect) {
static unsigned long prevTime = 0;
static int prevState = HIGH;
int currentState = digitalRead(rpmPin);
if (prevState == HIGH && currentState == LOW) { // Falling edge
unsigned long currentTime = micros();
lastFallTime = currentTime;
if (prevTime != 0) {
period = currentTime - prevTime;
}
prevTime = currentTime;
}
prevState = currentState;
}
void loop() {
// ... existing sensor readings ...
// New RPM Calculation (atomic read + timeout handling)
unsigned long now = micros();
unsigned long temp_lastFallTime;
unsigned long temp_period;
// Atomic read of volatile variables
noInterrupts();
temp_lastFallTime = lastFallTime;
temp_period = period;
interrupts();
if (temp_lastFallTime == 0) {
rpm = 0; // No pulse ever detected
} else if (now - temp_lastFallTime > 500000) { // 500ms timeout
rpm = 0;
} else {
rpm = (temp_period > 0) ? 60000000UL / temp_period : 0;
}
// ... rest of loop ...
}
@ississ , ahaa eli lienee mahdollisuus, että tuo kierroslukumittauksen virhe kierrosluvun kasvaessa johtuisi tuosta?
Korjaa, jos ymmärrän väärin, mutta eikös tuo interrupt sitten olisi blokkaava?
Kiinanpojan tekoäly ehdottaisi tällaisia muutoksia kierrosluvun laskentaan, onko aivan kaheleita vai voisiko jopa toimia äkkiä katsottuna?
C++:// ... existing code ... // RPM Calculation variables - volatile for interrupt safety volatile unsigned long lastFallTime = 0; // Time of last falling edge volatile unsigned long period = 0; // Pulse period in microseconds // ... existing setup ... void setup() { // ... existing setup code ... // RPM Pin with pull-up and PCI enabled pinMode(rpmPin, INPUT_PULLUP); PCICR |= (1 << PCIE2); // Enable PCINT2 group PCMSK2 |= (1 << PCINT21); // Enable interrupt for PCINT21 (pin 5) // ... rest of setup ... } // Pin Change Interrupt for RPM sensor (pin 5) ISR(PCINT2_vect) { static unsigned long prevTime = 0; static int prevState = HIGH; int currentState = digitalRead(rpmPin); if (prevState == HIGH && currentState == LOW) { // Falling edge unsigned long currentTime = micros(); lastFallTime = currentTime; if (prevTime != 0) { period = currentTime - prevTime; } prevTime = currentTime; } prevState = currentState; } void loop() { // ... existing sensor readings ... // New RPM Calculation (atomic read + timeout handling) unsigned long now = micros(); unsigned long temp_lastFallTime; unsigned long temp_period; // Atomic read of volatile variables noInterrupts(); temp_lastFallTime = lastFallTime; temp_period = period; interrupts(); if (temp_lastFallTime == 0) { rpm = 0; // No pulse ever detected } else if (now - temp_lastFallTime > 500000) { // 500ms timeout rpm = 0; } else { rpm = (temp_period > 0) ? 60000000UL / temp_period : 0; } // ... rest of loop ... }
volatile unsigned long prevTime = 0;
// Pin Change Interrupt for RPM sensor (pin 5)
ISR(PCINT2_vect) {
if (digitalRead(rpmPin) == LOW) { // Falling edge
unsigned long currentTime = micros();
lastFallTime = currentTime;
if (prevTime != 0) {
period = currentTime - prevTime;
}
prevTime = currentTime;
}
}