我们来看一下直流有刷电调驱动部分,常用的直流有刷电调的PWM信号频率通常是500HZ,也就是说每秒有500个脉冲信号,每一个脉冲信号的宽度为2毫秒(2000微秒)。有刷电调可以使用这2ms的脉冲来控制电机的正转、反转、转速。
1、脉冲信号1.5ms为电机正转与反转的分界线,也就是说电机停止转动;
2、脉冲信号1.5ms~2.0ms为正转,越接近2.0ms电机正转转数越大;
3、脉冲信号1.5ms~1.0ms为反转,越接近1.0ms电机反转转数越大。
知道了电调的PWM信号之后,我们就可以通过程序来控制电机的正转、反转、转数、停止等。一般来说,电调上电之后需要有3秒的初始化工作,在这3秒中要对电调持续发送1.5ms的PWM信号,当电机发出do re mi三声之后,说明电调准备就绪可以使用了。
我们先来写一个函数,使得我们给电调发送的电机速度转换成脉冲信号:
typedef struct { int time_w; int time_m; } driver_pwm; void driver_set_pwm(int speed, driver_pwm *pwm) { pwm->time_m = 1500 + speed; pwm->time_w = 2000 - pwm->time_m; }
再编写一个电调初始化3秒的函数:
//执行一次脉冲 void driver_run_pwm(driver_pwm *pwm) { //高电位 digitalWrite(PORT_SPEED, HIGH); usleep(pwm->time_m); //低电位 digitalWrite(PORT_SPEED, LOW); usleep(pwm->time_w); } //电调初始化 void driver_init() { driver_pwm pwm; //停止 int speed = 0; driver_set_pwm(speed, &pwm); //500HZ * 3秒 for (int i = 0; i < 500 * 3; i++) { driver_run_pwm(&pwm); } }
再来看一个MPU6050驱动,由于我们所使用的开源驱动是采用C++编写的,所以我们需要用g++来编译代码,在调用MPU6050驱动时,使用extern "C" { ... ... }形式来声明C函数,其它部分仍然是C函数。
extern "C" { void mpu6050_setup(); void mpu6050_value(double *x, double *y, double *z, double *ax, double *ay, double *az); }
接下来我们需要生成两个线程:一个线程向持续向电调发送500HZ的脉冲信号,另一个线程取得当前MPU6050倾斜角度,并通过PID控制调整脉冲信号从而使小车在出现倾斜之后能够恢复平衡。
//驱动线程:持续向电调发送500HZ脉冲信号 pthread_create(&pthddr, NULL, (void* (*)(void*)) &driver_run, NULL); //引擎线程:取得倾斜角并恢复平衡 pthread_create(&pthd, NULL, (void* (*)(void*)) &engine_balance, NULL);
Copyright © 2015-2023 问渠网 辽ICP备15013245号