The control of the servo generally requires a 20ms timing pulse, where the high level part of this pulse is typically within the range of 0.5ms to 2.5ms for angle control. For a 180-degree servo, the corresponding control relationship is as follows:0.5ms————–0 degrees;1.0ms————45 degrees;1.5ms————90 degrees;2.0ms———–135 degrees;2.5ms———–180 degrees;Please see the illustrative description below:
The operating voltage and current of the servo:
Each servo has its own parameters, for example, the TR213 servo has an operating voltage of 4.8-7.2V, while the TR205 servo has an operating voltage of 4.8-6V. The voltage should not exceed this range, otherwise, it can easily damage the servo. If the working voltage range of the servo is unclear, it is recommended to use 5V to power the servo.
The operating current of the servo depends on the actual conditions, such as the TR213 servo, which has almost 0 current when unloaded, while under normal load, the current is around 0.5A, depending on the actual situation. A six-legged robot requires 18 TR213 metal servos, and the increased current is approximately 8A. If the power supply is insufficient, it will affect the performance of the servo, with the most common phenomenon being that when one servo is loaded, the other servos may behave erratically.
The wiring of the servo is shown in the figure below:
In 90% of servos on the market, the middle wire is positive.
Having introduced the basic knowledge, you can check the servo manual on Baidu for more details.
Next, let’s talk about how to drive the servo to rotate freely using the wiringPi library in Raspberry Pi. Why use the wiringPi library? Because the author does not prefer to write Python; instead, they prefer writing C/C++ code. Without further ado, let’s get started.
First: I already know that the PWM cycle of the servo is 20ms, and it is as follows:
0.5ms————–0 degrees; 1.0ms————45 degrees; 1.5ms————90 degrees; 2.0ms———–135 degrees; 2.5ms———–180 degrees;
This means that giving it a high level of 1.5ms and a low level of 19.5ms will turn it to the 0-degree position. Here it is important to note that it is the 0-degree position, not that the servo turns to 0 degrees; of course, if the servo happens to be at the 0-degree position, it will not turn. Someone might ask, what position is considered the 0-degree position? Based on my understanding of the servo (180-degree servo), it is when you turn the servo in one direction with your hand until you reach a point where you cannot turn it anymore; this position is not the 0-degree position, but the 180-degree position. Then you can run the code below to find out.
while(1)//turn to 0
{
digitalWrite(15,HIGH);
delayMicroseconds(500);
digitalWrite(15,LOW);
delayMicroseconds(19500);
}
I simulate PWM like this. Once this code runs, the servo automatically goes to the 0-degree position.
Similarly, to turn to the 45-degree position, 90-degree position, 135-degree position, and 180-degree position, the code is as follows:
while(1) //turn to 45
{
digitalWrite(15,HIGH);
delayMicroseconds(1000);
digitalWrite(15,LOW);
delayMicroseconds(19000);
}
while(1) //turn to 90
{
digitalWrite(15,HIGH);
delayMicroseconds(1500);
digitalWrite(15,LOW);
delayMicroseconds(18500);
}
while(1) //turn to 135
{
digitalWrite(15,HIGH);
delayMicroseconds(2000);
digitalWrite(15,LOW);
delayMicroseconds(18000);
}
while(1) //turn to 180
{
digitalWrite(15,HIGH);
delayMicroseconds(2500);
digitalWrite(15,LOW);
delayMicroseconds(17500);
}
Here some might question why not use the delay() function, as the delay function is accurate to milliseconds. When I pass 1.5 to it and compare it with passing 1, you will find that the servo turns to the 45-degree position in both cases because delay(int x) loses precision when passing 1.5 (I made this mistake at first, which was embarrassing).
At this point, I believe you should know how to rotate to 45 degrees, 90 degrees, and so on. Then you might find that the servo rotates too quickly and may not be under your control. Here, I will provide you with an idea on how to solve this problem.
Of course, my abilities are limited, and mistakes are inevitable in writing; I hope to be corrected.
Below I provide a very good link for those interested in further research (they use a microcontroller):
http://www.njliaohua.com/lhd_5xtsq7jr1e0088t3wpu3_1.html
I believe that 0.5ms turns to 0 degrees, and 1ms turns to 45 degrees, so does it experience 0.5ms and turn 45 degrees? Therefore, I calculate 0.5=500us, 500us/45 degrees, resulting in approximately 11.11us/degree.
Next, my code is as follows:
int angle=0;
scanf(“%d”,&angle);//Input the angle to turn from the keyboard.
while(1)
{
x=11.11*i;
digitalWrite(15,HIGH);
delayMicroseconds(500+x);
digitalWrite(15,LOW);
delayMicroseconds(19500-x);
if(i==angle)
break;
i++;
}
In this way, the speed is indeed reduced, but each time the servo must first turn to the 0-degree position before it can turn to the angle position we input. I believe you understand this logic.
At this point, you should be able to reduce the speed of the servo; I will give you this much thought, and the rest is up to you to figure out.
Here I provide a demo:
#include<stdio.h>
#include<wiringPi.h>
void init();
int main()
{
init();
int angle=0;
scanf(“%d”,&angle);
int i=0;
float x=0;
k=180;//180 cycles are enough time
while(k–)
{
x=11.11*i;
digitalWrite(15,HIGH);
delayMicroseconds(500+x);
digitalWrite(15,LOW);
delayMicroseconds(19500-x);
if(i==angle)
break;
i++;
}
return 0;
}
void init()
{
wiringPiSetup();
pinMode(15,OUTPUT);
}