Помогите новичку с включением светодиода

yaros
Offline
Зарегистрирован: 17.10.2012

 Здравствуйте. 

Просьба помочь, направить в правильное русло.
 

Есть маленький пример:
digitalWrite(LED1,(((((millis() / 1000) % 2)==0) || (digitalRead(BUTTON1)) == HIGH)) ? HIGH : LOW );

Светодиод мигает каждые 2 секунды и при нажатии кнопки.

Необходимо на подобие этого сделать следующее:
При одноразовом нажатии кнопки -> загорается светодиод и мигает с частотой 1 Гц, при повторном нажатии 
сетодиод отключается.

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

Подскажите каким образом можно выполнить этот пример. 

Заранее спасибо. 

maksim
Offline
Зарегистрирован: 12.02.2012

Для начала научитесь вставлять код в комментарии и покажите ваш код полностью с комментариями.

yaros
Offline
Зарегистрирован: 17.10.2012

 Вот один из моих вариантов:

import muvium.compatibility.arduino.*; 




class  Blink extends Arduino{ 
 
	static final int LED1 = 13; 
	static final int LED2 = 12; 
	static final int LED3 = 11; 
 
	static final int BUTTON1 = 4; 
	static final int BUTTON2 = 3; 
	static final int BUTTON3 = 2; 
	

	public void setup()   {   

		pinMode(LED1, OUTPUT);        
		pinMode(LED2, OUTPUT);        
		pinMode(LED3, OUTPUT);  
		
		pinMode(BUTTON1, INPUT);        
		pinMode(BUTTON2, INPUT);        
		pinMode(BUTTON3, INPUT); 
	} 


	public void loop()      
	{ 

		digitalWrite(LED1, ((digitalRead(LED1)==0) && (digitalRead(BUTTON1) == HIGH)) ? HIGH : LOW );
		digitalWrite(LED1, ((digitalRead(LED1)==1) && (digitalRead(BUTTON1) == HIGH)) ? LOW : HIGH );
	
		
	}
}

Нажимаем кнопку -> загораеться диод
Нажимаем кнопку -> отключаеться диод

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

maksim
Offline
Зарегистрирован: 12.02.2012

Я не пойму вы откуда это вырвали? Вы библиотеку пишите?
Вам помогут 3 стандартных примера: 
File->Exemples->2.Digital->Button 
File->Exemples->2.Digital->BlinkwithoutDelay
File->Exemples->2.Digital->Debounce

yaros
Offline
Зарегистрирован: 17.10.2012

 Да это программа эмуляции микроконтролера VVB.

Пересмотрел уже куча примеров, но никак не могу понять как сделать, что бы при однократном нажатии кнопки - загорался диод,
при повторном нажатии - отключался 

public void loop(){  
		// считываем состояние кнопки и диода  
		buttonState = digitalRead(buttonPin); 
		pin = digitalRead(ledPin);
 
		// если кнопка нажата и лед отключен, включить        //лед 
		if( buttonState == HIGH && pin == LOW) {      
			// turn LED on:      
			digitalWrite(ledPin, HIGH);   
		}   
// если включить кнопку при включеном диоде , отключить диод
		else if (buttonState == HIGH && pin == HIGH){  
			// turn LED off:  
			digitalWrite(ledPin, LOW);   
		}  
	}  

 

step962
Offline
Зарегистрирован: 23.05.2011

yaros пишет:

Пересмотрел уже куча примеров, но никак не могу понять как сделать, что бы при однократном нажатии кнопки - загорался диод,
при повторном нажатии - отключался 

Как-то так (State - состояние кнопки):

if(oldState!=State) {
// делаем что-то и вновь взводим флажок
  if(State==HIGH) {
    if(LEDState==LED_ON) {
// гасим светодиод и меняем его флаг состояния 
      LEDState=LED_OFF;
    }
    else  {
// зажигаем светодиод и меняем его флаг состояния
      LEDState=LED_ON;
    }
  }
  oldState=State;
}

 Это, естественно, только рыба. Определение всех переменных/констант и прочая лабуда - за вами.

leshak
Offline
Зарегистрирован: 29.09.2011

 Вы очень близко подобрались к ответу  :)

Попробуйте просто "выполнить скетч в голове".

Вот нажали мы кнопку. В строке 07 условие выполнилось. Включился светик. Что дальше происходит? loop() закончился и "начался снова". 07 - условие не выполняется, 12 - выполняется - светик гаснет. Кнопку-то вы еще держите :) Даже если вы "кратко клацнули", для дуины это "целая эпоха". Loop успеет выполнится кучу раз.

Значит есть два выхода.

Либо втыкать в loop()  задержку (delay(1000), что-бы вы успевали отпустить кнопку (плохой подход).

Либо, где-то в глобальное переменной сохранять предыдущие состояние кнопки (от прошлого прохода loop), и что-то делать только если кнопка ИЗМЕНИЛА свое сотояние с low на high.

 

 

leshak
Offline
Зарегистрирован: 29.09.2011

 Примерно так:

#define buttonPin 3
#define LED 13

byte prevButtonState;

setup(){
  pinMode(LED,OUTPUT);
}

void loop(){
  byte buttonState=digitalRead(buttonPin);

  if(!prevButtonState && buttonState) digitalWrite(LED,!digitalRead(LED));
  
  prevButtonState=buttonState;
  
}

В эмуляторе, по идее, долно работать. А вот на реальном железе может хорошо глючить из-за дребезга контактов в кнопке.

Выхода четыре:

1. Все-таки вставлять задержку миллесекунд на 100-200, что-бы "пропускать дребезг" (плохой подход, но в "простых случаех" - допустим).

2. Засекать когда у нас кнопка сменила состояние, и что-то делать только если "с прошлого изменения" прошло достаточно времени

3. Привесить аппартный "дребезго-давитель" (конденсатор).

4. Нагуглить готовую библиотеку типа Button Debounce

Более подробно можно и на форуме и в гугле найти. По словам "кнопка", "дребезг", "debounce"

yaros
Offline
Зарегистрирован: 17.10.2012

 Огромное спасибо, флажок то что нада)
Вот еще заминка, как заставить его мигать с определенной частотой. Я так понимаю это только с использованием функции millis().

Пока мучаю, может есть идеи как впихнуть эту функцию в приведенный код?

public void loop(){  
		
		State = digitalRead(buttonPin); // записываем флажок
		if(oldState != State) {
			// делаем что-то и вновь взводим флажок
			if(State == HIGH) {
				if(digitalRead(ledPin) == HIGH) {
					// гасим светодиод и меняем его флаг состояния
					digitalWrite(ledPin, LOW);
				}
				else  {
							// зажигаем светодиод и меняем его флаг состояния
							digitalWrite(ledPin, HIGH);
				}
			}
			oldState = State;
		}

	}  

 

step962
Offline
Зарегистрирован: 23.05.2011

leshak пишет:

В эмуляторе, по идее, долно работать. А вот на реальном железе может хорошо глючить из-за дребезга контактов в кнопке.

Ну так это только удочка - рыбку страждущий сам должен поймать.

leshak
Offline
Зарегистрирован: 29.09.2011

yaros пишет:

 Огромное спасибо, флажок то что нада)
Вот еще заминка, как заставить его мигать с определенной частотой. Я так понимаю это только с использованием функции millis().

Нет. Можно и с помощью delay(). 

С millis() - более гиморно, но более "грамотно". Скетч не будет "останавливатся дуплить" (например двумя диодами одновременно с помощью delay() уже не помигаешь".

Как с помощью millis(); мигать диодом - смотрите в шапку сайта. Там есть ссылка "программирование". Идем по ней, находим в правой колонке пример ("Мигаем диодом без delay()"). Читаем :) Или поиском по форуме, в том или ином виде - 100 раз уже было.

Как совмстить с вашим кодом? А как можно ответить если вы задачу не поставили? Что кнопка будет делать? Включать мигание, менять частоту? Будет два диода (один по кнопке, другой "постоянно мигает")?

Общий подход такой: включаем диод, запоминаем в какую-то глобальную переменную (так же как делали с флажком) когда мы его включили. Потом, постоянно в loop, проверяем сколько прошло с тех пор времени (millis()- ВРЕМЯ_ИЗМЕНЕНИЯ_ДИОДА). Если больше какого-то вермени - меняем состояние диода на противоположное, и запоминаем в эту переменную нове время.

 

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

 

yaros пишет:

Вот еще заминка, как заставить его мигать с определенной частотой. Я так понимаю это только с использованием функции millis().

Еще раз посмотрите сообщение #3 пример BlinkwithoutDelay, там есть ответ на этот вопрос.

leshak
Offline
Зарегистрирован: 29.09.2011

 Примерно так:

unsigned long lastChangeTime=0;

loop(){
  if( (millis()-lastChangeTime)>1000){
    digitalWrite(LED,!digitalRead(LED));
    lastChangeTime=millis();
  }
}

P.S. А раздел "программирование" - все-таки почитайте. там много полезного что пригодится есть.

yaros
Offline
Зарегистрирован: 17.10.2012

 В любом случае буду ковырять функцию millis(), так как будет 3 диода.
Спасибо большое за помощь, начало лабы положено)

leshak
Offline
Зарегистрирован: 29.09.2011

maksim пишет:

Еще раз посмотрите сообщение #3 пример BlinkwithoutDelay, там есть ответ на этот вопрос.

Кстати да. Все три примера  must read. И кнопка, и дребезг, и "без delay()" показанны. Все три вещи которые обязательно потребуются.

Maks2010
Offline
Зарегистрирован: 08.11.2017

Знатоки помогите. ! Как с кнопки на бордель и с кнопки в блинке управлять реле. При нажатии физической кнопки статус кнопки в блинке менялся на такой же как физическая, и на оборот. спасибо!!!