Нужна помощь- считывание мигающего светодиода.
- Войдите на сайт для отправки комментариев
Поставил перед собой такую задачу:
Имеется 5 светодиодов на плате. по этим пяти светодиодам можно узнать состояние устройства.
Светодиоды могут: гореть, не гореть, мигать с частотой 2Гц, мигать с частотой 4 Гц.
Я хочу подключиться к этим 5-ти светодиодам с помощью Arduino Uno, считывать состояние всех пяти светодиодов и вывести сообщение через сериал в монитор ноута.
Всего 6 различных сочетаний горения светодиодов.
1) 1-0-0-1-(1)
2) 0-(1)-1-0-((1))
3) 0-((1))-1-0-((1))
4) (1)-0-1-0-((1))
5) ((1))-0-1-0-((1))
6) 0-0-1-0-((1))
где
0-выключенный светодиод
1-включенный светодиод
(1)-светодиод мигает с частотой 2Гц
((1))-светодиод мигает с частотой 4 Гц.
Для каждого из 6-ти случаев у меня есть готовое сообщение на русском языке, которое должно serial printиться.
Начинаю: подсоединяю 5 светодиодов к входам 3,4,5,6,7 на ардуине.
const int Led1= 3;
const int Led2= 4;
const int Led3= 5;
const int Led4= 6;
const int Led5= 7;
void setup() {
pinMode(Led1, Input);
pinMode(Led2, Input);
pinMode(Led3, Input);
pinMode(Led4, Input);
pinMode(Led5, Input);
}
void loop() {
if (Led1=High, Led2=Low, Led3=Low, Led4=High, Led5=Flash2);
serialprint= "срочно протрите стекло сканера. Устройство в работе."
else
if (Led1=Low, Led2=Flash2, Led3=HIgh, Led4=Low, Led5=Flash4)
serialprint= "Потрите стекло и перезапустите сканер"
Вот тут я и растерялся- написал пока Flash2 и Flash4, что значит мигание с частотой 2 либо 4 герца.
Как устроить циклическую проверку мигания светодиодов?
Аналоговые или цифровые входы использовать?
К шим входам надо подключать или всё равно...
Прошу помочь разобраться как грамотно написать такое...
dinovasya, тут возможны варианты алгоритмов. Первое, что пришло в голову - делать блоки считывания скажем по 2 секунды, с периодом например 10ms. Каждый пин опрашивается, и если его состояние меняется, то счётчик в течении 2 секунд инкременируется. Если не меняется, то считанное значение не инкременируется. Таким образом получим в конце функции переменные, в которых будут лежать либо единицы, либо нули, либо какие-то числа. По их значению этих чисел можно определить, что это было 2гц или 4гц.
Мнекажется что надо опрашивать все светодиоды в течении скажем, менее 2 секунд, чтоб не нарваться на изменение данных во время измерения..
Какие функции использовать нужно?
>Для каждого из 6-ти случаев у меня есть готовое сообщение на русском языке, которое должно serial printиться.
А вы вообще пытались что-нибудь на русском выводить? ну так, чисто перед тем как "в алгоритмы занырнуть"?
А вы вообще пытались что-нибудь на русском выводить? ну так, чисто перед тем как "в алгоритмы занырнуть"?
тс-с-с-с.... не спугни!
а по сути задачи замечания
1) комбинация диодов 4-5-6 горит всего в двух вариантах, поэтому можно вместо этих трех опрашивать только какой-нибудь один, например 4, а 5 и 6 однозначно от него зависят
2) диоды разные бывают, и на 1.5в, и на 3.4в. надо бы с уровнем сигнала определиться. взять и померить вольметром.
3) у моргания какая скважность? может, можно поставить/подобрать сглаживающий фильтр, чтобы потом просто читать (почти)постоянный уровень сигнала? он может быть разный при 2 гц и 4 гц
Если научиться опрашивать, то без разницы сколько комбинаций, вдруг там еще какие нить потом комбинации вылезут...
Не столь важно. главное до токоограничивающего резистора подключиться.
А зачем?, если это решается програмно
Если зная что сигнал меняется 4 раза в секунду (4 Гц). считывать его с частотой в 4 раза ваше (из теории сигналов достаточно в 2 раза выше, но нам же надо наверняка) . т.е. 16 Гц. (1 / 16 = 0.0625 сек ) Считывать по таймеру. Каждые 8 считываний проводить анализ полученных данных . Для 5 светодиодав имеем 5 массивов данных
со следующими вариантами
1) 11111111 - диод всегда включен
2) 00000000 - диод всегда выключен
3) 11001100 - мигание 4 гц, доп варианты (10011001, 00110011, 01100110)
4) 11110000- мигание 2 гц (11100001, 11000011, 10000111, 00001111 и т.д)
Далее для варианта 3 поочереди 8 раз проверяем смещеное на байт значение с 11001100. (ну или тупо сравниваем с разными комбинациями, благо из немного) Если хотябы 1 из 8 совпало то значит мигает с 4 гц. Для варианта 4 - аналогично
т.е. время определения состояния светодиода 0.0625 сек * 8 = 0.5 сек.
А нафига так сложно? Повышать частоту измерений, быть привязанным к точности времени
Что такое частота? Это "сколько раз он поменял свое состояние" за единицу времени.
Ну вот и берем, скажем "2 сек", с запасом, определяется самой "малой частотой".
Ну и считаем сколько раз он поменял свой state за это время. больше 6-ти - значит имеем 4 гц. Больше 3-рех - значит имеем 2 гц. Меньше... ну значит либо "горит постоянно", либо "не горит". Что именно - выясняем сделав digitalRead.
Все. Никаких массивов, никаких сдвигов....
Если нам потребуется детектить 10-ть частот, а не две, то.... на не нужно будет перебирать мульен вариантов. Комбинаторный же взрыв.
Не могу сказать что предложеный вариант легче, но в том что он будет работает, я не сомневаюсь.
В моев вариате вам никто не мешает переходы считать. При 4 Гц - 2 перехода из 0 в 1 (3 или 4 смены состояний), при 2 Гц- 1 переход из 0 в 1 (1 или 2 смены состояний). У dimax что то похожее на мое решение было, тока 10 ms не обосновано...
Я предлагал завиксировать время между измерениями, Вы предлагаете общее время измерения зафиксировать - способ выбирается кому как удобно :)
>Вы предлагаете общее время измерения зафиксировать
В первую очередь я предлагаю "фиксировать количество изменений". А тупо увеличивать какой-то счетчик и потом посмотреть "сколько там натикало", всяко легче чем:
1. Хранить "историю".
2. Анализировать ее (подсчеты, сравнение с паттернами-вариантами).
Ну и требование "к точности выдерживания таймингов" - ниже. Можно все делать "плюс/минус полметра". Ну и можно пользоватся аппаратными прерывания, для ловли изменений. Что тоже упрощает задачу.
Но вообщем, согласен - дело вкуса и предыдущего опыта (человек склонен повторять "сработавшие" приемы).
да уж... тема-то не из легких, как мне казалось раньше..
Кстати да, на русском не получалось выводить- латинскими буквами по-русски писал.
А что если просто на всех 5-ти пинах ожидать сигнала, и как только один из них получит сигнал- сразу же опросить все остальные..
>А что если просто на всех 5-ти пинах ожидать сигнала,
Гуглите "arduino pin change interrupt" (не attachInterrupt)
Я тут попробывал набить скетчик для одного пина по мотивам топикстартера - однако работает :) Специально на другой дуне сделал 2 генератора, -определяются точно, только гуляет на один отсчёт. На 2-х герцах -7..8 инкрементов, на 4х герцах 15-16 инкрементов.)
Если светик просто включится или выключится, то есть будет скажем одно изменение. То у вас получится "2Hz".
Так что, все-таки нужно и минимальное количество проверять. И если "меньше минимального", то... выводить нужно не первую читку, а "еще раз считать", что-бы вывести именно текущие состояние. (ну или инвертировать "первую читку" в зависимости от четности/не четности каунтера).
leshak, Вот так сделал, лучше пусть пойдёт на новый цикл. Сообщение вылезло один раз, когда надевал штырёк на выход генератора 4hz.
А зачем ему "вылазить" и оттягивать момент отчета? По условиям задачи - абсолютно шаттная ситуация.
В чем сложность сдлать?
if
(counter1 <6)
Serial
.println(
digitalRead(vxod)?"IsON":"IsOff");
Честно говоря "не тестил", лениво мне "генератор собирать" :) Но общая идея, думаю понятна. Мухи (анализ) - отдельно, Увеличение счетчика (котлеты) - отдельно. Никаких "первый чтений" и т.п. Вообщем то что я словами описывал в #7 закожено.
Проверил. на 2 гц всегда пишет 4 гц, когда надеваешь штырёк на +5 вольт может тоже написать 4 гц. Для скетча без отладки хороший результат :)
>на 2 гц всегда пишет 4 гц,
Ну на конкретные цифры я мозг не хмурил.Скорее от ваших отталкивался. Попробуйте в первом услоивии >6, как я "прикдывал в уме", в #7
Это не учитывая что мы еще не видили кода "тесктового генератора" :)
>когда надеваешь штырёк на +5 вольт может тоже написать 4 гц.
А вы не допускаете что "когда одеваешь", то там в реальности и 20 kГц может быть? Требезг контактов будет почти наверняка и весьма основальный.
>Для скетча без отладки хороший результат :)
спасибо ;)
P.S. Можете просто сделать println(cnt), увидеть какие реальные показатели счетчика, тогда и думать какие границы в if записать не прийдется.
leshak, да, при cnt>6 чётко показывает 2 герца! (добавлено позже: что-то я не туда посмотрел- вот после чего заработало: if(cnt>=15) Serial.println("4Hz"); else if(cnt>6) Serial.println("2Hz");
В моём скетче не было ложных считываний, у меня все глючные ругаются "неудачная попытка" :)
А генератор у меня простейший..:
> у меня все глючные ругаются "неудачная попытка" :)
Так почему же "неудачная"? По условиям задачи это вполне "штатная ситуация". И при ее детектировании тоже нужно сообщить "что же проиходит", а не "мы потом попробуем еще раз".
Иначе у вас "сбивается" регулярность отчетов.
А когда пинов будет несколько.... из за одного отказываться от чтения всех? Этак можно вообще не дождаться пока все 6-ть светиков будут в PWM-мить. Или вы хотите для каждого отдельно заводить prevmillis и дублировать всю логику переодичности? Это тоже как-то "мнэээ".
leshak, смотрел ваш скетч ещё раз, и никак не пойму, почему у вас не инкременируется счётчик, при чтении статического состояния HIGH ?
Если разбирать по строчкам, то: (2) prevState=0, (3) state=1, (4) ноль не равен 1- условие сработало, (5) счётчик инкременировался, (6) prevState стал 1. При следующем вызове prevState снова 0, и снова всё повторется с инкрементацией счётчика. Что я упускаю из виду? )
Вторая строка, слово static
Вторая строка, слово static
Ясности не добавилось, мне с разжёвыванием пожалуйста :)
А погуглить? От Вас не ожидал :)
Статик переменная инициализируется один раз. Так понятней? Лень писать больше, док море, почитайте
kisoft, всё, разобрался! static я иногда использовал что-бы сохранить содержимое выходя из функции. Поэтому совершенно не понял, для чего вы мне о нём говорите, ( ну сохраняет он, и что? пронеслось в голове :) Не знал, что попытка повторной инициализации с присваиванием конкретного значения не меняет переменной. В голову бы не пришло. Об этом не написано в справочнике. Оказывается всё можно делать проще, мне приходилось другими путями решать некоторые вопросы, например строчка 10 в 12 сообщении, как раз такой случай.
Я на практике часто со статиком сталкиваюсь, но чаще со статическими методами классов, а Статик переменные не люблю использовать. Но для ардуины вполне хороший метод использовать глобальные-локальные переменные, тут все проще и нет миллиона строк кода :)