Подсчёт импульсов (автоблокировка дверей)

День
Offline
Зарегистрирован: 26.11.2015

День добрый, потратил день на изучение нового мира :)

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

Вообщем имеются цифровые импульсы +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В так чтобы от помех ничего не происходило :)

Правильно ли я понимаю что подойдёт даже Digispark USB, а уже в программе использовать digitalRead или pulseIn? Как можно реализовать саму блокировку - замыканием на массу - это же не просто состояние LOW или оно? Если не оно - наверно придётся колхозить через сигнальное реле.
 
Вообщем буду рад посильной помощи в наверно для вас достаточно простой задаче. Просто смотрю на дигиспарке 5 пинов и теоретически можно было бы на питание посадить конденсатор и отслеживать еще и его на отдельном входе - и если питание пропало - замыкать на массу другой контакт, отвечающий за разблокировку дверей (получается как при выключении зажигания). 
День
Offline
Зарегистрирован: 26.11.2015

Вообщем родилось вот такое неказистое решение:

Программа:

//  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 и какой ток пробежит по этой дорожке то решил задействовать сигнальное реле для замыкания на землю контакта блокировки. Второе реле просто отключает устройство от питания, то есть после блокировки схема уже не активна.

Скажите хоть чего нить ) я понимаю что это костыль и всё решается функциями сигналки, но у меня неё нет и ставить её желания тоже, а вот попробовать что либо новое - есть.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

День, а что тут говорить, это ужасный  костыль. Функция pulsein обычно используется для измерения длительности одиночных импульсов, и то, при условии что передний фронт импульса начался точно с момента запуска функции. У вас же будет измеряться не пойми что и непойми как. Для периодического сигнала используют измерение таймером. Что-то типа этого вам нужно.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

День пишет:

При этом нужно считать испульсы выше 4,5В так чтобы от помех ничего не происходило :)

Вы читаете pulseIn'ом, т.е. просто счтаете HIGH состояние, а оно начинается от 0,6V (см. дадашит на ATMega328).
Если хотите считать от 4,5 - надо по другому это делать.
День
Offline
Зарегистрирован: 26.11.2015

Вот, начинает проясняться. Единственный оставшийся у меня вопрос - дигиспарк с тини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);
}

костыли в виде обвязки как я понял придётся оставить?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

День пишет:

Единственный оставшийся у меня вопрос - дигиспарк с тини85 судя по всему на 2-ом пине (если считать с 0) имеет вход на 7-ую ногу на таймер T0, то есть оный пример кода имеет место быть?

У этого метода есть ряд недостатков, но для вашего случая пожалуй подойдёт. Здесь таймер0 используется косвенно, его использует функция micros(), поэтому вход T0 не нужен, нужен INT0 Впрочем он на той-же 7 ноге.

День
Offline
Зарегистрирован: 26.11.2015

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

День
Offline
Зарегистрирован: 26.11.2015

На практике не всё так просто.

Импульсы совершенно случайны, даже на нажатие клаксона вырабатываются импульсные помехи. Не говоря уже о том что скорость - величина далеко не постоянная. Так что решил накапливать в массиве разницу между импульсами и уже затем в цикле отрабатывать проверку - если маленьких значений 70% - производить активацию реле.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Совершенно не понимаю как можно обсуждать и в конце концов не сделать частотомер....

День
Offline
Зарегистрирован: 26.11.2015

да я ж писал что механик :) с железяками проблем нет, решил изучить для себя другое, далёкое от меня. 

частотомер меряет частоту за время, я сделал тупо смену режима светика на rising и получил очень чудесатое мигание светика и при остановке автомобиля с неустойчивой частотой, вообще длительность импульсов очень плавно меняются в зависимости от скорости движения.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

День, частота измеряется двумя способами. Количество импульсов входного сигнала за единицу времени (это как раз "за время"), ваш скетч их #4 тоже на этом принципе.  Второй способ -измерение длительности периода сигнала через вход захвата таймера. Измеряется время между изменением логического уровня входного сигнала. Это очень быстродействующий способ измерения.  На скетч с подобным принцип работы я вам дал ссылку в #2.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Именно так. 
Низкие частоты:  измеряется время между фронтами импульсов.
Высокие частоты: измеряется количество импульсов за временнОе окно.

Считайте лучше сколько импульсов пришло за секунду. Так проще.
Прерыванием. И не забудьте РЦ чепочку поставить на входе.

З.Ы.  Была на машине сигналка- она закрывала двери на второе нажатие педали тормоза.
Мне это даже нравилось. Удобно закрывать  двери
Один раз проехал 300 км  (ранним утром) и был удивлён когда двери закрылись уже на въезде в Таллин.
Значит второе нажатие было только там.....

День
Offline
Зарегистрирован: 26.11.2015

За секунду я могу разогнаться по разному и тогда получится что в одном случае дверки заблокируются на скорости допустим 30км/ч, а при шустром разгоне - уже при 50-ти км/ч что внесёт определённый дискомфорт в мироощущение водителя :)

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

У меня на 5-10 км в час закрываются и никакого дискомфорта...