Параметры Switch case прерываются после вызова функции
Прошу прощения за основной вопрос, но у меня есть случай переключения, когда любой код, размещенный после вызова определенной функции, просто никогда не вызывается, и я потратил полдня на его изучение, так что большое вам спасибо за вашу помощь.
Работает на Arduino UNO.
Вот цикл, и каждый параметр в случае переключения после вызова moist_sensor.read() просто никогда не попадает:
void loop() {
while (Serial.available() > 0) {
char val = (char)Serial.read(); // считывать данные байт за байтом и сохранять их
Serial.println(val);
switch(val) {
case 'O':
digitalWrite(13, LOW);
break;
case 'I':
digitalWrite(13, HIGH);
break;
case 'W':
water(2000);
break;
case 'E':
int reading = moist_sensor.readd(); //ПРОБЛЕМНАЯ СТРОКА
//Serial.println(чтение); // отправить полученные данные обратно в raspberry pi
break;
// он никогда не входит ни в один из приведенных ниже случаев
case 'M':
//Чтение строки 2 = moist_sensor.packaged_reading();
//Serial.println(reading2); // отправить полученные данные обратно в raspberry pi
break;
case 'W':
water(5000);
break;
default:
delay(5000);
}
}
Я пробовал изменять имя функции с помощью специальных ключевых слов, заменяя его другими случаями (например, помещая регистр 'W' выше, где это работает, и наоборот), и я всегда получаю одно и то же поведение. Если я прокомментирую строку, все будет работать так, как ожидалось.
Я знаю, что метод на самом деле вызывается не постоянно, но ради здравомыслия moist_sensor.readd() прямо сейчас просто:
int readd() {
return 0;
}
Это также отлично работает, если это последний случай, но это меня раздражает, и я хочу создать другие случаи с помощью вызовов функций.
Большое вам спасибо!
@jmart, 👍3
2 ответа
Как только я опубликовал это, я посмотрел на объявление переменной внутри корпуса и подумал, что исправлю этот уродливый код, и оказалось, что именно это все и ломает, я понятия не имел ...
case 'E':
int reading = moist_sensor.readd(); //ПРОБЛЕМНАЯ СТРОКА
//Serial.println(чтение); // отправить полученные данные обратно в raspberry pi
break;
должно быть просто
case 'E':
reading = moist_sensor.readd(); //ПРОБЛЕМНАЯ СТРОКА
//Serial.println(чтение); // отправить полученные данные обратно в raspberry pi
break;
с объявлением "int reading;" где-то еще выше.
Казалось, вы решили эту проблему. По этой причине взгляните на ошибки компилятора:
sketch_nov22a:31: error: jump to case label [-fpermissive]
case 'M':
^
sketch_nov22a:25: error: crosses initialization of 'int reading'
int reading = moist_sensor.readd(); //THE PROBLEMATIC LINE
^
sketch_nov22a:38: error: jump to case label [-fpermissive]
case 'W':
^
sketch_nov22a:25: error: crosses initialization of 'int reading'
int reading = moist_sensor.readd(); //THE PROBLEMATIC LINE
^
sketch_nov22a:43: error: jump to case label [-fpermissive]
default:
^
sketch_nov22a:25: error: crosses initialization of 'int reading'
int reading = moist_sensor.readd(); //THE PROBLEMATIC LINE
^
exit status 1
Если вы получили его для компиляции, ваш компилятор должен быть настроен немного иначе, чем мой. Однако вы можете увидеть это , поставив int reading = ...
в блоке case компилятор пытается выполнить это первым (для инициализации чтения
), что приводит к переходу меток case.
Перемещая чтение int
за пределы оператора case, компилятору больше не нужно инициализировать переменную, и эта строка просто становится вызовом и назначением функции (а не инициализацией переменной).
Вы можете избежать этого, поместив код в его собственный блок, то есть вместо:
case 'E':
int reading = moist_sensor.readd(); //ПРОБЛЕМНАЯ СТРОКА
//Serial.println(чтение); // отправить полученные данные обратно в raspberry pi
break;
Использование:
case 'E':
{
int reading = moist_sensor.readd(); //ПРОБЛЕМНАЯ СТРОКА
//Serial.println(чтение); // отправить полученные данные обратно в raspberry pi
}
break;
- Как вызвать функции C из скетча ардуино?
- max7219 связанный дисплей, показывающий зеркальный текст
- Пиринговая коммуникация
- Запуск С для ардуино
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- Прерывание ардуино при смене контакта
- GSM-модуль IOT-GA6 Arduino + ошибка CME 58
- Разница между массивом char и массивом unsigned char
Да, я использую arduino-cli для компиляции / загрузки на плату из RPI, и хотя я получаю сообщения об ошибках, оказывается, я могу пропустить кучу предупреждений. Интересно на самом деле изучить "ошибку: переход к метке регистра" и то, как она портит логику компиляторов, по-прежнему считая объявление переменной действительным в следующих случаях переключения, но не при инициализации. Спасибо вам за исправление блока! Я всегда думал, что повторяющиеся объявления в подобных случаях будут оптимизированы компилятором, применимо ли это к данному случаю? Я бы предпочел избежать ненужной глобальной переменной., @jmart
Область действия и время жизни (нестатической) переменной внутри блока - это сам блок. Компилятор вполне может поместить эту переменную в регистр и вообще не использовать память. Поэтому я бы сказал, да, компилятор будет оптимизировать столько, сколько сможет., @Nick Gammon