Всем привет! Изучаю Ардуино и программирование только месяц.
Дабы не плодить темы, прошу помощи... В предыдущем посту, к примеру, есть скетч работы таймера по принципу: "нажал, светик горит, таймер пошел, отсчитался и выключилось". Отличное применение если делать проходной выключатель. А вот у меня появилась идея применить это к рольставням.
Дано: 2 светодиода, одна кнопка.
Логика: нажимаем, горит первый светик, пошел отсчет к приммеру 10 сек. По истечению гаснит. Но если нажал досрочно, светик потух досрочно. Ещё нажатие, загорается уже второй светик. И так же что бы можно было досрочно выключить. и Циклично все это.
int regim=1;
int flag=0;
void setup()
{
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
}
void loop()
{
if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата
// и перемення flag равна 0 , то ...
{
regim++;
flag=1;
//это нужно для того что бы с каждым нажатием кнопки
//происходило только одно действие
// плюс защита от "дребезга" 100%
if(regim>4)//ограничим количество режимов
{
regim=1;//так как мы используем только одну кнопку,
// то переключать режимы будем циклично
}
}
if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата
//и переменная flag равна - 1 ,то ...
{
flag=0;//обнуляем переменную "knopka"
}
if(regim==1)//первый режим
{
digitalWrite(9,LOW);//выключаем все светодиоды
digitalWrite(10,LOW);
//здесь может быть любое ваше действие
}
if(regim==2)//второй режим
{
digitalWrite(10,HIGH);//включае красный светодиод
digitalWrite(9,LOW);
//здесь может быть любое ваше действие
}
if(regim==3)//третий режим
{
digitalWrite(9,HIGH);//включае зеленый светодиод
digitalWrite(10,LOW);
//здесь может быть любое ваше действие
}
if(regim==4)//четвертый режим
{
digitalWrite(9,HIGH);//включаем светодиоды одновременно
digitalWrite(10,HIGH);
//здесь может быть любое ваше действие
}
}
как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню
Требуется помощь в программировании. UNO и Keypad Shield. Есть автомат подачи воды с внешним прерыванием. Требуется изменять время подачи кнопкой. Но не знаю как остановить программу. В итоге все время выводится 1 секунда.
/**
* Автомат подачи воды с регулировкой времени
* Сенсор стеклянный или пластик
*/
//Объявляем библиотеки
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//декларируем переменные для брызгалки с прерыванием
#define button 2 // кнопка
#define relay 6 // реле 2
volatile byte flag=0;
unsigned long prevmillis;
void setup()
{
pinMode(12, OUTPUT);
digitalWrite(12, HIGH);
//Инициализация LCD
lcd.begin(16, 2);
// Печать приветствия на LCD.
lcd.print(" VODOLEY ");
lcd.setCursor(0, 1);
lcd.print("podacha vodi");
delay(5000);
lcd.clear();
//режимы pin
pinMode(button,INPUT_PULLUP); // кнопка на вход вкл.подтягивающий резистор.
pinMode(relay,OUTPUT); // реле на брызгалку
attachInterrupt(0, my_func, FALLING); //прерывание на изменение логич. уровня
}
void loop()
{
int x;
x = analogRead (0);
int time;
time=1;
lcd.setCursor(0, 0);
lcd.print ("TIME: ");
lcd.print (time);
lcd.print (" sec");
//Регулировка времени подачи
if (x < 200) {
(time++);
lcd.setCursor(0, 0);
lcd.print ("TIME: ");
lcd.print (time);
lcd.print ("sec");
}
else if (time>= 6){
(time=1);
}
if (1 == flag)
{ // если кнопку отпустили
prevmillis = millis();
digitalWrite(relay,HIGH); //включаем реле
flag = 2;
}
if (2 == flag)
{
if ( millis()-prevmillis >=time*1000)
{ //если счёт time вышел, то
digitalWrite(relay,LOW); //отключаем воду
flag=0; //сбрасываем флаг работы
}
}
}
void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}
"как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню"
Ваш код на правильность не проверял но принцып я думаю Вы поймете: При клике - диоды, при удержании более 0.5сек regim = 0, а там делайте что хотите
int regim=1;
int flag=0;
unsigned long x; //Переменная для прошедшего периода
void setup()
{
pinMode(10,OUTPUT);
pinMode(9,OUTPUT);
}
void loop()
{
if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата
// и перемення flag равна 0 , то ...
{
flag=1;
x = millis();
//это нужно для того что бы с каждым нажатием кнопки
//происходило только одно действие
// плюс защита от "дребезга" 100%
}
if(digitalRead(14)==LOW&&flag==1)//если кнопка НЕ нажата
//и переменная flag равна - 1 ,то ...
{
flag=0;//обнуляем переменную "knopka"
regim++;
if(regim>4)//ограничим количество режимов
{
regim=1;//так как мы используем только одну кнопку,
// то переключать режимы будем циклично
}
}
if (digitalRead(14)==HIGH&&flag==1) // Здесь проверяем удержание
{
if(millis() - x >=500)
{
regim = 0;
}
}
if (regim ==0)
{
// Вот здесь входите в ВАШЕ меню
}
if(regim==1)//первый режим
{
digitalWrite(9,LOW);//выключаем все светодиоды
digitalWrite(10,LOW);
//здесь может быть любое ваше действие
}
if(regim==2)//второй режим
{
digitalWrite(10,HIGH);//включае красный светодиод
digitalWrite(9,LOW);
//здесь может быть любое ваше действие
}
if(regim==3)//третий режим
{
digitalWrite(9,HIGH);//включае зеленый светодиод
digitalWrite(10,LOW);
//здесь может быть любое ваше действие
}
if(regim==4)//четвертый режим
{
digitalWrite(9,HIGH);//включаем светодиоды одновременно
digitalWrite(10,HIGH);
//здесь может быть любое ваше действие
}
}
Вячеслав 151 Я стараюсь Вам помочь а Вы даже попробовать не хотите чтобы найти причину. Не подходит делай можно поставить милис если ошибка в этом. Нужно пробовать. С флагами я выложу вот такой скетч. Пробуйте
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//декларируем переменные для брызгалки с прерыванием
#define button 2 // кнопка
#define relay 6 // реле 2
volatile byte flag=0;
unsigned long prevmillis;
int flag1=0; //Для регулировки времени
int flag2=0;
void setup()
{
pinMode(12, OUTPUT);
digitalWrite(12, HIGH);
//Инициализация LCD
lcd.begin(16, 2);
// Печать приветствия на LCD.
lcd.print(" VODOLEY ");
lcd.setCursor(0, 1);
lcd.print("podacha vodi");
delay(5000);
lcd.clear();
//режимы pin
pinMode(button,INPUT_PULLUP); // кнопка на вход вкл.подтягивающий резистор.
pinMode(relay,OUTPUT); // реле на брызгалку
attachInterrupt(0, my_func, FALLING); //прерывание на изменение логич. уровня
}
void loop()
{
int x;
x = analogRead (0);
int time;
time=1;
lcd.setCursor(0, 0);
lcd.print ("TIME: ");
lcd.print (time);
lcd.print (" sec");
//Регулировка времени подачи
if (x < 200&&flag2==0) {
flag2=1;
time++ ;
if (time>= 6)time=1;
lcd.setCursor(0, 0);
lcd.print ("TIME: ");
lcd.print (time);
lcd.print ("sec");
}
else if (x > 200 && flag2==0) flag2 = 0;
if (1 == flag)
{ // если кнопку отпустили
prevmillis = millis();
digitalWrite(relay,HIGH); //включаем реле
flag = 2;
}
if (2 == flag)
{
if ( millis()-prevmillis >=time*1000)
{ //если счёт time вышел, то
digitalWrite(relay,LOW); //отключаем воду
flag=0; //сбрасываем флаг работы
}
}
}
void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}
Подправил скетч, переставил прерывание для Mega2560, вроде меняется время в цикле, но не знаю как остановить цикл на time++. loop выходит постоянно в 3sec.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
//декларируем переменные для брызгалки с прерыванием
#define button 21 // кнопка для Mega2560
#define relay 36 // реле для Mega2560
volatile byte flag=0;
unsigned long prevmillis;
int flag1=0; //Для регулировки времени
int flag2=0;
void setup()
{
// Serial.begin(9600);
// pinMode(12, OUTPUT);
// digitalWrite(12, HIGH);
//Инициализация LCD
lcd.begin(16, 2);
// Печать приветствия на LCD.
lcd.print(" VODOLEY ");
lcd.setCursor(0, 1);
lcd.print("podacha vodi");
delay(5000);
lcd.clear();
//режимы pin
pinMode(button,INPUT_PULLUP); // кнопка на вход вкл.подтягивающий резистор.
pinMode(relay,OUTPUT); // реле на брызгалку
attachInterrupt(2, my_func, FALLING); //прерывание на изменение логич. уровня
}
void loop()
{
int x;
x = analogRead (0);
int time;
time=3;
lcd.setCursor(0, 0);
lcd.print ("TIME: ");
lcd.print (time);
lcd.print (" sec");
// delay(2000);
//Регулировка времени подачи
if (x < 200&&flag2==0) {
flag2=1;
time++ ;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print ("TIME: ");
lcd.print (time);
lcd.print (" sec");
delay(1000);
}
if (1 == flag)
{ // если кнопку отпустили
prevmillis = millis();
digitalWrite(relay,HIGH); //включаем реле
flag = 2;
}
if (2 == flag)
{
if ( millis()-prevmillis >=time*1000)
{ //если счёт time вышел, то
digitalWrite(relay,LOW); //отключаем воду
flag=0; //сбрасываем флаг работы
}
}
}
void my_func() { //отжали
flag=1; //ставим флаг что работа идёт..
}
const int inPin1 = 2; // кнопка 2 порт 2
const int inPin2 = 3; // кнопка 2 порт 3
const int inPin3 = 4; //кнопка 3 порт 4
const int ledPin1 = 13; // порт 13, для светодиода
const int ledPin2 = 12; //порт 12 для светодиода
const int ledPin3 = 11; //порт 11 для светодиода
int flag=0;
void setup()
{
// Установим порты кнопок как входящие:
pinMode(inPin1, INPUT);
pinMode(inPin2, INPUT);
pinMode(inPin3, INPUT);
// Установим порт светодиода как исходящий:
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
}
void loop()
{
{
{
if(digitalRead(3)==HIGH&&flag==0)//
{
flag=1;
}
if(digitalRead(3)==LOW&&flag==1)
{
digitalWrite(12,!digitalRead(12));
flag=0;
}
{
if(digitalRead(2)==HIGH&&flag==0)//
{
flag=1;
}
if(digitalRead(2)==LOW&&flag==1)
{
digitalWrite(13,!digitalRead(13));
flag=0;
}
{
if(digitalRead(4)==HIGH)//если кнопка нажата ...
{
digitalWrite(11,LOW);//включаем светодиод
}
else//если не нажата...
{
digitalWrite(11,HIGH);//выключаем
}
}
}
}
}
}
добрй вечер. такой вопрос что-то я никак не уловлю что делать. по коду выше у меня получилось что кнопки 3 и 2 приходиться дерать около 2 секунд чтоб произошло действие. а если переделываем кнопку 2 в кнопку 4(просто моргать по нажатию) то кнопка 3 начинает работать нормально тоесть нажал и сразу же отпусти и диод загорелся. не надо держать долго.
подскажите может я какю переменную не знаю, но как сделать чтоб все две кнопки срабатывали по нажатию а не по удержанию?
так я просто непонимаю как флаг должен быть для каждой кнопки свой? я вот его и использую с переменными 0 и 1 для каждой кнопки. тут вот я реально непонимаю как флаг для каждой кнопки делать
Подскажите, есть ли информация, насколько короткий может быть импульс от нажатия кнопки? т.к. периодически, в достаточно больших кодах, я сталкиваюсь с тем, что короткие нажатия кнопки не отрабатываются контроллером. Кто-то сталкивался с такой проблемой?
Смотря каким способом обрабатываются кнопки. Если повесить их на прерывание - то должны срабатывать всегда. Если методом поллинга (постоянный опрос состояния кнопок) - то увеличить скорость опроса и избавиться от delay() в коде, если есть.
В скетче есть 11 условий if...else, которые так же обрабатывают нажатия кнопок, в том числе одновременные нажатия двух кнопок. Эти кнопки нажимаются при необходимости человеком. медленно. И есть одна кнопка (описанная выше), которая нажимается механизмом с достаточно быстрой периодичностью (пока стоит обычный микропереключатель, со временем заменю либо на датчик холла, либо на геркон).
при выполнении условий по нажатию происходят разные действия - запись в память, запись в аналоговый порт, и арифметические действия по + и - к существующим переменным. есть пару Delay внутри циклов, которые относятся к кнопкам пользователя.
Большая часть результата выводится на LCD, подключенному по I2C.
Я так понимаю, что у меня просто нажатия попадают иногда в такой момент loop() функции, что программа в этот момент просто опрашивает другие кнопки. Я так понимаю, что в моем случае достаточно будет увеличить время нажатой кнопки, и проблема решится (кнопка срабатывает 3-4 раза в секунду, на длительность около 1/20 секунды, а я могу увеличить хотя бы чтобы нажатие кнопки длилось пол цикла движения механизма - т.е. 1/6 секунды примерно.
есть пару Delay внутри циклов, которые относятся к кнопкам пользователя.
Если в момент работы этих delay() механизм нажмёт на кнопку - она не сработает.
Efremoff пишет:
Я так понимаю, что у меня просто нажатия попадают иногда в такой момент loop() функции, что программа в этот момент просто опрашивает другие кнопки.
Либо делает что-то другое, а пока дойдёт до опроса кнопки - она уже не нажата.
Efremoff пишет:
Я так понимаю, что в моем случае достаточно будет увеличить время нажатой кнопки, и проблема решится (кнопка срабатывает 3-4 раза в секунду, на длительность около 1/20 секунды, а я могу увеличить хотя бы чтобы нажатие кнопки длилось пол цикла движения механизма - т.е. 1/6 секунды примерно.
не-не. Delay во время работы не срабатывает. Они добавленны к пользовательским действиям, которые срабатывают при начальной настройке механизма, а нажатие "быстрой" кнопки происходит уже во время работы механизма, после его настроки пользователем. Она просто считает кол-во движений, и все. При достижении заданного кол-ва движений - отключается. так что попробуем увеличить время, при котором кнопка находится в нажатом состоянии.
Доброго времени суток. Ребята не откажите в помощи, очень надо. Хотим сделать сигнализацию на 8 каналов. Алгоритм такой:
1. При появлении на "vhod1" сигнала, на соответствующем выходе "AD1" зажигается и мигает светодиод,
с одновременным включением выхода (в скетче обозначен как "vyhodrele")
2. После нажатия кнопки "kvit" (если входной сигнал не пропал) светодиод зажигается постоянно, а выход "vyhodrele" - отключается
3. После пропадания сигнала на входе автоматически отключается и светодиод
4. Если через 5 минут после нажатия кнопки "kvit" со входа "vhod1" не исчез сигнал , снова включается мигающий светодиод
и включается выход "vyhodrele".
5. Если прошел кратковременный сигнал на вход схема отработала и после нажатия кнопки "kvit" откл. светодиода и "vyhodrele"
Каналы не должны зависеть друг от друга и после квитирования на любом из каналов схема готова принять сигнал с любого другого входа.
Я попытался написать скетч на один канал, пункт 1 работает, пункт 5 работает, пункт 2 работает только при постоянном удержании кнопки "kvit" как-то наверно нужно "зафиксировать" состояние кнопки? А вот пункт 3 и 4 совсем не "идут" . Подсобите, пожалуйста.
Попробовал прописать для второго канала, но теперь если сработал первый канал работает правильно, но если нажать кнопку kvit, начинает мигать светодиод второго канала и кнопкой kvit ничего не отключается. Не сочтите за назойливость, поправте, пожалуйста что не так. Задержку времени я изменил намеренно, чтобы долго не ждать при проверке.
#define vhod1 10
#define vhod2 11
int vhod3 = 12;
int vhod4 = 13;
int vhod5 = A0;
int vhod6 = A1;
int vhod7 = A2;
int vhod8 = A3;
bool AD1 = 0;
bool AD2 = 1;
int AD3 = 2;
int AD4 = 4;
int AD5 = 5;
int AD6 = 6;
int AD7 = 7;
int AD8 = 8;
#define kvit 9
#define vyhodrele 3
int flag1 = 0;
int flag2 = 0;
int flag3 = 0;
int flag4 = 0;
int flag5 = 0;
int flag6 = 0;
unsigned long time;
unsigned long time1;
unsigned long x; //Переменная для прошедшего периода "led"
unsigned long y; //Переменная для прошедшего периода "led1"
void setup()
{
pinMode(vhod1, INPUT_PULLUP);
pinMode(vhod2, INPUT_PULLUP);
pinMode(vhod3, INPUT_PULLUP);
pinMode(vhod4, INPUT_PULLUP);
pinMode(vhod5, INPUT_PULLUP);
pinMode(vhod6, INPUT_PULLUP);
pinMode(vhod7, INPUT_PULLUP);
pinMode(vhod8, INPUT_PULLUP);
pinMode(kvit, INPUT_PULLUP);
//digitalWrite(kvit, HIGH);
pinMode(AD1, OUTPUT);
pinMode(AD2,OUTPUT);
pinMode(AD3, OUTPUT);
pinMode(AD4,OUTPUT);
pinMode(AD5,OUTPUT);
pinMode(AD6,OUTPUT);
pinMode(AD7,OUTPUT);
pinMode(AD8,OUTPUT);
pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом
}
void loop()
{
if (digitalRead(vhod1) == LOW && flag1 ==0)
{
flag1=1;
digitalWrite(vyhodrele,1);
}
if (digitalRead(vhod1)==HIGH && flag3==1)
{
flag1=0;
flag2=0;
flag3=0;
digitalWrite(AD1, 0);
digitalWrite(vyhodrele,0);
}
if ( flag1==1 && flag2 == 0)
{
if (x != (millis() / 250))
{
x = millis() / 250;
digitalWrite(AD1, !digitalRead(AD1));
}
}
if (digitalRead(kvit) == LOW )
{
flag2=1;
flag3=1;
digitalWrite(vyhodrele,0);
if (digitalRead(vhod1) == LOW)
{
digitalWrite(AD1, 1);
time = millis();
}
}
if (flag1==1 && millis()-time>=3000)
{
flag2=0;
digitalWrite(vyhodrele,1);
}
//================================ канал 2
if (digitalRead(vhod2) == LOW && flag4 ==0)
{
flag4=1;
digitalWrite(vyhodrele,1);
}
if (digitalRead(vhod2)==HIGH && flag5==1)
{
flag4=0;
flag5=0;
flag6=0;
digitalWrite(AD2, 0);
digitalWrite(vyhodrele,0);
}
if ( flag4==1 && flag5 == 0)
{
if (y != (millis() / 250))
{
y = millis() / 250;
digitalWrite(AD2, !digitalRead(AD2));
}
}
if (digitalRead(kvit) == LOW )
{
flag4=1;
flag5=1;
digitalWrite(vyhodrele,0);
if (digitalRead(vhod2) == LOW)
{
digitalWrite(AD2, 1);
time1 = millis();
}
}
if (flag4==1 && millis()-time1>=3000)
{
flag5=0;
digitalWrite(vyhodrele,1);
}
}
Методом повтора не получится - Код нужно разбить на функции и вызывать с параметром сработавшего датчика. Скорей всего нужно создать новую тему потому что это уже не про кнопки!
Первый канал работает правильно, при проверке второго канала срабатывает правильно, но при нажатии кнопки kvit (при наличии сработки на входе)продолжает мигать светодиод 2 канала и не сбрасывается vyhodrele. Но если сигнала на входе не стало- сбрасывается кнопкой kvit.
Вот в Ваш предыдущий вариант я попробовал вставить по аналогии фрагмент второго канала и вроде как работает. Вот взгляните:
#define vhod1 10
#define vhod2 11
#define vhod3 12
#define vhod4 13
#define vhod5 A0
#define vhod6 A1
#define vhod7 A2
#define vhod8 A3
bool AD1 = 0;
bool AD2 = 1;
bool AD3 = 2;
bool AD4 = 4;
bool AD5 = 5;
bool AD6 = 6;
bool AD7 = 7;
bool AD8 = 8;
#define kvit 9
#define vyhodrele 3
int flag11 = 0;
int flag12 = 0;
int flag13 = 0;
int flag21 = 0;
int flag22 = 0;
int flag23 = 0;
unsigned long time;
unsigned long a; //Переменная для прошедшего периода "led1"
unsigned long b; //Переменная для прошедшего периода "led2"
void setup()
{
pinMode(vhod1, INPUT_PULLUP);
pinMode(vhod2, INPUT_PULLUP);
pinMode(vhod3, INPUT_PULLUP);
pinMode(vhod4, INPUT_PULLUP);
pinMode(vhod5, INPUT_PULLUP);
pinMode(vhod6, INPUT_PULLUP);
pinMode(vhod7, INPUT_PULLUP);
pinMode(vhod8, INPUT_PULLUP);
pinMode(kvit, INPUT_PULLUP);
//digitalWrite(kvit, HIGH);
pinMode(AD1, OUTPUT);
pinMode(AD2,OUTPUT);
pinMode(AD3, OUTPUT);
pinMode(AD4,OUTPUT);
pinMode(AD5,OUTPUT);
pinMode(AD6,OUTPUT);
pinMode(AD7,OUTPUT);
pinMode(AD8,OUTPUT);
pinMode(vyhodrele, OUTPUT); // выход управления через транзистор звуковым сигналом
}
void loop()
{
if (digitalRead(vhod1) == LOW && flag11 ==0)
{
flag11=1;
digitalWrite(vyhodrele,1);
}
if (digitalRead(vhod1)==HIGH && flag13==1)
{
flag11=0;
flag12=0;
flag13=0;
digitalWrite(AD1, 0);
digitalWrite(vyhodrele,0);
}
if ( flag11==1 && flag12 == 0)
{
if (a != (millis() / 250))
{
a = millis() / 250;
digitalWrite(AD1, !digitalRead(AD1));
}
}
if (digitalRead(kvit) == LOW )
{
flag12=1;
flag13=1;
digitalWrite(vyhodrele,0);
if (digitalRead(vhod1) == LOW)
{
digitalWrite(AD1, 1);
time = millis();
}
}
if (flag11==1 && millis()-time>=3000)
{
flag12=0;
digitalWrite(vyhodrele,1);
}
//============================== канал2
if (digitalRead(vhod2) == LOW && flag21 ==0)
{
flag21=1;
digitalWrite(vyhodrele,1);
}
if (digitalRead(vhod2)==HIGH && flag23==1)
{
flag21=0;
flag22=0;
flag23=0;
digitalWrite(AD2, 0);
digitalWrite(vyhodrele,0);
}
if ( flag21==1 && flag22 == 0)
{
if (b != (millis() / 250))
{
b = millis() / 250;
digitalWrite(AD2, !digitalRead(AD2));
}
}
if (digitalRead(kvit) == LOW )
{
flag22=1;
flag23=1;
digitalWrite(vyhodrele,0);
if (digitalRead(vhod2) == LOW)
{
digitalWrite(AD2, 1);
time = millis();
}
}
if (flag21==1 && millis()-time>=3000)
{
flag22=0;
digitalWrite(vyhodrele,1);
}
}
Как Вы считаете добавив по аналогии 3, 4 каналы и тд. Будет работать?
Смысл такойже только считается по другому, 250 это задержка в мс. Можете вместо милис подставить любое число и на калькуляторе посмотреть как оно работает
Помогите пожалуйста разобраться с программой. На Mega подключено две кнопки ( pin 41 и 43 ) . При нажатии на кнопку (41) должны загораться два светодиода на pin 47 и 53 на 5 секунд. При нажатии на кнопку на pin 43 должны загораться светодиоды на pin 51 и 53 на 10 секунд. Но получается что во втором случае светодиод на pin 53 гаснет через 5 сек. а на pin 51 через 10 сек. Подскажите пожалуйста где ошибка.
int flag=0;
int flag1=0;
unsigned long cmillis;
unsigned long i=5000;
void setup() {
pinMode (41, INPUT);
pinMode (43, INPUT);
pinMode (47, OUTPUT);
pinMode (53, OUTPUT);
pinMode (51, OUTPUT);
}
void loop() {
if ((digitalRead(41)==HIGH)&&(flag==0)){
cmillis=millis();
digitalWrite(47,!digitalRead(47));
digitalWrite(53,!digitalRead(53));
flag=1;
}
if (millis()-cmillis>i){
digitalWrite(47,LOW);
digitalWrite(53,LOW);
flag=0;
}
if (digitalRead(41)==LOW&&flag==1){
flag=0;
}
if ((digitalRead(43)==HIGH)&&(flag1==0)){
cmillis=millis();
digitalWrite(51,!digitalRead(51));
digitalWrite(53,!digitalRead(53));
flag1=1;
}
if (millis()-cmillis>i+5000){
digitalWrite(51,LOW);
digitalWrite(53,LOW);
flag1=0;
}
if (digitalRead(43)==LOW&&flag1==1){
flag1=0;
}
}
переделал
Огромное спасибо, что помогли и не отказали все работает вот теперь мне понятен алгоритм, респект и уважение!!!!!
только не забываем о дребезге контактов кнопки
Всем привет! Изучаю Ардуино и программирование только месяц.
Дабы не плодить темы, прошу помощи... В предыдущем посту, к примеру, есть скетч работы таймера по принципу: "нажал, светик горит, таймер пошел, отсчитался и выключилось". Отличное применение если делать проходной выключатель. А вот у меня появилась идея применить это к рольставням.
Дано: 2 светодиода, одна кнопка.
Логика: нажимаем, горит первый светик, пошел отсчет к приммеру 10 сек. По истечению гаснит. Но если нажал досрочно, светик потух досрочно. Ещё нажатие, загорается уже второй светик. И так же что бы можно было досрочно выключить. и Циклично все это.
Помогите пожалуйста как можно это сделать?
KiVor, вот примено так, кнопка включает и выключает попеременно то один, то другой светодиод.
Тоже на ассемблере весом в 60 байт
Просто для примера как это выглядит на ассемблере ;-)
Тоже на ассемблере весом в 60 байт
Получается ассемблер всех уделывает по размеру, самые меленькте hex.
Поморгать светодиодом на тини13
arduini IDE 214байт!((((
Atmel Studio 218байт((
ну хорошо кнопка так кнопка, вот на этом примере
как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню
Добрый день!
Требуется помощь в программировании. UNO и Keypad Shield. Есть автомат подачи воды с внешним прерыванием. Требуется изменять время подачи кнопкой. Но не знаю как остановить программу. В итоге все время выводится 1 секунда.
melnibo
"как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню"
Ваш код на правильность не проверял но принцып я думаю Вы поймете: При клике - диоды, при удержании более 0.5сек regim = 0, а там делайте что хотите
Вячеслав151 Зачем Вы строчки 47,54, time заключили в скобки () попробуйте убрать их
Скобки ничего не меняют
поставил флаги, все равно крутит loop бесконечно в единицу
Там внешнее прерывание, поэтому delay не стал забивать.
Почему на флаги не реагирует?
Вячеслав 151 Я стараюсь Вам помочь а Вы даже попробовать не хотите чтобы найти причину. Не подходит делай можно поставить милис если ошибка в этом. Нужно пробовать. С флагами я выложу вот такой скетч. Пробуйте
Подправил скетч, переставил прерывание для Mega2560, вроде меняется время в цикле, но не знаю как остановить цикл на time++. loop выходит постоянно в 3sec.
37 - строчка постоянно задает time=3; Если хотите стартовать с time=3 -
37 удалите а в 36 запишите static int time=3;
62 - строчка исправте flag2=0;
54 - строчка delay(1000); зачем? если флаг стоит.
добрй вечер. такой вопрос что-то я никак не уловлю что делать. по коду выше у меня получилось что кнопки 3 и 2 приходиться дерать около 2 секунд чтоб произошло действие. а если переделываем кнопку 2 в кнопку 4(просто моргать по нажатию) то кнопка 3 начинает работать нормально тоесть нажал и сразу же отпусти и диод загорелся. не надо держать долго.
подскажите может я какю переменную не знаю, но как сделать чтоб все две кнопки срабатывали по нажатию а не по удержанию?
flag должен быть свой для каждой кнопки, а не один на всех.
Какой смысл в строках 1-7, если они не используются в loop?
Чтото Вы столько много скобок на ставили, попробуйте так. А строчки 1-7 он в setup использовал
так я просто непонимаю как флаг должен быть для каждой кнопки свой? я вот его и использую с переменными 0 и 1 для каждой кнопки. тут вот я реально непонимаю как флаг для каждой кнопки делать
int
flag1 = 0;
int
flag2 = 0;
int
flag3 = 0;
int
flag4 = 0;
http://ru.wikihow.com/%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D1%84%...
Нафига флагу int? Достаточно byte.
Подскажите, есть ли информация, насколько короткий может быть импульс от нажатия кнопки? т.к. периодически, в достаточно больших кодах, я сталкиваюсь с тем, что короткие нажатия кнопки не отрабатываются контроллером. Кто-то сталкивался с такой проблемой?
Смотря каким способом обрабатываются кнопки. Если повесить их на прерывание - то должны срабатывать всегда. Если методом поллинга (постоянный опрос состояния кнопок) - то увеличить скорость опроса и избавиться от delay() в коде, если есть.
стоит как обычно, через флаг -
А как повесить на прерывание?
Delay в коде нет, кода на 140 строк всего. Почти все просто в условиях if...else.
Это методом поллинга (постоянного опроса). Покажите весь скетч.
А как повесить на прерывание?
http://arduino.ru/Reference/AttachInterrupt
В скетче есть 11 условий if...else, которые так же обрабатывают нажатия кнопок, в том числе одновременные нажатия двух кнопок. Эти кнопки нажимаются при необходимости человеком. медленно. И есть одна кнопка (описанная выше), которая нажимается механизмом с достаточно быстрой периодичностью (пока стоит обычный микропереключатель, со временем заменю либо на датчик холла, либо на геркон).
при выполнении условий по нажатию происходят разные действия - запись в память, запись в аналоговый порт, и арифметические действия по + и - к существующим переменным. есть пару Delay внутри циклов, которые относятся к кнопкам пользователя.
Большая часть результата выводится на LCD, подключенному по I2C.
Я так понимаю, что у меня просто нажатия попадают иногда в такой момент loop() функции, что программа в этот момент просто опрашивает другие кнопки. Я так понимаю, что в моем случае достаточно будет увеличить время нажатой кнопки, и проблема решится (кнопка срабатывает 3-4 раза в секунду, на длительность около 1/20 секунды, а я могу увеличить хотя бы чтобы нажатие кнопки длилось пол цикла движения механизма - т.е. 1/6 секунды примерно.
есть пару Delay внутри циклов, которые относятся к кнопкам пользователя.
Если в момент работы этих delay() механизм нажмёт на кнопку - она не сработает.
Я так понимаю, что у меня просто нажатия попадают иногда в такой момент loop() функции, что программа в этот момент просто опрашивает другие кнопки.
Либо делает что-то другое, а пока дойдёт до опроса кнопки - она уже не нажата.
Я так понимаю, что в моем случае достаточно будет увеличить время нажатой кнопки, и проблема решится (кнопка срабатывает 3-4 раза в секунду, на длительность около 1/20 секунды, а я могу увеличить хотя бы чтобы нажатие кнопки длилось пол цикла движения механизма - т.е. 1/6 секунды примерно.
Возможно и получится, попробуйте.
Вообще ардуиновские функции довольно медленные, иногда приходится работать с регистрами и портами AVR напрямую.
не-не. Delay во время работы не срабатывает. Они добавленны к пользовательским действиям, которые срабатывают при начальной настройке механизма, а нажатие "быстрой" кнопки происходит уже во время работы механизма, после его настроки пользователем. Она просто считает кол-во движений, и все. При достижении заданного кол-ва движений - отключается. так что попробуем увеличить время, при котором кнопка находится в нажатом состоянии.
Доброго времени суток. Ребята не откажите в помощи, очень надо. Хотим сделать сигнализацию на 8 каналов. Алгоритм такой:
1. При появлении на "vhod1" сигнала, на соответствующем выходе "AD1" зажигается и мигает светодиод,
с одновременным включением выхода (в скетче обозначен как "vyhodrele")
2. После нажатия кнопки "kvit" (если входной сигнал не пропал) светодиод зажигается постоянно, а выход "vyhodrele" - отключается
3. После пропадания сигнала на входе автоматически отключается и светодиод
4. Если через 5 минут после нажатия кнопки "kvit" со входа "vhod1" не исчез сигнал , снова включается мигающий светодиод
и включается выход "vyhodrele".
5. Если прошел кратковременный сигнал на вход схема отработала и после нажатия кнопки "kvit" откл. светодиода и "vyhodrele"
Каналы не должны зависеть друг от друга и после квитирования на любом из каналов схема готова принять сигнал с любого другого входа.
Я попытался написать скетч на один канал, пункт 1 работает, пункт 5 работает, пункт 2 работает только при постоянном удержании кнопки "kvit" как-то наверно нужно "зафиксировать" состояние кнопки? А вот пункт 3 и 4 совсем не "идут" . Подсобите, пожалуйста.
расечатать?
001
int
vhod1 = 10;
002
int
vhod2 = 11;
003
int
vhod3 = 12;
004
int
vhod4 = 13;
005
int
vhod5 = A0;
006
int
vhod6 = A1;
007
int
vhod7 = A2;
008
int
vhod8 = A3;
009
int
AD1 = 0;
010
int
AD2 = 1;
011
int
AD3 = 2;
012
int
AD4 = 4;
013
int
AD5 = 5;
014
int
AD6 = 6;
015
int
AD7 = 7;
016
int
AD8 = 8;
017
int
kvit = 9;
018
int
vyhodrele = 3;
019
int
flag1 = 0;
020
int
flag2 = 0;
021
int
flag3 = 0;
022
023
024
void
setup
()
025
{
026
pinMode(vhod1, INPUT_PULLUP);
027
pinMode(vhod2, INPUT_PULLUP);
028
pinMode(vhod3, INPUT_PULLUP);
029
pinMode(vhod4, INPUT_PULLUP);
030
pinMode(vhod5, INPUT_PULLUP);
031
pinMode(vhod6, INPUT_PULLUP);
032
pinMode(vhod7, INPUT_PULLUP);
033
pinMode(vhod8, INPUT_PULLUP);
034
pinMode(kvit, INPUT_PULLUP);
035
pinMode(AD1, OUTPUT);
036
pinMode(AD2,OUTPUT);
037
pinMode(AD3, OUTPUT);
038
pinMode(AD4,OUTPUT);
039
pinMode(AD5,OUTPUT);
040
pinMode(AD6,OUTPUT);
041
pinMode(AD7,OUTPUT);
042
pinMode(AD8,OUTPUT);
043
pinMode(vyhodrele, OUTPUT);
// выход управления через транзистор звуковым сигналом
044
045
}
046
047
void
loop
()
048
049
{
050
//Фрагмент 1 , отвечающий за включение и мигание светодиода, а так же включение звукового сигнала при поступлении
051
// сигнала на vhod1
052
if
(digitalRead(vhod1) == LOW && digitalRead(kvit) == HIGH)
053
054
{
055
flag1++;
056
}
057
else
058
{
059
flag1=0;
060
}
061
if
( flag1>=5)
062
063
{
064
if
(digitalRead(AD1) == LOW)
065
digitalWrite(AD1,1);
066
digitalWrite(vyhodrele,1);
067
delay(250);
068
digitalWrite(AD1, 0);
069
delay(250);
070
digitalWrite(AD1,1);
// чтобы светодиод оставался включенным при кратковременном
071
//срабатывании сигнала на входе
072
flag1=0;
073
}
074
// Фрагмент 2 должен после нажатия кнопки kvit мигающий светодиод зажечь постоянно,
075
// а выход vyhodrele отключить
076
077
if
(digitalRead(kvit) == LOW && digitalRead(vhod1) == LOW)
078
079
{
080
flag2++;
081
}
082
else
083
{
084
flag2=0;
085
}
086
if
(digitalRead(kvit) == LOW && flag2 >=5 )
087
088
{
089
if
(digitalRead(vyhodrele) == HIGH)
090
digitalWrite(vyhodrele,!digitalRead(vyhodrele));
091
digitalWrite(AD1,1);
092
flag2=0;
093
}
094
095
096
//Фрагмент 3 при пропадании сигнала на входе vhod1 и нажатии на кнопку kvit светодиод и выход vyhodrele отключаются
097
if
(digitalRead(kvit) == LOW && digitalRead(vhod1) == HIGH)
098
099
{
100
flag3++;
101
}
102
else
103
{
104
flag3=0;
105
}
106
if
(flag3>=5)
107
108
{
109
digitalWrite(AD1,0);
110
digitalWrite(vyhodrele,0);
111
flag2=0;
112
113
}
114
115
116
}
Попробовал прописать для второго канала, но теперь если сработал первый канал работает правильно, но если нажать кнопку kvit, начинает мигать светодиод второго канала и кнопкой kvit ничего не отключается. Не сочтите за назойливость, поправте, пожалуйста что не так. Задержку времени я изменил намеренно, чтобы долго не ждать при проверке.
Методом повтора не получится - Код нужно разбить на функции и вызывать с параметром сработавшего датчика. Скорей всего нужно создать новую тему потому что это уже не про кнопки!
Пробуйте вот по такому принцыпу
Первый канал работает правильно, при проверке второго канала срабатывает правильно, но при нажатии кнопки kvit (при наличии сработки на входе)продолжает мигать светодиод 2 канала и не сбрасывается vyhodrele. Но если сигнала на входе не стало- сбрасывается кнопкой kvit.
Вот в Ваш предыдущий вариант я попробовал вставить по аналогии фрагмент второго канала и вроде как работает. Вот взгляните:
Как Вы считаете добавив по аналогии 3, 4 каналы и тд. Будет работать?
Если работает значит хорошо, только типы переменных смените так как у меня в последнем посте AD-define, flag-bool
Вот подправил свой - работает. Посмотрите
vosara, поясните, не совсем соображу фрагмент с миганием светодиода:
и так по кругу...
Смысл такойже только считается по другому, 250 это задержка в мс. Можете вместо милис подставить любое число и на калькуляторе посмотреть как оно работает
Нпрод можете подсказать по работе с кнопкой?!
Есть две кнопки и одиин светодиод. Как повесить один светодиод на две кнопки?
На кнопку 1 нажал светодиод загорелся, на кнопку 2 нажал - выключился и на оборот
нажал на кнопку 2 - включился, на кнопку 1 выключился.
Тупо инвертировать состояние светодиода при нажатии любой из этих кнопок.
Тупо инвертировать состояние светодиода при нажатии любой из этих кнопок.
Что то я не понял... Так что ли?!
delay(500);
//небольшая защита от "дребезга" контактов кнопки
это большая защита и не от дребезга
Добрый день.
Помогите пожалуйста разобраться с программой. На Mega подключено две кнопки ( pin 41 и 43 ) . При нажатии на кнопку (41) должны загораться два светодиода на pin 47 и 53 на 5 секунд. При нажатии на кнопку на pin 43 должны загораться светодиоды на pin 51 и 53 на 10 секунд. Но получается что во втором случае светодиод на pin 53 гаснет через 5 сек. а на pin 51 через 10 сек. Подскажите пожалуйста где ошибка.
светодиода у тебя три, возможных состояний для них тоже три, а флага только два.
Вот скелет алгоритма, защиту от дребезга добавь сам.
А можно исправить Ваш скетч