/*
Forum: https://forum.arduino.cc/t/drehzahlmesser-am-auto/1396866/8
Wokwi: https://wokwi.com/projects/437089934882609153
Version mit ATOMIC_BLOCK und Simulation der Drehzahlpulse per Timer
auf Basis des Originalsketches
2025/07/22
ec2021
*/
#include <util/atomic.h>
constexpr byte inPin {3};
constexpr unsigned long pulseProRotation {161};
unsigned long letzterPuls = 0;
unsigned long letzteBerechnung = 0;
uint16_t Drehzahl = 0;
uint16_t impulsZaehler = 0;
unsigned long zeitFuerZehnRotationen = 0;
boolean zehnRotationen = false;
void setup() {
Serial.begin(115200);
pinMode(inPin, INPUT);
attachInterrupt(digitalPinToInterrupt(inPin), ImpulsLesen, FALLING);
starteSimulation(990);
}
void ImpulsLesen() {
if (micros() - letzterPuls > 2) {
letzterPuls = micros();
impulsZaehler++;
}
}
void drehzahlMessung() {
ATOMIC_BLOCK(ATOMIC_FORCEON)
{
if (impulsZaehler >= pulseProRotation * 10) {
zehnRotationen = true;
impulsZaehler = 0;
}
}
if (zehnRotationen) {
zeitFuerZehnRotationen = millis() - letzteBerechnung;
letzteBerechnung = millis();
zehnRotationen = false;
Drehzahl = round(60000.0 / zeitFuerZehnRotationen) * 10;
Serial.println(Drehzahl);
}
}
void loop() {
drehzahlMessung();
}
/*************************************************************************************/
/* Dieser Teil ist für das Simulieren der Pulse für die Drehzahlmessung erforderlich */
#include <TimerOne.h>
constexpr byte outPin {4};
unsigned long interval;
float zielDrehzahl = 1260;
byte togglePin = 0;
void starteSimulation(float ziel) {
pinMode(outPin, OUTPUT);
togglePin = 1 << outPin;
zielDrehzahl = ziel;
interval = round(1000000.0 / ((zielDrehzahl / 60.0) * pulseProRotation));
Serial.println(interval);
Timer1.initialize(interval);
Timer1.attachInterrupt(timer_isr);
}
void timer_isr() {
PIND = togglePin;
delayMicroseconds(3);
PIND = togglePin;
}
/*************************************************************************************/