Раз/два в секунду отображать информацию и пытаться отображать информацию на каждый оборот - ЭТО БОЛЬШАЯ РАЗНИЦА !!!
Прямой путь к переполнению micros и всем сопутствующим весёлостям.
А есть другие варианты? Из меня программист-то так себе…
Это не касается Вашей текущей проблемы, просто, над чем ещё поработать. А варианты, конечно, есть, они есть всегда. Вот, изучите.
@denis_22rus , вам указали на кучу ошибок
Если вы их исправили - выложите обновленный код новым сообщением
#define hall 2 // пин датчика холла (прерывание)
#define spark 16 // пин управляющий катушкой зажигания
uint32_t rpmTime; // время 1го оборота коленвала мксек
uint32_t vmtTime; // текущее время прохождения ВМТ (датчика холла)
uint16_t flashTime; // время работы катушки зажигания
uint32_t on; // время включения катушки зажигания
uint32_t off; // время выключения катушки зажигания
uint32_t onTime;
int16_t massign[14] = {30, 30, 30, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40}; // массив значений УОЗ
void setup()
{ Serial.begin(115200);
attachInterrupt(hall, taho, RISING); // пин на прерывания
pinMode(spark, OUTPUT); // пин катушки как выход
flashTime = 1500; // настройка времени работы катушки
}
void taho() // подсчет времени оборота
{
if (micros()-vmtTime > 8570) // если это убрать, то при прохождении ВМТ rpmTime выдает 3-4 мксек и иногда случайные значения
{
rpmTime = micros()-vmtTime; // время оборота
vmtTime = micros(); // время прохождения ВМТ
}
}
void loop()
{
off = on + flashTime; // считаем время отключения катушки
if (micros() >= on && micros() <= off) {onTime = micros(); digitalWrite(spark, HIGH); Serial.println(vmtTime); Serial.println(rpmTime); Serial.println(on); Serial.println(onTime);} // включить катушку если время от on до off
else {digitalWrite(spark, LOW);} // в остальное время выкл катушку
switch (rpmTime) // здесь считаем время включеия в зависимости от оборотов и УОЗ
{
case 120001 ... 900000 : on = vmtTime + rpmTime - massign[0] * rpmTime/360 ; break;
case 60001 ... 120000 : on = vmtTime + rpmTime - massign[1] * rpmTime/360; break;
case 40001 ... 60000 : on = vmtTime + rpmTime - massign[2] * rpmTime/360; break;
case 30001 ... 40000 : on = vmtTime + rpmTime - massign[3] * rpmTime/360; break;
case 24001 ... 30000 : on = vmtTime + rpmTime - massign[4] * rpmTime/360; break;
case 20001 ... 24000 : on = vmtTime + rpmTime - massign[5] * rpmTime/360; break;
case 17144 ... 20000 : on = vmtTime + rpmTime - massign[6] * rpmTime/360; break;
case 15001 ... 17143 : on = vmtTime + rpmTime - massign[7] * rpmTime/360; break;
case 13334 ... 15000 : on = vmtTime + rpmTime - massign[8] * rpmTime/360; break;
case 12001 ... 13333 : on = vmtTime + rpmTime - massign[9] * rpmTime/360; break;
case 10910 ... 12000 : on = vmtTime + rpmTime - massign[10] * rpmTime/360; break;
case 10001 ... 10909 : on = vmtTime + rpmTime - massign[11] * rpmTime/360; break;
case 9232 ... 10000 : on = vmtTime + rpmTime - massign[12] * rpmTime/360; break;
case 8571 ... 9231 : on = vmtTime + rpmTime - massign[13] * rpmTime/360; break;
}
}
пока мучаю вот так.
Вам же сказали. что это неверно. Нужно использовать вычитание, а не сложение.
я может не верно понял, сделал сначала умножение, а затем деление. Про вычитание ничего не было. Сейчас попробую…
Какие пределы по оборотам у двигателя ?
7000 об/мин в программе максимум, по ттх конкретного моего мотора 6000
мозг сломался в трех местах… как это можно вычислить путем только вычитания?
может вообще формула не верна? Я знаю время прохождения ВМТ, время между двумя ВМТ это время одного оборота. свечу мне надо зажечь за время до третьей и последующих ВМТ, определяемое углом опережения…
Не вычислять нужный момент в будущем, как это сделано тут - а проверять время, прошедшее с последнего переключения и сравнивать с нужным интервалом
ваш вариант(неправильный):
newTime = oldTime + interval;
if (micros() > newTime) { //момент настал
правильный:
if (micros() - oldTime > interval) { //момент настал
подробнее - ссылка в комменте 24
Отчего же не смогут? Смогут, если по уму написать.
От библиотеки это не зависит. Никакая библиотека не способна исправить кривизну рук программиста.
Арифметику в школе учил?
При наличии некоторой сообразительности этого вполне достаточно.
Собственно, любой проект начинается с проектирования (а не с написания кода). Неожиданно, правда?
И при проектировании устройства на МК во многих случаях требуется особенно тщательно проектировать распределение времени, чтобы все успевало и ничего не пропускалось.
Ну не по зубам работа, не по зубам.
Конечно нет. Ошибка в строках 1-61.
- Зачем измерять время, переводить его в градусы и потом обратно?
- Нет контроля допустимых оборотов. Что будет при запуске или когда заглох? Т.е. ниже 100-500 об в мин.
- Катушка программно включается и выключается. Бред. Там лучше "железный одновибратор.
Алгоритм подсчёта, который использовал я: - Замерить период вращения от ВМТ до ВМТ.
- Вычислить момент искры Х мс после ВМТ.
- Через X мс после ВМТ дать искру.
Вычисляется просто:
Взять период вращения, от него вычесть константу. Константа в миллисекундах не зависит от скорости вращения, да. Физически константа это время от искры до максимального горения смеси. Там порядка 4 мс вроде, не помню.
Допустим 10мс.
Обороты: период: поджиг через Х после ВМТ
600. 100 мс. 96 мс
6000. 10 мс. 6 мс
Даже на глазок видно, что УОЗ меняется в правильном ключе. И никаких “тугодумных” вычислений, только сложение и вычитание.
Конечно нет. Ошибка в строках 1-61.
- Зачем измерять время, переводить его в градусы и потом обратно?
- Нет контроля допустимых оборотов. Что будет при запуске или когда заглох? Т.е. ниже 100-500 об в мин.
- Катушка программно включается и выключается. Бред. Там лучше "железный одновибратор.
Алгоритм подсчёта, который использовал я: - Замерить период вращения от ВМТ до ВМТ.
- Вычислить момент искры Х мс после ВМТ.
- Через X мс после ВМТ дать искру.
Вычисляется просто:
Взять период вращения, от него вычесть константу. Константа в миллисекундах не зависит от скорости вращения, да. Физически константа это время от искры до максимального горения смеси. Там порядка 4 мс вроде, не помню.
Допустим 10мс.
Обороты: период: поджиг через Х после ВМТ
600. 100 мс. 96 мс
6000. 10 мс. 6 мс
Даже на глазок видно, что УОЗ меняется в правильном ключе. И никаких “тугодумных” вычислений, только сложение и вычитание.
[/quote]
- за тем, чтобы вычислить время УОЗ в зависимости от оборотов.
- нет контроля? потому, что пока еще не добрался.
- как работает автомобильная катушка? подано питание - есть искра, снято питание - нет искры. поправьте, если я не прав.
- константа не такая уж и константа. Постройте график исходя из Ваших исходных данных и сравните его со среднестатистическим графиком уоз.
Время горения смеси не постоянно и зависит от наполняемости цилиндра, степени сжатия(читай оборотов) температуры двс, стехиометрического состава ТВС, нагрузки на ДВС…
Я когда только задумал эту штуковину, тоже думал вычитать константу. Только нет ее там.
В автомобильных ЭБУ заложены топливные карты. ЭБУ там ничего не считает.
Я пошел таким путем, чтобы можно было регулировать УОЗ в процессе обкатки. Потому, что рабочих графиков или карт УОЗ на мой мотор просто нет.
#define hall 2 // пин датчика холла (прерывание)
#define spark 16 // пин управляющий катушкой зажигания
uint32_t rpmTime; // время 1го оборота коленвала мксек
uint32_t vmtTime; // текущее время прохождения ВМТ (датчика холла)
uint16_t flashTime; // время работы катушки зажигания
uint32_t off; // время выключения катушки зажигания
uint32_t onTime;
int16_t massign[14] = {45, 45, 45, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40}; // массив значений УОЗ
uint32_t uoz;
void setup()
{ Serial.begin(115200);
attachInterrupt(hall, taho, RISING); // пин на прерывания
pinMode(spark, OUTPUT); // пин катушки как выход
flashTime = 1500; // настройка времени работы катушки
}
void taho() // подсчет времени оборота
{
if (micros()-vmtTime > 50000) // если это убрать, то при прохождении ВМТ rpmTime выдает 3-4 мксек и иногда случайные значения
{
rpmTime = micros()-vmtTime; // время оборота
vmtTime = micros(); // время прохождения ВМТ
}
}
void loop()
{
off = uoz - flashTime; // считаем время отключения катушки
if (micros() - vmtTime < uoz && micros() - vmtTime > off) {onTime = micros(); digitalWrite(spark, HIGH); Serial.println(vmtTime); Serial.println(rpmTime); Serial.println(uoz); Serial.println(onTime);} // включить катушку если время от on до off
else {digitalWrite(spark, LOW);} // в остальное время выкл катушку
switch (rpmTime) // здесь считаем время включеия в зависимости от оборотов и УОЗ
{
case 120001 ... 99999999 : uoz = rpmTime - massign[0] * rpmTime/360; break;
case 60001 ... 120000 : uoz = rpmTime - massign[1] * rpmTime/360; break;
case 40001 ... 60000 : uoz = rpmTime - massign[2] * rpmTime/360; break;
case 30001 ... 40000 : uoz = rpmTime - massign[3] * rpmTime/360; break;
case 24001 ... 30000 : uoz = rpmTime - massign[4] * rpmTime/360; break;
case 20001 ... 24000 : uoz = rpmTime - massign[5] * rpmTime/360; break;
case 17144 ... 20000 : uoz = rpmTime - massign[6] * rpmTime/360; break;
case 15001 ... 17143 : uoz = rpmTime - massign[7] * rpmTime/360; break;
case 13334 ... 15000 : uoz = rpmTime - massign[8] * rpmTime/360; break;
case 12001 ... 13333 : uoz = rpmTime - massign[9] * rpmTime/360; break;
case 10910 ... 12000 : uoz = rpmTime - massign[10] * rpmTime/360; break;
case 10001 ... 10909 : uoz = rpmTime - massign[11] * rpmTime/360; break;
case 9232 ... 10000 : uoz = rpmTime - massign[12] * rpmTime/360; break;
case 8571 ... 9231 : uoz = rpmTime - massign[13] * rpmTime/360; break;
}
}
если я правильно понял, то это должно выглядить так?
Вообще-то наоборот.
Не то, чтобы прямо наоборот)) во время снятия напряжения с катушки происходит разряд… Но суть ясна, необходимо выключать пин на время разряда. Спасибо.
Осталось понять как победить дребезг датчика холла, которого вроде бы и не должно было быть…