Морзянка, моргаем 2 светодиодами без задержки... RTOS?
- Войдите на сайт для отправки комментариев
привет всем!
Делаю маленькое устройство, и не хочу ставить туда нормальный индикатор... Есть меню1 : 1-2-3-4 Меню2 1-2-3..9
Хочется поставить 2 светодиода, и они должны моргать оба, морзянкой. кол-во морганий == положение в меню. Все через прервывание, ничего дергать из loop не хочется. Кол-во светодиодов не обязательно 2. Хочется на пример подключить еще и вибромотор, который можно на пример 1 раз дернуть при смене меню вниз, 2 раза вверх и Тире, "остановка". Светодиды, и мотор работают на разных "частотах"
Зачем изобретать велосипед?. Может кто-то уже написал подобное? В какую сторону я думаю. Взять библиотеку Timer2, и на ее основе написать. добавить туда список следующих событий. Событие: {задержка, номер порта, новое состояние} . Прерывание: берется первый элемент из списка, выполняется, стирается из стека, таймер настраивается на следующий элемент... Проблема сводится только к библиотеке отсортированных arraylist. Но все еще не понятно как добавлять "циклические последовательности". Мелодия разложенная на шаги может получиться относительно длинной...
Короче я избретаю RTOS... У кого-нибудь есть идеи, или может видел библиотеку, как такое просто надежно сделать? вызывать run из loop категорически отказываюсь.
если моргать морзянкой , то на каждый пункт меню 5 морганий комбинацией коротких и длинных вспышек . для обычного пользователя это будет каторгой . а почему не ii2c и дисплей , это займет столькоже дата выводов что и 2 светодиода
Можно сдвиговый регистр и 8 светодиодов. В двоичной системе покажет 256 положений.
если моргать морзянкой , то на каждый пункт меню 5 морганий комбинацией коротких и длинных вспышек . для обычного пользователя это будет каторгой . а почему не ii2c и дисплей , это займет столькоже дата выводов что и 2 светодиода
На самом деле важно не второй светодиод, а вибромотор. Что бы нажал на кнопку и получил feedback, что команда дошла. Так как пользователь один и это я, и реально режимов всего 3, а второй параметр это "интенсивность" то это логичнее, чем дисплей.
На самом деле эта библиотека мне пригодится и в других проектах. На пример крутить 2 шаговых мотора...
achest, из вашего словесного описания всё равно не очень понятно, что же конкретно вы хотите. Я когда изучал таймеры в ардуине, то писал простенький скетч, там от некоего события, (в моём случае нажатие на кнопку), запускается таймер, и по определённой программе дёргает ногой. Может посвистеть в динамик, может поморгать светодиодом, или пожужжать виброй, -по вкусу. Программу (строка 11) можно менять, она не привязана жёстко. Никакого loop разумеется ) Вкратце о принципе работы: По нажатию кнопки (висящей на прерывании) запускается таймер2, и создаёт каждые 10миллисекунд прерывание. В векторе прерывания переменной n идёт подсчёт числа вхождений, если счёт совпадает с переменными a..e то инвертируется указанная нога порта. C первым входом включается нога 13. Переменная А -выключает её спустя a*10 мс, переменная b снова включает спустя b*10мс от первого входа, и так далее. Когда программа выполнится таймер отключается. По-моему примерно о этом вы и говорили, только набор переменных нужно подставлять для каждого события свой.
byte a,b,c,d,e; void setup() { pinMode(13,OUTPUT);// светодиод на 13 ноге pinMode(2,INPUT_PULLUP); //knopka attachInterrupt(0, key_start, FALLING); TCCR2A=(1<<WGM21)|(1<<WGM20); //FastPWM TIMSK2=0; TCCR2B=0; OCR2A=155; // every 10 ms interrupt } void key_start(){ a=10;b=15;c=35;d=40;e=50; TCNT2=0; TIMSK2=1<<TOIE2; TCCR2B=15; } ISR (TIMER2_OVF_vect) { static byte n=0; if (!n){PORTB|=1<<5;} //первый вход, включаем 13 ногу n++; if (n==a||n==b||n==c||n==d||n==e) {PORTB ^= (1<<5); } if (n==e){ PORTB&=~(1<<5); n=0; TCCR2B=0; TIMSK2=0; } } void loop() { }Спасибо за участие. Я к сожалению мыслю все еще на Java и концепты у меня OO. Я хочу написать более-менее универсальную библиотеку. т.е. Кол-во светодиодов и как они будут моргать оно не известно...
Мой конечный код может выглядеть примерно так:
#inclule"timecommander" int menu1; int menu2; int led1pin = 9; int led2pin = 10; int vibropin=11; void setup() { timeCommander.init(); timeCommander.AddCommand(1,LOW,led1pin, led1Callback); timeCommander.AddCommand(1,LOW,led2pin, led2Callback); } void loop () { if ( Key1Pressed()) { menu1++; // Включили вибромотор на 500 мс. timeCommander.AddCommand (1, HIGH, viborpin, null); timeCommander.AddCommand (500, LOW, viborpin, null); } if ( Key2Pressed()) { menu2++; // Включили вибромотор на 200 мс. timeCommander.AddCommand (1, HIGH, viborpin, null); timeCommander.AddCommand (200, LOW, viborpin, null); } ... } void led1Callback() { // Моргнули светодиодом menu1 раз . for(int i=0; i< menu1 ; i++ ) { timeCommander.AddCommand(100,HIGH,led1pin, null); timeCommander.AddCommand(100,LOW,led1pin, null); } // цикл закончился. Сначала пауза. Потом добавили себя еще раз. timeCommander.AddCommand(500,LOW,led1pin, led1Callback); } void led2Callback();Мне не понятно только как реализовать стек с вставками/ отсортировать список по возрастанию, что бы библиотека определяла только время следующего события, беря событие из одного списка.