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

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

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

180 度舵机可以:

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

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

3、机械臂 / 机械爪。

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

5、3D 打印的零部件。

……

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

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

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

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

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

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 之前的时间舵机不关心,所以这段时间无论输出信号是高电平还是低电平都可以,因此关注的核心变为高电平什么时候关闭(变为低电平)。

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

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

如果高电平在 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 度,即占空比:

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

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

        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 退出。

看看效果。

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

【.NET 与树莓派】控制舵机的更多相关文章

  1. PWM波控制舵机总结

    文章转自:http://www.geek-workshop.com/thread-70-1-1.html 一.关于舵机: 舵机(英文叫Servo):它由直流电机.减速齿轮组.传感器和控制电路组成的一套 ...

  2. C#串口控制舵机、arduino源码 及C#源码及界面

    原文 C#串口控制舵机.arduino源码 及C#源码及界面 1.舵机原理简介 控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压.它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基 ...

  3. 树莓派控制高电平蜂鸣器(c语言+新手向)

    话不多说,先上代码: #include <wiringPi.h> #include <stdio.h> #include <sys/time.h> #define ...

  4. 树莓派控制HC-SR04超声波模块测距(新手向+C语言向)

    因为作业要求使用c语言代码,这里先附上一段摘自网上的代码 感谢KalaerSun的c语言代码,摘自https://blog.csdn.net/qq_25247589/article/details/6 ...

  5. mpu6050控制舵机云台

    准备材料:2个舵机mg90,云台支架,1个arduino-uno,mpu6050 编程工具:VScode-platformio  or  ArduinoIDE 我使用的是VScode在编辑代码上会更方 ...

  6. 树莓派控制GPIO(Python)

    如果你的raspi没有安装python那么先   sudo apt-get update sudo apt-get install python-dev   例如想要控制35管脚的亮灭: 先建一个文本 ...

  7. Arduino控制舵机

    一.接线 舵机 Arduino GND GND +5V 5V PWN 10 其中信号线PWN接arduino上任意带波浪号的引脚都可,我这里选择的是10号引脚,注意在程序中绑定的引脚要和连接的引脚相同 ...

  8. 树莓派SG90舵机接法

    我的舵机的三条线是红的.黑色.棕色,接法如下: 棕 : GND 红 : VCC 黄: 信号线 如图所示: 图片来源 如上图所示,写代码时注意舵机的BCM编码是18,而不是物理引脚的编码12.

  9. micropython陀螺仪控制舵机

    2018-03-1220:14:00 import pyb import time from pyb import Pin xlights = (pyb.LED(2),pyb.LED(3)) MO = ...

随机推荐

  1. 通过动态构建Expression Select表达式并创建动态类型来控制Property可见性

    通过动态构建Expression Select表达式并创建动态类型来控制Property可见性 项目中经常遇到的一个场景,根据当前登录用户权限,仅返回权限内可见的内容.参考了很多开源框架,更多的是在V ...

  2. XCTF-黑客精神

    杂言 前段时间键盘坏了,电脑硬盘也坏了,买东西装系统再偷个懒放了一周左右假.期间学习巩固了一下安卓开发的知识.用了固态才知道什么叫纵享丝滑,当初就不该省这个钱. 前期工作 查壳,无.运行,点击按钮就跳 ...

  3. MySql(一)表类型(存储引擎)

    MySql(一)表类型(存储引擎) 一.MYSQL存储引擎概述 二.存储引擎的特性对比 2.1 MyISAM 2.2 InnoDB 2.2.1 自动增长列 2.2.2 外键约束 2.2.3 存储方式 ...

  4. Docker安装mysql5.7并且配置主从复制

    Docker安装mysql5.7并且配置主从复制 一.拉取mysql镜像 二.创建文件docker.cnf 2.1 mysql主机(192.168.21.55:3307) 2.1.1 创建文件夹 2. ...

  5. 子网划分、变长子网掩码和TCP/IP排错__子网、掩码、网络汇总

    1.如何创建子网? 要创建子网,就需要从IP地址的主机部分中借出一定的位,并且保留它们用来定义子网地址.这意味着用于主机的位减少,所以子网越多,可用于定义主机的位越少. 2.子网划分的好处: 1)缩减 ...

  6. this.$nextTick( 回调函数 )的作用

    首先要明确几个概念 1.Vue的核心思想 数据驱动 和 组件化系统 2.同步和异步 在没有特殊情下,程序一般先执行同步代码,等待同步执行完之后,执行异步代码 下面进入正题,首先贴出程序片段: 在该段代 ...

  7. F - Cheapest Palindrome

    有一个长度为m的字符串,由n种小写字母组成.对应的n种字母在这个字符串加上或者减去都有相应的费用,现在要将这个字符串变成回文串,问最低消费是多少? Keeping track of all the c ...

  8. Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) B. Journey Planning(映射)

    题意: 已知 n 所城市(从 1 至 n 编号)及其美丽值,选取一条旅行路线,满足路线中两两城市美丽值之差等于编号之差,求所有旅行路线中美丽值的最大值. 思路: 美丽值与编号作差,差值为键,映射累加 ...

  9. [Golang]-2 Map关联数组与下划线(_)的意义

    目录 map 下划线(underscore) 用在import 用在返回值 用在变量 map map 是 Go 内置关联数据类型(在一些其他的语言中称为哈希 或者字典 ). func main() { ...

  10. k8s二进制部署 - node节点安装

    创建kubelet配置 • set-cluster # 创建需要连接的集群信息,可以创建多个k8s集群信息 [root@hdss7-21 ~]# kubectl config set-cluster ...