diff --git a/espnow example/espnow_receiver_servo_dc_motor/espnow_receiver_servo_dc_motor.ino b/espnow example/espnow_receiver_servo_dc_motor/espnow_receiver_servo_dc_motor.ino new file mode 100644 index 0000000..97a7d36 --- /dev/null +++ b/espnow example/espnow_receiver_servo_dc_motor/espnow_receiver_servo_dc_motor.ino @@ -0,0 +1,58 @@ +#include "header.h" + +void setup() { + + // Initialize Serial Monitor + Serial.begin(115200); + + // Set device as a Wi-Fi Station + WiFi.mode(WIFI_STA); + + // Initialize ESP-NOW + if (esp_now_init() != ESP_OK) { + Serial.println("Error initializing ESP-NOW"); + return; + } + + // Register callback function to receive data + esp_now_register_recv_cb(OnDataRecv); + + // Allow allocation of all timers + ESP32PWM::allocateTimer(0); + ESP32PWM::allocateTimer(1); + ESP32PWM::allocateTimer(2); + ESP32PWM::allocateTimer(3); + + if(!servo1.attached()) { + servo1.setPeriodHertz(50); // standard 50 hz servo + servo1.attach(13, 1000, 2000); // Attach the servo after it has been detatched + } + servo1.write(servo1_init); + + if(!servo2.attached()) { + servo2.setPeriodHertz(50); // standard 50 hz servo + servo2.attach(12, 1000, 2000); // Attach the servo after it has been detatched + } + servo2.write(servo2_init); + + // Motor 1 Speeds + motor1.setMin(50); + motor1.setMax(255); + + // Motor 2 Speeds + motor2.setMin(50); + motor2.setMax(255); + + // Initialize Motors + motor1.begin(); + motor2.begin(); + + Serial.println("Receiver ready. Waiting for data..."); + +} + +void loop() { + + + +} diff --git a/espnow example/espnow_receiver_servo_dc_motor/header.h b/espnow example/espnow_receiver_servo_dc_motor/header.h new file mode 100644 index 0000000..4b4e976 --- /dev/null +++ b/espnow example/espnow_receiver_servo_dc_motor/header.h @@ -0,0 +1,118 @@ +//========================================================================== +// ESP32 SERVO +//========================================================================== + + // Servo Library + #include "ESP32Servo.h" + + // Servo Pins + #define SERVO1_PIN 13 + #define SERVO2_PIN 12 + + // Servo Objects + Servo servo1; + Servo servo2; + + // Constants + #define servo1_min 52 + #define servo1_max 134 + #define servo1_init 97 + + // Constants + #define servo2_min 52 + #define servo2_max 140 + #define servo2_init 95 + + +//========================================================================== +// ESPNOW +//========================================================================== + + // Libraries + #include "l298n_esp32.h" + + // Motor 1 Pins + #define MOTOR1_PIN1 27 + #define MOTOR1_PIN2 26 + #define MOTOR1_ENABLE 14 + + // Motor 2 Pins + #define MOTOR2_PIN1 25 + #define MOTOR2_PIN2 33 + #define MOTOR2_ENABLE 32 + + // Motor State + enum MotorState { + STOPPED, + FORWARD_M1, + BACKWARD_M1, + FORWARD_M2, + BACKWARD_M2 + }; + + // Motor Variables + MotorState currentMotorState = STOPPED; + unsigned long motorStateStartTime = 0; + const unsigned long MOTOR_ACTION_DELAY = 5000; // Delay between motor actions + + // Motor Objects + L298N_ESP32 motor1(MOTOR1_PIN1, MOTOR1_PIN2, MOTOR1_ENABLE, 0); + L298N_ESP32 motor2(MOTOR2_PIN1, MOTOR2_PIN2, MOTOR2_ENABLE, 1); + +//========================================================================== +// ESPNOW +//========================================================================== + + #include + #include + + // Structure example to receive data + // Must match the sender structure + typedef struct struct_message { + int x; + int y; + bool b; + } struct_message; + + // Create a struct_message called myData + struct_message myData; + + // Callback function that will be executed when data is received + void OnDataRecv(const esp_now_recv_info_t *esp_now_info, const uint8_t *incomingData, int len) { + + // Copy incoming data into the myData structure + memcpy(&myData, incomingData, sizeof(myData)); + + // Processing X + int x = map(myData.x, -100, 100, servo1_min, servo1_max); + // Serial.print(myData.x); + servo1.write(x); + Serial.print(x); + Serial.print(" "); + + // Processing Y + int y = myData.y; + if(y < 11 && y > -11) { + y = 0; + motor1.stop(); + motor2.stop(); + } else if(y >= 11 && y <= 100) { + y = map(y, 11, 100, 0, 255); + motor1.backward(); + motor2.backward(); + motor1.setPercentage(abs(y)); + motor2.setPercentage(abs(y)); + } else if(y <= -11 && y >= -100) { + y = map(y, -11, -100, 0, 255); + motor1.forward(); + motor2.forward(); + motor1.setPercentage(abs(y)); + motor2.setPercentage(abs(y)); + } + Serial.print(y); + Serial.print(" "); + + // Processing Button + Serial.println(myData.b); + + } diff --git a/espnow example/espnow_receiver_servo_dc_motor/l298n_esp32.h b/espnow example/espnow_receiver_servo_dc_motor/l298n_esp32.h new file mode 100644 index 0000000..3086e24 --- /dev/null +++ b/espnow example/espnow_receiver_servo_dc_motor/l298n_esp32.h @@ -0,0 +1,102 @@ + +#ifndef L298N_ESP32_h +#define L298N_ESP32_h + +#include + +class L298N_ESP32 { +private: + uint8_t in1Pin; + uint8_t in2Pin; + uint8_t enPin; + uint8_t pwmChannel; + uint8_t _speed; + uint8_t _min_speed = 0; + uint8_t _max_speed = 255; + bool _invert = false; + + void checkWrite(uint8_t value) { + if (_speed != value) { + _speed = value; + analogWrite(enPin, _speed); + } + } + +public: + L298N_ESP32(uint8_t in1, uint8_t in2, uint8_t en, uint8_t channel = 0) : + in1Pin(in1), in2Pin(in2), enPin(en), pwmChannel(channel), _speed(0) {} + + void begin() { + pinMode(in1Pin, OUTPUT); + pinMode(in2Pin, OUTPUT); + digitalWrite(in1Pin, LOW); + digitalWrite(in2Pin, LOW); + analogWriteResolution(enPin, 8); + analogWriteFrequency(enPin, 2000); + checkWrite(0); + } + + void setMin(uint8_t value) { + _min_speed = value; + } + + void setMax(uint8_t value) { + _max_speed = value; + } + + void invert() { + _invert = !_invert; + } + + void forward() { + if (!_invert) { + digitalWrite(in1Pin, LOW); + digitalWrite(in2Pin, HIGH); + } else { + digitalWrite(in1Pin, HIGH); + digitalWrite(in2Pin, LOW); + } + } + + void backward() { + if (!_invert) { + digitalWrite(in1Pin, HIGH); + digitalWrite(in2Pin, LOW); + } else { + digitalWrite(in1Pin, LOW); + digitalWrite(in2Pin, HIGH); + } + } + + void goMin() { + checkWrite(_min_speed); + } + + void goMax() { + checkWrite(_max_speed); + } + + void setSpeed(uint8_t speed) { + speed = constrain(speed, _min_speed, _max_speed); + checkWrite(speed); + } + + // Modified setPercentage function + void setPercentage(uint8_t percentage) { + percentage = constrain(percentage, 0, 100); + uint8_t speed = map(percentage, 0, 100, _min_speed, _max_speed); + checkWrite(speed); + } + + void override(uint8_t value) { + ledcWrite(pwmChannel, value); + } + + void stop() { + digitalWrite(in1Pin, LOW); + digitalWrite(in2Pin, LOW); + checkWrite(0); + } +}; + +#endif diff --git a/espnow-car/servo_esp32.h b/espnow-car/servo_esp32.h index 60743a7..7b872d2 100644 --- a/espnow-car/servo_esp32.h +++ b/espnow-car/servo_esp32.h @@ -3,23 +3,24 @@ #define Servo_ESP32_h #include + #include class Servo_ESP32 { private: - uint8_t servoPin; - uint8_t pwmChannel; - int minPulseWidth; - int maxPulseWidth; - int currentAngle; - const int freq = 50; // 50Hz for standard servos - const int resolution = 16; // 16-bit resolution for smoother control - bool _invert = false; - uint8_t _min_pos = 0; - uint8_t _max_pos = 180; - uint8_t _init_pos = 90; - uint8_t _prv_pos = 0; + uint8_t servoPin; + uint8_t pwmChannel; + int minPulseWidth; + int maxPulseWidth; + int currentAngle; + const int freq = 50; // 50Hz for standard servos + const int resolution = 16; // 16-bit resolution for smoother control + bool _invert = false; + uint8_t _min_pos = 0; + uint8_t _max_pos = 180; + uint8_t _init_pos = 90; + uint8_t _prv_pos = 0; bool verify(uint8_t input) { if (input != _prv_pos) {