Счетчик сигнала

Lightsworn
Offline
Зарегистрирован: 17.03.2015

Доброго времени суток!
Я только начинаю познавать Ардуино и программирование. Интересует следующий скетч:

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

Читая "толковые словари" библиотек времени только сильнее запутываюсь. 
Как реализовать отсчет времени по появлению сигнала на пине? Как установить время отсутствия сигнала и последующее включение другого пина? Или моя логика построения задачи неверна? 

Буду признателен теоретической помощью и по возможности примером кода. 

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

в setup запоминаете миллис в переменную.

При входе в loop проверяете входной пин .

Если на нем сигнал, записываете текущий миллис в переменную из сетупа.

Проверяете  разницу между текущим миллис и запомненным значением.

Если она более 3 минут включаете другой пин.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Или моя логика построения задачи неверна? 

сколько пинов надо мониторить ?
что значит и последующее включение другого пина?  ? мониторить другой пин или другим пином что-то вкл-выкл ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

можно через прерывания и millis(), можно так http://arduino.ru/Reference/PulseIn

Lightsworn
Offline
Зарегистрирован: 17.03.2015

Мониторить только 1. 
"И псоледующее" если на пине "1" нет сигнала на протяжении 3 минут - включить пин "2".

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

а когда выключить пин 2 ?

Lightsworn
Offline
Зарегистрирован: 17.03.2015

Выключать не нужно ним ничего. Пин 2 должен перейти в HIGH.

По поводу PulseIn я думаю это решение. Невнимательно читал про него. Думал функция считывает длительность импульса.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

Lightsworn пишет:

Выключать не нужно ним ничего. Пин 2 должен перейти в HIGH.

По поводу PulseIn я думаю это решение. Невнимательно читал про него. Думал функция считывает длительность импульса.

хорошо... по другому спрошу :)
как пин 2 вернётся в LOW ? при выключении питания ?

Lightsworn
Offline
Зарегистрирован: 17.03.2015

Именно при выключении. )

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define inPin 2
#define outPin 8
unsigned long oldMillis;
//================================================================
void setup()
{                
  pinMode(inPin,INPUT); 
  pinMode(outPin,OUTPUT); 
  digitalWrite(outPin,LOW);
  oldMillis=millis();
  attachInterrupt(0,inSignal,RISING);
}
//================================================================
void inSignal()
{
  oldMillis=millis();
}
//================================================================
void loop()
{
  if((millis()-oldMillis)>180000)
  {
    digitalWrite(outPin,HIGH);
  }
}
//================================================================

ещё нужно добавить признак флаг сработки чтобы не гонять больше проверку времени - нужно ?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012
#define inPin 2
#define outPin 8
unsigned long oldMillis;
boolean start=1;
//================================================================
void setup()
{                
  pinMode(inPin,INPUT); 
  pinMode(outPin,OUTPUT); 
  digitalWrite(outPin,LOW);
  oldMillis=millis();
  attachInterrupt(0,inSignal,RISING);
}
//================================================================
void inSignal()
{
  oldMillis=millis();
}
//================================================================
void loop()
{
  if(start)
  {
    if((millis()-oldMillis)>180000)
    {
      digitalWrite(outPin,HIGH);
      start=0;
    }
  }
}
//================================================================

 

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

А так не надо?    volatile unsigned long oldMillis;

Lightsworn
Offline
Зарегистрирован: 17.03.2015
unsigned long oldMillis;
  boolean start=1;

Объясни пожалуйста этот момент.
 

 
 

oldMillis=millis();

 

Вначале приравниваем, а потом отнимаем?

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

trembo пишет:

А так не надо?    volatile unsigned long oldMillis;

надо обязательно, спасибо ! хотел через флаг сделать, но вспомнил что говорят millis() в прерываниях работает...
......а добавить волатильности забыл :(

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

millis() - это значение регистра внутренних "часиков" МК ( часики считают сколько прошло времени от запуска кода )
вычитание в лупе - это проверка сколько натикало
на каком-то очередном проходе лупа, например на 1562-ом, сработает условие

короче - значение миллис() увеличивается на 1 каждую миллисекунду ( независимо от чего-либо )

приравнивание - это засечка времени, включение секундомера :)
через 15 мин надо выключить газ ( суп ), вы смотрите на часы и делаете ПРИРАВНИВАНИЕ = 15:42, потом занимаясь другими делами каждые 30 сек смотрите на часы и вычитаете 15:47-15:42=5 - рано
..................................................................................................15:57-15:42=15 - пора выключать
15:42 в коде - это oldMillis()

:)

и исправьте код как trembo поправил в #11

Lightsworn
Offline
Зарегистрирован: 17.03.2015

Огромное спасибо, мужики! Выручили. Теперь буду мозговать сидеть все строчки до полной ясности.

Vanya_87
Offline
Зарегистрирован: 31.03.2015

всем привет. думаю темой не ошибся. 

вообщем ситуация такая: на аналоговый пин приходят импульсы,

1) нужно посчитать их кол-во и вывести в значение что бы можно было потом в формулу вбить

2) при отсутствие этих самых импульсов что бы значение становилось равным нулю.

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

написал вот такой вот код:

  if (millis() - previousMillis > 5) 
{
     previousMillis = millis();
  if (analogRead(SPEED_PIN) == 1)
     {speed_1;}
 else if (analogRead(SPEED_PIN) == 1)
    {speed_1 = 0;}}

надеюсь на Вашу помощь.

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

нееее, пристраиваться к чЮжой теме плохо..... непонятно кому отвечать - 1 , тема разбухнет на 300....500 постов :)

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

Vanya_87
Offline
Зарегистрирован: 31.03.2015

период - секунда

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

 

ладно, щас создам новую тему.

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

Иван,  какая, как вы думаете, вероятность того, что ваш аналогРид считает точно  "единицу" ?

Я думаю она будет 1  к 1023  и даже сильно меньше

"0" и всё что в диапазоне 2-1023  читаться у вас будет постоянно .  И почти никогда вы ваш импульс не увидете.

digitalRead ( A0 ) -  вот  чтение  вашего импульса.
А ещё лучше использовать прерывание на 2 или 3 ноге.