Прерывание и запись переменной в EEPROM помощь
- Войдите на сайт для отправки комментариев
Добрый день всем.
Прошу помочь со скетчем. Уже дней 5 изучаю как записать в память переменную ни чего не получается.
Ситуация такая: Ардуино уно на атмеге 328, выклвдываю только рабочий скетч, все что начинаю добовлять по записи и чтению EEPROM не работает(
принцип работы: в покое ни чего не делает, далее если нажата кнопка пин 13, по шим плавно разгорается светодиод (пин3), если при этом нажать кнопку пин 7 светодиод плавно гаснет, если ее отпустить опять плавно разгорается, все до заданных в программе значений.
Что нужно: чтоб по нажатию кнопки пин 8 происходило прерывание и я мог выбрать этой же кнопкой 4 параметра яркости светодиода, далее выбранный параметр сохранить в энергонезависимую память. И чтоб при перезапуске ардуино сохраненная переменная считывалась и применялась в основном цикле (чтоб светодиод загорал плавно не выше сохраненной переменной).
Вот код тот что работает, далее тупик:
int button = 13; //кнопка условие включения ламп
int gbr = 8; //габариты, условие выключения ламп
int led = 3; //ДХО лампы
int value;
void setup() {
pinMode(led, OUTPUT); //выход на лампы
pinMode(button, INPUT); //вход кнопки
pinMode(gbr, INPUT);
}
void loop(){
if ((digitalRead(button) == HIGH)&&(digitalRead(gbr) == LOW)&&(value<=0)) //кнопка нажата,габариты выкл, яркость 0
{
for (value = 0; value <= 75; value += 1) //плавно прибавляем яркость
{
analogWrite(led, value);
delay(20);
}
}
else if ((digitalRead(button) == LOW)&&(digitalRead(gbr) == HIGH)&&(value>=75))
{
for (value = 75; value >= 0; value -= 1)
{
analogWrite(led, value);
delay(20);
}
}
if ((digitalRead(gbr) == HIGH)&&(value>=75))
{
for (value = 75; value >= 0; value -= 5)
{
analogWrite(led, value);
delay(20);
}
}
if ((digitalRead(button) == LOW)&&(value>=75))
{
for (value = 75; value >= 0; value -= 1)
{
analogWrite(led, value);
delay(20);
}
}
}
Пробовал добавлять прерывание по кнопке, но перестает работать четыре режима настройки, если без прерывания поместить в лооп 4 режима переключаются, но если пытаться сохранить переменные вообще не коректно работает скетч. Помогите кто может.
int flag =0;
int regim = 1;
void setup() {
attachInterrupt(0, blink, FALLING);
void blink (){
if(digitalRead(pp)==HIGH&&flag==0)
{
regim++;
flag=1;
if(regim>4)//ограничим количество режимов
{
regim=1;//так как мы используем только одну кнопку,
}
}
if(digitalRead(pp)==LOW&&flag==1)//если кнопка НЕ нажата
//и переменная flag равна - 1 ,то ...
{
flag=0;//обнуляем переменную "knopka"
}
if(regim==1)//первый режим
{
int value2 = 10;
analogWrite(led, value2);
delay(1000);
}
if(regim==2)//второй режим
{
int value2 = 100;
analogWrite(led, value2);
delay(1000);
}
if(regim==3)//третий режим
{
int value2 = 150;
analogWrite(led, value2);
delay(1000);
}
if(regim==4)//четвертый режим
{
int value2 = 254;
analogWrite(led, value2);
delay(1000);
}
Зачем нам рабочий скетч, давайте тот что не работает.
Только правильно выкладывайте! В таком виде как у Вас его почти никто читать не будет (кроме тех, у кого приступ синдрома матери Терезы)
Вот, извиняюсь за неправильное размещение
#include <EEPROM.h> #define Led (3) //пин светодиода #define button 13 //кнопка парковки (и регулировки яркости) //pin 2; кнопка регулировки вызывается прерыванием #define gab 8 //вход габаритов int ledState; //яркость светодиода int flag=0; //переменная нажатий кнопок int regim=1; int address = 0; int value; void setup (){ pinMode(Led, OUTPUT); pinMode(button, INPUT); pinMode(gab, INPUT); attachInterrupt(0, Regul, FALLING); } void Regul() { if(digitalRead(button)==HIGH&&flag==0)//если кнопка нажата и перемення flag равна 0 , то ... { regim++; //это нужно для того что бы с каждым нажатием кнопки flag=1; //происходило только одно действие if(regim>4) //ограничим количество режимов { regim=1; //так как мы используем только одну кнопку,то переключать режимы будем циклично } } if(digitalRead(button)==LOW&&flag==1)//если кнопка НЕ нажата { flag=0;//обнуляем переменную "knopka" } if(regim==1)//первый режим { ledState = 25; analogWrite(Led, ledState); delay(10); } if(regim==2)//второй режим { ledState = 50; analogWrite(Led, ledState); delay(10); } if(regim==3)//третий режим { ledState = 70; analogWrite(Led, ledState); delay(10); } if(regim==4)//четвертый режим { ledState = 90; analogWrite(Led, ledState); delay(10); } EEPROM.update(address, ledState); address = address + 1; if (address == EEPROM.length()) { address = 0; } } void loop(){ EEPROM.get(address, ledState); if ((digitalRead(button) == HIGH)&&(digitalRead(gab) == LOW)&&(value<=0)) //кнопка нажата,габариты выкл, яркость 0 { for (value = 0; value <= ledState; value += 1) //плавно прибавляем яркость { analogWrite(Led, value); delay(20); } } else if ((digitalRead(button) == LOW)&&(digitalRead(gab) == HIGH)&&(value>=ledState)) { for (value = ledState; value >= 0; value -= 1) { analogWrite(Led, value); delay(20); } } if ((digitalRead(gab) == HIGH)&&(value>=ledState)) { for (value = ledState; value >= 0; value -= 5) { analogWrite(Led, value); delay(20); } } if ((digitalRead(button) == LOW)&&(value>=ledState)) { for (value = ledState; value >= 0; value -= 1) { analogWrite(Led, value); delay(20); } } }Строки 63-68 заменить на EEPROM.put(address, ledState);
74 строку перенести в setup.
Ну и delay в прерывании не работает да и не нужны они там.
Строки 63-68 заменить на EEPROM.put(address, ledState);
74 строку перенести в setup.
Ну и delay в прерывании не работает да и не нужны они там.
Поменял, работает только по 1 яркости, выбора режимов нет, сколько в первый regim установишь яркость до того состояния и разгорается.
Много и по разному нажимал кнопки, вроде как меняет режимы если почти одновременно нажимать две кнопки пин2 и пин13, но при этом зависает и не выходит в лооп.
А после ресета и нажатия на пин 13 и отпускании светодиод остаеться еле еле гореть.
Я только по еепром глянул, осталную логику не смотрел. Как минимум не понятно из описания, какие-то кнопки то на 13 пине то на 7м которого вообще нет, то на 8м по прерыванию при том что у уно внешние прерывания на 2 и 3 если память не изменяет.
Я только по еепром глянул, осталную логику не смотрел. Как минимум не понятно из описания, какие-то кнопки то на 13 пине то на 7м которого вообще нет, то на 8м по прерыванию при том что у уно внешние прерывания на 2 и 3 если память не изменяет.
сейчас закоментирую логику и скину
Вот обновленный и закоментированный
#include <EEPROM.h> #define Led (3) //пин светодиода #define button 13 //кнопка включения светодиода (и она же регулировка яркости при прерывании) //pin 2; кнопка вызова прерывания автоматом установленна attachInterrupt 0 #define gab 8 //кнопка если нажата выключает светодиод при любых условиях int ledState; //яркость светодиода 4 режима int flag=0; //переменная нажатий кнопок int regim=1; // режимы яркости светодиода int address = 0; int value; //яркость светодиода в лоопе void setup (){ pinMode(Led, OUTPUT); pinMode(button, INPUT); pinMode(gab, INPUT); EEPROM.get(address, ledState); attachInterrupt(0, Regul, FALLING); } void Regul() { //функия выбора 4 режимов максимальной яркости светодида if(digitalRead(button)==HIGH&&flag==0) { regim++; flag=1; if(regim>4) //ограничим количество режимов { regim=1; //переключать режимы будем циклично } } if(digitalRead(button)==LOW&&flag==1)//если кнопка НЕ нажата { flag=0;//обнуляем переменную "knopka" } if(regim==1)//первый режим { ledState = 0; analogWrite(Led, ledState); } if(regim==2)//второй режим { ledState = 50; analogWrite(Led, ledState); } if(regim==3)//третий режим { ledState = 100; analogWrite(Led, ledState); } if(regim==4)//четвертый режим { ledState = 254; analogWrite(Led, ledState); } EEPROM.put(address, ledState); //запись выбранного режима в переменную } void loop(){ if ((digitalRead(button) == HIGH)&&(digitalRead(gab) == LOW)&&(value<=0)) //если кнопка вкл нажата, кнопка выключения нет и светодиод не горит { for (value = 0; value <= ledState; value += 5) //плавно прибавляем яркость { analogWrite(Led, value); delay(20); } } else if ((digitalRead(button) == LOW)&&(digitalRead(gab) == HIGH)&&(value>=ledState)) //кнопка вкл выключена, кнопка выключения нажата и светодиод горит { for (value = ledState; value >= 0; value -= 5) //плавно выключаем светодиод { analogWrite(Led, value); delay(20); } } if ((digitalRead(gab) == HIGH)&&(value>=ledState)) //кнопка выключения нажата, светодиод горит { for (value = ledState; value >= 0; value -= 5) //плавно выключаем { analogWrite(Led, value); delay(20); } } if ((digitalRead(button) == LOW)&&(value>=ledState)) //кнопка вкл выключена, светодиод горит { for (value = ledState; value >= 0; value -= 5) //плавно гасим { analogWrite(Led, value); delay(20); } } }021
attachInterrupt(0, Regul, FALLING);Что у вас на 2 пине висит?021
attachInterrupt(0, Regul, FALLING);Что у вас на 2 пине висит?кнопка прерывания, подтянута резистором на плюс, при нажатии минус
Это ДХО будут? Опишите обычным языком русским без всяких мифических button что должно делаться. Тогда и сами поймете как делать.
Это ДХО будут? Опишите обычным языком русским без всяких мифических button что должно делаться. Тогда и сами поймете как делать.
Да ДХО, просто подумал, что тоже не все поймут кто не связан с авто.
то что должно быть я понимаю. Мне уже помогли с сохранением в память все работает, а загвоздка все в том что выбор яркости по прерыванию не могу понять как работает. Уловил закономерность, что надо нажать кнопку прерывания и держать ее, далее нажимаем кнопку выбора режима, потом надо быстро отпустить кн. прерывания за ней выбора. По иному ни как не выбирает режимы. Вот это и осталось отладить. За остальное большое спасибо всем кто помог.
Я бы совсем все по другому сделал, но раз нужны костыли и инвалидные коляски...
В прерывании ничего не проверяйте, просто увеличивайте режим на 1, в зависимости от режима задавайте лэдстэйт и записывайте в еепром и все. Выполнение вернется на то место где произошло прерывание, и сразу начнет работать с новым лэдстэйт, правда тогда возможны резкие изменения яркости.
Я бы совсем все по другому сделал, но раз нужны костыли и инвалидные коляски...
В прерывании ничего не проверяйте, просто увеличивайте режим на 1, в зависимости от режима задавайте лэдстэйт и записывайте в еепром и все. Выполнение вернется на то место где произошло прерывание, и сразу начнет работать с новым лэдстэйт, правда тогда возможны резкие изменения яркости.
Вам легко говорить, а я не профи в этом деле. На словах то понятно, а как реализовать не очень(
Перелопатил много информации и скажу, что даже где люди выкладывают примеры и пытаються учить, не все всегда работает. Поэтому и прошу помощи подсказать, направить. Как смог так и написал скетч, не смог разобраться почему не работает, хотя делаю как везде пишут, обратился сюда за помощью, с одной проблемой помогли. Одна осталась(
Сильно не вникал, но попробуйте так
void Regul() { regim++; if (regim > 4) regim = 1; switch(regim) { case 1: ledState = 0; break; case 2: ledState = 50; break; case 3: ledState = 100; break; case 4: ledState = 254; } analogWrite(Led, ledState); EEPROM.put(address, ledState); }т.е. нажимаете на кнопку которая на прерывании и у вас с каждым нажатием меняется режим и записывается в еепром. Но тут есть один момент, в еепром у Вас пишется значение ШИМ, а режим не пишется. Поэтому после перезагрузки у Вас ШИМ будет правильно работать но если захотите поменять режим он снова будет с единицы перебираться.
Сильно не вникал, но попробуйте так
Спасибо работает)))