Прерывание и запись переменной в EEPROM помощь

matrixk
Offline
Зарегистрирован: 21.02.2018

Добрый день всем.

Прошу помочь со скетчем. Уже дней 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);
        }
        }

}

matrixk
Offline
Зарегистрирован: 21.02.2018

Пробовал добавлять прерывание по кнопке, но перестает работать четыре режима настройки, если без прерывания поместить в лооп 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);
                   }

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Зачем нам рабочий скетч, давайте тот что не работает.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Только правильно выкладывайте! В таком виде как у Вас его почти никто читать не будет (кроме тех, у кого приступ синдрома матери Терезы) 

matrixk
Offline
Зарегистрирован: 21.02.2018

Вот, извиняюсь за неправильное размещение

#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);
        }
        }
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Строки 63-68 заменить на EEPROM.put(address, ledState);

74 строку перенести в setup.

Ну и delay в прерывании не работает да и не нужны они там.

matrixk
Offline
Зарегистрирован: 21.02.2018

Penni пишет:

Строки 63-68 заменить на EEPROM.put(address, ledState);

74 строку перенести в setup.

Ну и delay в прерывании не работает да и не нужны они там.

Поменял, работает только по 1 яркости, выбора режимов нет, сколько в первый regim установишь яркость до того состояния и разгорается.

Много и по разному нажимал кнопки, вроде как меняет режимы если почти одновременно нажимать две кнопки пин2 и пин13, но при этом зависает и не выходит в лооп.

А после ресета и нажатия на пин 13 и отпускании светодиод остаеться еле еле гореть.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Я только по еепром глянул, осталную логику не смотрел. Как минимум не понятно из описания, какие-то кнопки то на 13 пине то на 7м которого вообще нет, то на 8м по прерыванию при том что у уно внешние прерывания на 2 и 3 если память не изменяет.

matrixk
Offline
Зарегистрирован: 21.02.2018

Penni пишет:

Я только по еепром глянул, осталную логику не смотрел. Как минимум не понятно из описания, какие-то кнопки то на 13 пине то на 7м которого вообще нет, то на 8м по прерыванию при том что у уно внешние прерывания на 2 и 3 если память не изменяет.

сейчас закоментирую логику и скину

matrixk
Offline
Зарегистрирован: 21.02.2018

Вот обновленный и закоментированный

#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);
        }
        }
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

021
attachInterrupt(0, Regul, FALLING);

Что у вас на 2 пине висит?

matrixk
Offline
Зарегистрирован: 21.02.2018

qwone пишет:

021
attachInterrupt(0, Regul, FALLING);

Что у вас на 2 пине висит?

кнопка прерывания, подтянута резистором на плюс, при нажатии минус

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Это ДХО будут? Опишите обычным языком русским без всяких мифических button что должно делаться. Тогда и сами поймете как делать.

matrixk
Offline
Зарегистрирован: 21.02.2018

Penni пишет:

Это ДХО будут? Опишите обычным языком русским без всяких мифических button что должно делаться. Тогда и сами поймете как делать.

 

Да ДХО, просто подумал, что тоже не все поймут кто не связан с авто.

то что должно быть я понимаю. Мне уже помогли с сохранением в память все работает, а загвоздка все в том что выбор яркости по прерыванию не могу понять как работает. Уловил закономерность, что надо нажать кнопку прерывания и держать ее, далее нажимаем кнопку выбора режима, потом надо быстро отпустить кн. прерывания за ней выбора. По иному ни как не выбирает режимы. Вот это и осталось отладить. За остальное большое спасибо всем кто помог.

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Я бы совсем все по другому сделал, но раз нужны костыли и инвалидные коляски...

В прерывании ничего не проверяйте, просто увеличивайте режим на 1, в зависимости от режима задавайте лэдстэйт и записывайте в еепром и все. Выполнение вернется на то место где произошло прерывание, и сразу начнет работать с новым лэдстэйт, правда тогда возможны резкие изменения яркости.

matrixk
Offline
Зарегистрирован: 21.02.2018

Penni пишет:

Я бы совсем все по другому сделал, но раз нужны костыли и инвалидные коляски...

В прерывании ничего не проверяйте, просто увеличивайте режим на 1, в зависимости от режима задавайте лэдстэйт и записывайте в еепром и все. Выполнение вернется на то место где произошло прерывание, и сразу начнет работать с новым лэдстэйт, правда тогда возможны резкие изменения яркости.

 

Вам легко говорить, а я не профи в этом деле. На словах то понятно, а как реализовать не очень(

Перелопатил много информации и скажу, что даже где люди выкладывают примеры и пытаються учить, не все всегда работает. Поэтому и прошу помощи подсказать, направить. Как смог так и написал скетч, не смог разобраться почему не работает, хотя делаю как везде пишут, обратился сюда за помощью, с одной проблемой помогли. Одна осталась(

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Сильно не вникал, но попробуйте так

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);
}

т.е. нажимаете на кнопку которая на прерывании и у вас с каждым нажатием меняется режим и записывается в еепром. Но тут есть один момент, в еепром у Вас пишется значение ШИМ, а режим не пишется. Поэтому после перезагрузки у Вас ШИМ будет правильно работать но если захотите поменять режим он снова будет с единицы перебираться.

matrixk
Offline
Зарегистрирован: 21.02.2018

Penni пишет:

Сильно не вникал, но попробуйте так

Спасибо работает)))