I am new on this forum so I hope to do everything right. I have a Tomos A55 2 stroke moped with a stock CDI. This is an ignition module that charges a capacitor and releases the spark whenever a magnet passes the hall effect sensor on the flywheel.
Stock the ignition timing has a curve so at low rpm the timing advance is larger than at high rpm. I could not really get good info about this CDI but I think it starts at 1.5mm btdc and lowers to around 0.6mm.
I would like to use an ESP32 to trick the cdi by modifying the hall effect signal. I did this by connecting the hall effect sensor with a NPN 2n222 transistor to the ESP32 GPIO 34. This way I could get great rpm data. Because the hall effect sensor usually emits around 1 to 5v AC, I just connected GPIO 33 with the CDI directly so the CDI gets a 3.3v spike.
I managed to get the engine running and it idles fine, it also starts up quiet quickly. But if I give it some throttle the engine beginnes to act like some sort of rev limiter. It is really quiet strange.
Maybe someone has already done this and knows about what I should do differently? I will upload my code as well. I should also mention that I have very little experience with ESP and coding, so I mostly use chatgpt to help.
Thanks a lot!
Wouter
const int pickupPin = 34;
const int cdiPin = 33;
volatile bool pulseFlag = false;
volatile unsigned long lastPickupMicros = 0;
float currentRPM = 0;
unsigned long pulseCount = 0;
// Pulslengte instellingen (µs)
const int minPulseWidth = 80;
const int maxPulseWidth = 350;
// Extra vertraging in microseconden (kan negatief zijn)
long extraDelay = 0; // start bij 0 µs
void IRAM_ATTR pickupISR() {
pulseFlag = true;
lastPickupMicros = micros();
pulseCount++;
}
float mapPulseLength(float rpm) {
if(rpm > 8000) rpm = 8000;
return maxPulseWidth - ((rpm * (maxPulseWidth - minPulseWidth) / 8000.0));
}
void sendCDIPulse(float pulseLength) {
digitalWrite(cdiPin, HIGH);
delayMicroseconds((int)pulseLength);
digitalWrite(cdiPin, LOW);
}
unsigned long lastTime = 0;
void setup() {
Serial.begin(115200);
pinMode(pickupPin, INPUT);
pinMode(cdiPin, OUTPUT);
digitalWrite(cdiPin, HIGH); // idle HIGH
attachInterrupt(digitalPinToInterrupt(pickupPin), pickupISR, RISING);
Serial.println("Type een vertraging in µs (bv 200 of -100) om de vonk te finetunen.");
}
void loop() {
unsigned long now = millis();
// RPM berekenen elke 500ms
if(now - lastTime >= 500){
noInterrupts();
unsigned long pulses = pulseCount;
pulseCount = 0;
interrupts();
currentRPM = pulses * 1.2; // 500ms interval -> *2*60
lastTime = now;
}
// Pickup-flank afgehandeld
if(pulseFlag){
pulseFlag = false;
float pulseLength = mapPulseLength(currentRPM);
// Bereken geplande tijd voor vonk
long plannedMicros = lastPickupMicros + extraDelay;
// Wacht tot geplande tijd bereikt is
while((long)(micros() - plannedMicros) < 0){
// even niets doen, wachten
}
sendCDIPulse(pulseLength);
}
// Serial input voor dynamische vertraging
if(Serial.available()){
String input = Serial.readStringUntil('\n');
input.trim();
if(input.length() > 0){
long newDelay = input.toInt();
if(newDelay >= -5000 && newDelay <= 5000){ // limiet -5ms tot 5ms
extraDelay = newDelay;
Serial.print("Nieuwe extra delay: ");
Serial.println(extraDelay);
}
}
}
// Debug
static unsigned long lastPrint = 0;
if(millis() - lastPrint > 500){
lastPrint = millis();
Serial.print("RPM: ");
Serial.print(currentRPM);
Serial.print(" | Extra delay: ");
Serial.println(extraDelay);
}
}
I am trying to build a kind of ECU. I hope to quickly change the ignition timing based on engine temp, load and drive modes that I can choose from. I think this is possible using the stock cdi but modifying the pickup signal.
Pickup signal white wire -> 470r resistor -> OPTO PC817 anode (I measured the pickup output and it was around 1v per 1000rpm AC)
Pickup signal black wire -> OPTO PC817 cathode
Betwoon the anode and cathode a 1N4148 diode
ESP D33 -> 220R resistor -> CDI in (White wire)
ESP and moped GND -> CDI GND (black wire)
Yesterday I managed to get a full on rpm reading that worked and up to 9000 rpm reliable firing. The bike ran great! I could not yet test it under load while riding because of all the loose wiring.
I also have a MAX6675 temp sensor, and GM6 gps, a SPI 2.4 inch lcd, an electronic throttle, a servo for the throttle, some buttons, etc.
Are there things that can be optimised in my system? Once again 90% of this is ChatGPT and me prototyping.
I suggest you use an opto-coupler as a way to drive the CDI as well, and even more important to protect the ESP32 from the voltage spikes from the Bike & reverse voltages from the GND.
What happens when it gets a 60V spike on the battery line or if the battery gets connected backwards. Here is some good reading for you: Valuable Resources for Automotive Electronics:
STMicroelectronics Application Note AN2689:
This application note provides guidelines on protecting automotive electronics from electrical hazards, focusing on design and component selection. Reading this will greatly enhance your understanding of automotive circuit protection. Read AN2689
Analog Devices: Automotive Electronics Design:
This article distills key insights into designing automotive electronics, offering practical advice for engineers. Read the article
Diodes Incorporated: Transient Voltage Suppression in Automotive:
Learn about techniques to protect automotive circuits from transient voltage, which is critical for ensuring reliable operation in harsh conditions. Read the article
AEC-100 Standards Webinar:
This webinar from Monolithic Power Systems provides a detailed overview of AEC standards, essential for understanding automotive electronics requirements. Watch the webinar
Understanding Automotive Electronics, An Engineering Perspective by William B. Ribbens:
This comprehensive book offers an in-depth look into automotive electronics from an engineering perspective, making it an invaluable resource. Access the book
Is the engine running normal when you remove your stuff? Please show us a schematic of your circuit and how it is attached to the rest of the moped circuit.