Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
Есть Атмега328 с прошитым загрузчиком (16мгц). Я затеял управление лампой на радиомодуле Использую RemoteReceiver.h
Проблема в ттом, что я бы хотел сделать плавное включение и выключения. Для этого использую функцию Delay, но она в моей коде работает некоректно. Т.е ставлю Делэй(500) и зная что 255*0,5 будет 125 сек, а цикл проходит за 1.5 сек. Понимаю что, функция void showCode() завязана где то на прерывании, так как радиомодуль подключен к 4 ноге ардуино (Int0).Может быть в этом проблема. создал подобный вопрос на http://arduino.ru/forum/programmirovani ... rovka-shim но там так и не смогли мне помочь. Даю весь код
Код:
// include the library code: #include <LiquidCrystal.h> #include <RemoteReceiver.h> #include <avr/eeprom.h>
// initialize the library with the numbers of the interface pins //LiquidCrystal lcd(12, 11, 5, 4, 3, 2); LiquidCrystal lcd(12, 11, 5, 4, 6, 7); //const unsigned long receivedCode=0; void setup() { // set up the LCD's number of columns and rows: lcd.begin(16, 2); // Print a message to the LCD. //lcd.print("hello, world!"); //Connect the receiver to digital pin 2.-пин 2.это вход для Радиоприёмника RemoteReceiver::init(0, 3, showCode); pinMode(8, OUTPUT); pinMode(13, OUTPUT); pinMode(9, OUTPUT); //шим на выход, там частот около 1кгц // Пины D9 и D10 - 31.4 кГц (Переопределяем частоту ШИМ) TCCR1A = 0b00000001; // 8bit TCCR1B = 0b00000001; // x1 phase correct }
void showCode(unsigned long receivedCode, unsigned int period) { lcd.clear(); lcd.print(":"); lcd.print(receivedCode); lcd.print(",p:"); lcd.print(period);
int AR6; int AR; // on if (receivedCode==66100) { AR6 =eeprom_read_byte(0); //AR6=255; AR=0; while (AR<=AR6) { analogWrite(9, AR); AR=AR+1; //delay(500); lcd.setCursor(0, 1); lcd.print(AR); } } // off if (receivedCode==66132) { AR6 =eeprom_read_byte(0); do { analogWrite(9, AR6); AR6=AR6-1; delay(500); lcd.setCursor(0, 1); lcd.print(AR6); } while (AR6>0) ; } // ступенчатое увеличение яркости if (receivedCode==66099) { lcd.setCursor(0, 1); lcd.print(AR6); AR6 =eeprom_read_byte(0); AR6=AR6+20; if (AR6>255) {AR6=255;}// analogWrite(9, AR6); // якрость eeprom_write_byte(0,AR6); lcd.setCursor(0, 1); lcd.print(AR6); } // ступенчатое уменьшение яркости if (receivedCode==66105) { AR6 =eeprom_read_byte(0); AR6=AR6-20; if (AR6<10) {AR6=10;}// ничего не делаем - яркость минимальная analogWrite(9, AR6); // якрость eeprom_write_byte(0,AR6); lcd.setCursor(0, 1); lcd.print(AR6); }
У вас delay() вызывается только в одном случае, когда if (receivedCode==66132). И сдается мне, что колбэк showCode() вызывается только раз, когда приходит новый код. Что вообще на LCD вывод в этом случае показывает? Уменьшается плавно ваше AR6 или как?
Значит наверное RemoteReceiver::init вешает колбэк showCode() на прерывание. И пока у вас с 1го срабаывания работает delay() уже вызывается новое прерывание и повторно ф-я showCode() еще до окончания прошлого delay(). Чтобы это проверить, попробуйте так поменять кусок кода с delay():
Код:
if (receivedCode==66132) { AR6 =eeprom_read_byte(0); do { analogWrite(9, AR6); AR6=AR6-1; cli(); delay(500); lcd.setCursor(0, 1); lcd.print(AR6); sei(); } while (AR6>0) ; }
Но это не хорошо так делать. Вообще длительные задержки в прерывании - зло. Но проверить сойдет, чтобы не лезть в исходники RemoteReceiver
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
но вставка сама по себе Дэлей() с любым значением приводи к плавному 1.5 секунднгму гашению/разгорнию. Без Дэлей() светодиод вспыхивает без задержки.
Ну так без delay() у вас там цикл, который конечно же пробегает моментально. А тут когда срабатывает прерывание по приходу нового кода.
Вообще правильно когда сработало прерывание - проверили код и в некую переменную записали себе что было нажато и в какое состояние мы переходим. А уже затем в цикле loop() если значение этой переменной равно нужному действию - там плавно и гасим. Тогда новые прерывания не будут мешать.
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
NStorm писал(а):
ообще правильно когда сработало прерывание - проверили код и в некую переменную записали себе что было нажато и в какое состояние мы переходим. А уже затем в цикле loop() если значение этой переменной равно нужному действию - там плавно и гасим. Тогда новые прерывания не будут мешать.
вот это мне и нужно. Спасибо. буду пробовать так организовать совй код. Пока правда мысле нет. Надо сосредоточиться
p..s. c остановками прерывание по cli и sei ничего не вышло. Все осталось попреженму
счас еще ради смеха протестирую for(int m=0; m<100;m++) { delay(100); lcd.setCursor(0, 1); lcd.print(AR); }
и буду делать нормаьлно.
Добавлено after 2 minutes 29 seconds: вот это получилось for(int m=0; m<100;m++) { delay(100); lcd.setCursor(0, 1); lcd.print(AR); } работате с непонятно задержкой правда, но медленно
Добавлено after 1 hour 19 seconds: все переписал под loop, списибо
NStorm, как так получается что я пишу eeprom_write_byte(0,255);
а в память ложиться ff. Это такая фишка среды ардуино,что бы я не волновался?
Добавлено after 1 minute 17 seconds: то же самое и при чтении из еепрома!
Это во "внутренностях функции" упрятано - Си не ассемблер, как привести в реальный набор команд решает сам компилятор. Простому пользователю те "дебри" особо не требуются. Во встроенной (off-line) помощи ардуиноIDE есть все необходимые примеры по базовым функциям. ( C:\Program Files\Arduino\reference\www.arduino.cc\en\Reference запустить файл HomePage.html )
А вот "расширенные" уже потребуют подключения к инету...
Карма: 14
Рейтинг сообщений: 115
Зарегистрирован: Сб май 21, 2016 11:04:52 Сообщений: 2957 Откуда: Беларусь
Рейтинг сообщения:0
т.е получается что если я ему float с плавающей точкой "скормлю" в память, он (Ардуин) мне без труда оттуда в том самом виде вернет? Надо попробовать! То.есть и память сам распределит и на байты этот число нашинкует?
Добавлено after 1 minute 33 seconds: Удобно, конечно, если это так.
Two 8-bit Timer позволяет плавно включать и выключать лампу с шагом 0...255. One 16-bit Timer позволяет плавно включать и выключать лампу с шагом 0...65535.
... Для плавное включение и выключения в Атмега328 есть аж целых 3 таймера !
Вложение:
Screenshot_1.jpg
Two 8-bit Timer позволяет плавно включать и выключать лампу с шагом 0...255. One 16-bit Timer позволяет плавно включать и выключать лампу с шагом 0...65535....
Это при работе под ассемблером или Си "в чистом виде" - при работе в рамках референса ардуиноIDE необходимо учитывать его особенности применения. Там таймеры участвуют в определенных системных функциях. Посему при фривольном их использовании могут иметь место "нежданчики" довольно сложного происхождения. Собственно там также Си да еще и с добавкой С++... НО... имеют место и дополнительные функции из встроенных библиотек - нечто вроде базового БИОС/ОС, в которых уже задействуются аппаратные ресурсы МК. Работу с "DIP-микросборкой" упрощают, но добавляют своей специфики. Данные о тех "нюансах" к сожалению приходится по разным источникам самому выискивать. Вот, к примеру, одна цитатка из не помню уже какой(чьей) книжи - ("добавка", которую надо учитывать работая с самодельными функциями внешних прерываний): "... внутри функции обработки прерывания не работает функция delay(), значения, возвращаемые функцией millis(), не изменяются. Возможна потеря данных, передаваемых по последовательному соединению (Serial data) в момент выполнения функции обработки прерывания. Переменные, изменяемые в функции, должны быть объявлены как volatile. ..."
Кстати... у адуринки весьма неплохой симулятор имеется (UNO V3, megaV3): https://radiokot.ru/forum/viewtopic.php ... 5#p3901095 Работает на компах начиная с ХР sp3 и выше Да еще и "стандартную" внешнюю обвязку симулирует...
"Ардуиноподобные" всего лишь один из видов элементной базы, содержащих различные МК и сопутствующую периферию. Выполняются в виде платок формата "DIP-микросборка". Могут содержать как AVR (самые первые) так и ARM, ESP8266 и иные МК или микропроцессоры. Обрабатываются как обобщенной IDE (arduino IDE), так и любыми известными пользователю средами, применяемыми в отношении установленных на платках МК. Однако обладают "двойственностью" в правилах применения: 1. можно использовать как DIP-микросборку и создавать программу в рамках референса ардуиноIDE 2. нужно достать схему конкретной платки и работать с установленными на ней компонентами под ассемблером или Си. Оба варианта одинаково применимы - но во втором случае надо поднимать гораздо больше документации, ибо на платках не только один МК устанавливается.
В то же время стиль программирования в каждом случае будет заметно отличаться. В первом - это ближе к обработке данных и связи с внешней "периферией с мозгами" с применением протоколов последовательного обмена плюс частичное управление "лаподрыгом". А уж прикладное применение в обработке данных делают внешние СБИС (специализированные или на основе самоделок на МК). Требует от программиста соблюдения некоторых самоограничений, как платы за "универсальность подхода" к различным МК. Во втором - это обычная работа с МК, правда с учетом уже выполненного фрагмента схемы минимальной обвязки, который имеется на платке адуринки. Тут все зависит от желания и целей автора проекта.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения