Использование одной и той же переменной между операторами if в loop()
Интересно, есть ли хороший способ использовать одно и то же значение переменной между двумя разными операторами if в цикле().
В разделе серводвигателя кода я хочу использовать значение из первого if-оператора RewardTime в следующем if-операторе RewardTime. До сих пор я не могу найти способ сделать это. (Поскольку сейчас между этими переменными нет связи, время вознаграждения остается равным 0).
Я был бы признателен за определенное руководство в этом вопросе.
#include <Servo.h> // Библиотека, необходимая для серводвигателя (обязательно скачайте, если ее нет в библиотеке)
#include <Button.h> // Библиотека, необходимая для микропереключателя (обязательно скачайте, если ее нет в библиотеке)
// ПАРАМЕТРЫ
// СКОПИРУЙТЕ ЭТИ ЗНАЧЕНИЯ В КОД ОБРАБОТКИ ВРУЧНУЮ
// Пояснение: Для предотвращения возможного переполнения Arduino-обработки. Не нужно слишком много информационного потока между Arduino и Обработкой.
const float Scale = 1 * 1000; // миллисекунды
const float Base = 1 * 1000; // миллисекунды
Servo Servo1;
int servoPin = 9; // Объявить вывод сервопривода
Button button(7); // Объявить вывод микропереключателя (может варьироваться от настройки к настройке)
unsigned long previousMillis = 0;
bool switching = false;
int State = LOW;
char BirdSings = 0;
//static float RewardTime = 0;
void setup() {
Servo1.attach(servoPin);
analogWrite(9, 0);
Serial.begin(9600);
button.setDebounceTime(100); // установите время дебоунса равным 100 миллисекундам.
}
void loop(){
// МИКРОПЕРЕКЛЮЧАТЕЛЬ
// Получить время начала и смещения, когда птица прилетает и покидает насест
button.loop();
if(button.isPressed())
Serial.println(1);
if(button.isReleased())
Serial.println(0);
// СЕРВОДВИГАТЕЛЬ
// Получить время, когда кормушка закрыта (присутствует пища) и раскрыта (отсутствует пища)
unsigned long currentMillis = millis();
while (Serial.available() > 0) {
unsigned long currentMillis = millis();
if (Serial.read() == '\n') { //Когда есть песня
//Serial.println(2); // Еда раскрыта
previousMillis = currentMillis; // 0 becomes the current milli
static float RewardTime = (Serial.parseFloat() * Scale) + Base; // CALCULATE THE RewardTime HERE
Serial.println(RewardTime);
if (State == LOW)
State = HIGH;
else
State = LOW;
}
}
if (State == HIGH && switching == false){
Servo1.write(0); // 0 градусов
unsigned long secondCurrentMillis = millis();
if (secondCurrentMillis - previousMillis > RewardTime) { // ИСПОЛЬЗУЙТЕ ВЫШЕУПОМЯНУТОЕ RewardTime ЗДЕСЬ
switching = true;
previousMillis = secondCurrentMillis;
if (State == LOW)
State = HIGH;
else
State = LOW;
}
}
if(State == LOW && switching == true){
Servo1.write(90); // 90 градусов
switching = false;
//Serial.println(3); // Еда покрыта
}
}
@John, 👍2
2 ответа
Сделайте переменную глобальной, таким образом, выведите ее за пределы функции цикла
; кроме того, вам больше не нужно ключевое слово static.
float RewardTime = 0;
Чем внутри вашего первого оператора if, удалите
ключевые слова static float:
RewardTime = (Serial.parseFloat() * Scale) + Base;
Некоторые другие советы:
- обычно локальные переменные не начинаются с заглавной буквы (поэтому
rewardTime
похож на большинство соглашений о кодировании). Всегда используйте скобки.
if (Состояние == НИЗКОЕ) Состояние = ВЫСОКОЕ; ещё Состояние = НИЗКОЕ;
Изменение на:
if (State == LOW)
{
State = HIGH;
}
else
{
State = LOW;
}
Однако, чтобы сделать его более простым, используйте тернарный оператор, вы можете изменить его на:
Состояние = (Состояние == НИЗКОЕ ? ВЫСОКИЙ : НИЗКИЙ);
Что значит: если какое-то условие ? Сделай это : Еще сделай это;
Поскольку вы определили его в первом операторе if, он является только "in-scope" или определен в этом блоке. Чтобы сделать его видимым для обоих операторов if, определите его в следующем внешнем блоке, содержащем оба
оператора if - в данном случае где-то между
void loop(){
и if (Serial.read()...
- Мигните светодиодом 5 раз с помощью цикла for
- Сохранение файла .txt на SD-карту и чтение данных каждого содержимого в файл txt, а затем сохранение его в переменной
- Как остановить цикл в последовательном мониторе?
- Объявленная переменная внутри void setup не видится в void loop
- Хранить переменную?
- Объектно-ориентированное программирование Arduino
- Сбросить переменную каждую 1 секунду на Arduino.
- Как повторить другое действие внутри цикла?
HIGH / LOW и
true
/false
идентичны, поэтомуState = ! Состояние;
достаточно., @DataFiddler@DataFiddler Но вы не должны зависеть от значений внутри библиотеки. Предположим, в будущем они изменят значения на 20 и 30 вместо true/false. Если API Arduino предназначался для логического значения, они должны были использовать логический тип., @Michel Keijzers
если они когда-нибудь изменят определение ВЫСОКОГО и НИЗКОГО, я перестану использовать Arduino. Они даже не решаются изменить тип возврата digitalRead, что является хорошим решением., @DataFiddler
@DataFiddler ... хорошая мысль, и я полностью согласен, что это сломает многие скетчи. Но они действительно должны использовать логическое значение в качестве типа входного аргумента, или перечисление EPinState (LOW, HIGH), или что-то в этом роде., @Michel Keijzers
Этот вопросительный знак называется оператором Элвиса для людей, которые не знают, он похож на if else, но с некоторым компилятором это может быть быстрее (это происходит на intel, например, с инструкцией cmov)., @alessandromrc
@alessandromrc Я думаю, что оператор Элвиса действительно является более неформальным именем (спасибо за добавление). Кстати, я думаю, что это вообще не очень хорошая идея писать по соображениям производительности, если это не известно заранее или когда это необходимо (впоследствии), он просто читается легче (если он помещается в одной строке в основном)., @Michel Keijzers