• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Вопрос Как разбирать ответ от 8266

Georgiy

New member
Делаю опрос счетчиков через Arduino и esp8266, неожиданно нарвался на проблему.
Дело в том, что из-за нехватки знаний в программировании не могу понять как принимать-отправлять через esp данные не в формате символов (char, string), а байты. Подскажите пожалуйста, ведь с модулем ардуинка общается at-командами, которые имеют формат char, а после команды +IPD, данные у меня байтовые. как делается преобразование форматов? или я что-то не понимаю?
Вот кусок кода где я получаю данные от esp:
if (mySerial.available())
{
delay(100);
memset (buffer, 0, sizeof buffer);
while ( mySerial.available() && i < 201)
{
buffer[i++] = mySerial.read();
}
//---------------собираем первые 5 символов-----------------
char tempbuf1 = buffer [2];
char tempbuf2 = buffer [3];
char tempbuf3 = buffer [4];
char tempbuf4 = buffer [5];
char tempbuf5 = buffer [6];

char cmd1[] = {tempbuf1, tempbuf2, tempbuf3, tempbuf4, tempbuf5};

//------------------------------------------------------------
//--------------------теперь сравниваем с +IPD----------------
if (strncmp(cmd1, "+IPD,", 5) == 0) // Если пришли данные
{
sscanf(buffer + 7, "%d,%d", &id_soed, &packet_len); // Узнаем id соединения и длинну пакета

//-----------------------------------------------------------
char *pb; //--------
pb = buffer; //--------тут в массив pb собираем данные из пакета
while (*pb != ':') //--------
pb++; //--------
pb++; //--------
//--------------------------------------------------------
// Serial.print("pb=");

digitalWrite(SerialTxControl, HIGH); //--------передача в 485
digitalWrite(ledPin13, SerialTxControl); //--------передача в 485
delay (50);

Serial.write(pb);
Serial.print("pb=");
Serial.println(pb);
delay (50);

у меня все что прилетает от esp складывается в массив buffer, потом он парсится и узнается что пришли данные (есть +IPD) и пришедшие данные складываются в pb. Вот когда я шлю символы, все хорошо, как только шлю байты - ничего не приходит....
 

Georgiy

New member
А WTerm-ом шлю байты. если байту есть сопоставимый символ ASCII, то нормально прилетает, а если шлю например 00, 01 - то ничего не прилетает
 

Сергей_Ф

Moderator
Команда форума
А WTerm-ом шлю байты. если байту есть сопоставимый символ ASCII, то нормально прилетает, а если шлю например 00, 01 - то ничего не прилетает
А вы уверены, что WTerm может слать байты ? Насколько я понимаю терминал работает в текстовом режиме с ANSI символами только. Что за прошивка будет на esp?
 

Georgiy

New member
Прошивка на модуле заводская, WTerm байты шлет, там выбор есть - слать символы или в другом поле байты пишешь. Ну я не только им пользуюсь, само ПО которое счетчик опрашивает тоже байты шлет.
 

Сергей_Ф

Moderator
Команда форума
Что то мне кажется, что заводская прошивка тут не справится. Если ошибаюсь, гуру поправят. Если можете, шлите символы - sprintf вам в помощь. Кстати, не совсем понял манипуляций с tempbuf# . Почему не напрямую копируете?
 

Georgiy

New member
Спасибо. tempbuf я использую чтобы выдернуть из пришедшего массива 5 символов и сравнить их с +IPD если они пришли, то я вижу что в модуль пришли данные и начинаю их собирать в pb
 

Georgiy

New member
вот я шлю в модуль данные:
шлю конечно char....

void otvet_klienty()
{

mySerial.print("AT+CIPSEND="); // ответ клиенту
mySerial.print(id_soed);
mySerial.print(",");
mySerial.println(i1);
delay(20);
//
if(mySerial.find(">"))
{
mySerial.write(buffer1);
delay(200);
}
clearSerialBuffer();
}
 

=AK=

New member
У меня бинарные данные приходят без проблем. Да и то ведь, нафиг ESP знать, что там за байты он пересылает? Он же их не парсит на лету. Что принял, то и вывалил.

Правда, для меня нарезка на сообщения никакой роли не играет. Поскольку я сам обнаруживаю начало и конец своего пакета, а то, что сыплет мне ESP считаю просто (непрерывным) потоком байтовых символов. Поэтому мне ESP может передавать данные по кусочкам как угодно.
 

Georgiy

New member
@Georgiy почему вы сразу в cmd1[] не копируете? Зачем буфер ?
Это у меня используется дальше. Ну и уровень моих знаний в программировании немногим отличается от нулевого )).
Похоже начинаю доходить, что мне все данные нужно в байтах принимать а не char-ами, и дальше уже с ними работать.....
 

Atom

Member
Преобразование в C делается кастингом:
unsigned char ch = (unsigned char)my_byte;
И вообще, в С нет типа byte. А есть char и unsigned char. И так же более укороченые типы, опять же дублирующие основные int8_t и uint8_t. Так что не имеет значение в каком виде вы принимаете данные.

Чтo касается обработки потоковых данных, то там целая теория. Но вкраце попробую объяснить на пальцах.
Есть кольцевой буфер в AVR, который запоминается независимо от лсновного цикла. То есть по прерыванию.
В основном цикле делается проверка последний записанный в буффер индекс отличается от последнего обработанного. Если да, то берем следующий принятый символ и и пытаемся на основании предыдущей цепочки построить команду в виде числа.
Например если посмотреть мнимые команды 'AT+1', 'AT+2', 'AT+I1', 'AT+K 1000', то с четвертого символа начиваются различия. И код команды (внутренний) для первого будет 1, для второго 2, для третьего 3 и четвертого 4. Причем у четвертого нужно потом распознать число до символа перевода каретки.

Работа кропотливая, но увлекательная. Скорость выполнения очень большая и начинается прямо со времени прихода первого символа. Для отладки пользовался протеусом с коннекченым с esp по com порту.
 

Georgiy

New member
Спасибо, вроде потихоньку начинаю разбираться, со счетчиком уже общаюсь ))
 
Сверху Снизу