Создаем мобильное приложение для управления «Умной теплицей» на Arduino
На 5 уроке про Умную теплицу на Ардуино, мы создадим свое собственное мобильное приложение для устройств на Андроиде. Для этого мы используем редактор визуального программирования Android App Invertor 2
Напомним: в предыдущих статьях по Умной теплице (проект «Домашний цветок») «Умная теплица на Arduino- делаем первые шаги» и «Индикация показаний при проектировании Умной теплицы на Ардуино» и Организация полива, обдува и освещения в Умной теплице на Ардуиномы реализовали функции мониторинга и вывода данных на дисплей и светодиоды, а также функции управления — полив цветка, обдув, освещение нажатием соответствующих кнопок.
В следующей статье про перенос «функции мониторинга и управления теплицей на телефон или планшет с ОС Android» мы установили связь нашей системы с телефоном (или планшетом) с операционной системой Android по Bluetooth, что позволило нам отправлять данные мониторига данных нашей теплицы на телефон и получать команды управления с телефона. Но для связи теплицы с телефоном мы использовали на телефоне приложение Bluetooth Terminal, что совсем неудобно. Нам нужно полноценное приложение. В этом уроке мы и займемся его созданием.
Глубоко внимать в вопросы программирования для операционной системы Android не входит в наши планы, поэтому нам нужна простая и понятная система создания кода для Android, наподобие системы Sctratch для Arduino, которую мы рассматривали на этом уроке – Программируем с Arduino… К счастью подобный визуальный редактор есть. Это онлайн визуальный редактор для визуального программирования для Android App Invertor 2. Страница проекта – http://ai2.appinventor.mit.edu.
Рисунок 1. Страница онлайн-редактора App Invertor 2.
После авторизации (можно использовать профиль google) или регистрации попадаем в свой профиль программы, где можем создать новый проект.
Рисунок 2. Ваш профиль программы. Создание проекта.
Сначала в панети Design создаем интерфейс нашего приложения, перетаскивая на экран необходимые компоненнты. Кроме визуальных компонентов необходимо добавить 3 невизуальных:
Bluetooth client из раздела Connectivity;
Clock из раздела Sensors (для получения данных из Bluetooth c периодичностью, установленной в Clock);
Notifer из UserInterface.
Рисунок 3. Создание интерфейса в Design.
Теперь создаем код. Переходим в раздел Block. Сначала создаем код для инициализации Bluetooth соединения и создания Bluetooth клиента (рисунок 4).
Рисунок 4. Код для инициализации Bluetooth соединения и создания Bluetooth клиента.
Затем код для отправки сообщений при изменениии состояний chexckbox-ов для насоса, вентилятора и лампы (рисунок 5).
Рисунок 5. Код для отправки сообщений при изменениии состояний chexckbox-ов.
И код получения по таймеру сообщений, поступающих по Bluetooth из Arduino (рисунок 6).
Рисунок 6. Код получения по таймеру сообщений, поступающих из Arduino
Создаем app приложение (рисунок 7) и загружаем его на телефон.
Рисунок 7. Генерация app приложения
Нам надо внести самые маленькие изменения в наш предыдущий скетч, заменив разделитель с пробела на символ ‘*’ при отправке данных с Arduino на Android.
Создадим в Arduino IDE новый скетч, занесем в него код из листинга 1 и загрузим скетч на на плату Arduino. Напоминаем, что в настройках Arduino IDE необходимо выбрать тип платы (Arduino UNO) и порт подключения платы.
Листинг 1.
// подключение библиотеки SoftwareSerial #include // подключение библиотеки DHT #include "DHT.h" // тип датчика DHT #define DHTTYPE DHT11 // контакты подключения bluetooth-модуля HC-05 int pinBlRx=17; int pinBlTx=18; // контакт подключения входа данных модуля DHT11 int pinDHT11=9; // контакт подключения аналогового выхода модуля влажности почвы int pinSoilMoisture=A0; // контакт подключения аналогового выхода датчика температуры TMP36 int pinTMP36=A1; // контакт подключения аналогового выхода фоторезистора int pinPhotoresistor=A2; // пины светодиодов индикации #define LED_TEMP 5 #define LED_MOISTURE 6 #define LED_LIGHT 7 // значения для условий #define TEMP_DETECT 30 #define MOISTURE_DETECT 500 #define LIGHT_DETECT 250 // реле int pinRelays[]={2,3,4}; // статусы полива, освещения, вентилятора boolean statusRelays[]={false,false,false}; // создание экземпляра объекта SoftwareSerial SoftwareSerial HC05Serial(pinBlRx,pinBlTx); // создание экземпляра объекта DHT DHT dht(pinDHT11, DHTTYPE); unsigned long millisupdate=0; // для получения данных из SoftwareSerial String inputString0 = ""; // признак конца полученной строки boolean stringComplete0 = false; void setup() { // запуск последовательного порта Serial.begin(9600); // pinMode(LED_TEMP,OUTPUT);digitalWrite(LED_TEMP,LOW); pinMode(LED_MOISTURE,OUTPUT);digitalWrite(LED_MOISTURE,LOW); pinMode(LED_LIGHT,OUTPUT);digitalWrite(LED_LIGHT,LOW); // инициализация dht dht.begin(); // запуск SoftwareSerial HC05Serial.begin(9600); // резервирование 50 bytes для the inputString: inputString0.reserve(50); } void loop() { // ожидание конца строки для анализа поступившего запроса: serialEvent0(); if (stringComplete0) { Serial.println(inputString0); parse_string0(inputString0); // очистить : inputString0 = ""; stringComplete0 = false; } // каждые 5 сек - получение показаний датчиков // и вывод на дисплей if(millis()-millisupdate>5000) { millisupdate=millis(); // получение данных с DHT11 float h = dht.readHumidity(); if (isnan(h)) { Serial.println("Failed to read from DHT"); HC05Serial.println("H1=101"); delay(10); } else { Serial.print("HumidityDHT11= "); Serial.print(h);Serial.println(" %"); HC05Serial.print("aH=");HC05Serial.print(h);HC05Serial.print("*"); delay(10); } // получение значения с аналогового вывода модуля влажности почвы int val0=analogRead(pinSoilMoisture); Serial.print("SoilMoisture= "); Serial.println(val0); HC05Serial.print("SM=");HC05Serial.print(h);HC05Serial.print("*"); delay(10); // получение значения с аналогового вывода датчика температуры TMP36 int val1=analogRead(pinTMP36); // перевод в мВ int mV= val1*1000/1024; // перевод в градусы цельсия int t=(mV-500)/10+75;//t=23; Serial.print("TempTMP36= "); Serial.print(t);Serial.println(" C"); HC05Serial.print("aT=");HC05Serial.print(t);HC05Serial.print("*"); delay(10); // получение значения с аналогового вывода фоторезистора int val2=analogRead(pinPhotoresistor); Serial.print("Light= "); Serial.println(val2); HC05Serial.print("Ph=");HC05Serial.print(val2);HC05Serial.print("*"); delay(10); // обновить // вывод состояние полива, лампы, вентилятора Serial.print("pump - "); Serial.println(statusRelays[2]); Serial.print("fun - "); Serial.println(statusRelays[1]); Serial.print("lamp - "); Serial.println(statusRelays[0]); HC05Serial.print("PM=");HC05Serial.print(statusRelays[2]);HC05Serial.print("*"); delay(10); HC05Serial.print("FN=");HC05Serial.print(statusRelays[1]);HC05Serial.print("*"); delay(10); HC05Serial.print("LM=");HC05Serial.print(statusRelays[0]); delay(10); //// проверка условий // увлажненность почвы if(val0 > MOISTURE_DETECT) digitalWrite(LED_MOISTURE,HIGH); else digitalWrite(LED_MOISTURE,LOW); // температура воздуха if(t > TEMP_DETECT) digitalWrite(LED_TEMP,HIGH); else digitalWrite(LED_TEMP,LOW); // освещенность if(val2 < LIGHT_DETECT) digitalWrite(LED_LIGHT,HIGH); else digitalWrite(LED_LIGHT,LOW); // пауза 5 секунд Serial.println(); } } // SerialEvent для HC05 void serialEvent0() { while (HC05Serial.available()) { // получить очередной байт: char inChar = (char)HC05Serial.read(); // добавить в строку inputString0 += inChar; // /n - конец передачи if (inChar == '#') { stringComplete0 = true; } } } // парсинг строки из android void parse_string0(String inputString) { // длина строки int length1=inputString.length(); if(length1!=5) {Serial.println("ERROR1"); return;} if(inputString.charAt(2)!='=') {Serial.println("ERROR2"); return;} if(inputString.charAt(4)!='#') {Serial.println("ERROR3"); return;} String param1=inputString.substring(0,2); int param2=inputString.substring(3,4).toInt(); Serial.print("param1=");Serial.println(param1); Serial.print("param2=");Serial.println(param2); if(param1=="PM") doCommand(2,min(param2,1)); else if(param1=="FN") doCommand(1,min(param2,1)); else if(param1=="LM") doCommand(0,min(param2,1)); } // исполнение команды от смартфона void doCommand(int relay, int status1) { // изменить статус statusRelays[relay]=status1; // изменить состояние реле digitalWrite(pinRelays[relay],statusRelays[relay]); }
Загружаем скетч на Arduino, на телефоне запускаем приложение.
Рисунок 8, 9, 10. Приложение в работе.
На следующем уроке рассмотрим вопрос превращения нашей теплицы в объект IoT (Интернет вещей).
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.