Подсчёт импульсов (автоблокировка дверей)
- Войдите на сайт для отправки комментариев
День добрый, потратил день на изучение нового мира :)
По складу я больше механик и весьма далёк от программирования, но вот появилось желание разобраться самому, поскольку человек который сделал мне данный девайс, сделал его так, что машина сама закрылась стоящая с ключом внутри.
Вообщем имеются цифровые импульсы +5В следующего вида:

На деле выглядят вот так:
http://storage6.static.itmages.ru/i/15/1126/h_1448554457_7824204_dd38af6170.png
При этом как и в любой бортовой сети имеются помехи от потребителей при стоянке автомобиля:
http://storage4.static.itmages.ru/i/15/1126/h_1448554706_8970535_723cff33f2.png
Так же имеется +12 вход от индикатора подсветки заблокированных дверей и третий контакт - сама блокировка дверей производится замыканием на землю +5 поступающих с салонного блока управления.
Сам алгоритм:
В цикле производится подсчёт длительности импульса, если он попадает в промежуток 10...50 мс и на входе от индикатора блокировки ничего нет - замыкать третий контакт на землю длительностью 100мс. В идеале я думаю надо делать три замера дабы исключить ложные срабатывания и после блокировки я думаю нужно уходить в спячку на пару-тройку секунд.
Либо в цикле проверять состояние входа индикатора блокировки и если нет сигнала - производить подсчёт импульсов и уже тогда замыкать на землю.
При этом нужно считать испульсы выше 4,5В так чтобы от помех ничего не происходило :)
Вообщем родилось вот такое неказистое решение:
Программа:
// Door automatic lock for Nissan/Renault. #define pinSpeed 0 // пин вход ШИМ скорости (+5V) #define pinLockRelay 1 // пин выхода на сигнальное реле блокировки (+5V) #define impulse 200 // импульс блокировки дверей - 200мс unsigned long duration; //================================================================================== void setup() { pinMode(pinSpeed,INPUT); // входной пин digitalWrite(pinSpeed, HIGH); // внутренняя подтяжка входа pinMode(pinLockRelay,OUTPUT); // выходной пин реле digitalWrite(pinLockRelay, LOW); // внутренняя подтяжка входа } //====== void loop() { duration = pulseIn(pinSpeed, HIGH); // Считаем длительность импульса в микросекундах if (duration >100 && duration <= 75000) // импульс 75000 микросекунд - это примерно 20км/ч, { // но лучше поставить 35000 - около 40км/ч digitalWrite(pinLockRelay, HIGH); // Включаем реле delay(impulse); digitalWrite(pinLockRelay, LOW); // Выключаем реле delay(1000); // Пауза сеунда } }Поскольку не знаю digitalWrite действительно ли даёт ground при LOW и какой ток пробежит по этой дорожке то решил задействовать сигнальное реле для замыкания на землю контакта блокировки. Второе реле просто отключает устройство от питания, то есть после блокировки схема уже не активна.
Скажите хоть чего нить ) я понимаю что это костыль и всё решается функциями сигналки, но у меня неё нет и ставить её желания тоже, а вот попробовать что либо новое - есть.
День, а что тут говорить, это ужасный костыль. Функция pulsein обычно используется для измерения длительности одиночных импульсов, и то, при условии что передний фронт импульса начался точно с момента запуска функции. У вас же будет измеряться не пойми что и непойми как. Для периодического сигнала используют измерение таймером. Что-то типа этого вам нужно.
При этом нужно считать испульсы выше 4,5В так чтобы от помех ничего не происходило :)
Вот, начинает проясняться. Единственный оставшийся у меня вопрос - дигиспарк с тини85 судя по всему на 2-ом пине (если считать с 0) имеет вход на 7-ую ногу на таймер T0, то есть оный пример кода имеет место быть?
// Frequency counter sketch, for measuring frequencies low enough to execute an interrupt for each cycle // Connect the frequency source to the INT0 pin (digital pin 2 on an Arduino Uno) volatile unsigned long firstPulseTime; volatile unsigned long lastPulseTime; volatile unsigned long numPulses; void isr() { unsigned long now = micros(); if (numPulses == 1) { firstPulseTime = now; } else { lastPulseTime = now; } ++numPulses; } void setup() { pinMode(3, OUTPUT); // put a PWM signal on pin 3, then we can connect pin 3 to pin 2 to test the counter analogWrite(3, 128); } // Measure the frequency over the specified sample time in milliseconds, returning the frequency in Hz float readFrequency(unsigned int sampleTime) { numPulses = 0; // prime the system to start a new reading attachInterrupt(0, isr, RISING); // enable the interrupt delay(sampleTime); detachInterrupt(0); return (numPulses < 3) ? 0 : (1000000.0 * (float)(numPulses - 2))/(float)(lastPulseTime - firstPulseTime); } void loop() { float freq = readFrequency(1000); delay(1000); }костыли в виде обвязки как я понял придётся оставить?
Единственный оставшийся у меня вопрос - дигиспарк с тини85 судя по всему на 2-ом пине (если считать с 0) имеет вход на 7-ую ногу на таймер T0, то есть оный пример кода имеет место быть?
У этого метода есть ряд недостатков, но для вашего случая пожалуй подойдёт. Здесь таймер0 используется косвенно, его использует функция micros(), поэтому вход T0 не нужен, нужен INT0 Впрочем он на той-же 7 ноге.
Спасибо за подсказки, осталось пересчитать импульсы на нужный диапазон и попробовать.
На практике не всё так просто.
Импульсы совершенно случайны, даже на нажатие клаксона вырабатываются импульсные помехи. Не говоря уже о том что скорость - величина далеко не постоянная. Так что решил накапливать в массиве разницу между импульсами и уже затем в цикле отрабатывать проверку - если маленьких значений 70% - производить активацию реле.
Совершенно не понимаю как можно обсуждать и в конце концов не сделать частотомер....
да я ж писал что механик :) с железяками проблем нет, решил изучить для себя другое, далёкое от меня.
частотомер меряет частоту за время, я сделал тупо смену режима светика на rising и получил очень чудесатое мигание светика и при остановке автомобиля с неустойчивой частотой, вообще длительность импульсов очень плавно меняются в зависимости от скорости движения.
День, частота измеряется двумя способами. Количество импульсов входного сигнала за единицу времени (это как раз "за время"), ваш скетч их #4 тоже на этом принципе. Второй способ -измерение длительности периода сигнала через вход захвата таймера. Измеряется время между изменением логического уровня входного сигнала. Это очень быстродействующий способ измерения. На скетч с подобным принцип работы я вам дал ссылку в #2.
Именно так.
Низкие частоты: измеряется время между фронтами импульсов.
Высокие частоты: измеряется количество импульсов за временнОе окно.
Считайте лучше сколько импульсов пришло за секунду. Так проще.
Прерыванием. И не забудьте РЦ чепочку поставить на входе.
З.Ы. Была на машине сигналка- она закрывала двери на второе нажатие педали тормоза.
Мне это даже нравилось. Удобно закрывать двери
Один раз проехал 300 км (ранним утром) и был удивлён когда двери закрылись уже на въезде в Таллин.
Значит второе нажатие было только там.....
За секунду я могу разогнаться по разному и тогда получится что в одном случае дверки заблокируются на скорости допустим 30км/ч, а при шустром разгоне - уже при 50-ти км/ч что внесёт определённый дискомфорт в мироощущение водителя :)
У меня на 5-10 км в час закрываются и никакого дискомфорта...