CDI Zündimpuls in 12V Digitalsignal umwandeln

Zündaussetzer, Seitenständerschalter, Lichtmaschine usw.
Tibor
Beiträge: 228
meble kuchenne Ruda Śląska Rybnik Tychy
Registriert: Mi 5. Jan 2011, 18:08

Re: CDI Zündimpuls in 12V Digitalsignal umwandeln

Beitrag von Tibor »

Moin,

keine Ahnung ob meine Posts einen Mehrwert bieten, aber ich will noch kurz den Code für einen Arduino UNO posten. Damit habe ich vorhin erfolgreich den Drehzahlmesser an der XT betrieben. Für einen ATTiny85 müsste man den noch auf TIMER1 umstellen. Da ein ATTiny85 mit einer anderen Taktfrequenz arbeitet, müssen auch noch prescaler und OCRx angepasst werden.

Code: Alles auswählen

#include <avr/sleep.h>

const uint8_t INPUT_PIN  = 2; // INT0
const uint8_t OUTPUT_PIN = LED_BUILTIN; // Pin 13

enum TimerState {
    OUTPUT_PULSE,
    IGNORE_PULSES
};

volatile TimerState timerState = OUTPUT_PULSE;

void isrInt0() {
  EIMSK &= ~(1 << INT0); // INT0 off

  TCNT2 = 0; // Reset TIMER2
  TIFR2 = (1 << OCF2A); // Clear compare flag
  OCR2A = 187; // ~3 ms
  TIMSK2 |= (1 << OCIE2A); // Activate TIMER2 compare interrupt
  TCCR2B = (1 << CS22) | (1 << CS21); // Set prescaler to 256

  digitalWrite(OUTPUT_PIN, HIGH);
}

ISR(TIMER2_COMPA_vect) {
  TCCR2B = 0; // Stop TIMER2
  TIMSK2 &= ~(1 << OCIE2A); // Compare interrupt off

  switch(timerState) {
    case OUTPUT_PULSE: {
      timerState = IGNORE_PULSES;

      digitalWrite(OUTPUT_PIN, LOW);

      TCNT2 = 0; // Reset TIMER2
      TIFR2 = (1 << OCF2A); // Clear compare flag
      OCR2A = 250; // ~4 ms
      TIMSK2 |= (1 << OCIE2A); // Activate TIMER2 compare interrupt
      TCCR2B = (1 << CS22) | (1 << CS21); // Set prescaler to 256
      break;
    }
    case IGNORE_PULSES: {
      timerState = OUTPUT_PULSE;

      EIFR = bit(INTF0); // Clear pending INT0 flag
      EIMSK |= (1 << INT0); // INT0 on
      break;
    }
  }
}

void setup() {
  pinMode(OUTPUT_PIN, OUTPUT);
  digitalWrite(OUTPUT_PIN, LOW);

  pinMode(INPUT_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(INPUT_PIN), isrInt0, RISING);

  // Set TIMER2 to CTC mode
  TCCR2A = (1 << WGM21);
  TCCR2B = 0;
  TCNT2 = 0;

  set_sleep_mode(SLEEP_MODE_IDLE);
}

void loop() {
  sleep_mode();
}

Straßenschrauber
Beiträge: 1239
Registriert: So 29. Mär 2020, 21:38

Re: CDI Zündimpuls in 12V Digitalsignal umwandeln

Beitrag von Straßenschrauber »

Klar hat das Mehrwert. Leonhard kann damit was anfangen, denke ich.
Und andere, die versehentlich einen Drehzahlmesser für Unterbrecherzündung gekauft haben.
~-o|-

lowrider82
Beiträge: 2017
Registriert: Di 16. Okt 2007, 11:17

Re: CDI Zündimpuls in 12V Digitalsignal umwandeln

Beitrag von lowrider82 »

@Tibor
Auch ich finde das spitze! Auch wir XT-Fahrer leben im Jahr 2026 und sowas kann hilfreich sein.
Spendenkonto für den Forenbetrieb:
viewtopic.php?f=306&t=157066

Tibor
Beiträge: 228
Registriert: Mi 5. Jan 2011, 18:08

Re: CDI Zündimpuls in 12V Digitalsignal umwandeln

Beitrag von Tibor »

Das Projekt ist jetzt so weit abgeschlossen. Man kann da bestimmt noch ganz viel optimieren, aber der Aufwand würde den Nutzen übersteigen. Z. B. vermute ich, dass man den 1 MOhm Widerstand weglassen kann. Die Leckströme der Dioden sollten reichen.

Ich habe die Dateien auch alle in ein git Repository hochgeladen: https://gitlab.com/Tibor3141/cdi-rev-meter-adapter

Hier noch mal der Aktuelle Code für den ATTiny85:

Code: Alles auswählen

#include <avr/sleep.h>

const uint8_t INPUT_PIN  = PIN_B2; // Physical pin 7 (INT0)
const uint8_t OUTPUT_PIN = PIN_B4; // Physical pin 3

enum TimerState {
  OUTPUT_PULSE,
  IGNORE_PULSES
};

volatile TimerState timerState = OUTPUT_PULSE;

void isrInt0() {
  GIMSK &= ~(1 << INT0); // Clear the INT0 enable bit to temporarily disable the external interrupt

  TCNT1 = 0; // Reset Timer1 counter
  OCR1A = 187; // Compare A value (~3 ms)
  OCR1C = 187; // Set timer TOP value for CTC mode
  TIFR = (1 << OCF1A); // Clear pending Timer1 Compare A flag
  TIMSK |= (1 << OCIE1A); // Enable Timer1 Compare A interrupt
  TCCR1 = (1 << CTC1) | (1 << CS13); // Start Timer1 in CTC mode with prescaler = 128

  digitalWrite(OUTPUT_PIN, HIGH);
}

ISR(TIMER1_COMPA_vect) {
  TCCR1 = 0; // Stop Timer1 by removing its clock source
  TIMSK &= ~(1 << OCIE1A); // Disable Timer1 Compare A interrupt

  switch(timerState) {
    case OUTPUT_PULSE: {
      timerState = IGNORE_PULSES;

      digitalWrite(OUTPUT_PIN, LOW);

      TCNT1 = 0; // Reset Timer1 counter
      OCR1A = 250; // Compare A value (~4 ms)
      OCR1C = 250; // Update timer TOP value
      TIFR = (1 << OCF1A); // Clear pending Compare A flag
      TIMSK |= (1 << OCIE1A); // Re-enable Compare A interrupt
      TCCR1 = (1 << CTC1) | (1 << CS13); // Restart Timer1 in CTC mode with prescaler = 128
      break;
    }
    case IGNORE_PULSES: {
      timerState = OUTPUT_PULSE;

      GIFR = bit(INTF0); // Clear any pending INT0 interrupt flag
      GIMSK |= (1 << INT0); // Re-enable the external INT0 interrupt
      break;
    }
  }
}

void setup() {
  pinMode(OUTPUT_PIN, OUTPUT);
  digitalWrite(OUTPUT_PIN, LOW);

  pinMode(INPUT_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(INPUT_PIN), isrInt0, RISING);

  TCCR1 = 0; // Keep Timer1 stopped
  TCNT1 = 0; // Initialize Timer1 counter

  set_sleep_mode(SLEEP_MODE_IDLE);
}

void loop() {
  sleep_mode();
}
Und weil's so schön ist noch ein paar Bilder:
rev_meter.png
rev_meter.png (59.04 KiB) 212 mal betrachtet
photo_2026-07-10_14-13-36.jpg
photo_2026-07-10_14-13-36.jpg (257.67 KiB) 212 mal betrachtet
photo_2026-07-10_14-13-42.jpg
photo_2026-07-10_14-13-42.jpg (254.35 KiB) 212 mal betrachtet
photo_2026-07-10_14-13-50.jpg
photo_2026-07-10_14-13-50.jpg (295.87 KiB) 212 mal betrachtet
photo_2026-07-10_14-13-54.jpg
photo_2026-07-10_14-13-54.jpg (400.54 KiB) 212 mal betrachtet

lowrider82
Beiträge: 2017
Registriert: Di 16. Okt 2007, 11:17

Re: CDI Zündimpuls in 12V Digitalsignal umwandeln

Beitrag von lowrider82 »

Ich ziehe meinen Sonnenhut!
Spendenkonto für den Forenbetrieb:
viewtopic.php?f=306&t=157066

Antworten