// =========================================================
// Dit is een schakeling om het signaal van een mechanische
// ontsteking om te zetten naar een toerenteller.
// De gebruikte toerenteller is een AutoMeter Monstertach
// van 0-10000 RPM, ingesteld voor een V8.
// Er is nu ook een uitgang beschikbaar voor een schakellicht.
//
// De ingang van deze schakeling is voorzien van een
// opto-coupler (H11L1HS) die zorgt voor een veilig en
// schoon signaal voor de micro-controller.
//
// Het ontsteking signaal is aangesloten ingang 2, en
// wordt opgepikt door een interrupt. De interrupt routine
// negeert eventuele contact dender, en bepaalt de
// periodetijd van het signaal.
//
// De toerenteller wordt continue voorzien van een
// signaal dat afhankelijk is van het berekende toerental.
// Bij een instelbaar toerental wordt er ook een uitgang
// hoog gemaakt dat wordt gebruikt voor een schakel-licht.
// Er is ook een signaal als de motor loopt.
// Het schakelpunt voor het schakellicht kan worden getoond,
// en of worden bijgesteld.
// Tijdens het opstarten wordt een test uitgevoerd voor de
// toerenteller en het schakellicht. De test kan ook door
// de gebruiker worden gestart.
//
// Voor de micro-controller is uitgegaan van een 16 MHz klok.
//
// Bij een echte toepassing kunnen de "Serial.println"
// opdrachten worden verwijderd.
//
// =========================================================
// Auteur: Richard Lagendijk
// Datum: 31-10-2025
// Versie: 1.0
// =========================================================
// Inladen bibliotheken
#include <Arduino.h>
// Defineer de pinnen (ingangen)
#define PulsIn 2
#define Hoger 4
#define Lager 3
#define Test 6
#define Status 5
// Defineer de pinnen (uitgangen)
#define PulsUit 12
#define MotorLoopt 10
#define SchakelLicht 11
#define Min100 A0
#define Min200 A1
#define Min300 A2
#define Min400 A3
#define Min500 A4
// Inititalisatie
void setup() {
// Pin is een ingang of een uitgang
pinMode(PulsIn, INPUT);
pinMode(Hoger, INPUT);
pinMode(Lager, INPUT);
pinMode(Status, INPUT);
pinMode(PulsUit, OUTPUT);
pinMode(MotorLoopt, OUTPUT);
pinMode(SchakelLicht, OUTPUT);
pinMode(Min100, OUTPUT);
pinMode(Min200, OUTPUT);
pinMode(Min300, OUTPUT);
pinMode(Min400, OUTPUT);
pinMode(Min500, OUTPUT);
attachInterrupt(digitalPinToInterrupt(PulsIn), pulsMeting, RISING); // Interrupt voor ontsteking signaal.
TCCR1A = 0; // Initialiseer timer 1.
TCCR1B = 0; // Initialiseer timer 1.
TCCR1B = 0b00000011; // Deler timer op 1:64.
TCNT1 = 28036; // Startwaarde voor timer 1 (minimum toerental 50 tpm).
TIMSK1 |= 0b00000001; // Overflow actief voor timer 1.
Serial.begin(9600); // Seriele verbinding.
}
// Globale variabelen
bool pulsUit = false; // Signaal naar toerenteller.
int pulsActief = 0; // Controle of er nog pulsen komen (motor loopt.)
long statusActief = 0; // Tijd die de statusknop wordt ingedrukt.
int schakelLichtInstelling = 5000; // Instelling voor schakellicht (tpm).
volatile long timerWaarde = 0; // Berekende timer waarde voor signaal naar toerenteller
float aantalCilinders = 4; // Aantal cilnders van de motor.
float aantalSlagen = 2; // Tweetakt (1) of Viertakt (2)
volatile unsigned long tijdDender = 500; // Kontaktdender van ontsteking.
volatile unsigned long tijdOud = micros(); // Tijd van vorige interrupt.
volatile unsigned long pulsPeriode = 0; // Tijd tussen twee interrupts
volatile unsigned int metingGereed = 0; // Nieuwe meting bveschikbaar.
float toerenPerMinuut = 1; // Berekend toerental.
// Uitgangssignaal voor toerenteller (V8 0-10000 rpm).
ISR(TIMER1_OVF_vect) {
pulsUit = !pulsUit;
digitalWrite(12,pulsUit); // Maak het toerenteller signaal (blokvorm)
timerWaarde = 65536 - (1875000 / (long) toerenPerMinuut); // Timer waarde uitrekenen.
if (timerWaarde < 0) {timerWaarde = 0;} // Minimum toerental.
TCNT1 = timerWaarde; // Nieuwe start waarde voor timer 1.
}
// Interupt bij puls van de ontsteking.
void pulsMeting() {
// Controleer of er geen signaaldender is, zoniet dan bereken de tijd.
if ((micros() - tijdOud) > tijdDender) {
pulsPeriode = micros() - tijdOud;
// Zet de tijd voor volgende periode.
metingGereed = 1;
tijdOud = micros();
}
}
// Test functie voor de toerenteller.
void testToerenteller() {
int teller;
// Toerenteller van 1000 naar 10000 toeren in 2 seconden.
for (teller = 1; teller < 11; teller++) {
toerenPerMinuut = teller * 1000;
Serial.println(toerenPerMinuut);
delay(200);
}
// Schakellicht Aan / Uit x keer.
for (teller = 0; teller < 3; teller++) {
digitalWrite(SchakelLicht, HIGH);
digitalWrite(Min100, HIGH);
digitalWrite(Min200, HIGH);
digitalWrite(Min300, HIGH);
digitalWrite(Min400, HIGH);
digitalWrite(Min500, HIGH);
delay(500);
digitalWrite(SchakelLicht, LOW);
digitalWrite(Min100, LOW);
digitalWrite(Min200, LOW);
digitalWrite(Min300, LOW);
digitalWrite(Min400, LOW);
digitalWrite(Min500, LOW);
delay(500);
}
// Toerenteller van 10000 naar 1000 toeren in 2 seconden.
for (teller = 10; teller > 0; teller--) {
toerenPerMinuut = teller * 1000;
Serial.println(toerenPerMinuut);
delay(200);
}
}
// Laat het instelpunt zien van het schakellicht. (Knop > 5s dan test.)
void toonStatus() {
statusActief = millis();
while (digitalRead(Status) == HIGH) {
toerenPerMinuut = schakelLichtInstelling;
digitalWrite(SchakelLicht, HIGH);
delay(200);
digitalWrite(SchakelLicht, LOW);
delay(200);
Serial.println(toerenPerMinuut);
if ((millis() - statusActief) > 5000) {
testToerenteller();
}
}
}
// Instellen van het schakelpunt van het schakellicht.
void instellenSchakelLicht() {
while ((digitalRead(Hoger) == HIGH) && (digitalRead(Lager) == LOW)) {
schakelLichtInstelling = schakelLichtInstelling + 100;
if (schakelLichtInstelling > 10000) {schakelLichtInstelling = 10000;}
toerenPerMinuut = schakelLichtInstelling;
Serial.println(schakelLichtInstelling);
delay(300);
}
while ((digitalRead(Hoger) == LOW) && (digitalRead(Lager) == HIGH)) {
schakelLichtInstelling = schakelLichtInstelling - 100;
if (schakelLichtInstelling < 100) {schakelLichtInstelling = 100;}
toerenPerMinuut = schakelLichtInstelling;
Serial.println(schakelLichtInstelling);
delay(300);
}
}
// Hoofdprogramma
void loop() {
while (1) {
// Bij opstarten wordt eerst de toerenteller getest.
if (millis() < 1000) {
testToerenteller();
}
// Test uitvoeren via test knop.
if (digitalRead(Test) == HIGH) {
testToerenteller();
}
// Status tonen (instelling van schakellicht).
if (digitalRead(Status) == HIGH) {
toonStatus();
}
// Instellen schakellicht (hoger).
if ((digitalRead(Hoger) == HIGH) && (digitalRead(Lager) == LOW)) {
instellenSchakelLicht();
}
// Instellen schakellicht (loger).
if ((digitalRead(Hoger) == LOW) && (digitalRead(Lager) == HIGH)) {
instellenSchakelLicht();
}
delay(100);
// Uitrekenen van het toerental.
if (metingGereed > 0) {
toerenPerMinuut = (60000000 / pulsPeriode) * (aantalSlagen / aantalCilinders);
metingGereed = 0;
pulsActief = 10;
}
// Controleer of motor nog loopt (minimaal 1 puls per sec)
pulsActief--;
if (pulsActief < 1) {
pulsActief = 0;
toerenPerMinuut = 1;
digitalWrite(MotorLoopt, LOW);
} else {
digitalWrite(MotorLoopt, HIGH);
}
// Schakellicht
if (toerenPerMinuut >= schakelLichtInstelling) {
digitalWrite(SchakelLicht, HIGH);
} else {
digitalWrite(SchakelLicht, LOW);
}
// Min 500 toeren
if (toerenPerMinuut >= (schakelLichtInstelling - 500)) {
digitalWrite(Min500, HIGH);
} else {
digitalWrite(Min500, LOW);
}
// Min 400 toeren
if (toerenPerMinuut >= (schakelLichtInstelling - 400)) {
digitalWrite(Min400, HIGH);
} else {
digitalWrite(Min400, LOW);
}
// Min 300 toeren
if (toerenPerMinuut >= (schakelLichtInstelling - 300)) {
digitalWrite(Min300, HIGH);
} else {
digitalWrite(Min300, LOW);
}
// Min 200 toeren
if (toerenPerMinuut >= (schakelLichtInstelling - 200)) {
digitalWrite(Min200, HIGH);
} else {
digitalWrite(Min200, LOW);
}
// Min 100 toeren
if (toerenPerMinuut >= (schakelLichtInstelling - 100)) {
digitalWrite(Min100, HIGH);
} else {
digitalWrite(Min100, LOW);
}
Serial.println(toerenPerMinuut);
}
}
Hoger
Lager
Schakellicht
Motor loopt
Test
Status
Ontsteking
Toerenteller
-500
-100
-400
-300
-200