Получаем уровень связи WiFi модуля ESP8266

Отправляем состояния теплых полов из Arduino UNO ESP8266 WiFi на сервер ThingSpeakМожно ли заставить работать «C2000-Ethernet»? Получаем уровень связи WiFi модуля ESP826616 января 2020 г.Просмотров: 2011Комментарии: 0
ArduinoМониторингArduinoESP8266WiFi

Использовать плату, на которой совмещены UNO R3 + WiFi Esp8266, показалось очень удобным способом.

В предыдущей статье добились, чтобы совмещенная плата Arduino UNO с WiFi посылала POST при помощи AT-команд, без использования библиотеки WiFiEsp.

Теперь найдем способ получать уровень сигнала RSSI WiFi точки доступа, к которой подсоединен модуль ESP8266 платы.

Получаем уровень связи WiFi модуля ESP8266

Стоимость будет аналогичная.

Но, если стоимость отдельных устройств 214+100=314р, то стоимость совмещенной платы будет 460р.

460р 214р 100р

Получаем уровень связи WiFi модуля ESP8266

UNO R3 + WiFi

Получаем уровень связи WiFi модуля ESP8266

UNO R3

Получаем уровень связи WiFi модуля ESP8266

ESP8266 Esp-01 WIFI

Считаю, что разницу в 132р можно и доплатить за удобство.

Для работы WiFi модуля с Arduino предлагается использовать библиотеку WiFiESP, для чего необходимо было бы обновить прошивку.

Но зачем это делать и зачем использовать лишний код библиотеки, если имеется совсем тривиальная задача просто отсылать значения датчиков на сервер?

Это делается просто, AT командами.

Но иногда может быть необходимо изучить результат работы

Как обработать результат выполнения AT команды ESP8266.

Все в той же предыдущей статье было необходимо убедиться, что POST запрос к серверу с показаниями датчиков отправлен.

Для этого искали в ответе признак успешности передачи при помощи функции Serial.find():

readReplay = «OK»;
if (Serial.find(readReplay))
{
}

Для получения из ESP8266 сведений о доступных ей WiFi сетях служит команда AT+CWLAP, которая возвращает перечень сетей с дополнительной информацией о них:

+CWLAP:ecn,ssid,rssi,mac,channel
OK

Отсюда и можно получить RSSI.

В списке доступных сетей может быть несколько сетей и нам нужно осуществить селекцию по нужному имени WiFi сети текущего соединения.

В библиотеке WiFiESP для получения RSSI сети, к которой подключен ESP8266, использовалась функция WiFi.RSSI().

Как это реализовано для парсинга Serial с целью получения RSSI текущего соединения можно посмотреть в процедуре EspDrv::getCurrentRSSI() файла EspDrv.cpp:

int32_t EspDrv::getCurrentRSSI()
{
int ret=0;
char buf[10];
sendCmdGet(F(«AT+CWJAP?»), F(«,-«), F(«rn»), buf, sizeof(buf));
if (isDigit(buf[0])) {
ret = -atoi(buf);
}
return ret;
}

Парсинг Serial осуществляет функция sendCmdGet(), реализованная в том же файле.

Это универсальная функция, основанная на библиотеке RingBuffer.h, и можно было бы вычленить из файла EspDrv.cpp нужный функционал.

Но в моем случае задача значительно упрощается.

Ответ ESP8266 на команду AT+CWLAP вот такой:

+CWLAP:(3,»Keenetic-0138″,-81,»85:a8:5d:85:eb:a8″,1)

Поэтому, достаточно найти в Serial последовательность «38», пропустить два символа, и взять три символа в которых будет содержаться RSSI.

Вот какой кусок кода это делает:

// получим и отобразим уровень сигнала
// код рабочий для очень частного случая
// String curRSSI; объявлено ранее
// на Serial в совмещенной плате UNO + ESP8266 сидит ESP8266.
void getRSSI()
{
char c1;
char c2;
curRSSI = «»;
Serial.println(«AT+CWLAP»);
if (Serial.available())
{
delay(100);
while (Serial.available() > 0)
{
c1 = (char)Serial.read();
c2 = (char)Serial.read();
if ((c1==’3′) and (c2==’8′))
{
c1 = (char)Serial.read(); // пропускаем два значения
c2 = (char)Serial.read();
for(int i=0; i<3; i++) // читаем три значения
{
c1 = Serial.read();
curRSSI += c1;
}
lcd.setCursor(5, 0);
lcd.print(curRSSI);
break;
}
}
}
}

Код работает не всегда и не на всех платах.

Проблемы в строке if ((c1==’3′) and (c2==’8′))

Вместо 8 у нас что-то непонятное.

Поэтому придумаем другой код для чтения RSSI:

// глобальные переменные объявлены ранее:
// String curRSSI=»0″;
// int crssi=0;
// String ssid =»Keenetic-0138″;
void getRSSI()
{
char c1;
String val;
int i;
curRSSI = «»;
Serial.println(«AT+CWLAP=»» + ssid + «»»);
delay(1500);
if (Serial.available())
{
delay(500);
while (Serial.available() > 0)
{
for (i=0; (i<27); i++)
{ c1 = (char)Serial.read(); delay(2); }
for (i=0; (i<2); i++)
{
c1 = (char)Serial.read(); val += c1; delay(2);
}
}
crssi = val.toInt();
if (crssi)
{
curRSSI = val;
lcd.setCursor(5, 0);
lcd.print(-crssi);
}
}
}

С эти кодом тоже не всегда все гладко.

Через раз вместо ожидаемого

+CWLAP:(3,»Keenetic-0138″,-81,»85:a8:5d:85:eb:a8″,1)

в Serial находится еще и сама команда.

Придется все таки поместить весь ответ в переменную String и затем взять подстроку после имени сети.

void getRSSI()
{
char c1;
String val = «»;
int i;
curRSSI = «»;
Serial.print(«AT+CWLAP=»» + ssid + «»rn»);
delay(500);
if (Serial.available())
{
while (Serial.available() > 0)
{
c1 = (char)Serial.read(); val = val + c1; delay(2);
}
int pos = val.indexOf(ssid);
pos = pos+ssid.length()+3;
curRSSI = val.substring(pos, pos+2);

// Serial.println(curRSSI);
crssi = curRSSI.toInt();
if (crssi)
{
lcd.setCursor(5, 0);
lcd.print(-crssi);
}
}
}

Этот код уже работает без проблем.

Использовал этот код в скетче для мониторинга состояния отопления теплыми полами при помощи облачного сервиса ThingSpeak.

Источник: fil-tec.ru