В этой статье рассмотрим совмещение ESP8266 с Arduino.
ESP8266.h
Код управления модулем будет находиться в отдельном классе, который затем очень просто преобразовать в библиотеку для Arduino IDE. Для начала в папке с проектом создадим заголовочный файл ESP8266.h. Его код:
#ifndef ESP8266_h
#define ESP8266_h
class ESP8266
{
public:
ESP8266(int en, String ssid, String port); // Подключение пинов
bool Init(); // Инициализация модуля
String Readln(); // Чтение полной строки, полученной по wi-fi вместе с обертками
String GetMessage(String str); // Вырезать сообщение из принятой строки
bool Writeln(String str); // Отправить сообщение
private:
int _en, i;
char b[63];
String _ssid, _port;
};
#endif
ESP8266.cpp
Создадим в папке проекта файл ESP8266.cpp, в котором, собственно, и находится описание всех методов класса.
#include
#include "ESP8266.h"
unsigned int const BEFORE_EN = 2000; // Задержка перед подачей enable на ESP8266
unsigned int const AFTER_EN = 1000; // Задержка для инициализации ESP8266
int _en;
int i = 0;
char b[63];
String _ssid, _port;
// Подключение пинов
/* en - выход ch_pd модуля
* ssid - название wi-fi сети
* port - порт сервера
*/
ESP8266::ESP8266(int en, String ssid, String port)
{
_en = en;
_ssid = ssid;
_port = port;
pinMode(en, OUTPUT);
}
// Инициализация модуля
bool ESP8266::Init()
{
Serial.begin(115200);
while (!Serial) {
; // Ожидание подключения к COM порту. Необходимо для USB портов
}
delay(BEFORE_EN); // Задержка перед подачей enable на ESP8266
digitalWrite(_en, HIGH);
delay(AFTER_EN); // Задержка для инициализации ESP8266
while (Serial.available() > 0) Serial.read(); // Полная очистка буфера
String s;
Serial.println("AT");
s = Serial.readString();
if (s.indexOf("OK") == -1) return false;
Serial.println("AT+CWMODE=2");
s = Serial.readString();
if (s.indexOf("OK") == -1) return false;
Serial.println("AT+CWSAP=\"" + _ssid + "\",\"\",1,0");
s = Serial.readString();
if (s.indexOf("OK") == -1) return false;
Serial.println("AT+CIPMUX=1");
s = Serial.readString();
if (s.indexOf("OK") == -1) return false;
Serial.println("AT+CIPSERVER=1," + _port);
s = Serial.readString();
if (s.indexOf("OK") == -1) return false;
return true;
}
// Чтение полной строки, полученной по wi-fi вместе с обертками
String ESP8266::Readln()
{
while (Serial.available() > 0) {
b[i] = Serial.read();
if (b[i] == 10) {
String str_all = "";
for (int j = 0; j < i - 1; j++) {
str_all = String(str_all + b[j]);
}
i = 0;
return str_all;
}
i++;
}
return "";
}
// Вырезать сообщение из принятой строки
String ESP8266::GetMessage(String str) {
int idx = str.indexOf(':');
if (idx == -1) return "";
return str.substring(idx + 1);
}
// Отправить сообщение
bool ESP8266::Writeln(String str) {
Serial.println("AT+CIPSEND=0," + String(str.length()));
String s = Serial.readString();
if (s.indexOf("OK") >= 0) {
Serial.println(str);
if (s.indexOf("OK") >= 0) return true; else return false;
} else {
return false;
}
}
Величину задержек BEFORE_EN и AFTER_EN придется подбирать опытным путем.
Т.к. после включения микросхема ESP8266 выдает множество данных о себе (версия прошивки и т.д.), то перед работой требуется очистить порт сразу после задержки AFTER_EN.
while (Serial.available() > 0) Serial.read();
Управление светодиодом
Для теста модуля можно поморгать светодиодом, посылая ардуине команды по локальной сети с помощью любого TCP-клиента по wi-fi. Ниже показан листинг верхнего файла проекта.
#include "ESP8266.h" // Подключаем ранее написанную библиотеку через заголовочный файл
//------------------------- Pins -------------------------
#define led 8 // Пин для подключения светодиода
#define esp_en 13 // CH_PD - ESP8266 enable
//----------------------- Const -------------------------
String const ssid = "ESP_test"; // SSID
String const port = "585"; // Port
//----------------------- Class -------------------------
ESP8266 wifi(esp_en, ssid, port);
void setup() {
pinMode(led, OUTPUT);
bool retval = wifi.Init();
// Светодиод загорится в случае ошибки инициализации модуля
digitalWrite(led, !retval);
}
void loop() {
String str = wifi.Readln();
if (str != "") {
String msg = wifi.GetMessage(str);
bool retval = false;
if (msg == "PING") retval = wifi.Writeln("PONG");
if (msg == "ON")
{
digitalWrite(led, HIGH);
retval = wifi.Writeln("ON__OK");
}
if (msg == "OFF")
{
digitalWrite(led, LOW);
retval = wifi.Writeln("OFF_OK");
}
/*
if (retval)
{
При желании добавить обработчик ошибок
отправки сообщения ТУТ
}
*/
}
}
Запускаем проект на ардуино, подключаемся к wi-fi сети ESP_test, подключаемся tcp-клиентом к серверу по порту 585 и последовательно посылаем 3 команды:
- PING - в ответ получим строку PONG;
- ON - в ответ получим строку ON__OK, а светодиод включится;
- OFF - в ответ получим строку OFF__OK, а светодиод отключится.
В будущем, вместо набора операторов «if» лучше использовать конструкцию «case» – это немного сэкономит процессорное время.
#esp8266 #arduino