Форум программистов, компьютерный форум, киберфорум
Arduino
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
1

Состояние светодиода

25.01.2017, 13:36. Просмотров 2037. Ответов 17
Метки нет (Все метки)

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

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

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

Вот как я делал это, но как оказалось неверно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//состояние светодиода
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, чтобы знать что он именно мигает, при условии что он мигает раз в секунду.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
25.01.2017, 13:36
Ответы с готовыми решениями:

Потенциометр и 3 светодиода
начала знакомство с ардуино есть 3 светодиода и потенциометр При повороте потенциометр на...

Определение габарита светодиода
как расшифровать габариты, по типоразмеру? есь светодиод http://www.chipdip.ru/product/lyt676-q.aspx

Плавное нарастание яркости светодиода
надо сделать так чтоб светодиод медленно загорался

Параметры светодиода 5AR4PD (5013HD)
Помогите узнать: 1.Прямое напряжение светодиода 2.Прямой ток светодиода Хочу подобрать резистор,...

17
339 / 327 / 68
Регистрация: 18.03.2015
Сообщений: 1,141
26.01.2017, 18:56 2
Считать количество переключений (вкл-выкл и выкл-вкл) за определенный период и не заморачиваться со скважностью.
1
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
27.01.2017, 07:21  [ТС] 3
Сергей 190, Уже так и реализовал. Спасибо!
0
techpriest
631 / 210 / 57
Регистрация: 27.02.2014
Сообщений: 1,170
27.01.2017, 14:17 4
Если вам примерно известна частота, имеет смысл отсчитывать время от момента последнего переключения.

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

Таким образом можно будет изменить десятисекундные замеры на работу в реальном времени.
1
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
28.01.2017, 14:26  [ТС] 5
Mirmik, Проблема еще в том что возникает иногда ситуация когда в момент подачи питания на систему, при запуске светодиод моргает 2 раза и сигнализирует о том что система запустилась, потом переходит в состояние либо вкл, либо выкл, либо пульсирует...Так вот без замеров по количеству смен состояний, может получиться что первые 2 пульса отработают как состояние пульсирования а это неверно.

Добавлено через 22 часа 20 минут
Сергей 190, Не совсем понятно как определить последовательность вкл-выкл и выкл-вкл...
сейчас я считаю таким образом как раз количество
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unsigned long timestamp = 0;
unsigned long loopTime = 0;
byte CheckLedState()
{
  byte res = 0;
  byte sumTick = 0;
 
  loopTime = millis() - timestamp;
  if (loopTime <= 10000)
  {
    if (digitalRead(led_pin_in) == 1)
      sumTick += digitalRead(led_pin_in);
    return;
  }
  timestamp = millis();
 
  res = LedAnalize(sumTick);
  sumTick = 0;
  return res;
}
0
339 / 327 / 68
Регистрация: 18.03.2015
Сообщений: 1,141
28.01.2017, 15:34 6
Цитата Сообщение от KorPaEv Посмотреть сообщение
определить последовательность вкл-выкл и выкл-вкл...
Не совсем понял про последовательность. Если диод включен он не может опять включиться, только вЫключиться. И наоборот.
Произошло изменение состояния диода делаем sumTick ++;
0
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
28.01.2017, 16:26  [ТС] 7
Сергей 190, просто сейчас как видишь у меня на протяжении 10 секунд все время идет чтение состояния...Я так понял ты предлагаешь ввести флаг какой то и соответственно плючовать sumTick только при изменении состоянии, т.е не всегда?
0
Модератор
8137 / 6013 / 799
Регистрация: 14.02.2011
Сообщений: 20,780
28.01.2017, 16:42 8
KorPaEv, есть еще один путь, осилишь или нет?
считывать состояние ноги с частотой, допустим 100 Гц, потом преобразование Фурье
и можешь выделить постоянную и переменную составляющую
Цитата Сообщение от KorPaEv Посмотреть сообщение
необходимо за определенное количество времени (в моем случае за 10 секунд) определить состояние светодиода,
как будешь поступать если светодиод 5 секунд моргает 5 секунд горит?
0
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
28.01.2017, 16:54  [ТС] 9
ValeryS, Если он 5 секунд моргает и 5 секунд горит, то не наш случай) все это придется в функции анализа прописать...Смотри - у нас по сути 3 варианта
1 - Когда светодиод горит всегда на протяжении 10 секунд у меня по алгоритму sumTick сплюсуется всего один раз..
2 - Аналогично когда он не горит
3 - Теперь случай когда он моргает все 10 секунд - по сути это sumTick / 2 мой случай - это в идеальном варианте. Если в момент мигания он стал гореть, то импульсов будет как минимум (sumTick / 2) + 1 так? это уже не наш случай.

Ну а если по вашему предложению, то да надо считывать состояние с частотой 50-100 герц в течении тех же 10 секунд и оценивать количество положительных импульсов. Но тут есть проблема - может так получиться что частота мигания совпадёт с частотой проверки, тогда при каждой проверке он будет в каком-то одном и том же состоянии и получится, что он и не мигает вовсе.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
unsigned long timestamp = 0;
unsigned long loopTime = 0;
byte sumTick = 0;
boolean ledFlagOn = true;
boolean ledFlagOff = true;
byte CheckLedState()
{
  byte res = 0;
  loopTime = millis() - timestamp;
  if (loopTime <= 10000)
  {
    if (digitalRead(led_pin_in) == 1 && ledFlagOn)
    {
      sumTick++;
      ledFlagOn = false;
      ledFlagOff = true;
    }
    else if (digitalRead(led_pin_in) == 0 && ledFlagOff)
    {
      sumTick++;
      ledFlagOn = true;
      ledFlagOff = false;
    }
    return;
  }
  timestamp = millis();
 
  logger.LogPrintlnStr("sumTick = " + String(sumTick, DEC));
   
 res = LedAnalize(sumTick);
 
  sumTick = 0;
  ledFlagOn = true;
  ledFlagOff = true;
 
  return res;
}
0
Модератор
8137 / 6013 / 799
Регистрация: 14.02.2011
Сообщений: 20,780
28.01.2017, 17:24 10
Цитата Сообщение от KorPaEv Посмотреть сообщение
Но тут есть проблема - может так получиться что частота мигания совпадёт с частотой проверки,
классика
Теорема Котельникова, частота дискретизации должна быть выше максимальной частоты, минимум в два раза
Цитата Сообщение от KorPaEv Посмотреть сообщение
Если он 5 секунд моргает и 5 секунд горит, то не наш случай) все это придется в функции анализа прописать...
придется фазу то как ловить?
0
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
28.01.2017, 17:59  [ТС] 11
ValeryS, Так все таки каким путем пойти?) что лучше реализовать? какой алгоритм?
0
339 / 327 / 68
Регистрация: 18.03.2015
Сообщений: 1,141
28.01.2017, 20:36 12
Цитата Сообщение от KorPaEv Посмотреть сообщение
что лучше реализовать? какой алгоритм?
Тут матанализ надо вспоминать.
Зачем вводить два флага? Не проще ли ledFlag = true – включен, ledFlag = false – вЫключен.
0
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
29.01.2017, 15:13  [ТС] 13
Цитата Сообщение от Сергей 190 Посмотреть сообщение
Тут матанализ надо вспоминать.
Зачем вводить два флага? Не проще ли ledFlag = true – включен, ledFlag = false – вЫключен.
Уже убрал флаг, но все таки не понятно пока, если заранее не известна частота пульсирования светодиода, то каким образом мне вычислить ситуацию когда он именно мигает за заданный промежуток времени..
0
339 / 327 / 68
Регистрация: 18.03.2015
Сообщений: 1,141
29.01.2017, 22:19 14
Лучший ответ Сообщение было отмечено KorPaEv как решение

Решение

Цитата Сообщение от KorPaEv Посмотреть сообщение
каким образом мне вычислить ситуацию когда
На ардуине реализовать искусственный интеллект сложновато.

Думаю, необходимо в приказном порядке задать начальные условия, что считать миганием (min/max длительности импульса, частоты, скважности, количества).
Разрисовать временные диаграммы возможных вариантов. Когда перед глазами будут картинки, найти математические отличия проще.
1
339 / 327 / 68
Регистрация: 18.03.2015
Сообщений: 1,141
29.01.2017, 22:27 15
Примерно так
1
Миниатюры
Состояние светодиода  
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
30.01.2017, 06:32  [ТС] 16
Сергей 190, как вариант, кстати, мне предложил один преподаватель физики ввести свой сгенерированный сигнал на заданный временной участок...тогда мы всегда с точностью будем знать в каких местах у нас есть пересечение нашего текущего значения по светодиоду с нашим постоянным сгенерированным сигналом, соответственно определить границы уже по сгенерированному сигналу - тут уже как вы сказали - если 3-4-5 пересечений, то пусльсирует, если меньше то горит или не горит.
Тогда независимо от того какой у нас текущий сигнал мы сможем определить состояние.
+ можно сигнал сгенерированный самим регулировать по параметрам.
0
techpriest
631 / 210 / 57
Регистрация: 27.02.2014
Сообщений: 1,170
30.01.2017, 10:39 17
Ребят. Десятисекундные замеры, это априори плохо. Во первых система неотзывчива, во вторых получается, что поведение ее нестационарно.

Предлагаю записывать времена десяти - двадцати последних переключений и вывод о текущем состоянии светодиода проводить на основе их анализа. Тогда останется определиться с критерием мигания светодиода и с включенным и выключенным состоянием все станет предельно ясно. И система опять же будет работать в реальном времени.
1
57 / 33 / 8
Регистрация: 08.07.2011
Сообщений: 209
30.01.2017, 12:04  [ТС] 18
Mirmik, т.е получается как то так?

1 - При запуске системы (еще не знаем в каком состоянии светодиод) отлавливаем импульс
2 - Поднимаем флаг, вкл или выкл светодиод
3 - Смотрим если состояние не меняется тупо ждем
4 - Если состояние изменилось, то +1 счетчик изменения состояний
5 - Меняем флаг
6 - Ждем дальше, если состояние меняется то +1 счетчик

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

7 - Если счетчик состояний > 10 или 20 и время между замерами более менее равномерное то светодиод моргает - возвращаем результат
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.01.2017, 12:04

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

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

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

Время мигания светодиода в Arduino UNO
Здравствуйте я приобрёл себе Arduino UNO и при загрузки в его sketch на мигание 13 светодиода он...

Вопрос по поводу дистанционного включ/выключения светодиода
Привет Люди! Сам я в микроэлектронике полный 0, так что особо не пинать. Не знаю, правильно ли...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.