I'm experiencing pretty severe servo twitching in my project. I've done a lot of research on this issue, but I can't find exactly what I need to try to attempt to stop this.
Notes/Ideas:
The voltage in my 'bucks' is set to 5V, but does fluctuate some (+- 0.07V). This is noticeable when checking the voltage PAST my 470uF capacitors, directly where the servo connects.
Per research, I've played with adding a delay in my loop and around the write calls, a delay of 100 in my loop does appear to lessen the twitching. Granted, I have kept / tested 20ms+ delays around the servo write calls. I'd like to avoid the delays as I'm using up a finite state machine. Using a state machine to delay writes did not seem to help it. Am I correct in thinking this must be more due to the buck / 7.5V 3.2A adapter. Oh and, it is a regulated switching adapter -- I can't really find a good regulated-only adapater anywhere yet. Granted, I've been mainly scouring Amazon for items.
Researching, I see mention of using a resistor, but I'm not understanding where or how that would help. Also, I'm not sure I should be looking at the data line or the 5+/Grnd -- I haven't yet grasped how these are 'related'.
I’m powering this with a 7.5V 3.2A DC power supply (regulated switching).
The voltage coming out of the bucks is 5V, but, I didn’t check the amps, I will. The buck unit specs are:
Input voltage: 4.5 V to 28 V; Output voltage: 0.8 V to 20 V
Output current: 3 A (maximum); Conversion efficiency: 92% (maximum)
Output ripple: less than 30 mV; Switching frequency: 1.5 MHz (highest), typically 1 MHz
Below is compilable code:
#include <Servo.h>
#define SERVO_EYE_PIN 9
Servo eye_servo;
int max_ang = 160;
int min_ang = 20;
int ang = 20;
int cur_ang = 20;
unsigned int tick = 1000;
unsigned long tmr;
void setup() {
Serial.begin(9600);
eye_servo.attach(SERVO_EYE_PIN);
tmr = millis();
}
void loop() {
if(getAngle() != cur_ang) {
cur_ang = ang;
eye_servo.write(cur_ang);
delay(52);
}
}
int getAngle() {
if (millis() >= tmr) {
tmr += tick;
ang += 5;
if(ang > max_ang) {
ang = min_ang;
}
}
return ang;
}
Each buck converter must be able to handle the stall current of the servo, and the power supply must be able to handle the total. What are those values?
I'll have an amperage reading in about an hour, but I have a question about that process to ensure I provide proper data: Is this correct: I'll power the entire circuit, but I'll add my multimeter clips inline with the 5V line going from the buck to one of my servos. I'll put the servos through some motion and get a max/min amp reading hopefully. I'll then power it down, reconnect servo A and then run the multimeter inline with servo 2, power it up and get min/max readings there too.
I transposed the mA on the arduino, the arduino is pulling ~74mA — this doesn't seem like a lot knowing the two LEDs (granted, they're at half brightness, but all RGB are used) and the proximity sensor is running on the arduino 5V line.
PWMServo uses PWM signals for immunity to interrupts, which can corrupt the signals generated by the standard Servo library. SoftwareSerial, Adafruit_NeoPixel and DmxSimple are the most common cause of these problems. PWMServo allows use of servo motors when these or other interrupt blocking libraries are required.
A) You forget to connect the negative side of the servo power supply to Arduino Ground.
or
B) You use a library like SoftwareSerial() that often disables interrupts for more than a microsecond.
Turns out it was a conflict with the Servo library and the Adafruit_NeoPixel library or maybe along with a combination of the pins/circuit.
I resolved this, or maybe just mitigated the issue by using this PWMServo library.
If I revisit this issue to dig deeper, I'll post findings.