Создаем мобильное приложение для управления «Умной теплицей» на 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 (Интернет вещей).

Книга Джереми Блума Изучаем Arduino: инструменты и методы технического волшебства.
25 крутых проектов с Arduino
Мобильные роботы на базе Arduino книга М. Момота
Добавить комментарий
Для отправки комментария вам необходимо авторизоваться.