Receiving garbage output in ESP8266

Howdy!

I'd like to apologize in advance for my lack of concentration and understanding. Too mentally exhausted from IRL responsibilities and such, but i don't mind providing as much details as possible regarding my issue. Regardless, here's my story behind this issue.

Context: i'd received Arduino Uno ATmega328P WiFi R3 with built-in ESP8266 module. With this thing in my posession, i started working on my project. The goal of this project is to provide sensor data (i.e. current light level recieved via the light sensor - "MH-Sensor-Series" is written on the back of the board) by sending it from Arduino (acts as a data transmitter) to ESP8266 (acts as a data receiver). ESP8266 itself is supposed to act as an access point. And it does well in that regard after some tinkering. ESP8266 outputs HTML page where sensor data can be located.

Issue: no matter what i do, i get gibberish output out of this whole thing. I'd been searching the forums here and there until i realized that nothing suggested is working in my case. I'd tried multiple things:

  • Checked wiring - everything is intact and wired correctly;
  • Checked all devices - everything is stable and works flawlessly; i even tried using my other Arduino Uno connected to standalone ESP8266-01 module - no dice whatsoever;
  • Set baud rates on both devices to the exact same value (9600);
  • Trial and error - tried various combinations of the setup;
  • Used Serial.read() command - data is inadequate (i do understand that i get data as a series of bytes);
  • Used Serial.readString() command - data is completely unreadable;
  • Used Serial.parseInt() command - the value is always returned as zero.

Question: what should i do in order to get a readable data? Obviously i'm missing something trivial in this setup, but i can't see it.

This is what my wiring currently looks like:

Arduino (A0) --> Sensor (A0)
Arduino (D2) --> Sensor (D0)
Arduino (GND) --> Sensor (GND)
Arduino (5V) --> Sensor (VCC)

Arduino (GND) --> Voltage Divider (IN-)
Arduino (D4) as TX --> Voltage Divider (IN+)

Voltage Divider (OUT-) --> ESP8266 (GND)
Voltage Divider (OUT+) --> ESP8266 (RX)

Arduino (transmitter) code:

#include <SoftwareSerial.h>

SoftwareSerial esp8266(3, 4);

void setup() {
  //
  // Initialize serial communications at 9600 bps:
  //
  Serial.begin(9600);
  esp8266.begin(9600);

  return;
}

void run() {
  int analogSensorValuePrevious = 0;
  int analogSensorValueCurrent = 0;

  //
  // Receive data from the sensor.
  //
  analogSensorValueCurrent = analogRead(A0);

  //
  // Do not print the current sensor value if it's the same as the previous one that can be found in the previous tick.
  //
  if (analogSensorValuePrevious != analogSensorValueCurrent) {
    analogSensorValuePrevious = analogSensorValueCurrent;

    Serial.print("Current light level is ");
    Serial.println(analogSensorValueCurrent);
    esp8266.write(analogSensorValueCurrent);
  }

  delay(5000);

  return;
}

void loop() {
  run();

  return;
}

ESP8266 (receiver) code:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

#ifndef APSSID
#define APSSID "<ssid>"
#define APPSK "<password>"
#endif

const char *ssid = APSSID;
const char *password = APPSK;

String data = "";
String body = "";
ESP8266WebServer server(80);

void respond() {
  //
  // Get sensor data if available.
  //
  while (Serial.available() > 0) {
    int digit = Serial.read();

    if (isDigit(digit)) {
      data += (char)digit;
    }
  }

  Serial.print("Current light level is ");
  Serial.println(data);

  if (data.isEmpty()) {
    body = "<div style=\"color: white; background-color: maroon; border-radius: 8px; box-shadow: 0 0 10px black inset; display: flex; align-items: center; height: 100%; justify-content: center; width: 100%;\"><h1>Sensor data is unreachable. Check connection.</h1></div>";
  } else {
    body = "<div style=\"color: white; background-color: green; border-radius: 8px; box-shadow: 0 0 10px black; 8px; display: flex; align-items: center; height: 100%; justify-content: center; width: 100%;\"><h1>Current light level is " + data + "</h1></div>";
  }

  Serial.print("Currently, the body contains the following: ");
  Serial.println(body);

  server.send(200, "text/html", body);

  //
  // Don't forget to clear the string.
  //
  data = "";

  return;
}

void setup() {
  delay(1000);
  Serial.begin(9600);
  Serial.println();
  Serial.print("Configuring access point...");
  WiFi.softAP(ssid, password);

  IPAddress myIPAddress = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIPAddress);
  server.on("/", respond);
  server.begin();
  Serial.println("Server started");

  return;
}

void loop() {
  server.handleClient();

  return;
}

Is this a genuine Arduino board or something offered from a 3rd party manufacturer? Have you verified how the ESP8266 is connected to the 328P controller? I'm not familiar with a rev3 UNO with WiFi. I know there's an UNO R3. There's also an UNO with WiFi - an initial one, and a rev2, and a rev4. They're all fundamentally different.

Since you mention a 328P controller + ESP8266, it seems to be the original UNO WiFi. Can you confirm you have this older board and not the newer R2 or R4? The original one that you seem to be referring to is no longer offered in the Arduino shop, suggesting you either obtained old stock/second hand somehow, or a similar/equivalent board from a different maker. Can you post a photo of yours?

Assuming you've got the original UNO WiFi: the ESP8266 is connected to UART in a rather weird way - in order to maintain compatibility with Serial monitor for debugging and programming the 328P over UART. However, the net result of all this is that you should be able to "talk to" the ESP8266 by simply using Serial (instead of SoftwareSerial). Have you tried this?

I see you're trying to address the ESP8266 through SoftwareSerial on pins 3 & 4 of the 328P, but no ESP8266 is connected on the UNO WiFi board on those pins.

I think this is genuine. At least, it's quite similar to the one you can find in this post, but i can be wrong though.

Here's the picture of my board:

1 Like

Which very clearly states it's a RobotDyn product, so not Arduino.

Note the dip switches, which are not a feature of the original Arduino UNO WiFi. These switches may control how the UART is routed across the board; i.e. to the ESP8266 and/or elsewhere. You'll have to revert to the documentation of your board to figure out what the correct position of the switches is. That, and/or try to trace the UART RX and TX from the 328P across the board and see how/if they end up at the ESP8266.

Have you tried the DIP switch settings outlined in the thread you linked to?

Yes, i'd already seen the name of microcontroller mentioned in the thread. However, what i have is advertised as "Arduino Uno ATmega328P WiFi R3 + ESP8266". I don't know how to confirm that statement. I reckon that the product mentioned in the thread and the one that i have are similar or exactly the same. You are probably right in that regard.

Have you tried the DIP switch settings outlined in the thread you linked to?

Yes, i did. Otherwise, i wouldn't be able to upload the sketches to the devices.

So can you confirm that you're doing the testing of the actual 328<>8266 communication with the DIP switches set like this:

**ATmega <-> ESP8266** 1100000

And have you actually done what I proposed earlier:

Because of what I also said:

This is for the official Arduino board, but given the presence of these DIP switches, it follows logically that the hardware UART on the 328P is also used to address the ESP8266. Hence, the DIP switches need to be set in the right way to perform either device programming or communications between the 8266 and 328.

No, not yet, but i'll try to do exactly that. I know for certain that i already did that in the past, but that proved to be fruitless for some reason. Probably a wrong setup because i barely changed anything at the time.

Ok, give it a try and report back.

If all else fails, you can actually do this with SoftwareSerial, too, but you have to connect the appropriate pins of the 328P to those on the ESP8266. Here's a guy that does it this way: GitHub - KamranBabar16/UNO-WiFi-R3-ATmega328P-ESP8266

However, I'd just try with the hardware UART first and not bother with SoftwareSerial unless you really have to. What makes this easier is that you only want to output to the ESP8266, which means that whatever you make the 328P send to the ESP8266 won't interfere with your serial monitor debugging (it will show up there, but that's OK as you can see what's going on).

Success! For the first time i can actually see accurate values. :slightly_smiling_face:

You were right. I should've tried hardware UART first before using another approach. Good thing i found a pair of fresh eyes that could see what the issue is. I'll test this setup a little bit more just to verify even that everything is reliable and correct for the long-term use.

Hey, that's great to hear! Thanks so much for reporting back on the issue and I'm glad that you can now proceed with your project.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.