Bought the Ackermann intelligent Chassis. A car chasis with 3 motors.
The steering mechanism uses LD-1501MG servo motor. Tried a lot to get it to work so that the rotor is positioned to an exact position. But it didn't work. But cannot directly position to an angle I want.
Using servo.h tried the servo.write(angle) function to position to exact position. It works only if the angle is incremented or decremented by 1 or a small number. A common sweep script ( sweep.ino - avaialable on the internet) works.since the code increments or decreases the angle by 1.
To add - reached out to the vendor Thinkrobotics/HiWonder. They asked to do lots of tests. Did that. They gave a replacement motor. This replacement motor behaved exactly the same as before. The vendor hasn't responded yet.
Welcome to the forum
Instead of using servo.write() try using servo.writeMicroseconds(). It may give you finer control of the servo angle but that depends on the quality of the sevo
Tried. Didn't work
Tried plenty of scripts. After that only I came to the conclusion that the behaviour of this motor is it works only if the angle is incremented or decremented by 1 or a small number.
So what increments does your sketch use ?
Please post it here, using code tags when you do.
#include <Servo.h>
Servo servo2;
const int servo2Pin = 9;
const int every2 = 15;
int servo2Target = 0;
int servo2Dir = 1;
int posOfServo2 = 90;
void setup() {
servo2.attach(servo2Pin, 500, 2500); // pin9
Serial.begin(9600);
servo2.write(posOfServo2);
delay(500);
}
void loop( ) {
checkServo2();
if (posOfServo2 > 179)
servo2Target = 0;
if (posOfServo2 < 1 )
servo2Target = 180;
}
void checkServo2( ) {
static uint32_t Timer;
if (Timer > millis())
return;
Timer = millis() + every2;
if (servo2Target > posOfServo2) {
posOfServo2 += servo2Dir;
} else if (servo2Target == posOfServo2) {
return;
} else {
posOfServo2 += -servo2Dir;
}
servo2.write(posOfServo2);
}
The above script works without issues. Searching this forum found few had similar issues earlier. But didn't see any one confirm which solution worked. Someone suggested the power may be less and to power the servo directly with 6V and connect battery GND and the Arduino ground. Tried that as well. Didn't work.
Simplified setup. Ground and Vin connected to the motor power terminals.
Pin 9 of Arduino connected to the signal pin of the motor.
Yellow is the usb cable to laptop for programming.
9v Duracell battery connected to the power input of Arduino.
That is your problem.
Why don't you connect it the way Hiwonder recommends.
Use a high current 7.4V battery to power the Uno.
#define servoPin 9
void setup() {
pinMode(servoPin, OUTPUT);
}
void loop() {
// A pulse each 20ms
digitalWrite(servoPin, HIGH);
delayMicroseconds(1450); // Duration of the pusle in microseconds
digitalWrite(servoPin, LOW);
delayMicroseconds(18550); // 20ms - duration of the pusle
// Pulses duration: 600 - 0deg; 1450 - 90deg; 2300 - 180deg
delay(500);
}
Have tried this script and various timings / variations. This is without the servo.h The rotor didn't move at all.
Couldn't get a 7.4v battery. I used 9v and measured the power to the motor and it is around 5v.
Will continue trying to get a 7.4v battery or arduino power adapter.
Did you( or anyone else) face this issue and got it resolved by changing the battery? If yes,will put all efforts to get new battery and not try anything else. Btw, had long to and fro email exchange with Hiwonder support team. Finally they replaced the motor but the new one behaves exactly the same?
Note that the sweep script - posted above works consistently.
That is not a suitable battery for your application as it cannot reliably supply the current required to run a servo for long, if at all.
In passing I note this in your code
Timer = millis() + every2;
It may not matter in this case but that is not the safe way to do timing using millis(). To avoid problems with millis() rollover to zero you should save the time when a period starts and subtract that from the current value of millis() to test whether the required interval has passed. This method works even when millis() rollover occurs
Incidentally, you say that you have a problem positioning the servo at a particular angle but the sketch that you posted does not do that
The servo power must be connected to Vin not the 5V pin.
You must power the Uno with 7.4V.
If you power the Uno with USB or 9V then the servo must be powered separately with a battery or power supply between 6V and 8.4V
Thanks. Can you recommend ideal battery for this?
That was one of the scripts I pasted. I may have tried quite a lot of modifications. A very simple one trying to position to exact position is given below. Have tried lots of variations of this -->
//以15毫秒一步的速度转动
#include <Servo.h>
Servo servo2;
const int servo2Pin = 9; // servo2 接 Pin 9
void setup() {
servo2.attach(servo2Pin); // pin9
Serial.begin(9600);
}
void loop( ) {
servo2.write(100);
delay(1000);
}

