Как повторить else if (cmd == '3'), пока я не нажму другой cmd?
Этот код предназначен для автоматического открывания и закрывания окна с помощью двигателя с такими датчиками, как пыль, влажность, температура и датчик дождя с модулем Bluetooth через телефон. С этим кодом, если я нажму 1,2, он закроет или откроет окно, а 3 позволит окну открыться или закрыться в зависимости от показателей, которые считывает датчик. Прямо сейчас нажатие 3 будет имитировать это только один раз, а затем выключится, пока я не нажму снова. Так что я бы хотел эту часть иначе если (cmd == '3') повторяться, пока я не нажму другую кнопку cmd, чтобы окно продолжало открываться и закрываться.
///////////////////////////////////////////// ///////////////////////////////
#include <SoftwareSerial.h>
#include <Stepper.h>
#include <DHT.h>
#define DHTPIN A1
#define DHTTYPE DHT11
#define D_IN 3
#define A_IN A0
int Txpin = 7;
int Rxpin = 8;
int stepsmotor = 1024;
const int stepsPerRevolution = 64;
SoftwareSerial BTSerial(Txpin, Rxpin);
DHT dht(DHTPIN, DHTTYPE);
int measurePin = 0; // устанавливаем для измеренияPin значение 0 установить .
int ledPower = 2; // устанавливаем мощность светодиода на 2 установить .
int samplingTime = 280; // устанавливаем время выборки на 280 установить .
int deltaTime = 40; // устанавливаем deltaTime на 40 установить .
int sleepTime = 9680; // устанавливаем время сна на 9690 установить .
float voMeasured = 0; // установить voMeasured в 0 установить .
float calcVoltage = 0; // установить calcVoltage в 0 установить .
float dustDensity = 0; // установить плотность пыли в 0 установить .
Stepper myStepper(stepsPerRevolution, 8, 10, 9, 11);
void setup()
{
Serial.begin(9600);
BTSerial.begin(9600);
myStepper.setSpeed(550);
pinMode(ledPower,OUTPUT);
pinMode(D_IN, INPUT);
}
void loop()
{
if (BTSerial.available())
{
char cmd = (char)BTSerial.read();
if(cmd == '1'){
for(int i=0; i<(32*3-6); i++){
myStepper.step(stepsPerRevolution);
}}
else if (cmd == '2')
for(int i=0; i<(32*3-6); i++){
myStepper.step(-stepsPerRevolution);
}
else if (cmd == '3'){
int dIn = digitalRead(D_IN);
double aIn = analogRead(A_IN);
int h = dht.readHumidity();
int t = dht.readTemperature();
digitalWrite(ledPower,LOW);
delayMicroseconds(samplingTime);
voMeasured = analogRead(measurePin);
delayMicroseconds(deltaTime);
digitalWrite(ledPower,HIGH);
delayMicroseconds(sleepTime);
calcVoltage = voMeasured * (5.0 / 1024.0);
dustDensity = (0.17 * calcVoltage - 0.1) * 1000;
Serial.print(dustDensity);
Serial.println(" ug/m3");
Serial.print("Digital Input = "); Serial.println(dIn);
Serial.print("Analog Input = "); Serial.println(aIn);
Serial.println();
Serial.print("humidity:");
Serial.println(h);
Serial.print("temperature:");
Serial.println(t);
delay(1000);
if (t >= 25 or h >= 70 or dustDensity >= 100 or aIn <= 50)
for(int i=0; i<(32*3-6); i++){
myStepper.step(stepsPerRevolution);
}
else
for(int i=0; i<(32*3-6); i++){
myStepper.step(-stepsPerRevolution);
}
delay(3000);
}
else if (cmd == '4'){
}
}
}
@Jacob, 👍1
Обсуждение1 ответ
Лучший ответ:
Я бы предложил переписать вашу программу как конечный автомат (FSM). Это простая, но мощная концепция. Сначала вы моделируете свою программу в нескольких состояниях, которые связаны через переходы между состояниями. Это хороший способ сначала нарисовать это в виде графика. Вы можете увидеть один пример в моем ответе на этот вопрос.
Для вашего случая я бы использовал ваши "режимы" как состояния для FSM плюс состояние бездействия, когда просто ничего не происходит. Вы начнете с состояния бездействия, а затем перейдете в разные состояния в зависимости от последовательного ввода. В состояниях/режимах 1 и 2, которые являются однократными действиями, вы должны выполнить действие в состоянии, а затем снова напрямую перейти в состояние ожидания.
С точки зрения программирования FSM может быть реализован несколькими способами. Я видел автоматы, использующие переменные и переключатели, а также автоматы, использующие указатель на функцию. Последний элегантен, но не так прост для понимания новичками. Поэтому я предлагаю вам использовать вариант с переключателем, как вы можете видеть в ответе, указанном выше. В основном вы используете переменную (что-то вроде int
или char
) для представления текущего состояния. Затем в функции loop()
вы создаете оператор switch-case для разных значений вашей переменной состояния. Часто перечисление используется как тип переменной, чтобы сделать код более читабельным. В каждом операторе case вы пишете код для соответствующего состояния. В вашем состоянии/режиме 3 вы проверяете свои датчики и закрываете/открываете окно по мере необходимости, а затем оставляете оператор case. Когда произойдет следующая итерация функции loop()
, FSM все еще будет находиться в этом состоянии, снова проверяя датчики. В ваших состояниях/режимах 1 и 2 вы должны проверить, находится ли окно уже в нужном состоянии, и, если нет, задействовать двигатель, чтобы закрыть/открыть окно. Затем - все еще в операторе case - вы должны установить переменную состояния в состояние ожидания, а затем оставить оператор case. Таким образом, при следующем взаимодействии функции loop()
FSM будет находиться в состоянии ожидания, ничего не делая, делая состояния/режимы 1 и 2 одноразовыми каждый раз, когда вы их активируете.
В отличие от кода в связанном ответе, я бы читал последовательные данные вне оператора switch, так как вы будете писать там непосредственно в переменную состояния.
Я настоятельно рекомендую вам попробовать реализовать это. Это важный принцип, который делает ваше звучание более структурным и легким для расширения. Отличный опыт обучения.
Огромное спасибо!, @Jacob
- Как использовать SPI на Arduino?
- Как решить проблему «avrdude: stk500_recv(): programmer is not responding»?
- Как создать несколько запущенных потоков?
- Как подключиться к Arduino с помощью WiFi?
- avrdude ser_open() can't set com-state
- Как узнать частоту дискретизации?
- Что такое Serial.begin(9600)?
- Я закирпичил свой Arduino Uno? Проблемы с загрузкой скетчей на плату
Пожалуйста, не используйте код как изображение. Его трудно читать, и никто не будет набирать код для тестирования на своем компьютере. У вас уже был правильно отформатированный код. Почему вы заменили его изображением?, @chrisl