Hey, having an issue getting smooth control of servos from a nano, using an input from another board. The servos need to turn opposite so the code needs to take the reading from a pin on the Ramps controller and convert it and write the appropriate position to each servo.
Externally powered servos, signals connected to pins D5 and D6, and pin A1 is connected to pwm pin on Ramps 1.4.
The servos jitter and don't move like I want them to. What am I missing?
int inputPin = A1; //pin from ramps with target position
int inputvalue;
int posvalue;
int servo1pos;
int servo2pos;
#include <Servo.h>
Servo servo1;
Servo servo2;
void setup() {
servo1.attach(5);
servo2.attach(6);
servo1.write(90);
servo2.write(90);
inputvalue = 500;
pinMode(A1,INPUT);
}
void loop() {
inputvalue = analogRead(inputPin); //read the state of pin from ramps
posvalue = map(inputvalue, 0, 1023, 0, 180); //convert to angle
servo1pos = posvalue;
servo2pos = 180-posvalue;
servo1.write(servo1pos); //write servo 1 angle
servo2.write(servo2pos); //write servo 2 complimentary angle
}
Ok that makes sense, so I'm not reading the signal from the pwm pin correctly. Using your references, this should be more like how to do it, but still doesn't seem to read the input right. Just programming a value with "servo.Write" works fine, so I just need to translate the pwm input to a value between 0 and 180 for that to work.
I'm using this m-code via ramps to change the pins state.:
Are you seeing values of 0 - 100 for pwm_value? And is it predictable when the values change? Because the code looks fine if those are the real input values.
The puilseIn() function returns the number of microseconds the signal is HIGH not the percent high (duty cycle). A servo signal should be 1000us to 2000us, nominally.
Serial.println(pwm_value);
What range of values does that print return? That range should be in the map() statement.
Ok thanks, I almost have it. The output tops out at 1023-ish when pin is set to 255. It works pretty smooth but the readings fluctuate a little here and there, but with the delay its not too bad, but is there anyway to average them or smooth it somehow? The serial output looks like this:
This is the project, the code controls the gripper for a robotic arm. Final project for school. There is a control pendant to do everything or a pc, or run saved programs from an sd card
OK, my mistake in thinking that the ramps board is sending servo PWM (1000 to 2000 us pulse every 20ms). The M42 command sends analogWrite type PWM (0 to 100% duty cycle at 490Hz or 980Hz).
I can't get a good idea from this article how to code in the full duty cycle. And I can't get options two or three, from the "three ways to read pwm" mentioned above, to work.
Would you be able to show an example of how to add the full duty cycle into my code?
Thanks
That works well, thanks.
I still have the same problem, though, with a slightly varying output. Should I add some kind of averaging code to smooth it out? Or what is the best way to get a more static output? Otherwise the servo jumps here and there, sometime 4 percent all of the sudden.