Serial comm в UNO+WiFi R3 ATmega328P+ESP8266

В этой записи речь пойдет о том, как наладить отправку данных по последовательному (serial) порту с микроконтроллера ATmega328P в чип ESP8266 на плате UNO+WiFi R3 ATmega328P+ESP8266. Конкретно попробуем отправить показания температуры и влажности с датчика DHT22, подключенного к цифровому входу №2 Arduino UNO (ATmega328P), в Wi-Fi ESP8266 и отобразить значения в браузере.

Используемое железо:

  1. Плата UNO+WiFi R3 ATmega328P+ESP8266;
  2. модуль цифрового датчика температуры и влажности DHT22;
  3. макетная плата (по желанию).
Arduino UNO+Wi-Fi и модуль DHT22
Arduino UNO+Wi-Fi и модуль DHT22

Схема соединения.

Подробности о соединении DHT22 c Arduino UNO+WiFi R3 ATmega328P+ESP8266 в этой записи я опускаю, соединяем также как и с простой Ардуино. Есть об этом отдельная запись в блокноте: Подключение датчика DHT11/DHT22 к Arduino UNO.

Скетчи для платы.

Если ни разу не доводилось заливать скетчи в эту чудную плату, то обязательно прочтите о том, как это делается в записи Начало работы с UNO+WiFi R3 ATmega328P+ESP8266. Зальем сначала скетч для UNO:

//Arduino UNO. Отправка по serial значений H и Т
#include "DHT.h"
#define DHTPIN 2     // Пин, к которому подключен DHT
#define DHTTYPE DHT22  //тип DHT 

DHT dht(DHTPIN, DHTTYPE);
String to_esp; //будем отправлять на ESP массив

void setup() {
  Serial.begin(9600); 
  dht.begin();
}

void loop() {
    delay(2000);

  
  int h = dht.readHumidity();
  int t = dht.readTemperature();
    
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Ошибка чтения DHT сенсора!");
    return;
  }
//Отправляем в Serial посылку c данными влажности и температуры вида "$h t;"
to_esp =String("$")
  +String(h)+String(" ")
  +String(t)+String(";");
  Serial.println(to_esp);
  
   
}
Вывод в Serial данных. Ардуино.
Вывод в Serial данных. Ардуино.

Видим, в последовательный порт улетают значения влажности и температуры в виде «$h t;». Символом «$» мы обозначили начало посылки, » » (пробелом) разделили значения, «;» — завершаем посылку. Теперь на принимающей стороне остается парсить посылку, раскидать в массив и вывести данные. Как это сделать я подсмотрел на AlexGyver.ru. Офигенный сайт, спасибо его создателю! Теперь зальем скетч в ESP8266:

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>

//===данные к Wi-F, настраиваем Web сервер===
//SSID и Password для доступа к wifi сети
const char* ssid = "имя_вашей_сети";  // укажите SSID сети
const char* password = "пароль_к_вашей_сети";  //укажите пароль от wi-fi

// Задаем 80ый порт WEB серверу
WiFiServer server(80);
String header;
unsigned long currentTime = millis();
unsigned long previousTime = 0; 
const long timeoutTime = 2000;

//==========парсер AlexGyver'a================
#define PARSE_AMOUNT 2         // число значений в массиве, который хотим получить
int intData[PARSE_AMOUNT];     // массив численных значений после парсинга
boolean recievedFlag;
boolean getStarted;
byte ind_ex;
String string_convert = "";
void parsing() {
if (Serial.available() > 0) {
char incomingByte = Serial.read();        // обязательно ЧИТАЕМ входящий символ
if (getStarted) {                         // если приняли начальный символ (парсинг разрешён)
if (incomingByte != ' ' && incomingByte != ';') {   // если это не пробел И не конец
string_convert += incomingByte;       // складываем в строку
} else {                                // если это пробел или ; конец пакета
intData[ind_ex] = string_convert.toInt();  // преобразуем строку в int и кладём в массив
string_convert = "";                  // очищаем строку
ind_ex++;                              // переходим к парсингу следующего элемента массива
}
}
if (incomingByte == '$') {                // если это $
getStarted = true;                      // поднимаем флаг, что можно парсить
ind_ex = 0;                              // сбрасываем индекс
string_convert = "";                    // очищаем строку
}
if (incomingByte == ';') {                // если таки приняли ; - конец парсинга
getStarted = false;                     // сброс
recievedFlag = true;                    // флаг на принятие
}
}
}
//================================================

int h; // влажность
int t; // температура

void setup() {
Serial.begin(9600);

//подключаемся к локальной wi-fi сети             
  Serial.println("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  //проверяем подключение к wi-fi сети
  while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected..!");
  Serial.print("Got IP: ");  Serial.println(WiFi.localIP());

  server.begin();


}
void loop() {
parsing();       // функция парсинга
if (recievedFlag) {                           // если получены данные
recievedFlag = false;
for (byte i = 0; i < PARSE_AMOUNT; i++) { // выводим элементы массива
h = intData[0];
t = intData[1];}
}

//===формируем и выдаем по запросу клиента HTTP страничку (подсмотрено на randomnerdtutorials.com)===
WiFiClient client = server.available();   

  if (client) {                             
    Serial.println("New Client.");           
    String currentLine = "";                 
    currentTime = millis();
    previousTime = currentTime;
    while (client.connected() && currentTime - previousTime <= timeoutTime) { 
      currentTime = millis();         
      if (client.available()) {           
        char c = client.read();            
        Serial.write(c);                    
        header += c;
        if (c == '\n') {                    
         
          if (currentLine.length() == 0) {
           
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
                                    
            // Display the HTML web page
            client.println("<!DOCTYPE html><html>");
            client.println("<head><meta charset=\"UTF-8\" name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
            client.println("<link rel=\"icon\" href=\"data:,\">");
            
            // CSS to style  
            client.println("<style>html { font-family: Helvetica; display: inline-block; margin: 0px auto; text-align: center;}</style></head>");
                        
            // Web Page Heading
            client.println("<body><h1>On-line термометр</h1>");
            
            // Display current temps 
            client.println("Влажность:<br>" );
            client.println(h);
            client.println("%");
            client.println("<br><br>Температура:<br>" );
            client.println(t);
            client.println("&#8451");
            client.println("</body></html>");
            client.println("<br><br><a href=https://ivansmith.ru/temp.php>Массив показаний</a><br>" );
            
            // The HTTP response ends with another blank line
            client.println();
            // Break out of the while loop
            break;
          } else { // if you got a newline, then clear currentLine
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    // Clear the header variable
    header = "";
    // Close the connection
    client.stop();
    Serial.println("Client disconnected.");
    Serial.println("");
  }

}

Залили скетч в ESP8266, теперь установим переключатели 1, 2 и 5 на плате в положение ON и нажмем на кнопку «MCU Reset». Переключатели 1 и 2 связывают RX и TX обоих микроконтроллеров на плате между собой (Serial communication).

Выставим переключатели на плате в нужное положение
Выставим переключатели на плате в нужное положение

В результате в окне монитора порта увидим, как ESP подключается к нашей Wi-Fi сети и получает IP адрес:

Подключение ESP8266 к wi-fi сети
Подключение ESP8266 к wi-fi сети

Теперь удостоверимся, что данные от Arduino передаются на ESP8266, для этого откроем браузер и введем адрес, назначенный модулю (в нашем случае — 192.168.1.105). В случае успеха всего мероприятия наблюдаем вывод в браузере:

Вывод значений влажности и температуры в браузер. ESP8266.
Вывод значений влажности и температуры в браузер. ESP8266.

Работает! Данные исправно летят по последовательному порту от Arduino к ESP8266 и благополучно выводятся вторым в браузер. Вот так просто наладить оба чипа в плате «UNO+WiFi R3 ATmega328P+ESP8266» на совместную работу. Всем удачи, пока!

Заметки по теме:

Поделиться ссылкой:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *