9

【.NET 与树莓派】控制舵机

 3 years ago
source link: https://www.cnblogs.com/tcjiaan/p/14415377.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【.NET 与树莓派】控制舵机

不管是小马达,还是大马达,嗯,也就是电机,相信大伙伴们也不会陌生。四驱车是一种很优秀的玩具,从老周小时候就开始流行(动画片《四驱兄弟》估计很多大朋友都看过),直到现在还能看到很多卖四驱车的。为啥会想起四驱车呢?因为小时候玩四驱车让老周认识了很多奇葩马达,什么“红魔鬼”、“蓝芯”、“紫魔鬼”……也不知道是什么逻辑的命名方式,反正那时候大家都这么叫。

这些马达的结构有一个转轴,绕有红色或橙色的线圈(记忆中是这些颜色),有四块磁铁。金属外壳,上部开有两个散热孔。整体形状有圆的也有扁的,许多遥控车的马达是圆的。还有一马达像个竹筒似的,一些太阳帽小风扇里面有。

一般的马达的特点,就是一通电就往一个方向转(正负接反它就反向转),但舵机比普通马达更好玩。360度的舵机与一般马达相似,加电后会往一个方向转动,信号线控制其转动方向和转速;不过我们常说的舵机一般是指 180 度的舵机,这种舵机可以通过信号线让它转动一定的角度,当到达指定的角度后舵机会停下来。

180 度舵机可以:

1、机器人各个关节的运动,可模拟人的关节活动。因为程序可以控制舵机转到指定的角度。

2、遥控小车可以用舵机来拐弯。

3、机械臂 / 机械爪。

4、制作可以转动的摄像头。

5、3D 打印的零部件。

只要需要控制转动方向的,都用得上。

舵机依据其工作负荷以及扭力可以有很多种,咱们用来开发做实验的,最好选 9 克舵机。尽管这种舵机力气不大,但是开发板可以直接供电,不用外加电源补电。就是这种,蓝色透明外壳的。

367389-20210219111821188-416972003.png

 正因为外壳是透明的,所以你能看到里面有什么。当然了,你如果像老周这样喜欢搞破坏的,可以把拆开玩玩。

367389-20210219112216177-260571821.png

 拆的时候最好戴个手套,毕竟这是电机,你拆过就知道,里面有很多润滑油的。装回去的时候要注意那几个减速齿轮,有的大伙伴一时冲动拆了,然后装不回去。虽然这种舵机一般几块钱一个,但你也不能这么浪费。

367389-20210219112509003-1189731487.png

 舵机里面主要这几个部件:

1、马达。这个肯定有的,不然怎么转。

2、电位器。不同角度会改变不同的电阻值,使控制板能驱动马达转多少圈。

3、控制板。

4、N 个减速齿轮。

上面只是了解一下舵机,接下来看重点——怎么控制角度。一般的教程会跟你说,通过 PWM 设置不同占空比来控制舵机转动角度。这并不算错,因为控制舵机确实是用 PWM 实现的。不过,这样说其实不准确。实际上,让舵机转动多少度是通过高电平的持续时间来控制的。

通常情况下,控制脉冲的周期时长是 20 毫秒,即 20000 微秒。故用PWM时,频率设定 50 Hz(1 / 0.02秒 = 50 Hz)。舵机识别高电平的时间范围为 0.5 ms 到 2.5 ms,即 500 us 到 2500 us。下图是老周盗来的动图。

这就是为什么PWM能控制舵机的原因,在 0.5ms 之前的时间舵机不关心,所以这段时间无论输出信号是高电平还是低电平都可以,因此关注的核心变为高电平什么时候关闭(变为低电平)。

367389-20210219114716477-1994964666.png

 如上图,如果高电平持续到 0.5 毫秒时变为低电平,则舵机旋转至 0 度。

367389-20210219115112591-1013809658.png

 如果高电平在 1.5 毫秒时关闭,则舵机旋转到 90 度。

367389-20210219115451044-1999646114.png

 如果高电平在 2.5 毫秒时关闭,舵机旋转至 180 度。

综上所述,将控制舵机的信号换算为PWM的占空比,需要准备以下条件:

1、周期时间长度,一般为 20000 us,换算为PWM频率为 50Hz。

2、高电平有效的持续时间,一般值为:min = 500us,max = 2500us。

3、500 - 2500 us,其时间段为 2500-500 = 2000us,用180度平分这2000微秒,即每一度角对应的时间为 2000 / 180 ≈ 11.11 us / deg。

综合一下,占空比可这样算:

假设要旋转 90 度,即占空比:

 

367389-20210219122108570-65292923.png

 把公式翻译成中文,就是这样

367389-20210219122617902-1383636940.png

有了上面的基础,写代码就好办了。这里老周写了一个测试程序,这个命令行程序可以通过输入命令来修改参数,这样方便大家做实验。命令帮助信息如下:

        using static System.Console;

        static void ShowHelps()
        {
            WriteLine("{0,-15}{1}", "h", "显示帮助信息");
            WriteLine("{0,-15}{1}", "x", "退出");
            WriteLine("{0,-15}{1}", "d n", "设置周期(微秒)");
            WriteLine("{0,-15}{1}", "t n", "高电平起始时间(微秒)");
            WriteLine("{0,-15}{1}", "p n", "高电平结束时间(微秒)");
            WriteLine("{0,-15}{1}", "a n", "角度");
            WriteLine("{0,-15}{1}", "o", "发送脉冲信号");
            WriteLine("{0,-15}{1}", "s", "停止脉冲");
            WriteLine();
        }
        

下面的代码是计算 1 度角对应的时间长度(微秒)。

        static void ComputeMicroToAngle()
        {
            microForAngle = (maxMicrosec - minMicrosec) / 180.0d;
        }

minMicrosec 是高电平持续的最小时间:500us;maxMicrosec 是高电平持续的最大时间:2500us。

这几个变量的声明如下:

        /// <summary>
        /// 高电平持续的最小时间,一般为 500us
        /// </summary>
        static int minMicrosec = 500;

        /// <summary>
        /// 高电平持续的最大时间,一般为 2500us
        /// </summary>
        static int maxMicrosec = 2500;

        /// <summary>
        /// 一度角对应的持续时间,单位为微秒(us)
        /// </summary>
        static double microForAngle = 0d;

主体代码如下,其余的可以下载源代码查看。

            // 创建PWM通道实例
            PwmChannel ch = PwmChannel.Create(0, 0);
            ShowHelps(); //运行后打印一次帮助信息
            bool working = true; //用来跳出循环的标志变量
            while(working)
            {
                Write(">>>");
                // 读取键盘输入的一行文本
                string line = ReadLine();
                // 读取第一个字符
                char first = line[0];
                // 分析命令
                switch(first)
                {
                    case 'h': //显示帮助信息
                        ShowHelps();
                        break;
                    case 'x': //跳出循环,退出程序
                        working = false;
                        break;
                    case 'd': //设置周期,一般是20000us
                        ch.Frequency = ParseFreq(line[1..].Trim());
                        break;
                    case 't': //设置高电平持续的最小时间
                        ParseMinMicrosecond(line[1..].Trim());
                        ComputeMicroToAngle();
                        break;
                    case 'p': //设置高电平持续的最大时间
                        ParseMaxMicrosecond(line[1..].Trim());
                        ComputeMicroToAngle();
                        break;
                    case 'a': //设置要旋转的角度
                        double angle = ParseAngle(line[1..].Trim());
                        ch.DutyCycle = ComputeDuty(angle, ch.Frequency);
                        break;
                    case 'o': //开始发送脉冲
                        ch.Start();
                        break;
                    case 's': //停止发送脉冲
                        ch.Stop();
                        break;
                    default:
                        WriteLine("<<< 无效命令");
                        break;
                }
            }
            ch.Dispose();

编译,发布,上传到树莓派。注意舵机有三条线:

1、红线(一般在中间),接树莓派 5V 引脚(供电正极)。

2、黑线或棕色线,接树莓派任意一个 GND 引脚(供电负极)。

3、黄色(有的是白色)是信号线,用来控制舵机,接树莓派的 GPIO 18,这个是树莓派全系列通用的默认 PWM 引脚。

运行程序,第一步,输入 d 20000,设定周期(为了统一,所有时间参数都是以微秒为单位)。

 输入 t 500 设置高电平控制角度的起始时间,就是持续最小值,取500。

 输入 p 2500,设置高电平的结束时间,即持续的最大值,一般取 2500。

 输入小写字母 o,开始PWM。

 输入 a 120,旋转至 120 度。

输入 a 30 ,旋转至 30 度。

 输入小写字母 s ,停止PWM信号,输入 x 退出。

看看效果。

367389-20210219171735712-312369924.gif

相关源代码,请点这里下载


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK