Проблема с циклом while - PullRequest
       32

Проблема с циклом while

0 голосов
/ 07 октября 2019

Для моего проекта я пытаюсь измерить расстояние между моим датчиком и объектом, чтобы вызвать тревогу. Если сработала сигнализация, на мою учетную запись Telegram будет отправлено сообщение с библиотекой (UniversalTelegramBot). Для определения расстояния я использую петлю для расстояния между датчиком и объектом, но для проверки, получаю ли я какие-либо сообщения, мне также нужно использовать петлю. Я хочу сделать так, чтобы с комментарием "/ off" расстояние снова запутывалось, но когда вы набираете что-то еще, оно ждет, пока комментарий "/ off" снова не будет использован. Пока включен будильник и он проверяет сообщения, я хочу использовать «/ start» в качестве комментария, чтобы увидеть, какие другие комментарии использовать и как его использовать, не возвращаясь в цикл сообщений снова.

Мой главныйпроблема в том, что когда сработала сигнализация и я что-то набрал, неважно, что цикл снова начинает обмениваться сообщениями, но я хочу, чтобы он снова возвращался к обработке сообщений, когда я набираю "/ off" в телеграмме.

Мой код:

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

UniversalTelegramBot bot(TELEGRAM_BOT_TOKEN, client);

int delayBetweenChecks = 250;
unsigned long lastTimeChecked;

void handleNewMessages(int numNewMessages) {

  for (int i = 0; i < numNewMessages; i++) {
    String chat_id = String(bot.messages[i].chat_id);
    String text = bot.messages[i].text;

    String from_name = bot.messages[i].from_name;
    if (from_name == "")
      from_name = "Gast";

    Serial.print("De volgende knop is ingedrukt: ");
    Serial.println(text);

    if (text == F("/off")) {
      digitalWrite(LED_PIN, LOW);
      alarmStatus = 0;
      noTone(buzzer);
    }

    if (text == "/start") {
      String welcome = "Welkom bij jouw alarmsysteem, " + from_name + ".\n";
      welcome += "/off : om het alarm uit te zetten\n";
      bot.sendMessage(chat_id, welcome, "Markdown");
    }
  }
}

void loop() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);

  // Convert the time into a distance
  cm = (duration / 2) / 29.1;   // Divide by 29.1 or multiply by 0.0343
  inches = (duration / 2) / 74; // Divide by 74 or multiply by 0.0135

  Serial.print(inches);
  Serial.print("in, ");
  Serial.print(cm);
  Serial.print("cm");
  Serial.println();
  while (cm <= 9) {
    Serial.println("ALARM!");
    digitalWrite(LED_PIN, HIGH);
    tone(buzzer, 250);
    alarmStatus = 1;
    if (alarmStatus = 1) {
      if (millis() > lastTimeChecked + delayBetweenChecks) {
        int numNewMessages = bot.getUpdates(bot.last_message_received + 1);
        handleNewMess ages(numNewMessages);
        if (numNewMessages) {
          Serial.println("got response");
          handleNewMessages(numNewMessages);
        }
        lastTimeChecked = millis();
      }
    }
    break;
  }
  delay(250);
}

1 Ответ

1 голос
/ 07 октября 2019

Если я правильно понимаю, вы можете оставить две отдельные переменные состояния. Один для включения и выключения будильника, когда вы уходите / возвращаетесь домой, и один для включения будильника.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

const int delayBetweenChecks = 250;

bool alarmStatus = false;    // off by default
bool alarmTriggered = false; // off by default

UniversalTelegramBot bot(TELEGRAM_BOT_TOKEN, client);

double measure_distance_in_cm() {
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  pinMode(echoPin, INPUT);
  unsigned long duration = pulseIn(echoPin, HIGH);

  // Convert the time into a distance
  return static_cast<double>(duration) / (29.1 * 2.);
}

void trigger_on() {
  digitalWrite(LED_PIN, HIGH);
  alarmTriggered = true;
}

void trigger_off() {
  digitalWrite(LED_PIN, LOW);
  alarmTriggered = false;
}

void handleNewMessages() {
  int numNewMessages = bot.getUpdates(bot.last_message_received + 1);

  for (int i = 0; i < numNewMessages; i++) {
    String text = bot.messages[i].text;

    Serial.println(text);

    if (text == "/start") {     // when you're leaving home
      alarmStatus = true;
      trigger_off();
    }
    else if (text == "/stop") { // when you're returning home
      alarmStatus = false;
      trigger_off();
    }
    else if (text == "/off") {  // turn off a triggered alarm
      trigger_off();
    }
    else if (test == "/on") {   // force triggering of the alarm
      trigger_on();            
    }
  }
}

void loop() {
  static unsigned long lastTimeChecked = millis();

  handleNewMessages();

  if(alarmStatus) {                // you only need to do this if the alarm is on
    if(alarmTriggered == false) {  // only measure if the alarm isn't already triggered  
      double cm = measure_distance_in_cm();
      if(cm <= 9.) {
        Serial.println("ALARM!");
        trigger_on();
      }
    }
    // If it's triggered: Sound the alarm in 200ms bursts until /off or /stop is received 
    if(alarmTriggered) tone(buzzer, delayBetweenChecks-50);
  }

  // try to keep the polling at a steady pace
  lastTimeChecked += delayBetweenChecks;
  unsigned long now = millis();
  if(lastTimeChecked > now) delay(lastTimeChecked - now);
}

Отказ от ответственности: у меня нет Arduino, поэтому я сам не могу его проверить.

...