#define IN 4
#define OUT 5
bool detector;
bool oldDetector;
bool advanceGranted;
unsigned long fuseTime;
unsigned long newTime;
unsigned long oldTime;
unsigned long midTime;
unsigned long periodTime;
unsigned long chargeTime;
unsigned long ignitionAdvance;
int ignitionDegree;
long int rpm;
void setup() {
// put your setup code here, to run once:
Serial.begin(115200); // Start the Serial communication to send messages to the computer
Serial.println("\n");
oldTime = micros(); // сразу нужно установить, чтобы readAll() не споткнулся
fuseTime = micros(); // устанавливается время до выключения катушки
pinMode(IN, INPUT); // D2 от прерывателя
pinMode(OUT, OUTPUT); // D1 к драйверу
pinMode(13, OUTPUT); // LED
digitalWrite(13, LOW); // LED ENABLED
}
void readAll() {
newTime = micros();
periodTime = newTime-oldTime; // длительность всего периода (от закрытия до закрытия)
chargeTime = newTime-midTime; // отрезок цикла от открытия шторки до закрытия (зарядка катушки)
rpm = 60000000/periodTime; // число оборотов
oldTime = micros();
}
void loop() {
detector = digitalRead(IN);
if(detector == LOW && oldDetector == HIGH) { // момент когда шторка открылась
digitalWrite(OUT, LOW); // отключаем катушку в любом случае (ИСКРА) LOW;
oldDetector = detector; // oldDetector = HIGH
readAll(); // подсчёт всех параметров цикла
// калькулятор положения коленвала на всякий случай: http://www.torqsoft.net/piston-position.html#gudgeon
// примерный расчёт коэфициентов взят отсюда: https://customcult.netlify.app/
if(rpm >= 0 && rpm <= 700) {
ignitionDegree = 0;
goto bailout;
}
if(rpm >= 700 && rpm <= 1000) { // 0 - 2.2
ignitionDegree = 0.007 * rpm + (-4.800);
goto bailout;
}
if(rpm >= 1000 && rpm <= 2000) { // 2.2 - 15
ignitionDegree = 0.013 * rpm + (-10.800);
goto bailout;
}
if(rpm >= 2000 && rpm <= 3000) { // 15 - 30
ignitionDegree = 0.015 * rpm + (-15.000);
goto bailout;
}
if(rpm >= 3000 && rpm <= 4000) { // 30 - 40
ignitionDegree = 0.010 * rpm + (0.000);
goto bailout;
}
if(rpm > 4000) {
ignitionDegree = 40;
}
bailout:
ignitionAdvance = chargeTime - ((periodTime / 360) * ignitionDegree);
fuseTime = micros(); // начало отсчёта для предохранителя (отключение катушки зажигания при простое)
// антисбой датчика
//delayMicroseconds(periodTime/5);
}
if(detector == HIGH && oldDetector == LOW) { // момент когда шторка закрылась
digitalWrite(OUT, HIGH); // включаем катушку (ЗАРЯДКА) HIGH; digitalWrite(OUT, HIGH);
oldDetector = detector; // oldDetector = LOW
midTime = micros(); // отметка начала зарядки катушки (середина цикла)
advanceGranted = 1; // блок опережения разрешён
// антисбой датчика
//delayMicroseconds(periodTime/5);
}
if(micros() - midTime >= ignitionAdvance && advanceGranted == 1) { // собственно само опережение
digitalWrite(OUT, LOW); // отключаем катушку (ИСКРА) LOW; digitalWrite(OUT, LOW);
advanceGranted = 0; // больше сюда не возвращаемся до следующего цикла.
}
if(micros() - fuseTime >= 1000000) { // предохранитель, если катушка заряжается больше 1 секунды
digitalWrite(OUT, LOW); // отключаем катушку LOW; digitalWrite(OUT, LOW);
}
}