7 years, 8 months ago.

To ensure get OK consistently following AT+GMR

Sometimes when I display AT+GMR on terminal emulator, after that I get ERROR whilst other times I get OK, what would I need to add/edit to code to ensure get OK regularly on terminal emulator?

#include "mbed.h"
#include <stdio.h>
#include <string.h>

Serial serial(USBTX, USBRX);
Serial esp(P4_28, P4_29); // tx, rx
DigitalOut reset(P0_4);
DigitalOut blueLed(P2_3);
DigitalOut greenLed(P2_4);
DigitalOut redLed(P2_5);
DigitalOut vibr(P2_12);

Timer t;

int  count,ended,timeout;

int sample_ctemp;
int sample_humid;
int toggle = 0;

char buf[4096];
char snd[255];
char rcv[255];
char sendStr[11];

char ssid[32] = "eduroam";     // enter WiFi router ssid inside the quotes
char pwd [32] = "Rafaelnadal14"; // enter WiFi router password inside the quotes

void SendCMD();
void ReceiveCMD();
void getReply();

int main()
{
    //Make sure all feedback mechanisms are turned off
    blueLed=0;
    greenLed=0;
    redLed=0;
    vibr=0;

    //set buad rates for comms
    esp.baud(115200);
    serial.baud(115200);


    // Setup a serial interrupt function to capture received data
    esp.attach(&getReply, Serial::RxIrq);

    //Device doesn't appear to need a reset upon waking up so the device is not reset (i.e. reset = 1);
    reset=1;

    // Give the user some to setup the virtual terminal
    wait(10);


    serial.printf("\n---------- Clear Buffer ----------\r\n");  //Simple way to clear the buffer
    strcpy(snd, "AT+GMR\r\n");    //View version info
    timeout=1;
    SendCMD();
    getReply();
    serial.printf(buf);
}

//This function sends the command string to the ESP8266
void SendCMD()
{
    esp.printf("%s", snd);
}

//This function sends the command string to the ESP8266
void ReceiveCMD()
{
    esp.printf("%s", rcv);
}

//This function establishes the space for the received string, starts a timer so that if things get stuck, the 
//app won't hang.  
void getReply()
{

    memset(buf, '\0', sizeof(buf));
    t.start();
    ended=0;
    count=0;
    while(!ended) {
        if(esp.readable()) {
            buf[count] = esp.getc();
            count++;
        }
        if(t.read() > timeout) {
            ended = 1;
            t.stop();
            t.reset();
        }
    }
    
    /*   This function is for interrupt for gesture sensor */
    
    
}



<<code>> not <code>

posted by Andy A 07 Mar 2017

just updated it now

posted by Seb Creighton 07 Mar 2017

1 Answer

7 years, 8 months ago.

Try sending "\r\nAT+GMR\r\n"

Sometimes you get a single character of junk in the receive buffers on startup that gets taken as part of the command. Sending an extra new line before the first command stops this from happening. You may then get ERROR\r\nOK\r\n as the response but you at least get your OK at the end. If you want just the OK then send a new line, wait a short time, read and discard any data in the uart receive buffer and then send your command.

A couple of other notes:

1) You set up the serial portrx interrupt to call getReply every time a byte is received, you then call getReply directly. Do one or the other, not both.

2) getReply blocks for 1 second so you really shouldn't ever be calling it on an interrupt, Interrupts should be as fast as possible and never involve delays or loops with waits in them.

3) getReply stores the reply in buf with no checking for buffer overflow or end of message indicators, ideally it should check for overflow and also exit once the correct end of message character is seen. Also the memset is unnecessary and very slow, all you need to to is set buf[count] = 0 before exiting the function to ensure the result is null terminated.