Aceboot AD174 - changed to a tank with ESP-NOW

I have bought this type of robotic car AD174 from Aceboot, China, last year.
This one is in original delivered with modules ESP32-CAM-V1.0-QA011 and L298N and with the build manual without details about connections. This Car package included the software for Arduino IDE an Python and apk for Android mobiles.

The first problem was that main program for camera module and motors one 
was written in Espressif version till 2.0.2 and there is no simply possibility
 to change all sketches to version 3.0.0 and more ...

Instead of there was possible to upload all sketches with minimal changes
 to camera module and create the  Hot spot for the controlling of this car 
with mobile.

But this system with camera is a little complicated and this one  
is so not  reliable. 

So I have played with one some time and I have thought what to do with one as a better for children.

I have found after some time the system ESP-NOW (thanks to Rui Santos & Sara Santos 
and their Random Nerd Tutorials) and I have thought how to use this excellent
 ESP-NOW system for my AD174 car .

So I have my plan to use at first one joystick PS4 with x and y axes 
and switch

and as I have in my store ESP32 Dev Module of type Wemos D1 R32, I have used it as ESP-NOW sender .

There is impossible to use for sender cheaper module wit ESP8266, 
as it has only one analog input A0, but as the receiver I have used this one, 
as there are no necessary an analog inputs.

At my second attempt I have used one joystick PS4 (or PS2) for  axe y and potenciometer with a fancy roller for axe x . 
In this case I can use for receiver the same sketch as for my first variant before ..

And in my third and finally attempt I have used two joysticks , one for axe y and second  for axe x . 
Unfortunately I have to do many changes and so a half new sketch.

Your code is extremely hard to follow in the format it is presented. Over a thousand characters in one line is a bit on the extreme side.Try formatting it in a more conventional way.

Hello friend,

thank you for your info .. in my computer or Arduino IDE I have all well formated .. the problem went in Forum system by CTRL C / V ...

but I did not control it .. I will try to correct it on Forum, if it is possible .. later, not now ..

Next I am sorry, I cannot attach enclosure in ma W10 32 Thunderbird ..

Pavel Oupicky PavelOu

My one sketch with CRTL C/V CR+LF I think so ...

I think it seem to be OK ... but was not better ..

Instead of I think a plain text has to be as text in code field quite the same …

PavelOu

Please, correct the formatting in all your posts.

Hello, I am sorry, I cannot repair , please, tell me how is possible to do it .. I am sorry …

I did not find a link or advice, how is here possible to repair my main post .. PavelOu

Hi, I a small pen on the end of my probably post … so I have tried to repair my inserted sketches .. but I am sorry it is very terrible work .. so I see, it will be better to cancel this whole topic or codes and to set it there again … I will search for this possibility again .. I am sorry …

Hello,

I have seen that my schetches were copied on Forum without spaces and marks CR and LF, so their were seen in quite terrible format ..

At first I have tried some raws repair, but it was very terrible work, so I have erased all codes ..

and when I will find better posibility how to copy and paste these codes, I will set them there again.

Pavel Ou

ps. there is examle , how my text are copied from my file to e-mail :

//ESP8266_now_receiver_AD174_po_10_en.ino
//changed from ESP32-NOW for ESP8266-NOW
// used GPIO for ESP8266 NodeMCU V1.0
// ESP Board MAC Address: 50:02:91:EF:E6:06 NodeMCU V1.0 po

. . . . . . I erased it now … and I see now it it is worse as code in code field .. but question way is here still …

I try to copy my first (sender) sketch as plain text, as my first attempt with local code formating went out quite terrible, I am sorry …

//ESP32_now_sender_joystick_po_11_AD174_Node_en.ino
//version for Wemos D1 R32 as sender for ESP8266 NodeMCU V1.0 as receiver

. . . . . .

and I see that this result is worse as sketch in the code field …

so I erased it, too …

and here is my sketch for ESP-NOW AD174 sender in code field :

//ESP32_now_sender_joystick_po_11_AD174_Node_en.ino
//version for Wemos D1 R32 as sender for ESP8266 NodeMCU V1.0 as receiver
/*
  Thanks to Rui Santos & Sara Santos for their Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/

#include <esp_now.h>
#include <WiFi.h>
#include <SPI.h>
#include <Wire.h>

//alternative for OLED display
#include <Adafruit_GFX.h>
#include <Adafruit_SH110X.h>

bool serialOn = false;
bool displayOn = false;

#define I2C_SDA 21
#define I2C_SCL 22

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1   //   QT-PY / XIAO

#define i2c_Address 0x3c //initialize with the I2C addr 0x3C Typically eBay OLED's

Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define PIN_ANALOG_X 34  // je to x a bere se y potenciometru s volantem 
#define PIN_ANALOG_Y 35  // je to y , ale na joysticku je to osa x

// Wemos D! R32 version with OLED display
/*
#define PIN_JOYSTICK_SW 14
#define PIN_BUTTON_START 16
#define PIN_ESPNOWOFF 13
#define PIN_ESPNOWON 12
*/

// Wemos D! R32without display display
#define PIN_JOYSTICK_SW 27
#define PIN_BUTTON_START 16
#define PIN_ESPNOWOFF 13
#define PIN_ESPNOWON 12
#define PIN_ESPCARON 14


int osaX = 100;     // axe X
int osaXzero = 1800;
int osaY = 200;     // axe Y
int osaYzero = 1800;
String osaText ="";
String osaTextY ="";
String osaTextX ="";
int joystickSW = 1;
int buttonStart = 1;
int DELAY = 20;

int carOn = 0;
bool dataCalibration = false;
bool espNow = false;

// REPLACE WITH YOUR RECEIVER MAC Address
//uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
//uint8_t broadcastAddress[] = {0xF8, 0xB3, 0xB7, 0x50, 0xBC, 0x5C}; //Wemos D1 R32
//Wemos D1 R32 as receiver - F8:B3:B7:50:BC:5C
//ESP8266 NodeMcu V1.0 Board MAC Address:  50:02:91:EF:E6:06
//uint8_t broadcastAddress[] = {0xE4, 0x65, 0xB8, 0x78, 0x97, 0x20};   //AD174 + QA011
uint8_t broadcastAddress[] = {0x50, 0x02, 0x91, 0xEF, 0xE6, 0x06};   //AD174 + NodeMCU V1.0
//ESP32 AD174 - E4:65:B8:78:97:20

// Structure example to send data
// Must match the receiver structure
typedef struct struct_message 
 {
  int dataX;
  int dataY;
  int dataSW;
 } struct_message;

// Create a struct_message called myData
struct_message myData;

 void CteniOsXaY()  // Test - read of axes X and Y from joystick or potentiometer
{
   osaX = analogRead(PIN_ANALOG_X);
   // Some delay to clearly observe your values on serial monitor.
   Serial.print("osa X: ");
   Serial.println(osaX);
   osaY = analogRead(PIN_ANALOG_Y);
   delay(DELAY);
   // Print y axis values
   Serial.print("osa Y: ");
   Serial.println(osaY);
   delay(DELAY);   
}

esp_now_peer_info_t peerInfo;

// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) 
 {
  if (serialOn)
   {
    Serial.print("Last Packet Send Status: ");
    Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
   }
  status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail";
  if (status == ESP_NOW_SEND_SUCCESS)
   {
    digitalWrite(PIN_ESPNOWON, HIGH);
    digitalWrite(PIN_ESPNOWOFF, LOW);
   }
  else
   {
    digitalWrite(PIN_ESPNOWON, LOW);
    digitalWrite(PIN_ESPNOWOFF, HIGH);  
   }  
 }

 
void setup() 
 {
  // Init Serial Monitor
  Serial.begin(9600);
  delay(2000);
  serialOn = false;
  displayOn = false;
   
  pinMode(PIN_ANALOG_X, INPUT);
  pinMode(PIN_ANALOG_Y, INPUT);

  pinMode(PIN_JOYSTICK_SW,INPUT_PULLUP);  
  pinMode(PIN_BUTTON_START,INPUT_PULLUP);  

  pinMode(PIN_ESPNOWOFF,OUTPUT);
  pinMode(PIN_ESPNOWON,OUTPUT);
  pinMode(PIN_ESPCARON,OUTPUT);
  
  Serial.println();
  Serial.println("ESP32_now_sender_joystick_po_11_AD174_Node_test");
  Serial.println();  
  Serial.println("Test of indication: ");
  digitalWrite(PIN_ESPNOWOFF, HIGH);
  delay(2000);
  digitalWrite(PIN_ESPNOWON, HIGH);
  digitalWrite(PIN_ESPNOWOFF, LOW);
  delay(2000);
  digitalWrite(PIN_ESPCARON, HIGH);
  digitalWrite(PIN_ESPNOWON, LOW);
  delay(2000);
  digitalWrite(PIN_ESPCARON, LOW);
  
  if (displayOn)
    {
      Wire.begin(I2C_SDA, I2C_SCL, 100000);
      delay(250); // wait for the OLED to power up
      display.begin(i2c_Address, true); // Address 0x3C default
      //display.setContrast (0); // dim display
      display.display();
      delay(2000);
    }

  Serial.println("Test of joystick:");

  //CteniOsXaY();

  osaX = analogRead(PIN_ANALOG_X);
   // Some delay to clearly observe your values on serial monitor.
   delay(500);
   Serial.print("osa X: ");
   Serial.println(osaX);
   osaY = analogRead(PIN_ANALOG_Y);
   delay(DELAY);
   // Print y axis values
   Serial.print("osa Y: ");
   Serial.println(osaY);
   delay(DELAY);   

  joystickSW = digitalRead(PIN_JOYSTICK_SW);
  Serial.print("Switch = ");
  Serial.println(joystickSW);

  buttonStart = digitalRead(PIN_BUTTON_START);
  Serial.print("Start = ");
  Serial.println(buttonStart);

  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK) 
   {
    Serial.println("Error initializing ESP-NOW");
    return;
   }
  else
   {
    Serial.println("Initializing ESP-NOW OK");
   } 

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);
  
  // Register peer
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
  
  // Add peer        
  if (esp_now_add_peer(&peerInfo) != ESP_OK)
   {
    Serial.println("Failed to add peer");
    espNow = false;
   }
  else
   {
    Serial.println("ESP-NOW of joystick is ready");
    espNow = true;
   }
   carOn = 0;
   dataCalibration = false;
   Serial.println("Next serial communication is limited for better work in real time");
   digitalWrite(PIN_ESPNOWOFF, HIGH);
   delay(2000);
}
 
/*
void loop() 
 {
  //test
 }
*/

// proces 

void loop() 
 {
 if (!espNow)
   {
    if (serialOn)
     {
      Serial.println("ESP_NOW is off !!");
     } 
    delay(2000);
   }
else
  { 
  osaY = analogRead(PIN_ANALOG_Y);
  delay(DELAY);
  osaY = 4095 - osaY;  // reversed value - zero is near of the contacts
  
  //pinMode(PIN_ANALOG_X, INPUT);
  osaX = analogRead(PIN_ANALOG_X);
  osaX = 4095 - osaX ; // zero is on the left
  // Some delay to clearly observe your values on serial monitor.
  delay(DELAY);
  
  
  //delay(DELAY);   
  joystickSW = digitalRead(PIN_JOYSTICK_SW);
  if (joystickSW == 0) 
     {
       carOn = 0;
      digitalWrite(PIN_ESPCARON, LOW);
     }
  buttonStart = digitalRead(PIN_BUTTON_START);
  if (buttonStart == 0) 
     {
       carOn = 1;
       digitalWrite(PIN_ESPCARON, HIGH);
     }

  myData.dataX = osaX; 
  myData.dataY = osaY;
  myData.dataSW = carOn;
  
  // Send message via ESP-NOW
  esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
   
  if (result == ESP_OK) 
   {
    //Serial.println("Sent data OK");
   }
  else 
   {
    if (serialOn)
     {
      Serial.println("Error sending the data");
     } 
    digitalWrite(PIN_ESPNOWON, LOW);
    digitalWrite(PIN_ESPNOWOFF, HIGH);
    digitalWrite(PIN_ESPCARON, LOW);
    carOn = 0;
   }
  // Print y axis values
  if (!dataCalibration)
   {
      osaXzero = osaX;
      osaYzero = osaY;
      dataCalibration = true;
   }
  if (serialOn)
    {
     Serial.print("osa X: ");
     Serial.println(osaX);
     Serial.print("osa Y: ");
     Serial.println(osaY);
     Serial.print("Switch = ");
     Serial.println(joystickSW);
    }
  //delay(DELAY);  
  osaTextY = String(osaY - osaYzero);
  osaTextX = String(osaX - osaXzero);
  if (displayOn)
    {
      display.clearDisplay();
      display.setTextSize(2);
      display.setTextColor(SH110X_WHITE);
      display.setCursor(0, 0);
      display.print("Car ");
      if (carOn == 0)
        {
         display.println("Off");
        }
      else
        {
         display.println("On");
        }
      display.println();
      display.print("FB = ");
      display.println(osaTextY);
      //Serial.print("LR = ");
      display.print("LR = ");
      display.println(osaTextX);
      display.display();
    }  
   if (serialOn)
    {
     Serial.print("Car ");
     if (carOn == 1)
      {
         Serial.println("On");
      }
     else
      {
        Serial.println("Off");
      }
     Serial.print("FB = ");
     Serial.println(osaTextY); 
     Serial.print("LR = ");
     Serial.println(osaTextX);
    }
   //delay(2000);  // for test
  //delay(10);
  }
}

Hi, I have tried to copy my first sketch (sender) as plain text, so please see if the result is suitable, too. Thank you .

Pavel Ou

My question - I see here only Sign in … but where is Sign out ?? :slight_smile:

I can understand why you are having problems, either you did not read the forumn guidelines or did not understand them. Post your code using code tags. Click the “” in the top line of the reply box and enter code where prompted with ctl V.

... thank you for your message ... '' Click the “” in the top line '' my question, I do not know this pictogram, so I have used for code insertion this one ... code ... instead of ...

To my terrible sketch code .. how I have created them (I have mostly used LibreOffice for my plain texts) :

I have insert my intro text as plain text and someone was normal, someone in grey fields, not according of my effort, of course ..

Then I have posted my sketch as plain text again .. and then I have realised I had to insert this one into code field ..

So I have copied my sketch in the Forum editor and then I have pasted it in the code field ..

and you know the results .. terrible .. and you can try to repeat my ''manual' with your own sketch ...

Instead of I will try to insert my next sketch of receiver in the code field .. and I am wonder on the next result ..

Pavel Ou

I see now … there I see Sign in of my Firefox and Log in (or Sign in) of Forum … but I do not see Log Out (or Sign out), I am sorry …

…there is my sketch for ESP-NOW reseiver as ‘‘ a tank’’ … and I try to add it as code into a code field :

//ESP8266_now_receiver_AD174_po_17_tank_en.ino
// some as a tank controlled with two joysticks
// used GPIO for ESP8266 NodeMCU V1.0
// ESP Board MAC Address:  50:02:91:EF:E6:06 NodeMCU V1.0 po
/*
  Thanks to Rui Santos & Sara Santos and their Random Nerd Tutorials
  Complete ESP-NOW details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/  
  Permission is hereby granted, free of charge, to any person obtaining 
  a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included 
  in all copies or substantial portions of the Software.
*/
// reprogrammed for my AD174 with ESP8266 NodeMCU V1.0 by PavelOu

#include <ESP8266WiFi.h>
#include <espnow.h>

//bool serialOn = false;
String sketchName = "ESP8266_now_receiver_AD174_po_17_tank_en.ino";

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message 
 {
  int dataR;
  int dataL;
  int dataSW;
 } struct_message;

 // Create a struct_message called myData
struct_message myData;

long int timeLast = 0;
int timeOut = 1000;

bool dataOn = false;
//byte  = 0;

bool joystickCalibration = false;
bool carOn = false;
bool blinkOn = false;

//byte minLed = 1;
//byte carDirectFB = 0;

//definition from AD174 are changed for NodeMcu V1.0
int gpLF = 13; // Left forward  D7  // Two wheels left forward
int gpLB = 14; // Left back     D5  // Two wheels left backward

int gpRF = 15; // Right forward D8  // Two wheels right forward 
int gpRB = 12; // Right back    D6  // Two wheels right backward

int motoryR = 4;   // Enable Right  D2  // PWM from 0 to 255
int motoryL = 5;   // Enable Left   D1  // PWM from 0 to 255

int carPowerOnLed = 2; // D4 data off LED_BUILT_IN reversed level
int carDataOnLed = 2;   // D4 - " -
int carOnLed = 16; // D0  indikace car on

//NodeMCU free outputs for Leds
//GPIO00 = D3 = Flash Output
//GPIO16 = D0 = Wake
//GPIO02 = D4 = Output + LED_BUILTIN, too

const byte carStop = 0;
byte speedMax = 235;
int carDirectLFB = 0;
int carDirectRFB = 0;


int carSW = 0;  // = 0 = carOff , = 1 carOn
int osaR = 0;   // axe R = speed Right
int osaRzero = 2200;
int osaRtolerance = 80;
int osaL = 0; // axe L = speed Left
int osaLzero = 2200;
int osaLtolerance = 80;
int osaLFB = 0;  // recounted on position value speedL
int osaRFB = 0;  // - " -

// rychlosti pro motory
byte speedL = 0;
byte speedR = 0;

void InitMotors() //changed from AD174
{
  pinMode(gpLF, OUTPUT); //Left Wheels Forward
  pinMode(gpLB, OUTPUT); //Left Wheels Backward
  pinMode(gpRB, OUTPUT); //Right Wheels Forward
  pinMode(gpRF, OUTPUT); //Right WheelsBackward

  digitalWrite(gpLF, LOW);
  digitalWrite(gpLB, LOW);
  digitalWrite(gpRF, LOW);
  digitalWrite(gpRB, LOW);

  pinMode(motoryL, OUTPUT);
  pinMode(motoryR, OUTPUT);

  digitalWrite(motoryL, 0);
  digitalWrite(motoryR, 0);
}

void CarSim()
 {
   Serial.println("Car test stop");
   digitalWrite(gpLF,LOW);  //set gpLF high level
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpRF,LOW); //set gpRF high level
   analogWrite(motoryR,0);
   analogWrite(motoryL,0);
   delay(1000);
   Serial.println("Car test acceleration");
   for(int i = 0; i <= speedMax; i++)
    { 
     analogWrite(motoryL,i);
     analogWrite(motoryR,i);
     delay(10);
    } 
   //delay(1000);
   Serial.println("Car reduce speed");
   for(int i = speedMax; i >= 0; i--)
    { 
     analogWrite(motoryL,i);
     analogWrite(motoryR,i);
     delay(10);
    } 
   Serial.println("Car is stopped");
   digitalWrite(gpLF,LOW);  //set gpLF high level
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpRF,LOW); //set gpRF high level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   analogWrite(motoryL,0);
   analogWrite(motoryR,0);
   delay(1000);
 }
 
void CarTest()
  {
   // put your main code here, to run repeatedly
   Serial.println("Car will goes forward");
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpLF,HIGH);  //set gpLF high level
   digitalWrite(gpRF,HIGH); //set gpRF high level
   //accelerate
   for(int i = 0; i <= speedMax; i++)
    { 
     analogWrite(motoryL,i);
     analogWrite(motoryR,i);
     delay(10);
    } 
   //delay(1000);
   //Reduce speed
   for(int i = speedMax; i >= 0; i--)
    { 
     analogWrite(motoryL,i);
     analogWrite(motoryR,i);
     delay(10);
    } 
   Serial.println("Car will  stop");
   digitalWrite(gpLF,LOW);  //set gpLF high level
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpRF,LOW); //set gpRF high level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   analogWrite(motoryL,0);
   analogWrite(motoryR,0);
   delay(1000);

   Serial.println("Car will goes backward");
   digitalWrite(gpLF,LOW);  //set gpLF high level
   digitalWrite(gpRF,LOW); //set gpRF high level
   digitalWrite(gpLB,HIGH); //set gpLB Low level
   digitalWrite(gpRB,HIGH);  //set gpRB Low level
   //accelerate
   for(int i = 0; i <= speedMax; i++)
    { 
     analogWrite(motoryL,i);
     analogWrite(motoryR,i);
     delay(10);
    } 
   //delay(2000);
   //Reduce speed
   for(int i = speedMax; i >= 0; i--)
    { 
     analogWrite(motoryL,i);
     analogWrite(motoryR,i);
     delay(10);
    } 
   // car will  stop
   Serial.println("Car will  stop");
   digitalWrite(gpLF,LOW);  //set gpLF high level
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpRF,LOW); //set gpRF high level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   analogWrite(motoryL,0);
   analogWrite(motoryR,0);
   delay(1000); 
  }

void MoveCar(byte newDirect)  //for variant of receiver one and two
 {
  if (newDirect == 0)   //stop
   {
    //Serial.println("Car will stop");
    digitalWrite(gpLB,LOW); //set gpLB Low level
    digitalWrite(gpRB,LOW);  //set gpRB Low level
    digitalWrite(gpLF,LOW);  //set gpLF high level
    digitalWrite(gpRF,LOW); //set gpRF high level   
    analogWrite(motoryR,0);
    analogWrite(motoryL,0);
       
   }
  if (newDirect == 1)   //forward
   {
    //Serial.println("Car will goes forward");
    digitalWrite(gpLB,LOW); //set gpLB Low level
    digitalWrite(gpRB,LOW);  //set gpRB Low level
    digitalWrite(gpLF,HIGH);  //set gpLF high level
    digitalWrite(gpRF,HIGH); //set gpRF high level  
    //digitalWrite(carBackLed,LOW);    
   }
  if (newDirect == 2)  //bacward
   {
    //Serial.println("Car will goes backward");
    digitalWrite(gpLB,HIGH); //set gpLB Higy level
    digitalWrite(gpRB,HIGH);  //set gpRB High level
    digitalWrite(gpLF,LOW);  //set gpLF Low level
    digitalWrite(gpRF,LOW); //set gpRF LOW level         
    //digitalWrite(carBackLed,HIGH);    
   }
  if (newDirect == 3)  //turn left
   {
    Serial.println("Car will turn left");
    digitalWrite(gpLB,HIGH); //set gpLB Higy level
    digitalWrite(gpRB,LOW);  //set gpRB High level
    digitalWrite(gpLF,LOW);  //set gpLF Low level
    digitalWrite(gpRF,HIGH); //set gpRF LOW level         
   }
  if (newDirect == 4)  //turn right
   {
    Serial.println("Car will turn right");
    digitalWrite(gpLB,LOW); //set gpLB Higy level
    digitalWrite(gpRB,HIGH);  //set gpRB High level
    digitalWrite(gpLF,HIGH);  //set gpLF Low level
    digitalWrite(gpRF,LOW); //set gpRF LOW level         
   }
  }
  
void MoveLeftWheels(int directLW) //for third variant of receiver 
 {
  if (directLW == 1)
   {
     //Serial.println("Car will goes forward");
    digitalWrite(gpLF,HIGH);  //set gpLF high level
    digitalWrite(gpLB,LOW); //set gpLB low level     
   }
  if (directLW == 0)
   {
      //Serial.println("Car will goes forward");
    digitalWrite(gpLF,LOW); //set gpLF Low level
    digitalWrite(gpLB,LOW);  //set gpLB Low level
   }
  if (directLW == -1)
   {
    digitalWrite(gpLF,LOW);  //set gpLF low level
    digitalWrite(gpLB,HIGH); //set gpLB high level  
   }
 }  

void MoveRightWheels(int directRW)  //for third variant of receiver 
 {
  if (directRW == 1)
   {
     //Serial.println("Car will goes forward");
    digitalWrite(gpRF,HIGH);  //set gpRF high level
    digitalWrite(gpRB,LOW); //set gpRB high level     
   }
  if (directRW == 0)
   {
      //Serial.println("Car will goes forward");
    digitalWrite(gpRF,LOW); //set gpRF Low level
    digitalWrite(gpRB,LOW);  //set gpRB Low level
   }
  if (directRW == -1)
   {
    digitalWrite(gpRF,LOW);  //set gpRF low level
    digitalWrite(gpRB,HIGH); //set gpRB high level  
   }
 }  

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
 {
  memcpy(&myData, incomingData, sizeof(myData));
  osaR = myData.dataR; // speedR = speed right wheels
  osaL = myData.dataL; // speedL = speed left wheels
  carSW = myData.dataSW;
  dataOn = true;
  digitalWrite(carDataOnLed,HIGH); 
  if (carSW == 0)
   { 
       carOn = false;
       joystickCalibration = false;           
       digitalWrite(carOnLed,LOW); 
    }
  if (carSW == 1) 
   {
     if (!carOn)
        {
         if (!joystickCalibration)
          {
           osaLzero = osaL;
           osaRzero = osaR;
           joystickCalibration = true;
          }
         carOn = true;
         digitalWrite(carOnLed,HIGH); 
       }
   }  
  analogWriteResolution(8);
        
  carDirectLFB = 0;
  osaLFB = osaL - osaLzero;
  if (osaLFB<0)  // Y < 0 = left wheels Backward
      {
       osaLFB = osaLzero - osaL;
       if (osaLFB > osaLtolerance)  // axe Y < 0 = carBackward
        {
         carDirectLFB = -1;
        }
      }  
     else
      {
       if (osaLFB > osaLtolerance)  // carForward
        {
         carDirectLFB = 1;
        }
      }  
     MoveLeftWheels(carDirectLFB);          

     int speedintL = map(osaLFB,0,osaLzero,0,speedMax);
     speedL = constrain(speedintL,0,speedMax);
     
     carDirectRFB = 0;
     osaRFB = osaR - osaRzero;
     if (osaRFB<0)  // X < 0 = right  wheels go backward
      {
       osaRFB = osaRzero - osaR;
       if (osaRFB > osaRtolerance)  // speed RFB > tolerance
        {
         carDirectRFB = -1;
        }
      }  
     else
      {
       if (osaRFB > osaRtolerance)  // car wheels right go forward
        {
         carDirectRFB = 1;
        }
      }  
     MoveRightWheels(carDirectRFB);          

    int speedintR = map(osaRFB,0,osaRzero,0,speedMax);
    speedR = constrain(speedintR,0,speedMax);
  if (carOn)
   {          
    analogWrite(motoryL,speedL); 
    analogWrite(motoryR,speedR);
   }     
  else
   {
     //MoveCar(carDirectFB);
     carDirectLFB = carStop;
     MoveLeftWheels(carDirectLFB);          
     carDirectRFB = carStop;
     MoveRightWheels(carDirectRFB);          

     analogWrite(motoryL,0);
     analogWrite(motoryR,0);
   }
  timeLast = millis(); 
 }
 
void setup() 
 {
  // Initialize Serial Monitor
  Serial.begin(9600);
  delay(1000);
  //before using io pin, pin mode must be set first 
  Serial.println(sketchName);
  InitMotors();
  //pinMode(espnowLED, OUTPUT);
  pinMode(carOnLed, OUTPUT);
  pinMode(carDataOnLed, OUTPUT);
  pinMode(carPowerOnLed, OUTPUT);
  //delay(1000);
  Serial.println("ESP8266_now_receiver_AD174_po_10.ino");
  Serial.println("Test of outputs - indication:");  
  digitalWrite(carPowerOnLed,LOW); // reversed levels built in Led
  delay(1000);
  digitalWrite(carPowerOnLed,HIGH); // - " -
  delay(1000);
  digitalWrite(carDataOnLed,HIGH); 
  delay(1000);
  digitalWrite(carDataOnLed,LOW); 
  delay(1000);
  digitalWrite(carOnLed,HIGH); 
  delay(1000);
  digitalWrite(carOnLed,LOW); 
  delay(1000);
  Serial.println("Test motoru");
  //CarTest();
  analogWriteResolution(8);
  CarSim();
     
  Serial.println("Preliminary calibration of joystick ");
  //osaR = analogRead(motoryL);
  Serial.print("osaLzero: ");
  Serial.println(osaLzero);  // speed left zero
  Serial.print("osaRzero: ");
  Serial.println(osaRzero);  // speed right zero

  //speedY = 1;
  //speedX = 1;
  speedL = 1;
  speedR = 1;
  //speedLR = 1;
  carOn = false;
  joystickCalibration = false;
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) 
   {
    Serial.println("Error initializing ESP-NOW");    
    //digitalWrite(espnowLED,HIGH);
    return;
   }
  else
   {
       digitalWrite(carPowerOnLed,LOW); // reversed level
       Serial.println("ESP-NOW is initialized");    
   }

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
  //timeLast = millis();
  digitalWrite(carDataOnLed,LOW);
  digitalWrite(carOnLed,LOW);
  Serial.println("There is end of serial communication for work in better real time");
  delay(5000);
 }
 
void loop() 
 {
  long int timeActual = millis() - timeLast;
  if (timeActual > timeOut)
   {
    // watch dog
    if (!dataOn)
     {
      digitalWrite(carDataOnLed,LOW);
     }
    else
     {
      dataOn = false;
     }
    timeLast = millis();
   }
 }  
 

… and I see it seems to be well …

Maybe someone can be more interested in the variant of sender with one joystick for the control of AD174 car in two axes Y for speed and X for correction of direct move or with joystick wit axe Y for speed and potenciometer for axe X as a fancy ruller . So the sketch for both this variants is here :

//ESP8266_now_receiver_AD174_po_10_en.ino
//changed from ESP32-NOW for ESP8266-NOW
// used GPIO for ESP8266 NodeMCU V1.0
// ESP Board MAC Address:  50:02:91:EF:E6:06 NodeMCU V1.0 po

/*
  Thanks to Rui Santos & Sara Santos and their  Random Nerd Tutorials
  Complete project details at https://RandomNerdTutorials.com/esp-now-esp32-arduino-ide/  
  Permission is hereby granted, free of charge, to any person obtaining 
  a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included 
  in all copies or substantial portions of the Software.
*/
// programmed for my AD174 car by PavelOu
// version for my first and second variant with one PS2 or PS4 joystick or fancy ruller

#include <ESP8266WiFi.h>
#include <espnow.h>


const byte carStop = 0;
const byte carForward = 1;
const byte carBackward = 2;
const byte carTurnLeft = 3;
const byte carTurnRight = 4;

const byte carLeft = 1;
const byte carRight = 2;

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message 
 {
  int dataX;
  int dataY;
  int dataSW;
 } struct_message;

 // Create a struct_message called myData
struct_message myData;


long int timeLast = 0;
int timeOut = 1000;

bool dataOn = false;
byte carDirectLR = 0;

bool joystickCalibration = false;
bool carOn = false;
bool blinkOn = false;

byte minLed = 1;
byte carDirectFB = 0;

//definition  from AD174 changed for NodeMcu V1.0
int gpLB = 14; // Left back     D5  // Two wheels left backward
int gpLF = 13; // Left forward  D7  // Two wheels left forward
int gpRB = 12; // Right back    D6  // Two wheels right backward
int gpRF = 15; // Right forward D8  // Two wheels right forward

int motoryR = 4;   // Enable Right  D2  // PWM from 0 to 255
int motoryL = 5;  // Enable Left    D1  // PWM from 0 to 255

//int carBackLed = 0;  // D3 backward light pulled up for flash
int carBackLed = 1;  // TX backward light pulled up for boot
int carDataOnLed = 2; // D4 data off LED_BUILT_IN
int carOnLed = 16; // D0  indication car on


int carSW = 0;  // = 0 = carOff , = 1 carOn
int osaX = 0;   // axe X
int osaXzero = 2200;
int osaXtolerance = 80;
int osaXLR = 0;  // prepocten
int osaY = 0;    // axe Y
int osaYzero = 2200;
int osaYtolerance = 50;
int osaYFB = 0;  // recounted on position value

// rychlosti rozlozene do os
byte speedY = 0;
byte speedX = 0;

// speeds for motors
byte speedL = 0;
byte speedR = 0;

// diameter for Led from speedL and speedR
byte speedLR = 1; // 1 - 255


void InitMotors() // changed names from AD174
{
  pinMode(gpLB, OUTPUT); //Left Backward
  pinMode(gpLF, OUTPUT); //Left Forward
  pinMode(gpRB, OUTPUT); //Right Forward
  pinMode(gpRF, OUTPUT); //Right Backward

  digitalWrite(gpLF, LOW);
  digitalWrite(gpLB, LOW);
  digitalWrite(gpRF, LOW);
  digitalWrite(gpRB, LOW);

  pinMode(motoryR, OUTPUT);
  pinMode(motoryL, OUTPUT);

  digitalWrite(motoryR, 0);
  digitalWrite(motoryL, 0);
}

void CarSim()
 {
   Serial.println("Car test stop");
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpLF,LOW);  //set gpLF Hight level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpRF,LOW); //set gpRF Hight level
   analogWrite(motoryR,0);
   analogWrite(motoryL,0);
   delay(1000);
   Serial.println("Car test acceleration");
   for(int i = 0; i <= 235; i++)
    { 
     analogWrite(motoryR,i);
     analogWrite(motoryL,i);
     delay(10);
    } 
   //delay(1000);
   Serial.println("Car reduce speed");
   for(int i = 235; i >= 0; i--)
    { 
     analogWrite(motoryR,i);
     analogWrite(motoryL,i);
     delay(10);
    } 
   Serial.println("Car is stopped");
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpLF,LOW);  //set gpLF Hight level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpRF,LOW); //set gpRF Hight level
   analogWrite(motoryR,0);
   analogWrite(motoryL,0);
   delay(1000);
 }
 
void CarTest()
  {
   // put your main code here, to run repeatedly
   Serial.println("Car will goes forward");
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpLF,HIGH);  //set gpLF Hight level
   digitalWrite(gpRF,HIGH); //set gpRF Hight level
   //accelerate
   for(int i = 0; i <= 235; i++)
    { 
     analogWrite(motoryR,i);
     analogWrite(motoryL,i);
     delay(10);
    } 
   //delay(1000);
   //Reduce speed
   for(int i = 235; i >= 0; i--)
    { 
     analogWrite(motoryR,i);
     analogWrite(motoryL,i);
     delay(10);
    } 
   Serial.println("Car will  stop");
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpLF,LOW);  //set gpLF Hight level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpRF,LOW); //set gpRF Hight level
   analogWrite(motoryR,0);
   analogWrite(motoryL,0);
   delay(1000);

   Serial.println("Car will goes backward");
   digitalWrite(gpLB,HIGH); //set gpLB Low level
   digitalWrite(gpRB,HIGH);  //set gpRB Low level
   digitalWrite(gpLF,LOW);  //set gpLF Hight level
   digitalWrite(gpRF,LOW); //set gpRF Hight level
   //accelerate
   for(int i = 0; i <= 235; i++)
    { 
     analogWrite(motoryR,i);
     analogWrite(motoryL,i);
     delay(10);
    } 
   //delay(2000);
   //Reduce speed
   for(int i = 235; i >= 0; i--)
    { 
     analogWrite(motoryR,i);
     analogWrite(motoryL,i);
     delay(10);
    } 
   // car will  stop
   Serial.println("Car will  stop");
   digitalWrite(gpLB,LOW); //set gpLB Low level
   digitalWrite(gpLF,LOW);  //set gpLF Hight level
   digitalWrite(gpRB,LOW);  //set gpRB Low level
   digitalWrite(gpRF,LOW); //set gpRF Hight level
   analogWrite(motoryR,0);
   analogWrite(motoryL,0);
   delay(1000); 
  }

void MoveCar(byte newDirect)
 {
  if (newDirect == 0)   //stop
   {
    //Serial.println("Car will stop");
    digitalWrite(gpLB,LOW); //set gpLB Low level
    digitalWrite(gpRB,LOW);  //set gpRB Low level
    digitalWrite(gpLF,LOW);  //set gpLF Hight level
    digitalWrite(gpRF,LOW); //set gpRF Hight level   
    analogWrite(motoryR,0);
    analogWrite(motoryL,0);
       
   }
  if (newDirect == 1)   //forward
   {
    //Serial.println("Car will goes forward");
    digitalWrite(gpLB,LOW); //set gpLB Low level
    digitalWrite(gpRB,LOW);  //set gpRB Low level
    digitalWrite(gpLF,HIGH);  //set gpLF Hight level
    digitalWrite(gpRF,HIGH); //set gpRF Hight level  
    digitalWrite(carBackLed,LOW);    
   }
  if (newDirect == 2)  //bacward
   {
    //Serial.println("Car will goes backward");
    digitalWrite(gpLB,HIGH); //set gpLB Higy level
    digitalWrite(gpRB,HIGH);  //set gpRB High level
    digitalWrite(gpLF,LOW);  //set gpLF Low level
    digitalWrite(gpRF,LOW); //set gpRF LOW level         
    digitalWrite(carBackLed,HIGH);    
   }
  if (newDirect == 3)  //turn left
   {
    Serial.println("Car will turn left");
    digitalWrite(gpLB,HIGH); //set gpLB Higy level
    digitalWrite(gpRB,LOW);  //set gpRB High level
    digitalWrite(gpLF,LOW);  //set gpLF Low level
    digitalWrite(gpRF,HIGH); //set gpRF LOW level         
   }
  if (newDirect == 4)  //turn right
   {
    Serial.println("Car will turn right");
    digitalWrite(gpLB,LOW); //set gpLB Higy level
    digitalWrite(gpRB,HIGH);  //set gpRB High level
    digitalWrite(gpLF,HIGH);  //set gpLF Low level
    digitalWrite(gpRF,LOW); //set gpRF LOW level         
   }
  }


// callback function that will be executed when data is received
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) 
 {
  memcpy(&myData, incomingData, sizeof(myData));
  osaX = myData.dataX;
  osaY = myData.dataY;
  carSW = myData.dataSW;
  //timeLast = millis();
  dataOn = true;
  digitalWrite(carDataOnLed,LOW); // reversed level built in
  if (carSW == 0)
   { 
       carOn = false;
       joystickCalibration = false;           
       digitalWrite(carOnLed,LOW); 
       digitalWrite(carBackLed,LOW);    
    }
  if (carSW == 1) 
   {
     if (!carOn)
        {
         if (!joystickCalibration)
          {
           osaYzero = osaY;
           osaXzero = osaX;
           joystickCalibration = true;
          }         
         carOn = true;
         //Serial.println("carOn = true");
         digitalWrite(carOnLed,HIGH); 
       }
   }  
  analogWriteResolution(8);
      
  carDirectFB = 0;
  osaYFB = osaY - osaYzero;
  if (osaYFB<0)  // Y < 0 = carBackward
      {
       osaYFB = osaYzero - osaY;
       if (osaYFB > osaYtolerance)  // Y < 0 = carBackward
        {
         carDirectFB = carBackward;
        }
      }  
     else
      {
       if (osaYFB > osaYtolerance)  // carForward
        {
         carDirectFB = carForward;
        }
      }  
     MoveCar(carDirectFB);          

     int speedintY = map(osaYFB,0,osaYzero,0,235);
     speedY = constrain(speedintY,0,235);
     
     carDirectLR = 0;        
     osaXLR = osaX - osaXzero;
     if (osaXLR < 0)
      {
       osaXLR = osaXzero - osaX; 
       if (osaXLR > osaXtolerance) // car turn left
        {
          carDirectLR = carLeft;
        }
      }
     else
      {
       if (osaXLR > osaXtolerance) // car turn right
        {
          carDirectLR = carRight;
        }
      }    
    
    int speedintX = map(osaXLR,0,osaXzero,0,235);
    speedX = constrain(speedintX,0,235);

    if (carDirectLR == 0) // car will go direct forward or backward
        {
         speedL = speedY;
         speedR = speedY;
        }
    if (carDirectLR == carLeft)   //car will turn left
           { 
            speedR = speedY;
            if (speedY > speedX)
             {
               speedL = speedY - speedX;
             }
            else
             {
              speedL = 1;
             } 
            if (speedL < 2)
             {
              speedL = 1;
             }
           }
           
    if (carDirectLR == carRight)   //car will turn right
           {
            speedL = speedY;
            if (speedY > speedX)
             {
              speedR = speedY - speedX;
             }
            else
             {
              speedR = 1;
             } 
            if (speedR < 2)
             {
              speedR = 1;
             }
           }
  
  if (carOn)
   {          
    analogWrite(motoryR,speedR);
    analogWrite(motoryL,speedL); 
   }     
  else
   {
     carDirectFB = carStop;
     MoveCar(carDirectFB);
     analogWrite(motoryL,0);
     analogWrite(motoryR,0);
   }
  timeLast = millis();  
 }
 
void setup() 
 {
  // Initialize Serial Monitor
  Serial.begin(9600);
  delay(1000);
  //before using io pin, pin mode must be set first 
  analogWriteResolution(8);
  InitMotors();
  //pinMode(espnowLED, OUTPUT);
  pinMode(carOnLed, OUTPUT);
  pinMode(carDataOnLed, OUTPUT);
  delay(1000);
  Serial.println("ESP8266_now_receiver_AD174_po_10.ino");
  Serial.println("Test of outputs - indication:");  
  digitalWrite(carOnLed,HIGH);
  delay(1000);
  digitalWrite(carOnLed,LOW); // reversed levels
  delay(1000);
  Serial.println("Test of motors");
  //CarTest();
  CarSim();
     
  Serial.println("Preliminary calibration of joystick ");
  Serial.print("osaXzero: ");
  Serial.println(osaXzero);
  Serial.print("osaYzero: ");
  Serial.println(osaYzero);

  speedY = 1;
  speedX = 1;
  speedL = 1;
  speedR = 1;
  speedLR = 1;
  carOn = false;
  joystickCalibration = false;
  
  // Set device as a Wi-Fi Station
  WiFi.mode(WIFI_STA);

  // Init ESP-NOW
  if (esp_now_init() != 0) 
   {
    Serial.println("Error initializing ESP-NOW");    
    return;
   }
  else
   {
       digitalWrite(carDataOnLed,LOW);
       Serial.println("ESP-NOW is initialized");    
   }
  
  
  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(esp_now_recv_cb_t(OnDataRecv));
  delay(5000);
  digitalWrite(carDataOnLed,HIGH);
  Serial.println("There is end of serial communication for work in better real time");
  delay(1000);  
  pinMode(carBackLed, OUTPUT);
  digitalWrite(carBackLed,HIGH);
  }
 
void loop() 
 {
  int timeActual = millis() - timeLast;
  if (timeActual > timeOut)
   {
    if (!dataOn)
     {
      digitalWrite(carDataOnLed,HIGH);
     }
    else
     {
      dataOn = false;
     }
    timeLast = millis();
   }
 }