Всем привет! Совсем недавно купил себе Arduino. Изначально покупал плату для сбора проекта "умный дом" на даче, однако пока не все комплектующие доехали, решил собрать умную клетку для хомяка. Принцип работы достаточно прост: днем должен гореть зеленый свет, вечером- красный, а ночью- ничего. Относительно показаний датчика света и меняется цвет лампы, а температурный датчик включает небольшой компьютерный кулер, чтобы охлаждать клетку, когда в ней больше 32 С. Кроме того предусмотрен сбор и отправка данных через Serial-соединение, а также два режима работы, которые можно менять командами, отправляя их в COM-порт. Как раз на режимах работы и состоит проблема: при отправке единицы, микроконтроллер начинает выполнять цикл While, который проверяет равна ли единице переменная val (где val == Serial.read(). Если val перестает быть равен 1, то цикл завершается с помощью команды break. В теории то все вроде-бы понятно. Но вот как я не пытался, заставить arduino выйти из этого цикла не получается. Помогите сделать так, как было описано в теории. Код не влез в тему, т.к. сообщение с ним превышают ограничение в 10000 символов на формуме. P.S. Программа пока выглядит громоздко, т.к. писал "на черновую".
Тогда выложу сюда. Весь код не влезет, поэтому по частям. Код (Text): #define LED_RED 3 //дневной светодиод #define LED_GREEN 13 //ночной светодиод #define TEMP_PIN A1 //температурный датчик #define BUZZER 4 //пьезо-пищалка #define LIGHT_SENSOR A0 //датчик света int FAN = 7; //вентилятор int val; // переменная для данных с com-порта #define LIGHT_EVENING 450 //определяем световые пороги для режимов дня #define LIGHT_NIGHT 850 void setup() { pinMode(LED_GREEN, OUTPUT); //показываем где выход/вход pinMode(LED_RED, OUTPUT); pinMode(BUZZER, OUTPUT); pinMode(FAN, OUTPUT); pinMode(LIGHT_SENSOR, INPUT); pinMode(TEMP_PIN, INPUT); Serial.begin(9600); // запускаем serial-соединение } void loop() { // переводим информацию с термометра в нормальные значения float voltage = 5.0 / 1024.0 * analogRead(TEMP_PIN); float temp_c = ( voltage - 0.5 ) * 100; val = Serial.read(); //данные с Serial будем хранить в переменной val if (val == '0') { //главное меню Serial.println("------------------------------------------"); Serial.println("- Hello! Welcome to Hamster Smart Cage! -"); Serial.println("- Press 1 to go to auto mode -"); Serial.println("- Press 2 to go to manual mode -"); Serial.println("------------------------------------------"); }
И вторая часть: Код (Text): if (val == '2') { //меню ручного управления Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } if (val == '4') { // если нажимаем 4, охлаждение выключается digitalWrite(FAN, LOW); Serial.println("Fan is OFF"); Serial.print("Temperature: "); Serial.println(temp_c); delay(1000); Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } if (val == '3') { // если нажимаем 3, охлаждение включается digitalWrite(FAN, HIGH); Serial.println("Fan is ON"); Serial.print("Temperature: "); Serial.println(temp_c); delay(1000); Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } if (val == '6') { // если нажимаем 6, светодиод выключается digitalWrite(LED_RED, LOW); Serial.println("Red LED is OFF"); delay(1000); Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } if (val == '5') { // если нажимаем 5, светодиод включается digitalWrite(LED_RED, HIGH); Serial.println("Red LED is ON"); delay(1000); Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } if (val == '8') { // если нажимаем 8, светодиод выключается digitalWrite(LED_GREEN, LOW); Serial.println("Green LED is OFF"); delay(1000); Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } if (val == '7') { // если нажимаем 7, светодиод вкключается digitalWrite(LED_GREEN, HIGH); Serial.println("Green LED is ON"); delay(1000); Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } while (val == '1') { // если val равно 1, гоняем этот цикл: // еще раз переводим информацию с термометра в нормальные значения float voltage = 5.0 / 1024.0 * analogRead(TEMP_PIN); float temp = ( voltage - 0.5 ) * 100; delay(1000); //ждем, чтобы не бомбить значениями com-порт int light = analogRead(LIGHT_SENSOR); //читаем информацию с датчика освещенности if (temp < 32) { digitalWrite(FAN, LOW); // навсякий случай выключаем вентилятор Serial.print("Temperature: "); //если температура меньше 32, отправляем данные Serial.println(temp); Serial.print("Light: "); Serial.println(light); //------------------------------------------------------------------------ // освещение (изменяем свет в зависимости от времени суток) int ledLevel = map(light, LIGHT_EVENING, LIGHT_NIGHT, 180, 0); if (light < LIGHT_EVENING && light < LIGHT_NIGHT) { // день digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_RED, LOW); Serial.print("Day mode: "); Serial.println("Day"); } if (light > LIGHT_EVENING && light < LIGHT_NIGHT) { // вечер digitalWrite(LED_GREEN, LOW); analogWrite(LED_RED, ledLevel); Serial.print("Day mode: "); Serial.println("Evening"); } if (light > LIGHT_EVENING && light > LIGHT_NIGHT) { // ночь digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, LOW); Serial.print("Day mode: "); Serial.println("Night"); } //------------------------------------------------------------------------ } if (temp > 32) { // если критическая температура, то digitalWrite(FAN, HIGH); //включаем охлождение tone(BUZZER, 500, 300); //пищим зуммером Serial.println("ALERT!"); //пишем alert в com-порт digitalWrite(LED_RED, HIGH); delay(300); digitalWrite(LED_RED, LOW); delay(300); digitalWrite(LED_GREEN, HIGH); delay(300); digitalWrite(LED_GREEN, LOW); delay(300); } val == Serial.read(); //сохраняем значения с com-порта в val if (val == '2') { //если val равен 2, выходим из цикла While break; } } //закрываем цикл While delay(1000); }
Раз: Код (Text): void PrintInstruction() { Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); } Для вывода текста вызывайте PrintInstruction().
Два: Код (Text): #define LED_RED 3 //дневной светодиод #define LED_GREEN 13 //ночной светодиод #define TEMP_PIN A1 //температурный датчик #define BUZZER 4 //пьезо-пищалка #define LIGHT_SENSOR A0 //датчик света int FAN = 7; //вентилятор int val; // переменная для данных с com-порта #define LIGHT_EVENING 450 //определяем световые пороги для режимов дня #define LIGHT_NIGHT 850 void setup() { pinMode(LED_GREEN, OUTPUT); //показываем где выход/вход pinMode(LED_RED, OUTPUT); pinMode(BUZZER, OUTPUT); pinMode(FAN, OUTPUT); pinMode(LIGHT_SENSOR, INPUT); pinMode(TEMP_PIN, INPUT); Serial.begin(9600); // запускаем serial-соединение } void loop() { // переводим информацию с термометра в нормальные значения float voltage = 5.0 / 1024.0 * analogRead(TEMP_PIN); float temp = ( voltage - 0.5 ) * 100; int light = analogRead(LIGHT_SENSOR); //читаем информацию с датчика освещенности if(Serial.available() > 0)// считываем данные только тогда, когда они есть val = Serial.read(); switch(val) { case '0'://главное меню Serial.println("------------------------------------------"); Serial.println("- Hello! Welcome to Hamster Smart Cage! -"); Serial.println("- Press 1 to go to auto mode -"); Serial.println("- Press 2 to go to manual mode -"); Serial.println("------------------------------------------"); break; case '1': if (temp < 32)//если температура меньше 32, отправляем данные { digitalWrite(FAN, LOW); // на всякий случай выключаем вентилятор Serial.print("Temperature: "); Serial.println(temp); Serial.print("Light: "); Serial.println(light); //------------------------------------------------------------------------ // освещение (изменяем свет в зависимости от времени суток) int ledLevel = map(light, LIGHT_EVENING, LIGHT_NIGHT, 180, 0); if (light < LIGHT_EVENING && light < LIGHT_NIGHT)// день { digitalWrite(LED_GREEN, HIGH); digitalWrite(LED_RED, LOW); Serial.print("Day mode: "); Serial.println("Day"); } if (light > LIGHT_EVENING && light < LIGHT_NIGHT)// вечер { digitalWrite(LED_GREEN, LOW); analogWrite(LED_RED, ledLevel); Serial.print("Day mode: "); Serial.println("Evening"); } if (light > LIGHT_EVENING && light > LIGHT_NIGHT)// ночь { digitalWrite(LED_GREEN, LOW); digitalWrite(LED_RED, LOW); Serial.print("Day mode: "); Serial.println("Night"); } //------------------------------------------------------------------------ } if (temp > 32)// если критическая температура, то { digitalWrite(FAN, HIGH); //включаем охлождение tone(BUZZER, 500, 300); //пищим зуммером Serial.println("ALERT!"); //пишем alert в com-порт digitalWrite(LED_RED, HIGH); delay(300); digitalWrite(LED_RED, LOW); delay(300); digitalWrite(LED_GREEN, HIGH); delay(300); digitalWrite(LED_GREEN, LOW); delay(300); } break; case '2'://меню ручного управления PrintInstruction(); break; case '3':// если нажимаем 3, охлаждение включается digitalWrite(FAN, HIGH); Serial.println("Fan is ON"); Serial.print("Temperature: "); Serial.println(temp); PrintInstruction(); break; case '4':// если нажимаем 4, охлаждение выключается digitalWrite(FAN, LOW); Serial.println("Fan is OFF"); Serial.print("Temperature: "); Serial.println(temp); PrintInstruction(); break; case '5':// если нажимаем 5, светодиод включается digitalWrite(LED_RED, HIGH); Serial.println("Red LED is ON"); PrintInstruction(); break; case '6':// если нажимаем 6, светодиод выключается digitalWrite(LED_RED, LOW); Serial.println("Red LED is OFF"); PrintInstruction(); break; case '7':// если нажимаем 7, светодиод вкключается digitalWrite(LED_GREEN, HIGH); Serial.println("Green LED is ON"); PrintInstruction(); break; case '8':// если нажимаем 8, светодиод выключается digitalWrite(LED_GREEN, LOW); Serial.println("Green LED is OFF"); PrintInstruction(); break; } delay(1000); } void PrintInstruction() { Serial.println("---------------------------------------"); Serial.println("- Welcome to manual mode! -"); Serial.println("- Press 1 to swich to the auto mode -"); Serial.println(" "); Serial.println("- Press 3 to swich on the FAN -"); Serial.println("- Press 4 to swich off the FAN -"); Serial.println(" "); Serial.println("- Press 5 to swich on the Red led -"); Serial.println("- Press 6 to swich OFF the Red led -"); Serial.println(" "); Serial.println("- Press 7 to swich on the Green led -"); Serial.println("- Press 8 to swich OFF the Green led -"); Serial.println("---------------------------------------"); }
А break в цикле while вообще не нужен. Цикл сам завершится, когда условие перестанет выполняться. В вашем случае и сам цикл не нужен. Нажимайте Ctrl+T для автоматического форматирования кода.
Все хорошо, за исключением того, что при отправке единицы, case 1 должен крутиться постоянно, пока в COM-порт не послать, скажем, двойку.
А он и будет крутиться. Переменная val меняет свое значение толь при приходе новых данных. При каждом проходе loop крутится та ветка, которая соответствует val.
Все, сам въехал как сделать циклическое повторение: убрал break;, поставил вторичное считывание Serial в val и добавил delay(1000) чтобы не бомбить com-порт. В итоге, в конце case 1 получилось следующее: Код (Text): val == Serial.read(); delay(1000); Напоследок, выражаю огромную благодарность Megakoteyka. Демонстрация работы устройства: Код (Text): Использовалось: 1. Iskra Neo 2. Troyka Shield 3. Relay Shield 4. Аналоговый термометр 5. Красный светодиод 6. Зеленый светодиод 7. Зуммер (пьезо-пищалка) 8. Датчик освещенности 9. Провода 1mm 10. Зарядка от мобильного телефона (9V, 500mA) 11. Компьютерный кулер Tornado (2000 об/мин; 12V) 12. Трехпроводные шлейфы 13. USB-удлинитель 3 метра
Разве Код (Text): val == Serial.read(); считывает из серийного порта? Двойное равно не присваивает, а сравнивает, или я не прав?
Строка программы val == Serial.read(); бесследно убирает один байт из данных, идущих по последовательному порту (если он там имеется, естественно). Эквивалентно просто Serial.read(); , поскольку результат сравнения никак не используется.