PWM全称
50Hz也就是一秒内变换50次
根据上面的公式
一个高电平一个低电平叫一个脉冲。
例如每个脉冲占20毫秒,那么他的频率是多少?
就是用1去除以他的周期,也就是我们上面说的20,那么就是除0.02,1秒等于1000毫秒,20毫秒换算成秒。换算过来就是0.02, 1/0.02 = 50,那么他的频率也就是50.
例如这张图,他就是有4个周期
占空比,占空比是指在一定时间高电平保持的时间与总周期的比值
例如下面两段周期分别都是10毫秒的时间
那么高电平占了7ms,那么他在总过程当中就是占了70%
输入电流等于输出电量*占空比
输入为5v,占空比为20%,那么输出就是1
借鉴网址:搞懂什么是PWM控制_哔哩哔哩_bilibili
实例1:PWM与LED的故事
例如我们想要led灯常亮,那么只需要一直给高电平就行了
熄灭就给低电平
假如我们不停的切换高低电平,那么他就会闪烁熄灭
但是如果我们让切换的速度变的极快,那么就不会看见闪烁在熄灭,类似我们看玄幻小说的残影,只要速度够快,原地就会留下一个残影
我们将亮的时间延长,断灭的时间减少,再加上切换的速度,那么你只会看见光芒减弱
实例2:PWM与舵机的故事
舵机根据输入的PWM信号进行转动,舵机内部的芯片会将电位器的电压信号转换成PWM信号,与输入的PWM指令进行对比.最后得到控制电机转动的信号,比如旋转方向和速度
上面的图看来,不同的占比毫秒就能改变他的度数,例如2ms就能让舵机转到135度
程序实例:转动舵机到125度
#define ServoPin 2 // 舵机引脚2号
int highTime = 2000;//高电平占时换算成微秒。例如2毫秒就是2000微秒
int period = 20000;//固定周期20ms
void setup() {// put your setup code here, to run once:pinMode(ServoPin,OUTPUT);
}void loop() {digitalWrite(ServoPin,HIGH);delayMicroseconds(highTime);//高电平持续时间digitalWrite(ServoPin,LOW);delayMicroseconds(period-highTime);//低电平持续时间// put your main code here, to run repeatedly:}
舵机正极接5V 负极接GND,信号线接2
实例程序:让舵机依次旋转
#define ServoPin 2 // 舵机引脚2号
int highTime = 500;//高电平占时换算成微秒。例如2毫秒就是2000微秒
int a = 1000;
int c = 2000;
int d = 2500;
int period = 20000;//固定周期20ms
void setup() {// put your setup code here, to run once:pinMode(ServoPin,OUTPUT);
}void loop() {digitalWrite(ServoPin,HIGH);delayMicroseconds(highTime);//高电平持续时间digitalWrite(ServoPin,LOW);delayMicroseconds(period-highTime);//低电平持续时间delay(1000);digitalWrite(ServoPin,HIGH);delayMicroseconds(a);//高电平持续时间digitalWrite(ServoPin,LOW);delayMicroseconds(period-a);//低电平持续时间delay(1000);digitalWrite(ServoPin,HIGH);delayMicroseconds(c);//高电平持续时间digitalWrite(ServoPin,LOW);delayMicroseconds(period-c);//低电平持续时间delay(1000);digitalWrite(ServoPin,HIGH);delayMicroseconds(d);//高电平持续时间digitalWrite(ServoPin,LOW);delayMicroseconds(period-d);//低电平持续时间delay(100000);// put your main code here, to run repeatedly:}
实例程序:让他旋转的速度慢慢相加
#define ServoPin 2 // 舵机引脚2号
int highTime = 500;//高电平占时换算成微秒。例如2毫秒就是2000微秒int period = 20000;//固定周期20ms
void setup() {// put your setup code here, to run once:pinMode(ServoPin,OUTPUT);
}void loop() {digitalWrite(ServoPin,HIGH);delayMicroseconds(highTime);//高电平持续时间digitalWrite(ServoPin,LOW);delayMicroseconds(period-highTime);//低电平持续时间highTime += 1;// put your main code here, to run repeatedly:}
舵机自带的控制函数
舵机使用函数控制
实例1,:让舵机来回旋转
#include <Servo.h>
int pos = 0;Servo myservo;
void setup() {// put your setup code here, to run once:myservo.attach(3);//
}void loop() {for (pos = 0; pos <= 180; pos += 1){myservo.write(pos);//驱动舵机旋转delay(15);//等待舵机转到相应位置}for(pos = 180; pos >= 0; pos -= 1){//让舵机从180转到0myservo.write(pos);delay(15);}
}
16路舵机控制板
接线方式
注意看线的颜色,GND = GND SCL = D1 SOA = D2 VCC = 3V或5V V+ = VIN
这个是esp8266的接线方式,arduino需要大家去探索一下
#include <Wire.h> //I2C库文件wire
#include <Adafruit_PWMServoDriver.h> //驱动板库文件// 默认地址 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
int a = 102;
#define SERVO_0 a //寄存器的值 102 =0.5ms = 0°
#define SERVO_45 187
#define SERVO_90 280
#define SERVO_135 373
#define SERVO_180 510 void setup() {Serial.begin(9600);pwm.begin();pwm.setPWMFreq(50); // 50HZ更新频率,相当于20ms的周期delay(10);
}void loop() {pwm.setPWM(0, 0, SERVO_0);//舵机编号、脉冲起始时间、脉冲结束时间delay(10);SERVO_0 += 1;Serial.println(SERVO_0);}