Блокировка двигателя при повышенных оборотах
- Войдите на сайт для отправки комментариев
Сб, 11/01/2020 - 19:39
Добрый день!
Имею дизельный авто. Иногда, очень редко при дистанционном запуске авто обороты мотора "взлетают" больше 2000. Выключу - запущу двигатель все нормально. Для дизеля это очень много, при погреве.
Сервис сказал что необходимо менять топливную аппаратуру, стоит .....много.
Так как электронику знаю не плохо, решил собрать блокиратор двигателя. Естественно на современной базе.
Arduino занимаюсь совсем немного (начинающий), набросал небольшой скетч блокировки.
Собрал схему, но не работает. Сигнал на схему подаю от сетевого трансформатора + согласование уровней, гальвано развязка (50 Гц.=3000 об/мин.=25 импульсов/сек). Уровень входного сигнала проверил осцилографом, меандр качественный.
Скетч компилируется, но схема не работает.
В чем проблема не пойму, может кто объяснит, если не затруднит, в чем "косяк" или подсчет таким образом изначально тупик.
СПАСИБО!!!
#define Tahometr A0 // вход от тахометра #define LED 5 // выход на блокировку мотора unsigned long time; unsigned int PRM = 0; // задаем счетчик оборотов int a = 0; void setup() { pinMode(Tahometr, INPUT); // через резистор на 5V pinMode(LED, OUTPUT); } void loop() { if (digitalRead(Tahometr) == LOW && a == 0) // если есть сигнал тахометра LOW, запомнить время последнего оборота { time = millis(); } if (digitalRead(Tahometr) == HIGH ) // если на тахометре сигнал high { a = 1; } if (digitalRead(Tahometr) == LOW && a == 1) // если есть сигнал тахометра снова LOW { time = millis() - time; //вычислить время оборота PRM = 1000 / time; // вычисляем обороты, секунду делим на подсчитанное время между сигналами с тахометра } /*__если обороты больше 1500 об/мин =25 импульсов/сек, включаем Stop двигателя, (для эксперимента эл. сеть 50Гц = 50 импульсов/сек)__*/ if (PRM > 20) { // не правильно считает,всегда включается до значений PRM > 99, затем какоето переполнение при PRM > 100 не включается digitalWrite(LED, HIGH); } /*__если обороты меньше 1500 двигатель продолжает работать__*/ if (PRM <= 20) { // не сбрасывается при пропадании импульсов digitalWrite(LED, LOW); } a = 0; }
Можно проще, задействовать прерывание (int0 или int1)
Строка #35 точно на месте стоит?
Строка #35 точно на месте стоит?
тогда уж и micros() использовать, здесь жеж меньше одной миллисекунды не взять
Функцию pulseIn использовать. В loop будет 5 строк и всё будет работать. Даже в обороты не надо пересчитывать. Проверять ширину и всё. Помнить что без импульсов на ноге возвращает 0 через таймаут. http://arduino.ru/Reference/PulseIn
Скорректировал скетч, картина абсолютно не изменилась. Так же не считает корректно обороты при повышении и не сбрасывает при оборотах =0.
Каким образом Вы понимаете, что обороты посчитаны неправильно (в цифровом значении)?
Иван, опишите переменную PRM тоже как long
показывайте свою схему, а то 50 Гц = 25 импульсов/сек) - не катит по арифметике
и алгоритм стоило бы изменить, оценивать сколько импульсов пришло на заданный интервал, больше или меньше заданного значения.
Вот откопал код расчета скорости по импульсам. Пришлось высчитать волшебное число 618, уже не помню зачем, но работало очень четко.
Сообразил, тут считается не реальная скорость, а воображаемый диапазон 0-1000, пропорциональный max_speed и min_speed. Тогда из этого кода полезна только строчка
auto delay = max(millis() - last_fall, last_delay);
которая сводит скорость к нулю в случае полной остановки и отсутствия импульсов,
Зачем считать все миллисами/микросами и ТД ?
Аппаратный таймер включи , скажем с предделителем 64 и внешнее прерывание.
По прерыванию сбрасываешь счётчик TCNT если таймер дотикал до нужной отметки.
А если не дотикал, а прерывание пришло повторно, то тогда уже и вырубай.
15-20строк кода.
Читай про "аппаратный таймер", "внешнее прерывание".
Могу помочь на коммерческой основе, но это уже другая история.
с чего Вы решили, что не допустимо, в компьютере все устройства требующие безотлагательной обработки завязаны на прерывания, для этого они и придуманы, чтобы ничего не пропустить
К примеру если я возьму разработку автозапуска двигателя автомобиля из одного из источников;
http://arduino.ru/forum/proekty/avtomaticheskii-zapusk-dvigatelya-avtomo...
http://arduino.ru/forum/proekty/kotntroller-distantsionnogo-progreva-avt...
https://github.com/martinhol221/SIM800L_DTMF_control
То везде анализ заведенного двигателя берется с лампы зарядки или давления масла, что не корректно. Если я вставлю кусок кода приведенного выше, для подсчета оборотов-анализа работающего двигателя. То вовремя считывания оборотов двигателя по прерыванию, attachInterrupt. Программа автопрогрева будет непрерывно приостанавливаться. А хотелось бы что бы этот кусок кода не прерывал основной программы, а крутился в функции не мешающей основному коду.
Как уйти от анализа по прерыванию, к анализу без прерываний основного кода. Может это кто то уже решал, скинте ссылку.
ПОЖАЛУЙСТА! СПАСИБО!
Как уйти от анализа по прерыванию, к анализу без прерываний основного кода. Может это кто то уже решал, скинте ссылку.
так не бывает на AVR. если это будет не прерывание, то ваш кусок кода по-любому будет крутиться в "функции" (читай цикл loop) основного кода. А значит должен как можно быстрее выполняться, чтобы не мешать оному.
Дело в том, что как раз основной код будет тормозить ваш анализ оборотов, т.к. импульсы бегут быстро, а тот код по ссылкам писали далеко не профи и уверен, что там есть и delay- и/или блокирующие циклы.
ПС. всегда, задавая вопрос , связанный с автомобилем, пишите что за автомобиль.