Problem W/ Serial Communication Between ESP8266 and Elegoo Car Shield

I would first like to preface this by saying I am not an expert in Arduino Hardware/Software whatsoever. I am using the Elegoo Smart Robot Car Kit V3.0, and modifying it with an ESP8266 module.

The goal of my project is this: Make a ‘parking system’ of sorts wherein there is a parking space (which is an ESP8266 connected to an Ultrasonic Sensor) that is constantly publishing distances (in cm) to the Adafruit IO website. Then, I have the car with another ESP8266 connected to it; The ESP8266 on the car is subscribed to the feed, and this is as far as the project works. I want the car to move forward (using line-tracking code), have the parking space detect it, and finally have the ESP8266 on the car use SoftwareSerial to make the Smart Car stop and turn into the space.

The problem started when I tried to connect the ESP8266 and Smart Car Arduino Board together. The board on the car uses a special “Car Shield” module that you place on top of a normal Arduino Uno. I saw that in order to have Serial Communication, you have to connect the RX on one board to the TX on the other, and vice versa. However, when I have the boards connected like that, I get the error:
“esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header”

Here is the code I have for the ESP Module on the Car.

#include <SoftwareSerial.h>
SoftwareSerial transmitter(3, 1);
#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>
#include <ESP8266WiFi.h>

#define R_SSID "ProjectMISTY"
#define PASS "whoreads"
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "Volthum"
#define AIO_KEY "15c716e5795a49dc84f008c4cbaeb9ad"
  WiFiClient client;
  Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
  Adafruit_MQTT_Subscribe distance123 = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "/feeds/Distance");

void setup() {
  Serial.begin(115200);
  transmitter.begin(9600);
  delay(10);
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(R_SSID);
  WiFi.begin(R_SSID, PASS);
  int counter = 10;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter--;
    if (counter == 0) {
      // reset me
      ESP.reset();
    }
  }
  Serial.println();
  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());
  mqtt.subscribe(&distance123);

}

void loop() {
  MQTT_connect();
  Adafruit_MQTT_Subscribe *subscription;
  while ((subscription = mqtt.readSubscription(5000))) {
    if (subscription == &distance123) {
      Serial.println("The distance is: ");
      Serial.println(((char *)distance123.lastread));
      float parking_distance = atof ((char *)distance123.lastread);
      transmitter.println(parking_distance);
    }
  }
}


void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
  }
  Serial.println("MQTT Connected!");
}

And Here is the code I have for the line tracking car (Just the code provided by Elegoo.com but with added Software Serial code).

#include <SoftwareSerial.h>
SoftwareSerial receiver(0, 1);
//Line Tracking IO define
#define LT_R !digitalRead(10)
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

#define ENB 5
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define ENA 6

#define carSpeed 200

void forward(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}

void back(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

void left(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}

void right(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW); 
} 

void stop(){
   digitalWrite(ENA, LOW);
   digitalWrite(ENB, LOW);
} 

void setup(){
  receiver.begin(9600);
}

void loop() {

  if (receiver.read()) {
    float distance = receiver.read();
    if (distance < 10) {
      stop();
      right();
      delay(500);
      forward();
      delay(500);
      stop();
    }
  }
  
  if(LT_M){
    forward();
  }
  else if(LT_R) {
    right();
    while(LT_R);
  }
  else if(LT_L) {
    left();
    while(LT_L);
  }
}

Finally, the code I have for the sensor that is publishing the distance to the Adafruit IO website (Though I do not believe there is anything wrong with this, it’s just added information).

#include <Adafruit_MQTT.h>
#include <Adafruit_MQTT_Client.h>
#include <ESP8266WiFi.h>

#define R_SSID "ProjectMISTY"
#define PASS "whoreads"
#define AIO_SERVER "io.adafruit.com"
#define AIO_SERVERPORT 1883
#define AIO_USERNAME "Volthum"
#define AIO_KEY "15c716e5795a49dc84f008c4cbaeb9ad"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
Adafruit_MQTT_Publish Distance = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "/feeds/Distance");




const int trigPin = 5;
const int echoPin = 4;
float duration, distance;

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  Serial.begin(9600);

  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(R_SSID);
  WiFi.begin(R_SSID, PASS);
  int counter = 10;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    counter--;
    if (counter == 0) {
      // reset me
      ESP.reset();
    }
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.println("IP address: "); Serial.println(WiFi.localIP());
}

void loop() {
  MQTT_connect();
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration * .0343) / 2;
  Serial.print("Distance: ");
  Serial.println(distance);
  Distance.publish(distance);
  delay(2000);

}
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 5;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
    Serial.println(mqtt.connectErrorString(ret));
    Serial.println("Retrying MQTT connection in 5 seconds...");
    mqtt.disconnect();
    delay(5000);  // wait 5 seconds
    retries--;
    if (retries == 0) {
      // reset me
      ESP.reset();
    }
  }
  Serial.println("MQTT Connected!");
}

After some research with the error, I saw that most people got this error due to the connection of the RX and TX pins, but if that’s not the issue I do not know what else is.

does counter eventually end up a negative number?

notsolowki:
does counter eventually end up a negative number?

Well, it doesn’t even get to that point. The error appears when trying to upload the code.
Also, I did not put the full error message, so here it is:

Arduino: 1.8.0 (Windows 7), Board: "Generic ESP8266 Module, 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), ck, 26 MHz, 40MHz, DOUT (compatible), 512K (no SPIFFS), 2, nonos-sdk 2.2.1 (legacy), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

Sketch uses 280728 bytes (56%) of program storage space. Maximum is 499696 bytes.
Global variables use 28164 bytes (34%) of dynamic memory, leaving 53756 bytes for local variables. Maximum is 81920 bytes.
esptool.py v2.6
2.6
esptool.py v2.6
Serial port COM7
Connecting........_____....._____....._____....._____....._____....._____.....____Traceback (most recent call last):
  File "C:\Users\student\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2/tools/upload.py", line 25, in <module>
    esptool.main(fakeargs)
  File "C:/Users/student/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.5.2/tools/esptool\esptool.py", line 2653, in main
    esp.connect(args.before)
  File "C:/Users/student/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.5.2/tools/esptool\esptool.py", line 468, in connect
    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

_

have you tried resetting it manually right before it start the upload process or verify the reset pin is working? and im not sure if you trying to flash through serial while you have tx and rx plugged into another board holding tx/rx high or low?

No, I haven't. How would I go about doing that? I'll do that and report back results.

PinkLloyd:
No, I haven't. How would I go about doing that? I'll do that and report back results.

i dont know what esp board you are using. on a nodemcu you press reset while holding the flash button.

I have the RX on the NodeMCU ESP8266 connected to the TX on the Elegoo Car Shield (Modified Arduino Uno), and the TX on the NodeMCU to the RX on the Car Shield.

As for the Boot and Reset, I tried it multiple times. Once right before an upload. Another AS it was uploading. It returns the same error.

PinkLloyd:
I have the RX on the NodeMCU ESP8266 connected to the TX on the Elegoo Car Shield (Modified Arduino Uno), and the TX on the NodeMCU to the RX on the Car Shield.

As for the Boot and Reset, I tried it multiple times. Once right before an upload. Another AS it was uploading. It returns the same error.

sometimes it can be tricky to get an esp into flash mode. i would try to unplug the hardware tx/rx pins of the esp module from the shield while flashing. i cant really tell you anything without know what esp board/shield your using

It is also noteworthy that this error only appears when the RX and TX pins are connected. I've tried reversing the pins. Upon disconnecting them, the code uploads fine, but then there would be no way for the NodeMCU and Car Shield/Arduino to communicate (unless there is an alternative way for this).

To reiterate, I am using the NodeMCU ESP8266 module. I held flash, then press reset. I removed the RX and TX connection(s), and uploaded the code. It uploaded fine, but does that mean I just have to disconnect the RX and TX pins every time I upload the code?

PinkLloyd:
It is also noteworthy that this error only appears when the RX and TX pins are connected. I've tried reversing the pins. Upon disconnecting them, the code uploads fine, but then there would be no way for the NodeMCU and Car Shield/Arduino to communicate (unless there is an alternative way for this).

To reiterate, I am using the NodeMCU ESP8266 module. I held flash, then press reset. I removed the RX and TX connection(s), and uploaded the code. It uploaded fine, but does that mean I just have to disconnect the RX and TX pins every time I upload the code?

yes unless you add some diodes to the rx tx pins. something in your circuit is holding the rx or tx high or low prevent the data transmission

Unfortunately I do not have access to diodes. After uploading (with the RX/TX pins disconnected), and then reconnecting them, the serial monitor prints the distances, but the Arduino doesn't seem to be receiving or responding in any way.

what exactly do you mean?

PinkLloyd:
Arduino doesn't seem to be receiving or responding in any way.

what is not being received how does the input method work?

UPDATE: I've taken the car shield off, and used a conversion chart to connect all of the pins to the Arduino Uno directly. It runs exactly as it has with the shield, too. Unfortunately... with the same problems as well.

I'm trying to transmit the distance gotten from the NodeMCU's subscription; From the NodeMCU to the Arduino. The Arduino is gonna receive the distance and try to execute an if statement based on what it reads from the received transmission (Refer to code).

you dont get anything at all from the serial monitor? try placing serial.prints around your code and see if you can narrow it down

The thing is, everything seems to be running fine EXCEPT for the connection between the car's Arduino Uno board and the NodeMCU ESP8266 module. That's the only problem keeping me from finishing this project.

Any time the RX and TX pins are connected, the uploading process always ends in errors.

So I guess to further simplify the problem: How do I connect the NodeMCU and the Arduino Uno board such that the NodeMCU uses SoftwareSerial to sort of 'communicate' with the Arduino?

i dont remember what level the RX line is suppose to be during a write high? so if your arduino is attached to the esp RX pin holding it low it will not allow the data transmission and it will be garbled. ive never used software serial so i don't think i can help you with that. grab a pinout of the nodemcu sometimes pin D6 dont mean "inputPin = 6;"

maybe this can help you further. GitHub - plerup/espsoftwareserial: Implementation of the Arduino software serial for ESP8266