Алгоритм проверки состояния светодиода

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Приветствую уважаемые!
Думаю думаю и все не могу придумать как лучше реализовать следующую задачу:

необходимо за определенное количество времени (в моем случае за 10 секунд) определить состояние светодиода, которое может быть либо 0, либо 1 или 2, где
0 - выключен
1 - все время включен
2 - мигает

Т.е я мониторю светодиод в течении 10 секунд и на выходе получаю состояние.
Сначала думал мониторить в течении 10 секунд с задерхкой в 100 миллисекунд количество положительных импульсов, соответственно если 100 из 100, то светодиод горит всегда, если 0 из 100, то не горит, ну а мигает надо брать количество положительных импульзов делить грубо говоря пополам, если как минимум 50 положительных то он мигает.
Но возникла проблема...если светодиод моргнул 2 раза у нас насчиталось 20 положительных импульсов, потом он начал гореть и на выходе мы получили например 80 из 100, то выходит что он как бы мигает по логике, но на самом деле горит. Поэтому как определить именно диапазон мигания светодиода?

Вот как я делал это, но как оказалось неверно

//состояние светодиода
const byte led_state_off = 0;
const byte led_state_on = 1;
const byte led_state_blink = 2;
 
//Считываем светодиод в течении 10 секунд по 10 значений в секунду
const byte TICK_COUNTER = 100;
byte CheckLedState()
{
  byte res = 0;
  byte sumTick = 0;
  //Суммируем все значения светодиода за 100 считываний за 10 секунд
  //Задержка 100 миллисекунд, цикл до 100, получается 10 считываний в секунду
  for (byte i = 0; i < TICK_COUNTER; i++)
  {
    delay(TICK_COUNTER);
    sumTick += digitalRead(led_pin_in);
  }
  //передаем считанные значения в функцию анализа, чтобы понять в каком состоянии светодиод
  res = LedAnalize(sumTick);
  sumTick = 0;
  return res;
}
 
//Функция анализа считанных значений светодиода за 10 секунд
const byte MINLEDEDGE = 10;
const byte MAXLEDEDGE = 90;
byte LedAnalize(byte summary)
{
  //тут эмпирическим путем считаем что границы мигания светодиода = половине от значений если всегда вкл
  //примерно от 10 до 90 положительных значений
  if (summary < MINLEDEDGE)
    return led_state_off;
  else if (summary > MAXLEDEDGE)
    return led_state_on;
  else return led_state_blink;
}

Получается каким образом обойти ситуацию когда светодиод мигнул например 3ы а потом загорелся? По сути необходимо для анализа как минимум из 5 миганий за 10 секунд как минимум 4, чтобы знать что он именно мигает, при условии что он мигает раз в секунду.

gena
Offline
Зарегистрирован: 04.11.2012

 Так ведь Вам решать, что Вам важнее: то что моргнул пару раз или то, что потом постоянно светится. Складывается впечатление, что Вы сами не знаете, что Вам важнее знать.

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

Ваша проблема в том, что Вы не определили точно понятие "мигает". Дайте точное определение этого понятия и всё станет на свои места. Пока же его нет, Вы вечно будете ... "а если 1 раз миннул, это мигает или нет?" "а если два раза?" "а если сначала горел, потом погас и больше не загорался?" и т.п. Кроме того, мигает - это с какой-то частотой или беспорядочно тоже можно? В общем, это понятие нуждается в чётком определении.

Кроме того, Ваш алоритм не выдерживает никакой критики. Вы хотите проверять состояние светодиода с некоторой частотой. Так вот если частота мигания совпадёт с частотой Вашей проверки, то при каждой проверке он будет в каком-то одно и том же состоянии и Вы посчитаете, что он и не мигает вовсе.

Я бы заводил его на прерывание по CHANGE и просто считал бы сколько раз изменилось его состояние за время наблюдения не привязываясь ни к какой частоте.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 И зачем определять состояние светодиода, если вы им управляете.  Вот сам скетч https://yadi.sk/d/U_gtAoSN3AtYSM

И главный файл 

/* class_Led.ino  https://yadi.sk/d/U_gtAoSN3AtYSM
  #1 светодиод ->13
  #2 кнопка 1 -> 2 вкл светодиод
  #3 кнопка 2 -> 3 светодиод мигает
  #4 кнопка 3 -> 4 выкл светодиод
*/
// #1 светодиод
#include "Cl_led.h"
const byte led1_pin = 13;
Cl_led Led1; // создать
// #2 кнопка
#include "Cl_do_btn.h"
const byte btn1_pin = 2;
Cl_do_btn Do_btm1; // создать
void func_1() {
  Led1.ON();
}
// #3 кнопка
const byte btn2_pin = 3;
Cl_do_btn Do_btm2; // создать
void func_2() {
  Led1.OFF();
}
// #4 кнопка
const byte btn3_pin = 4;
Cl_do_btn Do_btm3; // создать
void func_3() {
  Led1.blink();
}
void setup() {
  //#1 светодиод
  Led1.T_blink = 500;
  Led1.logic = 1;
  Led1.setup(led1_pin);
  //#2 кнопка 1
  Do_btm1.setup(btn1_pin);
  //#3 кнопка 2
  Do_btm2.setup(btn2_pin);
  //#4 кнопка 3
  Do_btm3.setup(btn3_pin);
}

void loop() {
  // #1 светодиод
  Led1.loop();
  // #2 кнопка 1
  Do_btm1.loop(& func_1);
  // #3 кнопка 2
  Do_btm2.loop(& func_2);
  // #4 кнопка 3
  Do_btm3.loop(& func_3);
}

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

KorPaEv
Offline
Зарегистрирован: 24.11.2014

ЕвгенийП пишет:

Ваша проблема в том, что Вы не определили точно понятие "мигает". 

Я бы заводил его на прерывание по CHANGE и просто считал бы сколько раз изменилось его состояние за время наблюдения не привязываясь ни к какой частоте.

На самом деле определился уже. Просто надо определить точные границы при которых мы будем считать, что светодиод именно в состоянии мигания.

В моем случае светодиод пульсирует с частотой в 1 секунду, стало быть за 10 секунд я получаю 5 положительных импульсов. Либо же в моем случае диапазон от 40 до 50 положительных импульсов - соответственно светодиод моргнул 4-5 раз.

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

Ну, и делайте. Только не вздумайте его периодически опрашивать. Надеюсь Вы поняли почему это нельзя делать (см. второй абзац моего предыдущего поста).

KorPaEv
Offline
Зарегистрирован: 24.11.2014

ЕвгенийП пишет:

Ну, и делайте. Только не вздумайте его периодически опрашивать. Надеюсь Вы поняли почему это нельзя делать (см. второй абзац моего предыдущего поста).

тогда каким образом мне мониторить состояние светодиода в течении скажем 2-3-4-5 часов?

мне придется его опрашивать все равно некоторыми периодами - в данном случае я выбрал по 10 секунд..

как бороться с подобной ситуацией которую вы описали?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Похоже тема вылилась в анекдот: Британские ученые провели долгие исследования и выяснили, что они "британские ученые".  Когда закончите свои исследования со светодиодом, перейдите к исследованию кнопки. Надо определить долбит народ по ней или просто регулярно на нее нажимает.

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

KorPaEv пишет:

тогда каким образом мне мониторить состояние светодиода в течении скажем 2-3-4-5 часов?

мне придется его опрашивать все равно некоторыми периодами - в данном случае я выбрал по 10 секунд..

как бороться с подобной ситуацией которую вы описали?

Вы, похоже, вообще ничего не поняли. Когда я говорил про периодичность. я говорил не про 10 секунд, а про Вашу идею (из первого поста) опрашивать светодиод каждые 100мс в течение этих 10 секунд. Так вот опрашивать надо не каждые 100мс, а в течение этих 10сек непрерывно, как я описывал.

KorPaEv
Offline
Зарегистрирован: 24.11.2014

qwone пишет:

Похоже тема вылилась в анекдот: Британские ученые провели долгие исследования и выяснили, что они "британские ученые".  Когда закончите свои исследования со светодиодом, перейдите к исследованию кнопки. Надо определить долбит народ по ней или просто регулярно на нее нажимает.

причем тут исследование кнопки и ваши исходники выше вообще?!

есть задача! у меня стоит генератор, если он не заводится сам с 3х попыток при отсутствии фазы на входе, то об этом сигнализирует светодиод на панеле. Лезть в мозги генератора смысла нет. Алгоритм самого генератора не совсем простой чтобы учитывать все его параметры. Достаточно считывать его текущее состояние и отправлять мне результат.

KorPaEv
Offline
Зарегистрирован: 24.11.2014

ЕвгенийП пишет:

KorPaEv пишет:

тогда каким образом мне мониторить состояние светодиода в течении скажем 2-3-4-5 часов?

мне придется его опрашивать все равно некоторыми периодами - в данном случае я выбрал по 10 секунд..

как бороться с подобной ситуацией которую вы описали?

 Так вот опрашивать надо не каждые 100мс, а в течение этих 10сек непрерывно, как я описывал.

Понял о чем вы. Спасибо. Но все равно надо будет выяснять диапазон положительных импульсов. Может в тех документации к генератору есть инфо какие данные на выходе у него.

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

KorPaEv пишет:

есть задача! у меня стоит генератор, если он не заводится сам с 3х попыток при отсутствии фазы на входе, то об этом сигнализирует светодиод на панеле. Лезть в мозги генератора смысла нет. Алгоритм самого генератора не совсем простой чтобы учитывать все его параметры. Достаточно считывать его текущее состояние и отправлять мне результат.

эээ... казалось бы, а при чём тут светодиод?

если бы сигнализатором была пожарная сирена, то ея состояние нужно было бы проверять?

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

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Клапауций 823 пишет:

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

проблема только зимой..в сильные морозы сам он при длительном ожидании, скажем недельном, с первого пинка не заводится. Как правило, заводится с 4го сам...а для этого надо выкл-вкл зажигание ручками. Потому как новые 3 попытки получаем после вкл-выкл зажигания. Так работают его мозги. Либо же в моем случае посмотреть состояние, отправить мне если не завелся и получить обратно команду, чтобы дернуть реле зажигания. В иные сезоны стартует с первого раза.

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

KorPaEv пишет:

проблема только зимой..в сильные морозы сам он при длительном ожидании, скажем недельном, с первого пинка не заводится. Как правило, заводится с 4го сам...а для этого надо выкл-вкл зажигание ручками. Потому как новые 3 попытки получаем после вкл-выкл зажигания. Так работают его мозги. Либо же в моем случае посмотреть состояние, отправить мне если не завелся и получить обратно команду, чтобы дернуть реле зажигания. В иные сезоны стартует с первого раза.

ок. сначала.

ты находишься на ресурсе arduino.ru - не на avto.ru

на ресурсе arduino.ru под термином "генератор" подразумевают примерно это https://en.wikipedia.org/wiki/Signal_generator

====================

ну, ок. и что тебе запрещает сделать digitalRead(pin) через 20 секунд после старта генератора?

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

почему у тебя там светодиод мигает? - всё очень мутно и не понятно.

генератор завёлся - появилось напряжение, впень светодиод.

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Клапауций 823 пишет:

почему у тебя там светодиод мигает? - всё очень мутно и не понятно.

генератор завёлся - появилось напряжение, впень светодиод.

начнем сначала) Светодиод просто отражает текущее состояние самого генератора. Это могло быть что угодно, даже цифровые значение на LED дисплее или вовсе выход последовательного порта.

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

Почему я не привязываюсь к выходному напряжению? потому что писал выше - алгоритм работы генератора замудреный, есть куча ситуаций когда генератор может завестись но на выходе будет 0...Там есть так называемый прерыватель напряжения, когда при перегрузке сети срабатывает автомат. Тогда генератор продолжает работать но на выходе 0. Поэтому состояние прерывателя я тоже считываю. Далее - генератор после запуска не сразу подает напряжение в сеть, а только тогда, когда прогреется и время прогрева зимой не однозначно. Поэтому я и привязался к выходу который отображает текущее состояние генератора после всех вышеизложенных действий.

На этом выходе куча состояний, которые я считываю, анализирую и произвожу желаемые действия.

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

ок.

тогда расшифруй режимы работы генератора, когда светодиод:

0 - выключен
1 - все время включен
2 - мигает

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Клапауций 823 пишет:

ок.

тогда расшифруй режимы работы генератора, когда светодиод:

0 - выключен
1 - все время включен
2 - мигает

так в этом и состояла суть вопроса изначально) как определить диапазон этих самых значений в режиме мигания) Вроде как уже все ответы даны, поэтому можно тему закрывать!

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

KorPaEv пишет:

так в этом и состояла суть вопроса изначально) как определить диапазон этих самых значений в режиме мигания) Вроде как уже все ответы даны, поэтому можно тему закрывать!

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

ок. не нуно, так не нуно.

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Клапауций 823 пишет:

ок. не нуно, так не нуно.

Почему же,  я с радостью прочту ваши предложения!

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

KorPaEv пишет:

Почему же,  я с радостью прочту ваши предложения!

ну, и? #15

мне какие-то особые реверансы нужно сотворить, что бы ты начал сотрудничать, а не прикидываться?

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Клапауций 823 пишет:

ну, и? #15

мне какие-то особые реверансы нужно сотворить, что бы ты начал сотрудничать, а не прикидываться?

Собственно как то так и получается. Подумал, есть какие то нюансы..

const byte MINLEDEDGE = 20;
const byte MAXLEDEDGE = 90;
const byte AMINLEDEDGE = 40;
const byte AMAXLEDEDGE = 50;

byte LedAnalize(byte summary)
{
  if (summary < MINLEDEDGE)
    return led_state_off;
  else if (summary > MAXLEDEDGE)
    return led_state_on;
  else if (summary > AMINLEDEDGE && summary < AMAXLEDEDGE)
    return led_state_blink;
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ведь что такое мигание, это РЕГУЛЯРНАЯ смена состояния. В вашей же системе мегает же светодиод не с частотой раз в день. Выдерите какую-то временую константу (1 сек,0.5 сек, 0,2 сек) и если ваш светодиод не сменил состояние в течении этого времени, то он НЕ МИГАЕТ. Осталось найти временую точку, когда последний раз светодиод поменял показания и разница между текущим и тем состоянием покажет, мигал светодиод или уже находится в зафиксированом состоянии.

ПС: дорога к использованию к millis(). И еще в системах реального времени используются 3 вещи:millis(), millis() и еще раз  millis().

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

KorPaEv пишет:

Собственно как то так и получается. Подумал, есть какие то нюансы..

ок. иди нахуй.

KorPaEv
Offline
Зарегистрирован: 24.11.2014

qwone пишет:

Ведь что такое мигание, это РЕГУЛЯРНАЯ смена состояния. В вашей же системе мегает же светодиод не с частотой раз в день. Выдерите какую-то временую константу (1 сек,0.5 сек, 0,2 сек) и если ваш светодиод не сменил состояние в течении этого времени, то он НЕ МИГАЕТ. Осталось найти временую точку, когда последний раз светодиод поменял показания и разница между текущим и тем состоянием покажет, мигал светодиод или уже находится в зафиксированом состоянии.

ПС: дорога к использованию к millis(). И еще в системах реального времени используются 3 вещи:millis(), millis() и еще раз  millis().

Сразу бы так. Спасибо!

KorPaEv
Offline
Зарегистрирован: 24.11.2014

Клапауций 823 пишет:

KorPaEv пишет:

Собственно как то так и получается. Подумал, есть какие то нюансы..

ок. иди нахуй.

Ума палата нахуй посылать...

Клапауций 823
Клапауций 823 аватар
Offline
Зарегистрирован: 13.01.2017

KorPaEv пишет:

Клапауций 823 пишет:

KorPaEv пишет:

Собственно как то так и получается. Подумал, есть какие то нюансы..

ок. иди нахуй.

Ума палата нахуй посылать...

у меня одного осчущение, что кто-то играется с ботом?

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

Voodoo Doll
Voodoo Doll аватар
Offline
Зарегистрирован: 18.09.2016

KorPaEv, вот это считает миганием любые изменения состояния за период, включенным - горение не менее целого периода, откл - ни одной вспышки за весь период, с указанным разрешением (100 мс). Период равен 8*8*разрешение (9600 мс).

#define led_pin_in (1)
unsigned long timestamp=millis();
byte led_state[8];
void setup(){
  pinMode(led_pin_in,INPUT);
}
void loop(){
  byte i;
  int chksum=0;
  if(millis()-timestamp>=100){
    for(i=7;i>=0;i--){
      led_state[i]<<=1;        // shift one byte left in all bytes
      if(i>0) bitWrite(led_state[i-1],0,bitRead(led_state[i],7));  // copy prev MSB to next LSB
    }
    bitWrite(led_state[7],digitalRead(led_pin_in),0);   // overwrite last byte LSB
    timestamp=millis();            // set next interval
  }
  for(i=0;i<=7;i++) chksum+=led_state[i];
  if(chksum==2048){
    // led always on
  }else if(chksum==0){
    // led always off
  }else{
    // led blink
  }
}