I have an esp32 with an HC-SR04 triggering two servos. Looking for help to seperate HC-SR04 on one esp32 and Servos on a second ESP32 using ESP_NOW


#include <ESP32Servo.h>

#define TRIG_PIN  23  // ESP32 pin GPIO23 connected to Ultrasonic Sensor's TRIG pin
#define ECHO_PIN  19  // ESP32 pin GPIO19 connected to Ultrasonic Sensor's ECHO pin
#define SERVO_PIN1 26  // ESP32 pin GPIO26 connected to Servo Motor's pin
#define SERVO_PIN2 27  // ESP32 pin GPIO27 connected to Servo Motor's pin
#define DISTANCE_THRESHOLD  50 // centimeters

Servo servotop; // create servo object to control a servo
Servo servobot; // create servo object to control a servo

// variables will change:
float duration_us, distance_cm;

void setup() {
  Serial.begin (9600);       // initialize serial port
  pinMode(TRIG_PIN, OUTPUT); // set ESP32 pin to output mode
  pinMode(ECHO_PIN, INPUT);  // set ESP32 pin to input mode
  servotop.attach(SERVO_PIN1);   // attaches the servo on pin 26 to the servo object
  servotop.write(0);
  servobot.attach(SERVO_PIN2);   // attaches the servo on pin 27 to the servo object
  servobot.write(90);
}

void loop() {
  // generate 10-microsecond pulse to TRIG pin
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(1000);
  digitalWrite(TRIG_PIN, LOW);

  // measure duration of pulse from ECHO pin
  duration_us = pulseIn(ECHO_PIN, HIGH);
  // calculate the distance
  distance_cm = 0.017 * duration_us;

  if (distance_cm < DISTANCE_THRESHOLD)
    servotop.write(90); // rotate servo motor to 90 degree

  else

    servotop.write(0);  // rotate servo motor to 0 degree

  
  if (distance_cm < DISTANCE_THRESHOLD)
    servobot.write(90); // rotate servo motor to 90 degree

  else

    servobot.write(0);  // rotate servo motor to 0 degree

  // print the value to Serial Monitor
  Serial.print("distance: ");
  Serial.print(distance_cm);
  Serial.println(" cm");

  delay(500);
}

Please show your best effort on separating the codes.

Just quite can't get my head around it. I'm fairly new to this.

It's taken me a whle to get my head around what I have managed so far. There seems to be loads of ways to achieve same thing.

I'm not asking for finished code just some pointers.

The number can be considered as infinity. Carry on!

This is my best effort so far. I feel like I'm so close but.

ESP32 with HC-SR04 - with a trigger distance of <10 CM sending to second ESP32 with a servo. If distance <10cm on Initiator, servo moves 90 degrees and back to 0 degrees on responder.

//HC-SR04 - output Initiator
#include <WiFi.h>
#include <esp_now.h>
#define TRIG_PIN  23  // ESP32 pin GPIO23 connected to Ultrasonic Sensor's TRIG pin
#define ECHO_PIN  19  // ESP32 pin GPIO22 connected to Ultrasonic Sensor's ECHO pin
#define DISTANCE_THRESHOLD  10 // centimeters

float duration_us, distance_cm;

// Responder MAC Address (Replace with your responders MAC Address)
uint8_t broadcastAddress[] = {0x88, 0x13, 0xbf, 0xdf, 0x15, 0x20};

// Define data structure
typedef struct struct_message {
  float a;
  float b;

} struct_message;

// Create structured data object
struct_message myData;
 
// Register peer
esp_now_peer_info_t peerInfo;
 
// Sent data callback function
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
  Serial.print("Last Packet Send Status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}


void setup() {

    // Setup Serial monitor
  Serial.begin(115200);
  pinMode(TRIG_PIN, OUTPUT); // set ESP32 pin to output mode
  pinMode(ECHO_PIN, INPUT);  // set ESP32 pin to input mode

  // Set ESP32 WiFi mode to Station temporarly
  WiFi.mode(WIFI_STA);
 
  // Initialize ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
 
  // Define callback
  esp_now_register_send_cb(OnDataSent);
 
 
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;
 
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
 
}


void loop() {

  // generate 10-microsecond pulse to TRIG pin
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(1000);
  digitalWrite(TRIG_PIN, LOW);

  // measure duration of pulse from ECHO pin
  duration_us = pulseIn(ECHO_PIN, HIGH);
  // calculate the distance
  distance_cm = 0.017 * duration_us;

  // Add to structured data object
  myData.a = duration_us, distance_cm;
  myData.b = duration_us, distance_cm;
 


  // print the value to Serial Monitor
  Serial.print("distance: ");
  Serial.print(distance_cm);
  Serial.println(" cm");

  delay(500);
}


//servo 90 to 0 by sensor Responder
#include <WiFi.h>
#include <esp_now.h>
#include <ESP32Servo.h>
#define SERVO_PIN 26  // ESP32 pin GPIO26 connected to Servo Motor's pin
#define DISTANCE_THRESHOLD  100 // centimeters

Servo servo; // create servo object to control a servo
// variables will change:
float duration_us, distance_cm;



typedef struct struct_message {
    float a;
    float b;

} struct_message;

// Create structured data object
struct_message myData;

// Callback function
void OnDataRecv(const uint8_t * mac_addr, const uint8_t * data,  int len) 
{
  // Get incoming data
  memcpy(&myData, data, sizeof(myData));

  if (myData.a < DISTANCE_THRESHOLD)
    servo.write(90); // rotate servo motor to 90 degree
  else
    servo.write(0);  // rotate servo motor to 0 degree
  delay(500);

  // print the value to Serial Monitor
  Serial.print("distance: ");
  Serial.println(myData.a);
  Serial.println(" cm");
  Serial.println("");

 } 

void setup() {
  // put your setup code here, to run once:
  // Set up Serial Monitor
  Serial.begin(115200);

 // Start ESP32 in Station mode
  WiFi.mode(WIFI_STA);

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

  // Register callback function
  esp_now_register_recv_cb(OnDataRecv);
}


void loop() {

}



Hi! Welcome to the Forum.

Something looks odd...
I´m not seeing a function to send the data on your "initiator" sketch.

Thanks for the welcome.

I managed to get sensor and servo working on one ESP32 but wanted to split them using eps_now.

I posted my code and asked for help, b707 requested my best efforts, so that's what I have done. I'm new to this and just looking for some help and guidance if available.

Ok!
Try this sketch on the sender:

//HC-SR04 - output Initiator
#include <WiFi.h>
#include <esp_now.h>
#define TRIG_PIN  23  // ESP32 pin GPIO23 connected to Ultrasonic Sensor's TRIG pin
#define ECHO_PIN  19  // ESP32 pin GPIO22 connected to Ultrasonic Sensor's ECHO pin
#define DISTANCE_THRESHOLD  10 // centimeters

float duration_us, distance_cm;

// Responder MAC Address (Replace with your responders MAC Address)
uint8_t broadcastAddress[] = {0x88, 0x13, 0xbf, 0xdf, 0x15, 0x20};

// Define data structure
typedef struct struct_message {
  float a;
  float b;

} struct_message;

// Create structured data object
struct_message myData;
 
// Register peer
esp_now_peer_info_t peerInfo;
 
// Sent data callback function
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
  Serial.print("Last Packet Send Status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}


void setup() {

    // Setup Serial monitor
  Serial.begin(115200);
  pinMode(TRIG_PIN, OUTPUT); // set ESP32 pin to output mode
  pinMode(ECHO_PIN, INPUT);  // set ESP32 pin to input mode

  // Set ESP32 WiFi mode to Station temporarly
  WiFi.mode(WIFI_STA);
 
  // Initialize ESP-NOW
  if (esp_now_init() != 0) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }
 
  // Define callback
  esp_now_register_send_cb(OnDataSent);
 
 
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;
  peerInfo.encrypt = false;
 
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
 
}


void loop() {

  // generate 10-microsecond pulse to TRIG pin
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(1000);
  digitalWrite(TRIG_PIN, LOW);

  // measure duration of pulse from ECHO pin
  duration_us = pulseIn(ECHO_PIN, HIGH);
  // calculate the distance
  distance_cm = 0.017 * duration_us;

  // Add to structured data object
  myData.a = distance_cm;     //line changed
  myData.b = duration_us;       //line changed
 
  esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));  //line added

  // print the value to Serial Monitor
  Serial.print("distance: ");
  Serial.print(distance_cm);
  Serial.println(" cm");

  delay(500);
}
1 Like

Sorry for the delay (shoulder surgery).

Thanks for the updated initiator code! I can now see the required information (distance in cm) being sent/received in the serial monitor on both initiator and responder.

I have the following bit of code on the responder bit it is not triggering the servo.

  // Get incoming data
  memcpy(&myData, data, sizeof(myData));

  if (myData.a < DISTANCE_THRESHOLD)
    servo.write(90); // rotate servo motor to 90 degree
  else
    servo.write(0);  // rotate servo motor to 0 degree
  delay(500);

What else do need for it to work?

The only thing that comes to my mind is that you set on the receiver:

However, in the sender you have:

What is the correct distance threshold?

The distance I have settled on is 50cm. I will set the same on both send and receive and give it a go. I thought it would pick the value up from my data.a and be less then the DISTANCE_THRESHOLD on the responder.

Steep learning curve for me and appreciate your help and time so much. Thank you.

Actually, the threshold distance definition on the sender is useless, because you're not using DISTANCE_THRESHOLD anywhere else on the sender code.

This is what's expected to happen. How's the behaviour of the servo now?

No movement from the servo.

Both DISTANCE_THRESHOLD are set to the same value.

It's working!!!!

I missed out a couple of lines on the responder under

Serial.begin(115200);

servo.attach(SERVO_PIN);  //attach servo on pin
servo.write(0);

Thank you so much again for your help!!!!

1 Like

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