/*
Titel: Geschwindigkeit
Forum: https://forum.arduino.cc/t/tachometer-mit-esp32-oled-und-hallsensor/1442427
Wokwi: https://wokwi.com/projects/463002589818292225
Geänderter Sketch
Puls-Simulation ergänzt
Interval.h entfernt, dafür eine eigene kleine millis()-Funktion eingebaut
2026/05/03
ec2021
*/
#include <SPI.h> // Display: Benötigte Bibliothekebn
#include <Wire.h> // Serial Peripheral Interface: Kommunikation zwischen den Geräten
#include <Adafruit_GFX.h> // Kommunikation zu 12c (inter Intergrated Circuit) device (OLED-Display)
#include <Adafruit_SSD1306.h> // Grafik-Bibliothek
// Dimension des Displays
#define SCREEN_WIDTH 128 // OLED Displa Beite in (Pixel)
#define SCREEN_HEIGHT 64 // OLED Display Höhe in (Pixel)
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define signalHallsensor 5 // Signal des Hallsensors geht an den Pin4 des ESP32
// Dimension des Rades (26x1, 90 Zoll)
// Rad: 26 Zoll (1 Zoll = 25,4 mm) --> 660,4 mm / 1000 = 0,6604m (Durchmesser in Meter)
// Umfang = Pi * 0,6604m = 2,0747m (Umfang in Meter)
float radumfang = 2.0747;
// Dimension des Kugellagers 5mm
// Lager: 0,19685 Zoll (1 Zoll = 25,4 mm) --> 4,99999 mm / 1000 = 0,00499999m (Durchmesser in Meter)
// Umfang = Pi * 0,00499999m = 0.01571m (Umfang in Meter)
// float radumfang = 0.01571; // für 5mm Kugellager 0.01571m (Umfang in Meter)
void setup()
{
Serial.begin(115200);
Serial.println("Start");
// Display Grundeinstellungen
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // Adresse 0x3c für 128x64
display.clearDisplay(); // Leerer Bildschirm
display.setTextSize(1); // Display: Schriftgröße ("1"/"Normal")
display.setTextColor(WHITE); // Display: Schriftfarbe (Weiß)
display.println("Willkommen");
display.display();
pinMode(signalHallsensor, INPUT); // Interruproutine bei steigender Flanke
attachInterrupt(signalHallsensor, ISR, RISING);
}
volatile byte summeMagnete;
volatile long summeMillis;
unsigned long vorherigeMillis;
unsigned long gesamtUmdrehungen;
void ISR()
{
uint32_t aktuelleMillis = millis();
if (aktuelleMillis - vorherigeMillis >= 25) // 25ms entspricht maximal 40 Radumdrehungen pro Sekunde
{
summeMagnete++; // Magnete zählen und Aufsummieren
summeMillis += aktuelleMillis - vorherigeMillis; // Zeit zwischen den Signalen zählen und Aufsummieren
vorherigeMillis = aktuelleMillis ; // Zeit merken
}
}
void loop()
{
/****************************/
simulatePPM(300);
/****************************/
if (interval(2500)) {
tachometer();
}
}
bool interval(unsigned long time) {
static unsigned long lastTime = 0;
if (millis() - lastTime >= time) {
lastTime = millis();
return true;
}
return false;
}
void tachometer()
{
byte einzelUmdrehungen;
unsigned long zeit;
float drehzahl, geschwindigkeit, strecke;
noInterrupts(); // Interrupts werden gesperrt
einzelUmdrehungen = (summeMagnete) / 2; // Zahlvariable Magnete umkopieren
summeMagnete = 0; // Zahlvariable Magnete auf 0 zurücksetzen
zeit = summeMillis; // Zahlvariable Zeit umkopieren
summeMillis = 0; // Zahlvariable Zeit auf 0 zurücksetzen
interrupts(); // Interrupts werden wieder zugelassen
Serial.println(einzelUmdrehungen);
gesamtUmdrehungen += einzelUmdrehungen; // Aufsummieren aller Radumdehungen
strecke = (float)gesamtUmdrehungen * (radumfang / 1000.0); // Fahrtkilometerzähler
if (einzelUmdrehungen > 0) {
drehzahl = 60.0 * 1000.0 * ((float)einzelUmdrehungen) / ((float)zeit); // Raddrehzal
geschwindigkeit = 3.6 * 1000.0 * radumfang * ((float)einzelUmdrehungen) / ((float)zeit); // Geschwindigkeit
} else {
drehzahl = 0.0;
geschwindigkeit = 0.0;
}
display.clearDisplay();
display.setCursor(5, 0);
display.println("Tachometer");
display.setCursor(10, 36);
display.println(geschwindigkeit);
display.setCursor(68, 36);
display.println("km/h");
display.display();
}
/* The following function creates pulses in pulseOutPin that */
/* simulate pulses from a given sensor */
void simulatePPM(uint16_t RPM) {
constexpr byte pulseOutPin {5};
static unsigned long lastPulse = 0;
if (lastPulse == 0) {
pinMode(pulseOutPin, OUTPUT);
digitalWrite(pulseOutPin, HIGH);
}
unsigned long noOfPulses = RPM / 60;
unsigned long microsInterval = 1000000UL / noOfPulses;
if (micros() - lastPulse >= microsInterval) {
lastPulse = micros();
digitalWrite(pulseOutPin, LOW);
delayMicroseconds(5);
digitalWrite(pulseOutPin, HIGH);
}
}Loading
esp32-c3-devkitm-1
esp32-c3-devkitm-1