В этом DIY-проекте (сделай сам) проекте мы рассмотрим создание системы мониторинга за наполненностью контейнера/ведра на основе платы Arduino и Wi-Fi модуля ESP8266. Проект относится к категории интернета вещей (IoT) и с его помощью и сети интернет мы из любой точки мира сможем узнать состояние нашего контейнера или мусорного ведра: полно ли оно или пусто. Данное устройство может быть установлено как дома, так и в общественных местах.
Для оценки состояния наполненности будет использоваться ультразвуковой датчик, позволяющий измерять расстояние до препятствия. Этот датчик будет устанавливаться сверху на краю мусорного ведра/контейнера и будет измерять расстояние до содержимого контейнера. Мы можем установить соответствующую границу, зависящую от размера контейнера/ведра. Если измеренное расстояние будет меньше этой границы, это будет означать что контейнер полон и мы будем на веб-странице печатать сообщение “Basket is Full” (корзина полна). Если измеренное расстояние будет больше этой границы, это будет означать что контейнер пуст и мы будем печатать сообщение “Basket is Empty” (корзина пуста). В нашем проекте мы установили в программе эту границу равную 5 см.
Мы будем использовать Wi-Fi модуль ESP8266 чтобы наша плата Arduino могла подключаться к веб-серверу. В нашем проекте мы использовали локальный веб-сервер чтобы продемонстрировать работу нашего устройства.
Необходимые компоненты
- Плата Arduino Uno (купить на AliExpress) (или любая другая).
- Wi-Fi модуль ESP8266 (купить на AliExpress).
- Ультразвуковой датчик HC-SR04 (купить на AliExpress).
- Резисторы 1 кОм (купить на AliExpress).
- Макетная плата.
- Соединительные провода.
Принцип работы ультразвукового датчика HC-SR04
Ультразвуковой датчик HC-SR04 в нашем проекте используется для измерения расстояний в диапазоне 2-400 см с точностью 3 мм. Датчик состоит из ультразвукового передатчика, ультразвукового приемника и схемы управления. Основные принципы работы ультразвукового датчика состоят в следующем:
- Вначале с формируется сигнал высокого уровня длительностью 10 мкс, который запускает в работу ультразвуковой датчик.
- Затем модуль автоматически посылает 8 импульсов с частотой 40 кГц, а затем проверяет приняты они или нет.
- Если эти излученные сигналы принимаются, то вычисляется время между временем передачи этих импульсов и их приемом.
Расстояние затем можно рассчитать по следующей формуле:
Distance= (Time x Speed of Sound in Air (340 m/s))/2
где Time – измеренное датчиком время;
Speed of Sound in Air – скорость звука в воздухе, равная 340 м/с.
Также о принципах измерения расстояния с помощью ультразвукового датчика более подробно можно прочитать в следующих статьях на нашем сайте:
— измерение расстояний с помощью платы Arduino;
— измерение расстояний с помощью датчика HC-SR04 и микроконтроллера AVR.
Wi-Fi модуль ESP8266
ESP8266 представляет собой Wi-Fi модуль, который может подключить ваши устройства к сети Wi-Fi или интернет. Это очень дешевое устройство, но оно способно обеспечить вашему проекту огромную функциональность. Его внешний вид показан на следующем рисунке.
ESP8266 является одним из самых популярных вещей в проектах интернета вещей (IOT). Он работает от напряжения питания 3.3V, подача напряжения 5V может повредить его.
ESP8266 имеет 8 контактов: VCC и CH-PD необходимо подсоединять к 3.3V чтобы Wi-Fi стало доступным. Контакты TX и RX будут ответственны за связь модуля ESP8266 с платой Arduino. Контакт RX работает с напряжением 3.3V поэтому вы должны использовать делитель напряжения как и мы в нашем проекте.
Работа схемы
Схема устройства представлена на следующем рисунке.
Первым делом мы должны соединить модуль ESP8266 с платой Arduino. Если мы подсоединим ESP8266 к 5V Arduino, то мы можем повредить его поскольку он работает от напряжения 3.3V. Поэтому мы должны подсоединить контакты VCC и CH_PD к контакту 3.3V платы Arduino. Контакт RX ESP8266 работает с напряжением 3.3V и он не будет работать если мы непосредственно подключим его к Arduino. Поэтому для его подключения мы будем использовать делитель напряжения – три резистора по 1 кОм, соединенных последовательно. Соедините контакт RX ESP8266 с контактом 11 платы Arduino при помощи резисторов как показано на рисунке, а контакт TX подсоедините к контакту 10 платы Arduino.
Соедините контакты VCC и землю датчика HC-SR04 с контактами 5V и землей платы Arduino. Затем соедините контакты TRIG и ECHO ультразвукового датчика с контактами 8 и 9 платы Arduino соответственно.
Исходный код программы
Прежде чем загружать код программы в Arduino убедитесь что у вас работает Wi-Fi и к нему подключен ваш модуль ESP8266. В тексте программы приведены комментарии, поясняющие ее суть. Здесь же объяснены наиболее важные части программы.
Плата Arduino должна сначала получить информацию от ультразвукового датчика. Для этого на контакт TRIG датчика необходимо подать сигнал длительностью 10 мкс, после чего датчик излучает ультразвуковую волну в пространство. После отражения от препятствия этот сигнал улавливается ультразвуковым датчиком. Зная время распространения волны и скорость звука в воздухе можно определить расстояние до препятствия (содержимого контейнера в нашем случае).
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance= duration*0.034/2;
Для вывода сообщений на веб-страницу мы будем использовать HTML программирование. Мы создадим строку с именем webpage и сохраненным в ней текстом для вывода. Если измеренное расстояние будет менее 5 см, то на веб-странице мы будем показывать сообщение “Basket is Full”, а если больше 5 см – то сообщение “Basket is Empty”.
if(esp8266.available())
{
if(esp8266.find("+IPD,"))
{
delay(1000);
int connectionId = esp8266.read()-48;
String webpage = "<h1>IOT Garbage Monitoring System</h1>";
webpage += "<p><h2>";
if (distance<5)
{
webpage+= " Trash can is Full";
}
else{
webpage+= " Trash can is Empty";
}
webpage += "</h2></p></body>";
Следующий код передаст и покажет данные на веб-странице. Данные, которые мы сохранили в строке с именем ‘webpage’, мы сохраним в строке с именем ‘command’. Затем модуль ESP8266 будет считывать символы по одному из строки ‘command’ и печатать их на веб-странице.
String sendData(String command, const int timeout, boolean debug)
{
String response = "";
esp8266.print(command);
long int time = millis();
while( (time+timeout) > millis())
{
while(esp8266.available())
{
char c = esp8266.read();
response+=c;
}
}
if(debug)
{
Serial.print(response);
}
return response;
}
Тестирование проекта
После загрузки кода в Arduino откройте последовательный монитор (Serial Monitor) и в нем вы увидите IP адрес как на представленном рисунке.
Введите этот IP адрес в строку браузера и на открывшейся странице вы увидите результат, представленный на следующем рисунке. Необходимо будет обновить эту страницу если вы хотите посмотреть свежее состояние вашего контейнера/ведра (полон он или пуст).
Данный проект можно усовершенствовать при помощи введения дополнительных условий в код программы, например, передавать сообщения когда контейнер наполнен наполовину. Или можно добавить информирование о состоянии контейнера по SMS или на Email.
Далее представлен полный текст программы.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#include <SoftwareSerial.h> // библиотека для последовательной связи #define DEBUG true SoftwareSerial esp8266(10,11); // последовательный порт у нас с помощью подключенной библиотеки будет на контактах 10 и 11 к ним мы будем подключать Wi-Fi модуль ESP8266 const int trigPin = 8; // Making the arduino's pin 8 as the trig pin of ultrasonic sensor const int echoPin = 9; // Making the arduino's pin 9 as the echo pin of the ultrasonic sensor // инициализируем две переменные для хранения расстояния long duration; int distance; void setup() { Serial.begin(9600); // установка скорости последовательного порта 9600 бод/с esp8266.begin(9600); // установка скорости последовательного для ESP8266 pinMode(trigPin, OUTPUT); // установка trigPin в режим вывода данных pinMode(echoPin, INPUT); // установка echoPin в режим ввода данных sendData("AT+RST\r\n",2000,DEBUG); // команда чтобы сбросить WiFi модуль sendData("AT+CWMODE=2\r\n",1000,DEBUG); // конфигурируем WiFi модуль в качестве точки доступа (access point) sendData("AT+CIFSR\r\n",1000,DEBUG); // получаем ip адрес sendData("AT+CIPMUX=1\r\n",1000,DEBUG); // конфигурируем WiFi модуль чтобы он поддерживал множественные соединения sendData("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // подключаемся к серверу по порту 80 } void loop() { digitalWrite(trigPin, LOW); // подача напряжения низкого уровня на trigpin delayMicroseconds(2); // задержка 2 мкс digitalWrite(trigPin, HIGH); // подача на trigpin напряжения высокого уровня на 10 мкс чтобы запустить ультразвуковой датчик в работу delayMicroseconds(10); digitalWrite(trigPin, LOW); duration = pulseIn(echoPin, HIGH); // считывание echopin чтобы определить сколько времени распространялся сигнал до препятствия и обратно distance= duration*0.034/2; // рассчитываем дистанцию и сохраняем ее в переменной if(esp8266.available()) // эта команда проверяет передает ли WiFi модуль сообщение { if(esp8266.find("+IPD,")) { delay(1000); int connectionId = esp8266.read()-48; /* We are subtracting 48 from the output because the read() function returns the ASCII decimal value and the first decimal number which is 0 starts at 48* - вычитаем 48 чтобы начать считывание данных с нужной нам позиции/ String webpage = "<h1>IOT Garbage Monitoring System</h1>"; webpage += "<p><h2>"; if (distance<5) { webpage+= " Trash can is Full"; } else{ webpage+= " Trash can is Empty"; } webpage += "</h2></p></body>"; String cipSend = "AT+CIPSEND="; cipSend += connectionId; cipSend += ","; cipSend +=webpage.length(); cipSend +="\r\n"; sendData(cipSend,1000,DEBUG); sendData(webpage,1000,DEBUG); String closeCommand = "AT+CIPCLOSE="; closeCommand+=connectionId; closeCommand+="\r\n"; sendData(closeCommand,3000,DEBUG); } } } String sendData(String command, const int timeout, boolean debug) { String response = ""; esp8266.print(command); long int time = millis(); while( (time+timeout) > millis()) { while(esp8266.available()) { char c = esp8266.read(); response+=c; } } if(debug) { Serial.print(response); } return response; } |