Simple web server running on Arduino Nano + ESP8266 + DS18B20 gets stuck after first GET request

Hello all,

I have put together a simple project with an Arduino Nano, a ESP8266 microcontroller (using Wi-fi, not using it as a controller) and a DS18B20 waterproof temperature sensor.

Everything works as I can get temperature readings properly, and my web server is able to provide the readings to a client as a JSON but it works only after the first time; subsequent calls just sit there and eventually the ciient times out (the --ignore-content-length doesn't seem to help):

curl --verbose http://192.168.1.12:80
*   Trying 192.168.1.12:80...
* Connected to 192.168.1.12 (192.168.1.12) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.1.12
> User-Agent: curl/7.71.1
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
* no chunk, no close, no size. Assume close to signal end
< 
* Closing connection 0
23.19

I noticed than my debug printouts using the serial port sometimes get mangled, both with the serial monitor on the Arduino IDE 2 and minicom --baudrate 115200 --device /dev/ttyUSB0 (I'm coding on Linux).

08:15:45.964 -> AT+CIPSERVER=1,80

08:15:45.964 -> 
08:15:45.964 -> OK
08:15:49.370 -> ,76:GET / HTTP/1.1
08:15:49.402 -> Host: 193.168.1.12
08:15:49.402 -> User-Agent: curl/7.71.AT+CIPN
HRVP/1.1 80 OK
C�#	��
08:15:50.397 -> SEND OK
08:15:53.413 -> AR)��PALO�QOj
08:15:53.413 -> 0,CLOSED
08:15:53.413 -> 
08:15:53.413 -> OK

I managed to send AT commands with these settings (115200 8N1 | NOR) and the output doesn't break when doing that.

The code of the web server is pretty simple, maybe I do have a connection problem (but then how does it work fine the first time?):

/*
 * Simple webserver that captures temperature using a DST18B20 sensor and relays the results to a ESP8266 microcontroller
 * through an Arduino Nano board.
 */
#include <SoftwareSerial.h>
#include <OneWire.h>
#include <DallasTemperature.h>

#define DEBUG true

#define ONE_WIRE_BUS_PIN 2
#define PORT_SPEED 115200
#define IC_SENSOR_IDX 0
#define SLEEP_ONE_SEC 1000
#define HALF_SEC 1500
#define TWO_SEC 2000
#define THREE_SEC 3000
#define RX_PORT 10
#define TX_PORT 11

SoftwareSerial esp8266(RX_PORT, TX_PORT);
OneWire oneWire(ONE_WIRE_BUS_PIN);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(PORT_SPEED);
  sensors.begin();
  esp8266.begin(PORT_SPEED);
  InitWifiModule();
}

void loop() {

  if (esp8266.available()) {
    if (esp8266.find("+IPD,")) {
      
      sensors.requestTemperatures();
      float temp_c = sensors.getTempCByIndex(IC_SENSOR_IDX);
      float temp_f = sensors.getTempFByIndex(IC_SENSOR_IDX);
      delay(SLEEP_ONE_SEC);

      int connectionId = esp8266.read() - 48;
      String webpage = R"(HTTP/1.1 200 OK

Content-Type: application/json
Connection: close

)";
      webpage.concat("{\"celcius\": \"");
      webpage.concat(temp_c);
      webpage.concat("\", \"farenheit\": \"");
      webpage.concat(temp_f);
      webpage.concat("\"}\r\n");
      webpage.concat(R"(

      )");
      const int webpage_length = webpage.length();
      String cipSend = "AT+CIPSEND=";
      cipSend.concat(connectionId);
      cipSend.concat(",");
      cipSend.concat(webpage_length);
      cipSend.concat("\r\n");

      sendData(cipSend, SLEEP_ONE_SEC, DEBUG);
      sendData(webpage, SLEEP_ONE_SEC, DEBUG);

      String closeCommand = "AT+CIPCLOSE=";
      closeCommand.concat(connectionId);
      closeCommand.concat("\r\n");
      sendData(closeCommand, THREE_SEC, DEBUG);
    }
  }
}

String sendData(String command, const int timeout, boolean debug) {
  String response = "";
  esp8266.print(command);
  long int time = millis();
  while ((time + timeout) > millis()) {
    while (esp8266.available()) {
      char c = esp8266.read();
      response += c;
    }
  }
  if (debug) {
    Serial.print(response);
  }
  return response;
}

void InitWifiModule() {
  sendData("AT+RST\r\n", TWO_SEC, DEBUG);
  sendData("AT+CWJAP=\"XXXX\",\"YYYY\"\r\n", TWO_SEC, DEBUG);
  delay(3000);
  sendData("AT+CWMODE=1\r\n", HALF_SEC, DEBUG);
  delay(1500);
  sendData("AT+CIFSR\r\n", HALF_SEC, DEBUG);
  delay(1500);
  sendData("AT+CIPMUX=1\r\n", HALF_SEC, DEBUG);
  delay(1500);
  sendData("AT+CIPSERVER=1,80\r\n", HALF_SEC, DEBUG);
}

I can share the schematics here but this smells like a coding issue to me, my questions are:

  1. There are any libraries I can use to simplify my code? I want it to be more reliable, happy to trade speed over proper working.
  2. I do not want to use the ESP8266 controller directly. I'm aware of plenty of projects and examples that support that mode of operation but I want to extend my Arduino Nano, not replace it with the ESP8266 controller.
  3. I looked through the forums and I could not find a use case similar to mine, apologies if this was answered before and I missed it.

Thanks,

FYI, I found this tutorial, but the ESP8266 is used as a controller in this case.

Yeah, that's the way most people do it these days. That way, you don't need the Uno. This makes things much easier and more reliable, in my experience. Connecting esp-01 to Uno is a pain because you have to use software serial, the voltages have to be adapted between 3.3V & 5V and so on.

I would recommend a wemos d1 mini. This gives you more pins than esp-01, but not as many as an Uno, but you can of course extend the available pins with I/o extenders, and minimise the number of pins required by choosing components carefully, for example those using i²c bus.

I have an "old" ESP2866 controller, not as fancy as the one you showed above. Still, not all hope is lost, I'll take a look at Arduino ESP8266 DS18B20.