Skip to content

ESP8266 improving code to avoid crashes #2929

New issue

Have a question about this project? No Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “No Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? No Sign in to your account

Closed
kaczy1217 opened this issue Feb 4, 2017 · 6 comments
Closed

ESP8266 improving code to avoid crashes #2929

kaczy1217 opened this issue Feb 4, 2017 · 6 comments

Comments

@kaczy1217
Copy link

kaczy1217 commented Feb 4, 2017

Hardware

Hardware: ESP-12E

Description

Hello to everyone. This is gonna be my first post on Github, but recently I'm reading your posts almost every single day for many hours.

I'm developing ESP-12E board. A SoftwareSerial to communicate with RFID reader and ESP acting as a Server and Client. If RFID antenna has a tag in range it sends ID via my SoftwareSerial to ESP with 1s intervals. When a tag is not present near the antenna it sends nothing.
Basically my program checks the availability RFID and when it notices change of the tag value from 0 to 'something' or from 'something' to 0 it sends it only once in a message to the master unit.
If RFID doesn't send anything during 2500ms program founds it that the tag is not present in the range of reader.
Master unit occassionally checks if the slave has 'something' in its range by sending message with "U" letter. Slave is responding with its current status.

I have the ESP-12E adapter board with 3V3 stabilizer. Everything is soldered and secured with ceramic 100nF decoupling condensator, and two 470uF electrolytic condensators: one before and one behind the 3V3 stabilizer. Everything is powered from 5V 6A supply. CH_E and RST pulled up to 3V3. GPIO0 and GPIO2 pulled up to 3V3, GPIO15 pulled to GND.

I would like my ESP work for a weeks without problems, but I know that is hard to achieve. I'm ok with occassionally resets but I wouldn't be pleased with freezes. I rather would like the wdt to reset my chip than it crash or completely freeze.
Today I've tested it for a couple of hours and it worked well without any failures but I want to be better safe than sorry. I'm not sure if I haven't add too many yields or delay(0)s. I've added yields and delays because I've just wanted to give the processor time to handle system tasks but I didn't mean to unnecessarily feed the wdt. I want the wdt to eventually handle the heap and restart chip.
I would like you to see my code and help me if there is anything I can do to improve it (especially RFID reading part) to prevent from dead loops or mistakes that could cause a freeze?

And the second question: Is it ok to callback the WiFiSend function inside the if(!client) ?

I don't want you to write code for me. I'm just looking for good advices about yielding and wdt (examples are very welcome ;) ). I spent many hours searching the Internet for neccessary information but I didn't find too many concretes except generalities like:

"This is one of the most critical differences between the ESP8266 and a more classical Arduino microcontroller. The ESP8266 runs a lot of utility functions in the background – keeping WiFi connected, managing the TCP/IP stack, and performing other duties. Blocking these functions from running can cause the ESP8266 to crash and reset itself. To avoid these mysterious resets, avoid long, blocking loops in your sketch."

Is Ticker a good solution for me?

Sorry for the code mistakes but I'm not a professional programist.

Settings in IDE

Module: Generic ESP8266 Module
Flash Size: 4MB/1MB
CPU Frequency: 80Mhz
Flash Frequency: 40Mhz
Upload Using: SERIAL
Reset Method: ck

void loop() {
  yield();
  if (!client) 
  {delay(1);
    WiFiClient client = server.available();
  if (RFID.available() > 0)
      { yield();
        previous=millis();
        delay(0);
        int c=RFID.read();
        delay(0);
        odczyty[r]=c;  //storing reads in array in advance for future use
        delay(0);
        r++;       
        if (r>11)  //r means number of read bytes
          { 
                tag=odczyty[10];   //in my implementation tag id is .11 byte of readed RFID tag
              
            delay(0);
            RFID.flush();
            delay(0);
            tag1=tag;
            delay(0);
            Serial.println(tag1);
            delay(0);
                  if (tag2!=tag1 && tag2==0)
                    {
                      WiFiSend(String(tag1), "C");

                    }
            tag2=tag1;
            tag=0;
            r=0;
            delay(0);
          }

        yield();  
      } else if ((millis()-previous)>2500)
            { 
              tag=0;
              tag1=tag;
              r=0;
              delay(0);
              if (startup!=1)
              {
              if (tag2!=tag1 && tag1==0)
                    {
                      delay(0);
                      WiFiSend(String(tag2), "D");  //sending disconnected message
                      delay(0);
                    }} else  //executing once after startup
                        {   delay(0);
                            RFID.flush();
                            r=0;
                            delay(0);
                            WiFiSend(String(tag1), "U");   //sending update message
                            RFID.flush();
                            delay(0);
                            startup=0;  
                            r=0;
                            delay(0);
                        }
              tag2=tag1;
              previous=millis();
              r=0;
            }

        return;
      }
      
  // Wait until the client sends some data
  while (!client.available()) {
    myDelay(1);
  }

  if (client.available())
  { yield();
    myDelay(1);
    transmission = 1;
    previous=millis();
    String req = client.readStringUntil('\r');
    client.flush();
  }
  convert(req);  //slices request of the client to the specific parts like crc, tag id, slave nr

  if (last_char == "#" && cr.toInt()==crc) // if received message includes "#" symbol and the crc is correct then send "OK\r" reply
  { delay(0);
    client.print("OK\r");
    client.stop();
    previous=millis();
  } else
  { delay(0);
    client.print("ERR\r");
    client.stop();
    previous=millis();
  }
  RFID.flush();
  delay(0);
  r=0;
  
  if (last_char == "#" && transmission == 1 && cr.toInt()==crc )  //simply checks the crc and message syntax
    {
        if (event == "U") //if message contain "U" - send status update to master unit
            {
              WiFiSend(String(tag1),"U");
              previous=millis();
            }

         if (event == "R") //if message contain "R" - restart the ESP
            {
              Serial.println("RESTART");
              ESP.restart();
            }
        transmission = 0;
        last_char = "";
        delay(0);
        
    }
    

  
  yield();

}



void WiFiSend(String nr, String event) 
{
    delay(0);
    if (client.connect(host, httpPort)) {
    yield();
 
    // This will send the request to the server   
    if (nr=="0")
    {
      msg = station_id + event + nr + "00" + "#" + "\r";
    } else
        {   
            msg = station_id + event + nr + "#" + "\r";
        }
    
    client.print(msg);
    client.flush();
    yield();
    return;
    }
    unsigned long timeout = millis();
    while (client.available() == 0) {
      yield();
      if (millis() - timeout > 5000) {
        
        Serial.println(">>> Client Timeout !");
        client.stop();
        
        return;
      }
    }
    delay(0);
    // Read all the lines of the reply from server and print them to Serial
    if (client.available()) {
      yield();
      line = client.readStringUntil('\r');
      client.flush();
      
      if (line == "OK")
        {
          msg = "";
          event = "";
        }
    }
    
    if (!client.connected())
    { 
      client.stop();
    }
    
  myDelay(10);
  line = "";
  n = 0;
  previous=millis(); //when sending a message takes a while this line avoids the program to think that tag is not in the range of RFID reader
  
}

void myDelay(int time)
{
  for (int z = 0; z < time; z++)
  {
    delay(1);
    yield();
  }
}
@vicnevicne
Copy link
Contributor

Hi, kaczy1217,
The github issue tracking system is normally used to report bugs in the project, or request features to be added.
For code review and tips, I would advise you to post your question on the user forums at esp8266.com , where many people are ready to help for user questions.
So may I kindly ask you close this bug when you have posted on the forum, possibly leaving a link here to your post so that interested people can follow you there ?

@Sovatna
Copy link

Sovatna commented Nov 5, 2017

Hi,

I am getting such kind of problem:
ets Jan 8 2013,rst cause:4, boot mode:(1,7)

wdt reset

after first run. I do not know how to fix it. please kindly help.
I am trying to obtain data from OpenWeather

@kaczy1217
Copy link
Author

kaczy1217 commented Nov 5, 2017 via email

@Sovatna
Copy link

Sovatna commented Nov 5, 2017

Hi,

May you kindly show me the schematic of your connection? I am a bit young to this, please.

@kaczy1217
Copy link
Author

kaczy1217 commented Nov 5, 2017 via email

@Sovatna
Copy link

Sovatna commented Nov 5, 2017

Thank you so much for your kind. Enjoy your party!

No Sign up for free to join this conversation on GitHub. Already have an account? No Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants