Hello, I need to work on a project similar to this one: https://www.instructables.com/Simplified-3D-Printed-Animatronic-Dual-Eye-Mechani/, but instead of joystick control, I want it to move randomly. However, I’ve run into a major problem—the program doesn’t work when it reaches void loop
. I hope someone skilled can help me solve this issue. Thank you for your assistance!
Using ESP-32S and PWM PCA9685 and SG90 servo
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
// Adjust the pulse range for SG90 servos
#define SERVOMIN (500) // Minimum pulse for SG90 (corresponding to 0 degrees)
#define SERVOMAX (2500) // Maximum pulse for SG90 (corresponding to 180 degrees)
#define ANGLE_RANGE 60 // Set maximum movement range to 60 degrees
#define CENTER_ANGLE 90 // Set center angle to 90 degrees
int servo0 = 0; // Left-right movement
int servo1 = 1; // Up-down movement
int servo2 = 2; // Left upper eyelid blink
int servo3 = 3; // Right upper eyelid blink
int servo4 = 4; // Left lower eyelid blink
int servo5 = 5; // Right lower eyelid blink
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(60); // Set PWM frequency to 60 Hz
// Calibrate servos to minimum and maximum angles
calibrateServos();
}
void setServoPulse(uint8_t n, double pulse) {
double pulselength = 1000000 / 60 / 4096; // 60Hz, 12-bit resolution
pulse = pulse * 1000 / pulselength; // Convert to pulse width
pwm.setPWM(n, 0, pulse);
}
void calibrateServos() {
Serial.println("Calibrating servos...");
// Calibrate servos to the minimum position
for (int i = 0; i < 6; i++) {
pwm.setPWM(i, 0, SERVOMIN);
}
delay(300); // Shorten delay to reduce calibration time
// Calibrate servos to the maximum position
for (int i = 0; i < 6; i++) {
pwm.setPWM(i, 0, SERVOMAX);
}
delay(300); // Shorten delay to reduce calibration time
// After calibration, return to the center position
for (int i = 0; i < 6; i++) {
pwm.setPWM(i, 0, (SERVOMIN + SERVOMAX) / 2);
}
delay(300); // Shorten delay to reduce calibration time
Serial.println("Calibration complete.");
}
void loop() {
// Display message and start random movements
Serial.println("Starting random movements...");
lookLeftAndRight();
lookUpAndDown();
blinking();
}
void lookLeftAndRight() {
Serial.println("Moving left and right...");
// Set movement range to 60 degrees
int leftLimit = (SERVOMIN + SERVOMAX) / 2 - (ANGLE_RANGE * 11); // Left range
int rightLimit = (SERVOMIN + SERVOMAX) / 2 + (ANGLE_RANGE * 11); // Right range
for (uint16_t pulselen = leftLimit; pulselen < rightLimit; pulselen += random(3, 6)) {
pwm.setPWM(servo0, 0, pulselen); // Set servo pulse width
delay(random(10, 30)); // Random delay
}
for (uint16_t pulselen = rightLimit; pulselen > leftLimit; pulselen -= random(3, 6)) {
pwm.setPWM(servo0, 0, pulselen); // Set servo pulse width
delay(random(10, 30)); // Random delay
}
}
void lookUpAndDown() {
Serial.println("Moving up and down...");
// Set up and down movement range to 60 degrees
int upLimit = (SERVOMIN + SERVOMAX) / 2 - (ANGLE_RANGE * 11); // Upper range
int downLimit = (SERVOMIN + SERVOMAX) / 2 + (ANGLE_RANGE * 11); // Lower range
for (uint16_t pulselen = upLimit; pulselen < downLimit; pulselen++) {
pwm.setPWM(servo1, 0, pulselen); // Set servo pulse width
delay(random(10, 30)); // Random delay
}
for (uint16_t pulselen = downLimit; pulselen > upLimit; pulselen--) {
pwm.setPWM(servo1, 0, pulselen); // Set servo pulse width
delay(random(10, 30)); // Random delay
}
}
void blinking() {
Serial.println("Blinking eyes...");
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(servo2, 0, pulselen); // Left upper eyelid blink
pwm.setPWM(servo3, 0, pulselen); // Right upper eyelid blink
pwm.setPWM(servo4, 0, pulselen); // Left lower eyelid blink
pwm.setPWM(servo5, 0, pulselen); // Right lower eyelid blink
delay(8); // Reduce delay to increase blink speed
}
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(servo2, 0, pulselen); // Left upper eyelid blink
pwm.setPWM(servo3, 0, pulselen); // Right upper eyelid blink
pwm.setPWM(servo4, 0, pulselen); // Left lower eyelid blink
pwm.setPWM(servo5, 0, pulselen); // Right lower eyelid blink
delay(8); // Reduce delay to increase blink speed
}
}