Всем привет! Изучаю Ардуино и программирование только месяц.
Дабы не плодить темы, прошу помощи... В предыдущем посту, к примеру, есть скетч работы таймера по принципу: "нажал, светик горит, таймер пошел, отсчитался и выключилось". Отличное применение если делать проходной выключатель. А вот у меня появилась идея применить это к рольставням.
Дано: 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;
}
}
переделал
long previousMillis = 0; int val=0; int state = 0; void setup() { pinMode(13, OUTPUT); } void loop() { if(digitalRead(14) == HIGH && state == 0) //если кнопка нажата ... { state = 1; } if (state == 1) { digitalWrite(13,HIGH); // вкл. светодиод if (millis() - previousMillis >500) { previousMillis = millis(); val++; } if(val >= 40) { digitalWrite(13,LOW); // выкл. светодиод state = 0; val = 0; } } }Огромное спасибо, что помогли и не отказали все работает вот теперь мне понятен алгоритм, респект и уважение!!!!!
только не забываем о дребезге контактов кнопки
Всем привет! Изучаю Ардуино и программирование только месяц.
Дабы не плодить темы, прошу помощи... В предыдущем посту, к примеру, есть скетч работы таймера по принципу: "нажал, светик горит, таймер пошел, отсчитался и выключилось". Отличное применение если делать проходной выключатель. А вот у меня появилась идея применить это к рольставням.
Дано: 2 светодиода, одна кнопка.
Логика: нажимаем, горит первый светик, пошел отсчет к приммеру 10 сек. По истечению гаснит. Но если нажал досрочно, светик потух досрочно. Ещё нажатие, загорается уже второй светик. И так же что бы можно было досрочно выключить. и Циклично все это.
Помогите пожалуйста как можно это сделать?
KiVor, вот примено так, кнопка включает и выключает попеременно то один, то другой светодиод.
#define timer 10000 boolean pin_flag, work; uint32_t offtime=0; void setup() { Serial.begin(9600); pinMode(13,OUTPUT); pinMode(12,OUTPUT); pinMode(A5,INPUT_PULLUP); } void loop(){ if (digitalRead(A5)==LOW){ if(work){ work=0; digitalWrite(13,LOW); digitalWrite(12,LOW); } else { if (pin_flag) digitalWrite(12,HIGH); if (!pin_flag) digitalWrite(13,HIGH); pin_flag=!pin_flag; offtime=millis() + timer; work=1; } delay(200); //простое от дребезга } if (millis() > offtime){ digitalWrite(13,LOW); digitalWrite(12,LOW); } }Тоже на ассемблере весом в 60 байт
Просто для примера как это выглядит на ассемблере ;-)
Тоже на ассемблере весом в 60 байт
Получается ассемблер всех уделывает по размеру, самые меленькте hex.
Поморгать светодиодом на тини13
arduini IDE 214байт!((((
#include <avr/delay.h> void setup() {DDRB |= 1<<4; } void loop() { PORTB |= 1 << 4;_delay_ms(100); PORTB &= ~(1 << 4);_delay_ms(100);}Atmel Studio 218байт((
#include <avr/io.h> #include <avr/delay.h> int main(void) { DDRB |= 1<<4; while(1) { PORTB |= 1 << 4; _delay_ms(100); PORTB &= ~(1 << 4); _delay_ms(100); } }ну хорошо кнопка так кнопка, вот на этом примере
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; //ставим флаг что работа идёт.. }melnibo
"как его изменить, чтоб однократное нажатие кнопки включало, выключало светодиод, а удержание кнопки выводило в режим меню"
Ваш код на правильность не проверял но принцып я думаю Вы поймете: При клике - диоды, при удержании более 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 Зачем Вы строчки 47,54, time заключили в скобки () попробуйте убрать их
Скобки ничего не меняют
поставил флаги, все равно крутит loop бесконечно в единицу
/** * Автомат подачи воды с регулировкой времени * Сенсор стеклянный или пластик */ //Объявляем библиотеки #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; //Для регулировки времени 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&&flag1==0) { flag1=1; 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; //ставим флаг что работа идёт.. }if (x < 200) { (time++); lcd.setCursor(0, 0); lcd.print ("TIME: "); lcd.print (time); lcd.print ("sec"); if (time>= 6)time=1; delay(200); }Там внешнее прерывание, поэтому delay не стал забивать.
Почему на флаги не реагирует?
Вячеслав 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; //ставим флаг что работа идёт.. }37 - строчка постоянно задает time=3; Если хотите стартовать с time=3 -
37 удалите а в 36 запишите static int time=3;
62 - строчка исправте flag2=0;
54 - строчка delay(1000); зачем? если флаг стоит.
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 начинает работать нормально тоесть нажал и сразу же отпусти и диод загорелся. не надо держать долго.
подскажите может я какю переменную не знаю, но как сделать чтоб все две кнопки срабатывали по нажатию а не по удержанию?
flag должен быть свой для каждой кнопки, а не один на всех.
Какой смысл в строках 1-7, если они не используются в loop?
Чтото Вы столько много скобок на ставили, попробуйте так. А строчки 1-7 он в setup использовал
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); //выключаем } }так я просто непонимаю как флаг должен быть для каждой кнопки свой? я вот его и использую с переменными 0 и 1 для каждой кнопки. тут вот я реально непонимаю как флаг для каждой кнопки делать
intflag1 = 0;
intflag2 = 0;
intflag3 = 0;
intflag4 = 0;http://ru.wikihow.com/%D1%81%D0%B4%D0%B5%D0%BB%D0%B0%D1%82%D1%8C-%D1%84%...
Нафига флагу int? Достаточно byte.
Подскажите, есть ли информация, насколько короткий может быть импульс от нажатия кнопки? т.к. периодически, в достаточно больших кодах, я сталкиваюсь с тем, что короткие нажатия кнопки не отрабатываются контроллером. Кто-то сталкивался с такой проблемой?
Смотря каким способом обрабатываются кнопки. Если повесить их на прерывание - то должны срабатывать всегда. Если методом поллинга (постоянный опрос состояния кнопок) - то увеличить скорость опроса и избавиться от delay() в коде, если есть.
стоит как обычно, через флаг -
if (digitalRead(x)== HIGH && flag==0){ flag = 1; Нужное действие; } else { flag = 0; }А как повесить на прерывание?
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 совсем не "идут" . Подсобите, пожалуйста.
расечатать?
001intvhod1 = 10;002intvhod2 = 11;003intvhod3 = 12;004intvhod4 = 13;005intvhod5 = A0;006intvhod6 = A1;007intvhod7 = A2;008intvhod8 = A3;009intAD1 = 0;010intAD2 = 1;011intAD3 = 2;012intAD4 = 4;013intAD5 = 5;014intAD6 = 6;015intAD7 = 7;016intAD8 = 8;017intkvit = 9;018intvyhodrele = 3;019intflag1 = 0;020intflag2 = 0;021intflag3 = 0;022023024voidsetup()025{026pinMode(vhod1, INPUT_PULLUP);027pinMode(vhod2, INPUT_PULLUP);028pinMode(vhod3, INPUT_PULLUP);029pinMode(vhod4, INPUT_PULLUP);030pinMode(vhod5, INPUT_PULLUP);031pinMode(vhod6, INPUT_PULLUP);032pinMode(vhod7, INPUT_PULLUP);033pinMode(vhod8, INPUT_PULLUP);034pinMode(kvit, INPUT_PULLUP);035pinMode(AD1, OUTPUT);036pinMode(AD2,OUTPUT);037pinMode(AD3, OUTPUT);038pinMode(AD4,OUTPUT);039pinMode(AD5,OUTPUT);040pinMode(AD6,OUTPUT);041pinMode(AD7,OUTPUT);042pinMode(AD8,OUTPUT);043pinMode(vyhodrele, OUTPUT);// выход управления через транзистор звуковым сигналом044045}046047voidloop()048049{050//Фрагмент 1 , отвечающий за включение и мигание светодиода, а так же включение звукового сигнала при поступлении051// сигнала на vhod1052if(digitalRead(vhod1) == LOW && digitalRead(kvit) == HIGH)053054{055flag1++;056}057else058{059flag1=0;060}061if( flag1>=5)062063{064if(digitalRead(AD1) == LOW)065digitalWrite(AD1,1);066digitalWrite(vyhodrele,1);067delay(250);068digitalWrite(AD1, 0);069delay(250);070digitalWrite(AD1,1);// чтобы светодиод оставался включенным при кратковременном071//срабатывании сигнала на входе072flag1=0;073}074// Фрагмент 2 должен после нажатия кнопки kvit мигающий светодиод зажечь постоянно,075// а выход vyhodrele отключить076077if(digitalRead(kvit) == LOW && digitalRead(vhod1) == LOW)078079{080flag2++;081}082else083{084flag2=0;085}086if(digitalRead(kvit) == LOW && flag2 >=5 )087088{089if(digitalRead(vyhodrele) == HIGH)090digitalWrite(vyhodrele,!digitalRead(vyhodrele));091digitalWrite(AD1,1);092flag2=0;093}094095096//Фрагмент 3 при пропадании сигнала на входе vhod1 и нажатии на кнопку kvit светодиод и выход vyhodrele отключаются097if(digitalRead(kvit) == LOW && digitalRead(vhod1) == HIGH)098099{100flag3++;101}102else103{104flag3=0;105}106if(flag3>=5)107108{109digitalWrite(AD1,0);110digitalWrite(vyhodrele,0);111flag2=0;112113}114115116}#define vhod1 10 int vhod2 = 11; int vhod3 = 12; int vhod4 = 13; int vhod5 = A0; int vhod6 = A1; int vhod7 = A2; int vhod8 = A3; bool AD1 = 0; int 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; unsigned long time; unsigned long x; //Переменная для прошедшего периода "led" 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>=300000) { flag2=0; digitalWrite(vyhodrele,1); } }Попробовал прописать для второго канала, но теперь если сработал первый канал работает правильно, но если нажать кнопку 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); } }Методом повтора не получится - Код нужно разбить на функции и вызывать с параметром сработавшего датчика. Скорей всего нужно создать новую тему потому что это уже не про кнопки!
Пробуйте вот по такому принцыпу
#define vhod1 10 #define vhod2 11 #define vhod3 12 #define vhod4 13 #define vhod5 A0 #define vhod6 A1 #define vhod7 A2 #define vhod8 A3 #define AD1 0 #define AD2 1 #define AD3 2 #define AD4 4 #define AD5 5 #define AD6 6 #define AD7 7 #define AD8 8 #define kvit 9 #define vyhodrele 3 bool trevoga1 = 0; bool trevoga1a = 0; bool trevoga1b = 0; bool trevoga2 = 0; bool trevoga2a = 0; bool trevoga2b = 0; unsigned long time; unsigned long x; //Переменная для прошедшего периода "led" unsigned long time1; unsigned long x1; //Переменная для прошедшего периода "led" 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 && trevoga1 ==0) { trevoga1=1; digitalWrite(vyhodrele,1); } if (digitalRead(vhod1)==HIGH && trevoga1b==1) { trevoga1=0; trevoga1a=0; trevoga1b=0; digitalWrite(AD1, 0); digitalWrite(vyhodrele,0); } if ( trevoga1==1 && trevoga1a == 0) { if (x != (millis() / 250)) { x = millis() / 250; digitalWrite(AD1, !digitalRead(AD1)); } } if (digitalRead(kvit) == LOW ) { trevoga1a=1; trevoga1b=1; digitalWrite(vyhodrele,0); if (digitalRead(vhod1) == LOW) { digitalWrite(AD1, 1); time = millis(); } } if (trevoga1==1 && millis()-time>=1000) { trevoga1a=0; digitalWrite(vyhodrele,1); } /////////////////////////////////////////// if (digitalRead(vhod2) == LOW && trevoga2 ==0) { trevoga2=1; digitalWrite(vyhodrele,1); } if (digitalRead(vhod2)==HIGH && trevoga2b==1) { trevoga2=0; trevoga2a=0; trevoga2b=0; digitalWrite(AD2, 0); digitalWrite(vyhodrele,0); } if ( trevoga2==1 && trevoga2a == 0) { if (x1 != (millis() / 250)) { x1 = millis() / 250; digitalWrite(AD2, !digitalRead(AD2)); } } if (digitalRead(kvit) == LOW ) { trevoga2a=1; trevoga2b=1; digitalWrite(vyhodrele,0); if (digitalRead(vhod2) == LOW) { digitalWrite(AD2, 1); time1 = millis(); } } if (trevoga2==1 && millis()-time>=1000) { trevoga2a=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 каналы и тд. Будет работать?
Если работает значит хорошо, только типы переменных смените так как у меня в последнем посте AD-define, flag-bool
Вот подправил свой - работает. Посмотрите
#define vhod1 10 #define vhod2 11 #define vhod3 12 #define vhod4 13 #define vhod5 A0 #define vhod6 A1 #define vhod7 A2 #define vhod8 A3 #define AD1 0 #define AD2 1 #define AD3 2 #define AD4 4 #define AD5 5 #define AD6 6 #define AD7 7 #define AD8 8 #define kvit 9 #define vyhodrele 3 bool trevoga1 = 0; bool trevoga1a = 0; bool trevoga1b = 0; bool trevoga2 = 0; bool trevoga2a = 0; bool trevoga2b = 0; unsigned long time; unsigned long x; //Ïåðåìåííàÿ äëÿ ïðîøåäøåãî ïåðèîäà "led" unsigned long time1; unsigned long x1; //Ïåðåìåííàÿ äëÿ ïðîøåäøåãî ïåðèîäà "led" 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 && trevoga1 ==0) { trevoga1=1; digitalWrite(vyhodrele,1); } if (digitalRead(vhod1)==HIGH && trevoga1b==1) { trevoga1=0; trevoga1a=0; trevoga1b=0; digitalWrite(AD1, 0); digitalWrite(vyhodrele,0); } if ( trevoga1==1 && trevoga1a == 0) { if (x != (millis() / 250)) { x = millis() / 250; digitalWrite(AD1, !digitalRead(AD1)); } } if (digitalRead(kvit) == LOW ) { trevoga1a=1; trevoga1b=1; digitalWrite(vyhodrele,0); if (digitalRead(vhod1) == LOW) { digitalWrite(AD1, 1); time = millis(); } } if (trevoga1==1 && millis()-time>=1000) { trevoga1a=0; digitalWrite(vyhodrele,1); } /////////////////////////////////////////// if (digitalRead(vhod2) == LOW && trevoga2 ==0) { trevoga2=1; digitalWrite(vyhodrele,1); } if (digitalRead(vhod2)==HIGH && trevoga2b==1) { trevoga2=0; trevoga2a=0; trevoga2b=0; digitalWrite(AD2, 0); digitalWrite(vyhodrele,0); } if ( trevoga2==1 && trevoga2a == 0) { if (x1 != (millis() / 250)) { x1 = millis() / 250; digitalWrite(AD2, !digitalRead(AD2)); } } if (digitalRead(kvit) == LOW ) { trevoga2a=1; trevoga2b=1; digitalWrite(vyhodrele,0); if (digitalRead(vhod2) == LOW) { digitalWrite(AD2, 1); time = millis(); } } if (trevoga2==1 && millis()-time>=1000) { trevoga2a=0; digitalWrite(vyhodrele,1); } }vosara, поясните, не совсем соображу фрагмент с миганием светодиода:
и так по кругу...
Смысл такойже только считается по другому, 250 это задержка в мс. Можете вместо милис подставить любое число и на калькуляторе посмотреть как оно работает
Нпрод можете подсказать по работе с кнопкой?!
Есть две кнопки и одиин светодиод. Как повесить один светодиод на две кнопки?
На кнопку 1 нажал светодиод загорелся, на кнопку 2 нажал - выключился и на оборот
нажал на кнопку 2 - включился, на кнопку 1 выключился.
Тупо инвертировать состояние светодиода при нажатии любой из этих кнопок.
Тупо инвертировать состояние светодиода при нажатии любой из этих кнопок.
Что то я не понял... Так что ли?!
void setup() { pinMode(12, OUTPUT); } void loop() { if(digitalRead(8)==LOW)//если кнопка не нажата ... { digitalWrite(12,HIGH);//включаем светодиод } else//если нажата... { digitalWrite(12,LOW);//выключаем } if(digitalRead(9)==LOW)//если кнопка не нажата ... { digitalWrite(12,!digitalRead(12));//инвертируем состояние пина delay(500);//небольшая защита от "дребезга" контактов кнопки } }delay(500);//небольшая защита от "дребезга" контактов кнопкиэто большая защита и не от дребезга
Добрый день.
Помогите пожалуйста разобраться с программой. На 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; } }светодиода у тебя три, возможных состояний для них тоже три, а флага только два.
Вот скелет алгоритма, защиту от дребезга добавь сам.
#define btn41 41 #define btn43 43 #define led47 47 #define led51 51 #define led53 53 const unsigned long periodBtn41 = 5000; // длительность включения LED по нажатии Btn41 const unsigned long periodBtn43 = 10000; unsigned long timeoutLED47; // переменная для расчета времени отключения LED47 unsigned long timeoutLED51; unsigned long timeoutLED53; void setup() { pinMode (btn41, INPUT); pinMode (btn43, INPUT); pinMode (led47, OUTPUT); pinMode (led51, OUTPUT); pinMode (led53, OUTPUT); } void loop() { unsigned long currentTime = millis(); // проверяем кнопки if (!digitalRead(btn41)) { timeoutLED47 = currentTime + periodBtn41; timeoutLED53 = currentTime + periodBtn41; } if (!digitalRead(btn43)) { timeoutLED51 = currentTime + periodBtn43; timeoutLED53 = currentTime + periodBtn43; } // проверяем светодиоды if (currentTime < timeoutLED47) digitalWrite(led47, HIGH); else digitalWrite(led47, LOW); if (currentTime < timeoutLED51) digitalWrite(led51, HIGH); else digitalWrite(led51, LOW); if (currentTime < timeoutLED53) digitalWrite(led53, HIGH); else digitalWrite(led53, LOW); }А можно исправить Ваш скетч
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&&flag=1){//Необходимо добавить проверку флага 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&&flag1==1){//Необходимо добавить проверку флага digitalWrite(51,LOW); digitalWrite(53,LOW); flag1=0; } if (digitalRead(43)==LOW&&flag1==1){ flag1=0; } }