Найти тему

Управление Arduino с помощью модуля ESP8266 (ESP01)

Оглавление

В этой статье рассмотрим совмещение 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