Проект с кнопкой и светодиодами

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Элементы проекта

- 3 светодиода

- arduino uno

- кнопка

Задача:

1. Первое нажатие кнопки > на 10 сек включается led1 > постоянно мигает led2

2. Второе нажатие кнопки > на 10 сек включается led3 > постоянно горит led2

Вопрос:

- некоректно работает кнопка (может срабатывать с первого раза а может и с третего а может и с пятого)

- как сохранить состояние led2 после перепадов напряжения?

const int buttonPin = 2;
const int ledPin1 = 8;
const int ledPin2 = 7;
const int ledPin3 = 4;

void setup(){
               pinMode(ledPin1, OUTPUT);
               pinMode(ledPin2, OUTPUT);
               pinMode(ledPin3, OUTPUT);
               pinMode(buttonPin, INPUT);
            }

void loop(){
            digitalRead(buttonPin);
              delay(20);
			  
            while(!digitalRead(buttonPin)){}
              delay(20);
              digitalWrite(ledPin1, HIGH);
              delay(500);
              digitalWrite(ledPin1, LOW); 
              digitalWrite(ledPin2, HIGH);
  
            while(digitalRead(buttonPin)){}
              delay(20);

        do {
             digitalWrite(ledPin2, HIGH);
             delay(500);
             digitalWrite(ledPin2, LOW);
             delay(500);
	        }
            while(!digitalRead(buttonPin));
   
             delay(20);
             digitalWrite(ledPin3, HIGH);
             delay(500);
             digitalWrite(ledPin3, LOW);
  
            while (digitalRead(buttonPin)){}
             delay(20);
             digitalWrite(ledPin2, HIGH);
}

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

MARKSIST пишет:

Вопрос:

- некоректно работает кнопка (может срабатывать с первого раза а может и с третего а может и с пятого)

Разве это вопрос? Это утверждение.

Правильно делает, что так работает. Если Ваше нажатие пришлось на "delay()" то оно будет проигнорировано. Именно это Вы и наблюдаете.

MARKSIST пишет:

- как сохранить состояние led2 после перепадов напряжения?

Что Вы понимаете под "перепадами" - выключение и включение вновь? Если так, то пишите в постоянную память (EEPROM) (см. https://www.arduino.cc/en/Reference/EEPROM )

 

MARKSIST
Offline
Зарегистрирован: 16.07.2015

ЕвгенийП пишет:

Разве это вопрос? Это утверждение.

Правильно делает, что так работает. Если Ваше нажатие пришлось на "delay()" то оно будет проигнорировано. Именно это Вы и наблюдаете.

И как подскажете с этим боротся? спасибо

ЕвгенийП пишет:

Что Вы понимаете под "перепадами" - выключение и включение вновь? Если так, то пишите в постоянную память (EEPROM) (см. https://www.arduino.cc/en/Reference/EEPROM )

да выключение и включение вновь.

The page "" doesn't exist.

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

MARKSIST пишет:

И как подскажете с этим боротся? спасибо

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

MARKSIST пишет:

The page "" doesn't exist.

Сорри, конечно, но привыкайте смотреть на линки - тут часто какой-нибудь дебильный проблем в линку затешется. Достаточно его удалить. Вот и в данном случае - пробел  в конце :(

https://www.arduino.cc/en/Reference/EEPROM

 

 

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Спасибо за delay. Я просто начитался что есть дребежание контактов и натыкал delay. 

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Все тот же проэкт

Разобрался как записать и прочитать байт с eeprom но не понятно как записать в eeprom постоянное свечение или мигание светодиода и востановить его состояние после вкл/выкл платы. Буду очень признателен за подсказки. СПС


const int buttonPin = 2;
const int ledPin1 = 7;
const int ledPin2 = 4;
const int ledPin3 = 8;

void setup(){
               pinMode(ledPin1, OUTPUT);
               pinMode(ledPin2, OUTPUT);
               pinMode(ledPin3, OUTPUT);
               pinMode(buttonPin, INPUT);
            }

// октрываем клапан
void on(){
          while(!digitalRead(buttonPin)){} //пока кнопка не нажата ждем  
          digitalWrite(ledPin2, HIGH);
          delay(1000);
          digitalWrite(ledPin2, LOW);
  
          digitalWrite(ledPin1, HIGH); //индикатор горит
          while(digitalRead(buttonPin)){} //пока кнопка еще нажата ждем
         }	

// закрываем клапан
void off(){
           while(!digitalRead(buttonPin)){}; //пока кнопка не нажата ждем
           digitalWrite(ledPin3, HIGH);
           delay(1000);
           digitalWrite(ledPin3, LOW);
  
              do{                          
                 digitalWrite(ledPin1, HIGH);
                 delay(250);
                 digitalWrite(ledPin1, LOW);
                 delay(250); //индикатор мигает
	            }
                while(!digitalRead(buttonPin));                   
          }		 
			
void loop(){
              digitalRead(buttonPin); //считываем состояние кнопки 		                    
              on();	//открываем клапан		             			           
              off(); //закрываем клапан             
}			 
MARKSIST
Offline
Зарегистрирован: 16.07.2015

и всt таки не понимаю как реализовать. Я уже сделал переменную которой присваивается определенное значение в зависимости от состояния клапана. А вот как записать это значение в EEPROM и считать его после отключения и включения питания... ?

#include <EEPROM.h>

const int buttonPin = 2;
const int ledPin1 = 7;
const int ledPin2 = 4;
const int ledPin3 = 8;
int addr = 0;
byte count;
int val;
void setup(){
               pinMode(ledPin1, OUTPUT);
               pinMode(ledPin2, OUTPUT);
               pinMode(ledPin3, OUTPUT);
               pinMode(buttonPin, INPUT);
               Serial.begin(9600);
               val = EEPROM.read(addr);
               Serial.println(val);
            }

// октрываем клапан
void on(){          
          while(!digitalRead(buttonPin)){} //пока кнопка не нажата ждем  
          digitalWrite(ledPin2, HIGH);
          delay(1000);
          digitalWrite(ledPin2, LOW);  
          digitalWrite(ledPin1, HIGH); //индикатор горит 
          while(digitalRead(buttonPin)){} //пока кнопка еще нажата ждем
          count = 1;
          Serial.println(count);
          EEPROM.write(addr, count);
         }	

// закрываем клапан
void off(){           
           while(!digitalRead(buttonPin)){}; //пока кнопка не нажата ждем
           digitalWrite(ledPin3, HIGH);
           delay(1000);
           digitalWrite(ledPin3, LOW);
           count = 2;
           Serial.println(count);
           EEPROM.write(addr, count);
              do{                          
                 digitalWrite(ledPin1, HIGH);
                 delay(250);
                 digitalWrite(ledPin1, LOW);
                 delay(250); //индикатор мигает
	            }           
                while(!digitalRead(buttonPin));              
          }		 
			
void loop(){
              digitalRead(buttonPin); //считываем состояние кнопки 	
              on();	//открываем клапан               
              off(); //закрываем клапан   
           }			 

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

тебе не состояние клапана нужно запоминать, а булевое значение переменной, которую ты меняешь кнопкой и при её изменении пишешь в EEPROM.

состояние клапана, поддерживаешь равным переменной, считанной из EEPROM

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

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Та пускай будут эти дилеи они мне не мешают.

Мне важнее всего востановить последнее состояние механизма при отключении.

Вот тут у меня просто затык!!! Если не сложно хоть примерчик приблизительный. Спасибо.

vvadim
Offline
Зарегистрирован: 23.05.2012

и Энгельс, и Троцкий, и даже товарищ Сталин согласны, что делеи с кнопками не дружат...

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

MARKSIST пишет:

Та пускай будут эти дилеи они мне не мешают.

они тебе мешают.

MARKSIST пишет:

Мне важнее всего востановить последнее состояние механизма при отключении.

Вот тут у меня просто затык!!! Если не сложно хоть примерчик приблизительный. Спасибо.

блин. куда уж проще.

digitalWrite(pin, EEPROM.read(address));

 

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Клапауций 322 пишет:

блин. куда уж проще.

digitalWrite(pin, EEPROM.read(address));

Да но если светодиод мигает то как это мигание загнать в значение которое нужно подставлять вместо pin?

Как записать в EEPROM мигание?

Подкоректировал 

#define LED_PIN_BLINC  7
#define LED_PIN_ON  4
#define LED_PIN_OFF  8
#define BUTTON  2
#define INTERVAL  50UL
static unsigned long previousMillis = 0;

void setup(){
               pinMode(LED_PIN_BLINC, OUTPUT);
               pinMode(LED_PIN_ON, OUTPUT);
               pinMode(LED_PIN_OFF, OUTPUT);
               pinMode(BUTTON, INPUT);
               Serial.begin(9600);             
            }

// октрываем клапан
void on(){          
          while(!digitalRead(BUTTON)){} //пока кнопка не нажата ждем  
          digitalWrite(LED_PIN_ON, HIGH);
          delay(1000);
          digitalWrite(LED_PIN_ON, LOW);  
          digitalWrite(LED_PIN_BLINC, HIGH); //индикатор горит 
          while(digitalRead(BUTTON)){} //пока кнопка еще нажата ждем
          
         }	

// закрываем клапан
void off(){           
           while(!digitalRead(BUTTON)){}; //пока кнопка не нажата ждем
           digitalWrite(LED_PIN_OFF, HIGH);
           delay(1000);
           digitalWrite(LED_PIN_OFF, LOW);           
              do{                                         
                 if(millis() - previousMillis > INTERVAL) {
                         previousMillis = millis();  
                         digitalWrite(LED_PIN_BLINC,!digitalRead(LED_PIN_BLINC));
                 }
	             }           
                while(!digitalRead(BUTTON));              
          }		 
			
void loop(){
              digitalRead(BUTTON); //считываем состояние кнопки 	
              on();	//открываем клапан               
              off(); //закрываем клапан   
           }			 

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

MARKSIST пишет:

Клапауций 322 пишет:

блин. куда уж проще.

digitalWrite(pin, EEPROM.read(address));

Да но если светодиод мигает то как это мигание загнать в значение которое нужно подставлять вместо pin?

Как записать в EEPROM мигание?

включить мозги и прекратить пороть чушь.

*хрен поймёшь, то клапан у него открывается кнопкой, то светодиод неуправляемо мигает.

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Это не чушь все предельно ясно :)

Мне нужно как то запомнить последнее состояние светодиода. Записать его в EEPROM и потом при перезагрузке контролера прочитать из EEPROM последнее записаное состояние светодиода и запустить (или мигание или постоянное свечение.)

Не вижу бреда:) 

Постоянное свечение светодиода еще как то понимаю как записать (и то не до конца), а вот мигание никак не пойму.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

MARKSIST пишет:

Постоянное свечение светодиода еще как то понимаю как записать (и то не до конца),

тебе русский язык родной или ты, просто, невнимательный - сосредоточься #7 #10

MARKSIST пишет:

а вот мигание никак не пойму.

именно это - бред.

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Хорошо упрощу вопрос )

Как в переменную можно записать мигание светодиода?

Sindbad
Offline
Зарегистрирован: 08.12.2015

MARKSIST пишет:

Хорошо упрощу вопрос )

Как в переменную можно записать мигание светодиода?

Вы сами себя запутали. Рекомендую сделать паузу, погулять, например. Или выспаться.

Светодиод мигает не сам по себе, а в соответствии с заложенным в микроконтроллер алгоритмом. Именно алгоритм хранит состояние устройства - что именно нужно делать со светодиодом. Т.е. схематично должно быть так:

* Объявляем переменную для хранения информации о состоянии устройства:

int status;

* При загрузке, т.е в функции сетап читаем значение из EEPROM в переменную status

* В основном цикле программы, т.е в фунции луп делаем две вещи:

1. Организуем мигание или горение светодиода в зависимости от значения в переменной status

2. Проверяем нажатие клавиши, при нажатии присваиваем переменной status новое значение и сразу же сохраняем это значение в EEPROM

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Sindbad пишет:

* Объявляем переменную для хранения информации о состоянии устройства:

int status;

скорее всего

boolean status;

 

Sindbad
Offline
Зарегистрирован: 08.12.2015

Клапауций 322 пишет:

Sindbad пишет:

* Объявляем переменную для хранения информации о состоянии устройства:

int status;

скорее всего

boolean status;

У ТС задействовано целых три светодиода, что как-бы намекает, на то, что состояний может потребоваться больше чем два.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Sindbad пишет:

Клапауций 322 пишет:

Sindbad пишет:

* Объявляем переменную для хранения информации о состоянии устройства:

int status;

скорее всего

boolean status;

У ТС задействовано целых три светодиода, что как-бы намекает, на то, что состояний может потребоваться больше чем два.

ТС и тебя запутал... думаю, это заразно.

* состояние пина клапана-светодиода - булевое.
* cостояние пина кнопки - булевое.
* состояние "мигает&немигает" - булевое.
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

MARKSIST пишет:

Как записать в EEPROM мигание?

Тщательно изучение даташита показало, что никакБайты записать можно, один или больше - на сколько EEPROMа хватит, и мигание туда не записывается. Про мигание в даташите вообще ни разу не упоминается.

Придётся с этим жить.

Sindbad
Offline
Зарегистрирован: 08.12.2015

Клапауций 322 пишет:

Sindbad пишет:

Клапауций 322 пишет:

Sindbad пишет:

* Объявляем переменную для хранения информации о состоянии устройства:

int status;

скорее всего

boolean status;

У ТС задействовано целых три светодиода, что как-бы намекает, на то, что состояний может потребоваться больше чем два.

ТС и тебя запутал... думаю, это заразно.

* состояние пина клапана-светодиода - булевое.
* cостояние пина кнопки - булевое.
* состояние "мигает&немигает" - булевое.

Посмотрите на самый первый пост. Требуемое поведение описывается пятью состояниями:

а1 - led1 выкл, led2 выкл, led3 выкл

а2 - led1 горит, led2 мигает, led3 выкл

а3 - led1 выкл, led2 мигает, led3 выкл

а4 - led1 выкл, led2 горит, led3 горит

а5 - led1 выкл, led2 горит, led3 выкл

Переходы:

а1 (начальное)

а1 --> а2 (нажатие кнопки)

а2 --> а3 (по таймеру 10 сек)

а2 --> а4 (нажатие кнопки)

а3 --> а4 (нажатие кнопки)

а4 --> а5 (по таймеру 10 сек)

а5 (финальное)

Так что ни изначальная задача, ни её обсуждение на форуме не предполагало автомата с двумя состояниями.

 

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Sindbad пишет:

Посмотрите на самый первый пост. Требуемое поведение описывается пятью состояниями:

а1 - led1 выкл, led2 выкл, led3 выкл

а2 - led1 горит, led2 мигает, led3 выкл

а3 - led1 выкл, led2 мигает, led3 выкл

а4 - led1 выкл, led2 горит, led3 горит

а5 - led1 выкл, led2 горит, led3 выкл

ок. я же говорил, что заразно - теперь вместе с ТС думай, как в EEPROM записать мигание. :D

*помнишь анекдот про сгоревшую лампочку? - то потухнет, то погаснет, сука.

Sindbad
Offline
Зарегистрирован: 08.12.2015

Клапауций 322 пишет:

ок. я же говорил, что заразно - теперь вместе с ТС думай, как в EEPROM записать мигание. :D

*помнишь анекдот про сгоревшую лампочку? - то потухнет, то погаснет, сука.

Не понимаю я этого сарказма. У меня проблем с программированием Ардуино нет, хоть с EEPROM, хоть без.

В каком направлении двигаться ТС, я написал в 16-м сообщении.

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Sindbad пишет:

Не понимаю я этого сарказма. У меня проблем с программированием Ардуино нет, хоть с EEPROM, хоть без.

и, я не понимаю, зачем делать один int из двух и более boolean

 

Sindbad
Offline
Зарегистрирован: 08.12.2015

Клапауций 322 пишет:

и, я не понимаю, зачем делать один int из двух и более boolean

Для каждого светодиода свой boolean что-ли?

Ну так int более универсален и ближе к тому что называют конечным автоматом.

Как с помоющью логических переменных записать и сохранить состояния вида:

* при нажатии на кнопку светодиод горит

* при повторном нажатии светодиод быстро мигает (0,5 сек. на состояние)

* при последующем нажатии светодитод меделенно мигает (2 сек. на состояние)

* при последующем нажатии светодиод выключается

Тем более что даже в обсуждаемом примере у каждого светодиода не два, а три состояния (выключен, горит, мигает), как с помощью логических переменных описать каждое из состояний {а1, а2, а3, а4, а5} из поста 21 ?

Клапауций 322
Offline
Зарегистрирован: 31.12.2015

Sindbad пишет:

Для каждого светодиода свой boolean что-ли?

да. ты экономишь EEPROM?

Sindbad пишет:

Как с помоющью логических переменных записать и сохранить состояния вида:

* при нажатии на кнопку светодиод горит

* при повторном нажатии светодиод быстро мигает (0,5 сек. на состояние)

* при последующем нажатии светодитод меделенно мигает (2 сек. на состояние)

* при последующем нажатии светодиод выключается

это не состояния, а условия, которые прописаны в коде - после считывания из EEPROM состояний светодиодов код обрабатывает ифы.

Sindbad пишет:

Тем более что даже в обсуждаемом примере у каждого светодиода не два, а три состояния (выключен, горит, мигает), как с помощью логических переменных описать каждое из состояний {а1, а2, а3, а4, а5} из поста 21 ?

сначала: у светодиода два состояния горит&погашен. во время записи в EEPROM возможна запись одного из этих состояний.

Sindbad пишет:

а1 - led1 выкл, led2 выкл, led3 выкл

а2 - led1 горит, led2 мигает, led3 выкл

а3 - led1 выкл, led2 мигает, led3 выкл

а4 - led1 выкл, led2 горит, led3 горит

а5 - led1 выкл, led2 горит, led3 выкл

я сказал, что это заразно, т.к.:

led2 мигает - является производной базовых состояний выкл&горит

попытка слить булевые переменные в некую общую инт ведёт к потере информации о состоянии автомата во время записи в EEPROM. т.к. состояние led2 мигает не несёт информации о логическом состоянии пина светодиода.

нужно:

boolean светодиод1 - включен&выключен
boolean светодиод1 - мигает&немигает
 
**выше #19 уже говорил об этом.
Sindbad
Offline
Зарегистрирован: 08.12.2015

Клапауций 322 пишет:

Sindbad пишет:

Для каждого светодиода свой boolean что-ли?

да. ты экономишь EEPROM?

Ни в коем случае. Нагромождение из нескольких булевых переменных усложняет код. Без выигрыша хоть в чем-нибудь.

Клапауций 322 пишет:

Sindbad пишет:

Как с помоющью логических переменных записать и сохранить состояния вида:

* при нажатии на кнопку светодиод горит

* при повторном нажатии светодиод быстро мигает (0,5 сек. на состояние)

* при последующем нажатии светодитод меделенно мигает (2 сек. на состояние)

* при последующем нажатии светодиод выключается

это не состояния, а условия, которые прописаны в коде - после считывания из EEPROM состояний светодиодов код обрабатывает ифы.

Чтобы внести ясность. Тут слово "состояние" мною использовано в двух разных значениях:

- состояние абстрактного конечного автомата, реализуемого алгоритмом

- состояние мигающего светодиода (включен / выключен)

Виноват, если запутал. Тем не менее Ваш ответ понять не смог.

Клапауций 322 пишет:
сначала: у светодиода два состояния горит&погашен. во время записи в EEPROM возможна запись одного из этих состояний.

Клапауций 322 пишет:

я сказал, что это заразно, т.к.:

led2 мигает - является производной базовых состояний выкл&горит

попытка слить булевые переменные в некую общую инт ведёт к потере информации о состоянии автомата во время записи в EEPROM. т.к. состояние led2 мигает не несёт информации о логическом состоянии пина светодиода.

А, так вот оно как. Вопрос в том, что считать "состоянием автомата" и с какой точностью восстанавливать его состояние. У меня сложилось впечатление, что ТС интересовал вопрос как сохранить в памяти "мигание" и не более того. Сохранять текущее состояние пина отвечающего за мигание в таком случае излишне.

Врочем, это уже дело ТС. Подход к вопросу сохранения состояний это не меняет.

Sindbad
Offline
Зарегистрирован: 08.12.2015

....

Sindbad
Offline
Зарегистрирован: 08.12.2015

....

Sindbad
Offline
Зарегистрирован: 08.12.2015

...

MARKSIST
Offline
Зарегистрирован: 16.07.2015

Sindbad пишет:

 У меня сложилось впечатление, что ТС интересовал вопрос как сохранить в памяти "мигание" и не более того. Сохранять текущее состояние пина отвечающего за мигание в таком случае излишне.

Вы правы самый главный вопрос был сохранить в EEPROM и востановить из EEPROM мигание светодиода. Сегодня попробую вашу методику с status. спасибо