Описание
В этом проекте мы соберём умную теплицу, управляемую через интернет. Сделаем мы это при помощи нашего нового Ethernet Shield'а на чипе W5500 и сервиса iocontrol.ru. Нашей теплицей можно будет управлять и следить за её состоянием со смартфона, ноутбука, настольного компьютера или чего угодно, что имеет подключение к сети Интернет и современный браузер.
Видео
Нам понадобится
- 1x Ethernet Shield W5500
- 1x Piranha ULTRA
- 1x Trema Shield
- 1x Проставки для Shield'а
- 1x i2C Hub (Trema-модуль)
- 1x Датчик температуры и влажности, I2C-flash
- 1x Датчик освещенности, люксметр, I2C-flash
- 2x Силовой ключ (Trema-модуль V2.0)
- 1x Подобранный под нагрузку и напряжение источник питания. В нашем случае это Источник питания на 12В. 2А.
- 1x Провод RJ45-RJ45
- 1x Маршрутизатор со свободным разъёмом LAN и подключением к сети Интернет.
- Учётная запись на сайте iocontrol.ru
Создание и настройка панели на iocontrol.ru
- Создаём или входим в учётную запись на сайте iocontrol
- Нажимаем "Создать панель". Придумываем название панели, например "mySmartGreenhouse" (название панели должно быть уникальным на сайте. Если панель с таким именем уже есть, сайт уведомит об этом). Нажимаем Создать.
- Создаём следующие переменные с указанными типами
- fan, целочисленная
- fanThreshold, целочисленная
- humSensor, целочисленная
- lightThreshold, целочисленная
- Lights, целочисленная
- LightsPWM, целочисленная
- Luminosity, целочисленная
- Auto, целочисленная
- Temp, вещественная с плавающей точкой
- Теперь необходимо настроить вид карточек переменных. Для этого заходим в настройки каждой карточки, нажав на шестерёнку в правом верхнем углу карточки, затем выбираем соответствующие пункты из списков настроек (таблица ниже) и нажимаем на кнопку Сохранить. Подробнее про настройку карточек переменных можно узнать по этой ссылке
Схема настроек карточек переменных в панели на сайте
Название | Вид карточки | Минимум | Максимум | Шаг | Подпись |
---|---|---|---|---|---|
fan | Кнопка | - | - | - | - |
fanThreshold | Ползунок | 40 | 99 | 1 | % |
humSensor | Вывод значения | - | - | - | % |
lightThreshold | Ползунок | 0 | 300 | 1 | LUX |
Lights | Кнопка | - | - | - | - |
LightsPWM | Ползунок | 0 | 255 | 1 | - |
Luminosity | Вывод значения | - | - | - | LUX |
Auto | Кнопка | - | - | - | - |
Temp | Вывод значения | - | - | - | °C |
Подключение
Устанавливаем модуль Ethernet Shield W5500 на Piranha ULTRA
Устанавливаем сверху Trema Shield через проставки
Подключаем все модули к Trema Shield
По умолчанию все модули FLASH-I2C имеют установленный адрес 0х09.
— Перед подключением 1 модуля к шине I2C настоятельно рекомендуется изменить адрес модуля.
— При подключении 2 и более FLASH-I2C модулей к шине необходимо в обязательном порядке предварительно изменить адрес каждого модуля, после чего уже подключать их к шине.
Более подробно о том, как это сделать, а так же о многом другом, что касается работы FLASH-I2C модулей, вы можете прочесть в этой статье.
Скетч проекта
Для работы данного скетча необходимо заменить значение переменной myPanelName на название Вашей панели, которую мы создали раньше. Например: const char* myPanelName = "mySmartGreenhouse"
.
// Подключаем библиотеку для работы с сервисом ioContol #include <iocontrol.h> // Подключаем стандартную библиотеки для работы с Ethernet Shield'ом по шине SPI #include <SPI.h> #include <Ethernet.h> // Подключаем библиотеку для работы с аппаратной шиной I2C, до подключения библиотек iarduino_I2C_DSL и iarduino_I2C_SHT. #include <Wire.h> // Подключаем библиотеки датчиков влажности и освещённости #include <iarduino_I2C_DSL.h> #include <iarduino_I2C_SHT.h> // Определяем выводы силовых ключей вентилятора и светодиодной ленты #define FAN_PIN 2 #define LED_PIN 3 // Определяем постоянные On и Off #define On true #define Off false // Инстанцируем (создаём) объекты библиотек датчиков iarduino_I2C_DSL lumSensor; iarduino_I2C_SHT humSensor; // Название панели на сайте iocontrol.ru const char* myPanelName = "название_Вашей_панели_на_сайте_iocontrol.ru"; // Название переменных на сайте const char* panelFan = "fan"; const char* panelFanThreshold = "fanThreshold"; const char* panelHumSensor = "humSensor"; const char* panelLightThreshold = "lightThreshold"; const char* panelLights = "Lights"; const char* panelLightsPWM = "lightsPWM"; const char* panelLuminosity = "Luminosity"; const char* panelAuto = "Auto"; const char* panelTemperature = "Temp"; // Создаём объект клиента класса EthernetClient EthernetClient client; // Создаём объект iocontrol, передавая в конструктор название панели и клиента iocontrol mypanel(myPanelName, client); // Задаём статический IP-адрес на тот случай, // если динамическое присвоение адреса даст сбой IPAddress ip(192, 168, 1, 177); IPAddress myDns(192, 168, 1, 1); // // MAC адреса Ethernet шилда. Должен быть уникальным в сети byte mac[] = { 0xFE, 0xED, 0xDE, 0xAD, 0xFA, 0xCC }; // Переменные интервала и гистерезиса на вентилятора unsigned long currentMillis = 0; // текущие millis unsigned long interval = 60000; // интервал в мс bool fanHyst = false; // флаг гистерезиса вентилятора // Переменные для чтения с сайта ioControl bool Auto = false; // флаг автоматической работы // Переменные для записи на сайт ioControl int hum; // влажность uint16_t lum; // освещённость float tem; // температура void setup() { // Инициируем работу с последовательным портом на скорости 9600 бод Serial.begin(9600); // Выводим в монитор последовательного порта // сообщение о начале инициализации Shield'а Serial.println("Initialize Ethernet with DHCP:"); // Если соединение с динамической адресацией не было установлено, то if (Ethernet.begin(mac) == 0) { // Выводим сообщение об этом в монитор последовательного порта и Serial.println("Failed to configure Ethernet using DHCP"); // проверяем наличие самого Shield'а if (Ethernet.hardwareStatus() == EthernetNoHardware) { // Если Shield не найден, то выводим соответствующее // сообщение в монитор порта Serial.println("Ethernet shield was not found."); // Останавливаем скетч while (true) { delay(1); } } // Проверяем наличие соединения if (Ethernet.linkStatus() == LinkOFF) { // Если соединение не установлено, то выводим // соответствующее сообщение в монитор порта Serial.println("Ethernet cable is not connected."); } // Пробуем установить соединение, используя статический IP-адрес Ethernet.begin(mac, ip, myDns); // Выводи IP-адрес в последовательный порт Serial.print("My IP address: "); Serial.println(Ethernet.localIP()); } // Если соединение с динамической адресацией было установлено, то else { // Выводи IP-адрес в последовательный порт Serial.print(" DHCP assigned IP "); Serial.println(Ethernet.localIP()); } delay(1000); // Инициируем датчик освещённости lumSensor.begin(); // Инициируем датчик влажности и температуры humSensor.begin(); // Вызываем функцию первого запроса к сервису ioControl mypanel.begin(); } void loop() { // Записываем переменные из объекта mypanel в локальные переменные bool fan = mypanel.readBool(panelFan); int fanThreshold = mypanel.readInt(panelFanThreshold); int lightThreshold = mypanel.readInt(panelLightThreshold); bool lights = mypanel.readBool(panelLights); int lightsPWM = mypanel.readInt(panelLightsPWM); // Записываем флаг автоматической работы в глобальную переменную Auto = mypanel.readBool(panelAuto); // Если влажность превысила установленный порог if (hum > fanThreshold && Auto) { // устанавливаем флаг вентилятора fanHyst = true; // записываем текущие millis currentMillis = millis(); // включаем вентилятор fanOn(); } // Если не автоматический режим и флаг вентилятора установлен else if (!Auto && fan) { // включаем вентилятор fanOn(); } // Иначе, если флаг гистерезиса вентилятора не установлен else if (!fanHyst) { // Выключаем вентилятор fanOff(); } // Если флаг гистерезиса вентилятора установлен // и текущие истёк интервал if (fanHyst && (millis() - currentMillis > interval)) { // сбрасываем флаг гистерезиса вентилятора fanHyst = false; } // Если освещённость меньше установленного порога if (lum < lightThreshold && Auto) { // Включаем свет lightsIn(lum); } // Если не автоматический режим и флаг света установлен else if (!Auto && lights) { // Включаем свет lightsIn(mypanel.readInt(panelLightsPWM)); } // Иначе else { // выключаем свет lightsOut(); } // Записываем показания датчика влажности в переменную hum = int(humSensor.getHum()); // Записываем показания датчика освещённости в переменную lum = lumSensor.getLux(); // Записываем показания датчика температуры в переменную tem = humSensor.getTem(); // Записываем показания всех датчиков в объект mypanel mypanel.write(panelHumSensor, hum); mypanel.write(panelLuminosity, lum); mypanel.write(panelTemperature, tem); // Если показания успешно записаны на сайт ioControl if (mypanel.writeUpdate() == OK) { // выводим показания в последовательный порт Serial.println("Updated"); Serial.println("hum: "); Serial.println(hum); Serial.println("lum: "); Serial.println(lum); } // Читаем все переменные панели с сайта в объект mypanel mypanel.readUpdate(); } // Функция включения вентилятора void fanOn() { // Устанавливаем вывод к которому подключён вентилятор в режим "выход" pinMode(FAN_PIN, OUTPUT); // Устанавливаем уровень логической "1" на выводе вентилятора digitalWrite(FAN_PIN, HIGH); // Если установлен автоматический режим работы, обновляем переключатель // вентилятора на сайте if (Auto) mypanel.write(panelFan, On); } // Функция выключения вентилятора void fanOff() { // Устанавливаем вывод к которому подключён вентилятор в режим "вход" pinMode(FAN_PIN, INPUT); // Если установлен автоматический режим работы, обновляем переключатель // вентилятора на сайте if (Auto) mypanel.write(panelFan, Off); } // Функция включения светодиодной ленты void lightsIn(int l) { // Создаём переменную для расчёта ШИМ uint8_t pwm = 0; // Если установлен автоматический режим работы if (Auto) // устанавливаем ШИМ обратно пропорционально освещённости pwm = uint8_t(map(l, 0, 300, 255, 0)); // Иначе else // устанавливаем ШИМ, переданный функции pwm = uint8_t(l); // Устанавливаем вывод к которому подключена светодиодная лента // в режим "выход" pinMode(LED_PIN, OUTPUT); // Устанавливаем ШИМ на выводе analogWrite(LED_PIN, pwm); // Если установлен автоматический режим работы, обновляем переключатель // света на сайте if (Auto) mypanel.write(panelLights, On); } // Функция выключения светодиодной ленты void lightsOut() { // Устанавливаем вывод к которому подключён вентилятор в режим "вход" pinMode(LED_PIN, INPUT); // Если установлен автоматический режим работы, обновляем переключатель // света на сайте if (Auto) mypanel.write(panelLights, Off); }
Обсуждение