Странная проблема с software serial
Привет, я пытаюсь написать библиотеку для связи между Arduino и esp 8266. Я написал команду, которая отправляет AT-команду на чип esp. На данный момент я протестировал эти команды: AT, AT+GMR, AT+CIFSR, AT+CIPMUX=1 и т. д. без каких-либо проблем, связь кажется надежной.
Когда я попытался отправить команду AT+CIPSERVER=1, функция не сработала. После нескольких попыток отладки программы мне удалось заставить ее работать, но я не понимаю почему. И это моя проблема, хотя я думал, что она работает из-за дополнительной задержки, возникающей в моем коде, но после некоторого тестирования это не было причиной.
Может кто-нибудь объяснить мне, что происходит? Я продолжу работать над кодом, пока не разберусь с ним.
Код:
Файл заголовка
#ifndef _ESPLIB_h
#define _ESPLIB_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif
#include <SoftwareSerial.h>
// Определения
#define DEBUG 1
#define BUFFSIZE 64
#define TCPORT 23050
#define ESPTIMEOUT 10000
enum espResponse {
ok,
error,
other
};
// AT-команды
#define CRLF "\r\n"
#define Q "=?"
#define AT "AT"
#define GMR "+GMR"
#define RST "+RST"
#define CMUX "+CIPMUX=1"
#define CWMOD "+CWMODE"
#define CSERV "+CIPSERVER=1"
#define CFSR "+CIFSR"
#define CSEND "+CIPSEND"
class espdevice
{
public:
// Функции
espdevice(int rx, int tx, int baud);
void serialEnable(void);
//логическое значение tcpServerInit(void);
#if DEBUG
void serialDebug(void);
#endif
private:
// Переменные
// Параметры последовательной настройки
int _rx;
int _tx;
int _baud;
// Серийный номер программного обеспечения
int _espSerialIndex = 0;
char _espSerialBuffer[BUFFSIZE];
SoftwareSerial *_espSerial;
// частные функции
//espResponse _sendEspCommand(const char* cmd);
boolean _sendEspCommand(const char* cmd);
espResponse _espCommandOK(void);
boolean _espSerialAvailable(void);
// Режим отладки
#if DEBUG
// переменные
int _serialIndex = 0;
char _serialBuffer[BUFFSIZE];
// функции
void _serialDebug(int select);
int _arduinofreeRam(void);
boolean _serialAvailable(void);
#endif
};
#endif
Что я выполняю
_sendEspCommand("AT+CIPMUX=1\r\n");
_sendEspCommand("AT+CIPSERVER=1,23050\r\n");
_sendEspCommand("AT+CIFSR\r\n");
Теперь определение функции
boolean espdevice::_sendEspCommand(const char* cmd)
{
// переменные
int count = 0;
boolean flag = false;
espResponse status = other;
// отправляем команду в ESP
_espSerial->write(cmd);
#if DEBUG
Serial.print("command echo : ");
Serial.write(cmd);
Serial.println();
#endif
// while (!(status==ok||status==error) || count < 1000) **<- почему эта штука работает ???????????????**
//пока (статус == другое && count < ESPTIMEOUT) <- не работает
while ((status == other) || (count < ESPTIMEOUT)) <- THIS works too
// while(count < ESPTIMEOUT) <- не работает
{
// while (!_espSerial->available()) {};
if (_espSerialAvailable())
{
Serial.println ("Data Are available");
status = _espCommandOK();
#if DEBUG
Serial.print("Data Received from ESP : ");
Serial.print(_espSerialBuffer);
Serial.println("");
Serial.println(status);
#endif
/* //код, используемый с неработающей частью
if (status == ok)
{
flag = true;
break;
}
else if (status == error)
{
flag = false;
break;
}
else
{
}
*/
}
count++;
}
Serial.println(count);
return flag;
}
И две другие функции, которые вызываются
_espSerialAvailable()
boolean espdevice::_espSerialAvailable(void)
{
boolean stringFound = false;
// Читаем последовательный буфер, если данные доступны
while (_espSerial->available() > 0)
{
char charBuffer = _espSerial->read();
if (charBuffer == '\n')
{
_espSerialBuffer[_espSerialIndex] = 0; // завершаем строку
stringFound = (_espSerialIndex > 0); // хорошо, только если мы отправили больше пустой строки
_espSerialIndex = 0; // сброс для следующей строки данных
}
else if (charBuffer == '\r')
{
// игнорируем возврат каретки
}
else if (_espSerialIndex < BUFFSIZE && stringFound == false)
{
_espSerialBuffer[_espSerialIndex++] = charBuffer; // индекс автоматического увеличения
}
}
return stringFound;
}
_espCommandOK()
espResponse espdevice::_espCommandOK(void)
{
if (strcmp(_espSerialBuffer, "OK") == 0)
{
return ok;
}
else if (strcmp(_espSerialBuffer, "ERROR") == 0)
{
return error;
}
else
{
return other;
}
}
Выходные данные последовательных портов для каждого случая
работаю
creating an new tcp server
command echo : AT+CIPMUX=1
Data Are available
Data Received from ESP : AT+CIPMUX=1
2
Data Are available
Data Received from ESP : OK
0
10000
command echo : AT+CIPSERVER=1,23050
Data Are available
Data Received from ESP : AT+CIPSERVER=1,23050
2
Data Are available
Data Received from ESP : no change
2
Data Are available
Data Received from ESP : OK
0
10000
command echo : AT+CIFSR
Data Are available
Data Received from ESP : AT+CIFSR
2
Data Are available
Data Received from ESP : +CIFSR:STAIP,"192.168.1.16"
2
Data Are available
Data Received from ESP : +CIFSR:STAMAC,"5c:cf:7f:fd:ce:14"
2
Data Are available
Data Received from ESP : OK
0
10000
не работает
creating an new tcp server
command echo : AT+CIPMUX=1
Data Are available
Data Received from ESP : AT+CIPMUX=1
2
Data Are available
Data Received from ESP : OK
0
98
command echo : AT+CIPSERVER=1,23050
10000
command echo : AT+CIFSR
Data Are available
Data Received from ESP : AT+CIFSR
2
Data Are available
Data Received from ESP : +CIFSR:STAIP,"192.168.1.16"
2
Data Are available
Data Received from ESP : +CIFSR:STAMAC,"5c:cf:7f:fd:ce:14"
2
Data Are available
Data Received from ESP : OK
0
224
@Dual1ty, 👍0
3 ответа
Лучший ответ:
Я оставлю это здесь, если кому-то интересно. Итак, я общаюсь с модулем ESP на скорости 9600 бод. После того, как я отправил команду в ESP, я ждал его ответа, прежде чем без каких-либо задержек отправить следующую команду.
Я обнаружил, что по какой-то причине, хотя я отправлял команду в ESP, esp не выполнял команду. Поэтому я добавил задержку (100), чтобы увидеть, был ли RX ESP отключен в это время, и я думаю, что был прав, поскольку команды выполнялись правильно.
Мне удалось уменьшить задержку до задержки (5). после этого он ломается.
Я использую Arduino micro и ESP-01.
В вашем примере в отправляемой командной строке отображается запятая «,». Не уверен, как Serial.write обрабатывает данные; однако запятая может сбить с толку. вы пробовали Serial.print?
Возможно, это не тот ответ, который вам нужен, если вы используете его для чего-то другого, но если вы используете Micro, я бы использовал серийный номер Serial1 вместо SoftwareSerial. Я выполнил много проектов, используя Leonardo (тот же процессор) с ESP8266, поскольку он дает мне дополнительный аппаратный последовательный порт, который не подключен к последовательному порту Serial Monitor.
Я не пробовал библиотеку SoftwareSerial в течение нескольких лет, но тогда я помню, что она плохо справляется с дуплексным режимом или высокими скоростями передачи данных.
Какую скорость передачи данных вы используете? Я не увидел начала в коде.
РЕДАКТИРОВАТЬ: Возможно, вы также захотите добавить команду «ATE0», чтобы отключить эхо команд. Последовательный приемник, вероятно, перегружен данными.
- AT-команда не отвечает на последовательный монитор
- Как подключить Wi-Fi Shield ESP-12E-ESP8266-UART-WIFI-Wireless-Shield к Arduino
- Получить данные с сайта с помощью ESP8266 с помощью AT-команд
- Программное обеспечениеSerial с ESP8266
- Как связаться с ESP8266 ESP01, отправив данные через программный сериал на Arduino Uno?
- Отправить строку данных из Arduino UNO в ESP8266-01
- Последовательная связь arduino mega и D1 Wemos Mini
- Нет соответствующей функции для вызова SoftwareSerial::SoftwareSerial(int&,int&)? Как исправить эту проблему
Я не использовал запятую, но попробовал тот же код, отправив «AT+CIPSERVER=1», который запускает tcp-сервер на порту 333. Результат был тот же. Я попробую Serial.print позже сегодня и сообщу вам, что произойдет. Спасибо, что нашли время ответить., @Dual1ty
Я попытался использовать последовательную печать вместо последовательной записи, но, к сожалению, проблема все еще остается. Я не понимаю, почему мой код работает с этим дополнительным условием, которое ничего не делает. Наверное, я что-то упускаю., @Dual1ty