Расчет УОЗ и включение катушки

Всем привет. Пробую написать систему микропроцессорного зажигания…
Победил интерфейс с регулировками, все компилируется, крутится, но проблема возникла в самом, казалось бы, простом месте. пин на свечу не хочет включаться, либо включается в случайном порядке. И еще датчик холла KY-024 выдает случайные срабатывания на пин прерываний. Устройство пока собрано на макетке, вместо катушки светодиод, датчик холла считывает магнит приклеенный на одну лопасть кулера от ПК.

#include <GyverOLED.h>
GyverOLED<SSD1306_128x64> oled;
#define OLED_SOFT_BUFFER_64
#define hall 2                       // пин датчика холла (прерывание)
#define spark 16                     // пин управляющий катушкой зажигания
uint32_t rpmTime;           // время 1го оборота коленвала мксек
uint32_t vmtTime;           // текущее время прохождения ВМТ (датчика холла)
uint16_t flashTime;                  // время работы катушки зажигания
uint32_t on;                         // время включения катушки зажигания
uint32_t off;                   // время выключения катушки зажигания
int16_t massign[14] = {1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40}; // массив значений УОЗ

void setup() 
{
  attachInterrupt(hall, taho, RISING); // пин на прерывания
  pinMode(spark, OUTPUT);              // пин катушки как выход
  oled.init();                         // Инциализация дисплея
  flashTime = 1500;                    // настройка времени работы катушки
}
void taho() // подсчет времени оборота
{
  if (micros()-vmtTime > 8570)      // если это убрать, то при прохождении ВМТ rpmTime выдает 3-4 мксек и иногда случайные значения
  {
    rpmTime = micros()-vmtTime;     // время оборота
    vmtTime = micros();             // время прохождения ВМТ
  }
}
void loop()
{ 
  noInterrupts();                                   // откоючаем прерывания
  off = on + flashTime;                             // считаем время отключения катушки
  if (micros() > on && micros() < off) {digitalWrite(spark, HIGH);}   // включить катушку если время от on до off
  else digitalWrite(spark, LOW);                    // в остальное время выкл катушку
  switch (rpmTime)                                  // здесь считаем время включеия  в зависимости от оборотов и УОЗ
  {
     case 120001 ... 900000 : on = vmtTime + rpmTime - rpmTime/360 * massign[0]; break;
     case 60001  ... 120000 : on = vmtTime + rpmTime - rpmTime/360 * massign[1]; break;
     case 40001  ... 60000  : on = vmtTime + rpmTime - rpmTime/360 * massign[2]; break;
     case 30001  ... 40000  : on = vmtTime + rpmTime - rpmTime/360 * massign[3]; break;
     case 24001  ... 30000  : on = vmtTime + rpmTime - rpmTime/360 * massign[4]; break;
     case 20001  ... 24000  : on = vmtTime + rpmTime - rpmTime/360 * massign[5]; break;
     case 17144  ... 20000  : on = vmtTime + rpmTime - rpmTime/360 * massign[6]; break;
     case 15001  ... 17143  : on = vmtTime + rpmTime - rpmTime/360 * massign[7]; break;
     case 13334  ... 15000  : on = vmtTime + rpmTime - rpmTime/360 * massign[8]; break;
     case 12001  ... 13333  : on = vmtTime + rpmTime - rpmTime/360 * massign[9]; break;
     case 10910  ... 12000  : on = vmtTime + rpmTime - rpmTime/360 * massign[10]; break;
     case 10001  ... 10909  : on = vmtTime + rpmTime - rpmTime/360 * massign[11]; break;
     case 9232   ... 10000  : on = vmtTime + rpmTime - rpmTime/360 * massign[12]; break;
     case 8571   ... 9231   : on = vmtTime + rpmTime - rpmTime/360 * massign[13]; break;
  }
  interrupts(); // включаем прерывания
// тестовый вывод показаний
oled.clear();
oled.home();
oled.setScale(1);
oled.setCursor(0, 0); oled.print(" время ВМТ "); oled.setCursor(56, 0);oled.print(vmtTime);
oled.setCursor(0, 2); oled.print(" время 1 "); oled.setCursor(56, 2);oled.print(rpmTime);
oled.setCursor(0, 4); oled.print(" время вкл"); oled.setCursor(56, 4);oled.print(on);
oled.setCursor(0, 6); oled.print(" время выкл"); oled.setCursor(56, 6);oled.print(off);
oled.update();
}

это часть кода, которая не правильно работает. Без интерфейса.

Невидимый код !!!
В реальном авто будет миллион срабатываний прерывания от помех на одно реальное !

Добавил код… Это не для авто, а для лодочного одноцилиндрового мотора…

Хрен редьки не слашще …
А для чего отключаются прерывания ???

да это понятно)) но вопрос в другом был… почему это не срабатывает? всю голову уже сломал. Как тахометр - пожалуйста. А зная времена прохождения ВМТ и время оборота и время, через которое нужно вкл/выкл диод… не вкл и не выкл…

это уже родилось в порядке бреда. так как неделю уже голову ломаю. вроде все просто, но не работает

6 и 7 строки исправить на uint32_t

согласен. изначально было так && micros() < off но так тоже не работает. без && диод иногда включается)))

изначально так и было… но эффект тот же.

36-49 прописать 360.0 или сначала умножать - потом делить …

сейчас попробую, но проблема в том, что показания в таком виде кода на экран выводит более - менее адекватно.

А питание вашего контроллера на реальном объекте вы откуда собираетесь брать. Потому как именно по питанию будут идти помехи. На столе может что то и заработает, а в реальных условиях придёт большое разочарование.

Для отладки выводите просто в Serial - ХЗ что там Гайвер наваял …

питание акб…

отключил гайвера… диод замигал на каждый оборот… вот жеж кхм. я интерфейс этой штуке на гайвере писал доооолго))) в чем может быть проблема?

В золото(говно)коде
У вас на каждый чих идет обновление дисплея, а для I2C это обновление занимает ДОХУА времени !!!

т.е. вертушка разбалансирована и в результате биений выдает хз что по времени.

хм… получается либо тахометр на дисплей, либо система зажигания? вместе они жить не смогут? даже на какой-либо другой библиотеке OLED дисплея…

я ее пальцами кручу))) балансировка не при делах. даже если меееедленно мимо датчика проводить он срабатывает много-много раз…

В любом случае я понял в чем проблема была. Спасибо Вам огромное.