Странная проблема с 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

, 👍0


3 ответа


Лучший ответ:

0

Я оставлю это здесь, если кому-то интересно. Итак, я общаюсь с модулем ESP на скорости 9600 бод. После того, как я отправил команду в ESP, я ждал его ответа, прежде чем без каких-либо задержек отправить следующую команду.

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

Мне удалось уменьшить задержку до задержки (5). после этого он ломается.

Я использую Arduino micro и ESP-01.

,

-2

В вашем примере в отправляемой командной строке отображается запятая «,». Не уверен, как Serial.write обрабатывает данные; однако запятая может сбить с толку. вы пробовали Serial.print?

,

Я не использовал запятую, но попробовал тот же код, отправив «AT+CIPSERVER=1», который запускает tcp-сервер на порту 333. Результат был тот же. Я попробую Serial.print позже сегодня и сообщу вам, что произойдет. Спасибо, что нашли время ответить., @Dual1ty

Я попытался использовать последовательную печать вместо последовательной записи, но, к сожалению, проблема все еще остается. Я не понимаю, почему мой код работает с этим дополнительным условием, которое ничего не делает. Наверное, я что-то упускаю., @Dual1ty


0

Возможно, это не тот ответ, который вам нужен, если вы используете его для чего-то другого, но если вы используете Micro, я бы использовал серийный номер Serial1 вместо SoftwareSerial. Я выполнил много проектов, используя Leonardo (тот же процессор) с ESP8266, поскольку он дает мне дополнительный аппаратный последовательный порт, который не подключен к последовательному порту Serial Monitor.

Я не пробовал библиотеку SoftwareSerial в течение нескольких лет, но тогда я помню, что она плохо справляется с дуплексным режимом или высокими скоростями передачи данных.

Какую скорость передачи данных вы используете? Я не увидел начала в коде.

РЕДАКТИРОВАТЬ: Возможно, вы также захотите добавить команду «ATE0», чтобы отключить эхо команд. Последовательный приемник, вероятно, перегружен данными.

,