Включение сирены по кнопке (проблема)

bool flag;
bool alarm;
bool lastClick;
bool btn;
bool lastSignal;
void setup() {
  pinMode(2, INPUT_PULLUP);
    
}

void loop() {
  btn = !digitalRead(2);
  if(btn == 1 && flag == false && millis() - lastClick > 50){
    flag = true;
    alarm = !alarm;
    lastClick = millis();
  }
  if(btn == 0 && flag == true){
    flag = false;
  }
  if(alarm == true && millis() - lastSignal >4000){ //Проверка переменной включения сигнализации и сама сигнализация
    lastSignal = millis();
    tone(3, 2000, 2000);// пин, частота в гц, время
  }
}

ВОТ такой вот код есть. Он проверяет кнопку, и если ее однократно нажать переменная бул сменит значение, и если еще раз нажать - соответственно тоже сменит. есть проблема .я хочу сделать, что бы благодаря переменной alarm в зависимости от ее значение сигнализация на спикере включалась и выключалась. так вот у меня не получается сделать такую сирену без delay, используя millis (в коде последний блок if) у меня после нажатия кнопки происходит постоянный звук и выключить его кнопкой уже нельзя. подскажите пожалуйста, почему после написания этого блока он не отключается и почему он не издает прерывающийся звук…

*получается что блок проверяет значение переменной и прошло ли с последнего запуска 4 секунды, а так как после обновления переменной lastSignal 2 секунды звучит сигнал, то и молчать он будет еще 2 секунды. НУ КАК Я ДУМАЛ ОН БУДЕТ РАБОТАТЬ

Простите, а в какой строке кода Вы выключаете звук (ну, пытаетесь выключить)? Включаете в 23-ей, а выключаете … где? Вы не думали, что если пищалку включить и не выключать, то она сама себя не выключит?

разве последний параметр в функции tone() не длительность звучания? То есть пищалку можно и не выключать, она сама выключится через 2 секунды.

@octavo
какая ардуина у вас?

Я понял, что забыл поставить else после if . проблема с включением и отключением решена. теперь проблема в создании сирены. если просто добавить tone(pin, freq); в if, то будет просто звук сплошной. если добавить через delay noTone, то выключить сирену можно будет только в тайминг когда цикл кончился, и ожидая таймер mills еще не включился, а мне нужна возможность выключить сирену в любой момент

покажите исправленный код

Не знаю куда Вы else вставили, но ошибка у вас в строках 3 и 5.
А чтобы выключить сирену в “любой” момент, наверное, только прерывания могут помочь.

1 лайк

можно и без прерываний

Действительно. Тупанул, смешалось в голове несколько фактов.

Виноват! Поторопился :frowning:

bool flag;
bool alarm;
bool lastClick;
bool btn;
bool lastSignal;
bool soundState;

void setup() {
pinMode(2, INPUT_PULLUP);
}

void loop() {
btn = !digitalRead(2);
if(btn == 1 && flag == false && millis() - lastClick > 50){
flag = true;
alarm = !alarm;
lastClick = millis();
}
if(btn == 0 && flag == true){
flag = false;
}

if(alarm == true){
if(millis() - lastSignal >= 1000){
lastSignal = millis();
soundState = !soundState;
if(soundState){
tone(3, 2000);
} else {
noTone(3);
}
}
} else {
noTone(3);
soundState = false;
}
}

ну и как работает, проверял?
уже было сказано, что строки 3 и 5, это шедевр!

BABOS решил шедевр не портить)
А отступы в строках, похоже, платные.

1 лайк

нет конечно, не проверял,(времени сейчас нет) но как минимум я пнул в нужном направлении!
к тому же исправлено lastSignal >4000 когда 2к там у него и звуки не перекрывают друг друга!
а так же железно выключение добавлено, если понимает что он пишет(так как я не особо понял))) ) то он думаю доделает, а строки 3 и 5 я не понял что там… вы ему если что объясните))) я просто предложил код)))

естественно, к тому же мне так удобнее …

а я бы проверил в bool (он же байт занимает) что будет когда туда миллис пихают :open_hands:

У меня в bool пихает 1, если ulong любой не 0. Вне зависимости от того, помещалось ли его значение в 1 байт или нет.
Не знаю, стандарт это или от компилятора зависит.

А чего его проверять? Любое арифметическое выражение при преобразовании в bool даёт false, равно 0 и true во всех остальных случаях. Это же с самых первых страниц К&R. Чё это Вы все … пятница что ли?

А вот тут то и пригодился бы отладчик :grinning_face:

Отладчик придумали трусы, как и тормоза.

Я бы сделал вывод диагностический для проверки входа в циклы.

Понятно, что true. Но как Вы сами написали, все что не 0, то true.
Интересно было сохранится ли значение при обратном преобразовании.
Т.е. после

```
bool bVar = false;
unsigned long ulVar = 50;
ulVar = bVar = ulVar;
```
чему будет равно значение ulVar? 50 или 1?
Хотя, с другой стороны, еще понятнее, что такой код писать в принципе не надо.

Конечно 1, какие сомнения?

Это вообще, очень распространённый приём решения частой задачи: “число оставить 0-лём, если оно ноль или сделать 1-цей в противном случае

n = !! n;
2 лайка