The purpose of the test is to verify the proper operation of a P1L servo. We'll use the common SG90 servo as a reference.
Equipment
1 P1L servo
1 SG90 servo
2 breadboards (830 tie points each)
One 3.3-5v Power Supply Module with power cable
1 BittleX battery
ESP32S microcontroller
ESP32 USB cable
5 male-male black wires
3 male-male red wires
4 male-male green wires
We will control the circuit with an ESP32 sketch that will have both servos "sweep" through positions between 0 and 180. This allows us to compare the P1L behavior with the SG90.
It is worth noting that the circuit uses 3 separate power supplies, USB for the ESP32, 3.3-5v module for the SG90 servo, and tje BittleX Battery for the P1L servo. The voltage requirements of each of tthese devices is different from the others. The ESP32 uses a 3.3 volt, the SG90 uses 4.8 v, and the P1L uses 8v.
First, we add the ESP32 module to the breadboard 1 (on the top). The module is inserted into row 1, columns b and i. This provides a single column of ties on either side of the module (columns a and j) that simplfies locating the GPIO pins.
We add the 3.3-5v power supply to breadboard 2, inserting it on the power rails on the right side, taking the first 5 rows.
To provide a common ground for the circuit we connect the ground rails of the top power rail of each breadboard and add a jumper wire from the ESP32 GND pin to the ground rail of the bottom board
For the SG90 servo connections add a red wire to the power (red) connector, a black wire to the ground (brown) connector, and a green wire to the signal (yellow) connector.
Connect the SG90 power and ground jumper wires to the second breadboard top power rail at row 25. This rail is connected to the 5v output of the power supply.
Connect the SG90 signal jumper wire to row 25, a. This completes the circuit for the SG90 servo.
For the P1L servo, repeat the steps to add jumper wires for power, ground, and signal to the P1L connector.
Connect the P1L power and ground jumper wires to the top breadboard, top power and ground rail at row 35.
Connect the P1L signal jumper wire to the top breadboard at row 35, a
For the battery, add red and black wires to the power (red) and ground (black) connectors
For the SG90 signal, use GPIO pin 32, located at row 13, i. Add a jumper wire that to the top breadboard at row 25,c. This connects the GPIO pin to the SG90 signal wire.
For the P1L signal, use GPIO pin 33 located at row 12, i. Add a jumper wire that to the bottom breadboard at row 25,d. This connects the GPIO pin to the P1L signal wire.
Connect the power lines by connecting the USG to the ESP32, the power cable to the 3.3-5 power module, and the battery to the top power rail red wire to the positive and black wire to the negative rails. The battery connection is not shown in the picture.
The ESP32 sweep sketch to control the servos is an adaptation of a common sketch that "sweeps" the servo back and forth through 180 degrees.
/* Adapted from ..
Sweep
by BARRAGAN
This example code is in the public domain.
modified 8 Nov 2013
by Scott Fitzgerald
modified for the ESP32 on March 2017
by John Bennett
see http://www.arduino.cc/en/Tutorial/Sweep for a description of the original code
* Different servos require different pulse widths to vary servo angle, but the range is
* an approximately 500-2500 microsecond pulse every 20ms (50Hz). In general, hobbyist servos
* sweep 180 degrees, so the lowest number in the published range for a particular servo
* represents an angle of 0 degrees, the middle of the range represents 90 degrees, and the top
* of the range represents 180 degrees. So for example, if the range is 1000us to 2000us,
* 1000us would equal an angle of 0, 1500us would equal 90 degrees, and 2000us would equal 1800
* degrees.
*
* Circuit: (using an ESP32 Thing from Sparkfun)
* Servo motors have three wires: power, ground, and signal. The power wire is typically red,
* the ground wire is typically black or brown, and the signal wire is typically yellow,
* orange or white. Since the ESP32 can supply limited current at only 3.3V, and servos draw
* considerable power, we will connect servo power to the VBat pin of the ESP32 (located
* near the USB connector). THIS IS ONLY APPROPRIATE FOR SMALL SERVOS.
*
* We could also connect servo power to a separate external
* power source (as long as we connect all of the grounds (ESP32, servo, and external power).
* In this example, we just connect ESP32 ground to servo ground. The servo signal pins
* connect to any available GPIO pins on the ESP32 (in this example, we use pin 18.
*
* In this example, we assume a Tower Pro MG995 large servo connected to an external power source.
* The published min and max for this servo is 1000 and 2000, respectively, so the defaults are fine.
* These values actually drive the servos a little past 0 and 180, so
* if you are particular, adjust the min and max values to match your needs.
*/
#include "ESP32Servo.h"
namespace esp32 {
namespace example {
namespace sweep {
// create servo object to control a servo
// 16 servo objects can be created on the ESP32
Servo SG90;
Servo P1L;
int pos{ 0 }; // variable to store the servo position
// Recommended PWM GPIO pins on the ESP32 include
// 2,4,12-19,21-23,25-27,32-33
int SG90_servoPin{ 32 };
int P1L_servoPin{ 33 };
void on_setup() {
Serial.begin(115200);
// Allow allocation of all timers
ESP32PWM::allocateTimer(0);
ESP32PWM::allocateTimer(1);
ESP32PWM::allocateTimer(2);
ESP32PWM::allocateTimer(3);
SG90.setPeriodHertz(50); // standard 50 hz servo
P1L.setPeriodHertz(50); // standard 50 hz servo
// attaches the servo on pin SG90_servoPin to the servo object
// using default min/max of 1000us and 2000us
// different servos may require different min/max settings
// for an accurate 0 to 180 sweep
SG90.attach(SG90_servoPin, 500, 2400);
P1L.attach(P1L_servoPin, 500, 2500);
SG90.write(0);
P1L.write(0);
}
void on_loop() {
Serial.print("Forward\n");
// goes from 0 degrees to 180 degrees
// in steps of 1 degree
for (pos = 0; pos <= 180; pos += 1) {
// tell servo to go to position in variable 'pos'
SG90.write(pos);
P1L.write(pos);
delay(15); // waits 15ms for the servo to reach the position
}
Serial.print("Backward\n");
// goes from 180 degrees to 0 degrees
for (pos = 180; pos >= 0; pos -= 1) {
SG90.write(pos);
P1L.write(pos);
delay(15);
}
}
} // namespace sweep
} // namespace example
} // namespace esp32
using namespace esp32::example::sweep;
void setup() { on_setup(); }
void loop() { on_loop(); }
This produces the output:
Sketch uses 272949 bytes (20%) of program storage space.
Maximum is 1310720 bytes.
Global variables use 21716 bytes (6%) of dynamic memory,
leaving 305964 bytes for local variables. Maximum is 327680 bytes.
If all goes well, then turn the power supply on with the button on the module and the SG90 servo should start to rotate. Turn the battery on by pressing the button and the P1L servo should start rotating.
Test Result
Here's the video of the circuit in action. https://youtube.com/shorts/aSo24Ph85Go?feature=share
The test verification is visual. You should see the servos move, with the SG90 sweeping through ~180 degrees and the P1L servo sweep ~250 degrees. There's a problem with the P1L servo if it doesn't move, or moves in a erratic or jerky manner.
To test additional P1L servos, simply swap the servo out via its jumper wires.
Question: I know that the P1L servo has a large angle of rotation (like 240-270) but clearly the position of the SG90 and the P1L for the same angle don't agree. My question is, "How do I know where the P1L actually servo is when I tell it to move to a n angle?" What's the transform between 180 degree and P1L position?