怎样增加网站浏览量,个人怎么做网站,如何将网站开发成微信小程序,wordpress+主题+试用重要的内容写在前面#xff1a;
该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后#xff0c;整体感觉是很好的#xff0c;如果有条件的可以先学习一些相关课程#xff0c;学起来会更加轻松#xff0c;相关课程有数字电路…重要的内容写在前面
该系列是以up主太极创客的零基础入门学用Arduino教程为基础制作的学习笔记。个人把这个教程学完之后整体感觉是很好的如果有条件的可以先学习一些相关课程学起来会更加轻松相关课程有数字电路强烈推荐先学数电不然可能会有一些地方理解起来很困难、模拟电路等然后就是C注意C是必学的。文章中的代码都是跟着老师边学边敲的不过比起老师的版本我还把注释写得详细了些并且个人认为重要的地方都有详细的分析。一些函数的介绍有参考太极创客官网给出的中文翻译为了便于现查现用把个人认为重要的部分粘贴了过来并做了一些修改。如有错漏欢迎指正。
视频链接2-1 MeArm项目概述_哔哩哔哩_bilibili
太极创客官网太极创客 – Arduino, ESP8266物联网的应用、开发和学习资料
一、伺服电机舵机
1、认识伺服电机
1伺服电机是一种根据输入PWM信号占空比来控制输出角度的装置二者具体有什么对应关系取决于电机的型号其硬件结构如下图所示电位器与转轴相连转轴每一个转动角度都分别对应电位器的一个旋转角度控制电路负责将电位器部分传来的信号和输入的PWM信号作比对如果当前转轴的转动角度不符合输入PWM信号占空比对应的输出角度则控制电路将控制电机带动齿轮组旋转直到转轴的旋转角度与输入的PWM信号相对应。 2舵机一般有三根引线需要连接且引线的颜色一般有统一标准如下所示其中橙色线负责给电机输入PWM信号它不一定必须连接在Arduino的9号引脚只要带PWM输出的引脚都可以连接。 3通常舵机需要的供电功率比较高如果需要控制1个以上的舵机那么必须使用单独的电源为舵机供电而不能使用Arduino开发板的5V引脚为1个以上的舵机供电。另外如果使用独立电源为舵机供电那么独立电源与Arduino必须共地电源GND与Arduino的GND相互连接在一起。
2、Servo库概述
1通过Servo库可以用Arduino控制舵机伺服电机。常见的Arduino舵机有两种一种舵机轴可以旋转180度还有一种舵机轴可以连续旋转这种舵机的旋转速度是可以控制的。
2Servo库允许大多数Arduino开发板如Arduino Uno同时控制12个舵机对于Arduino Mega可以用Servo库同时控制48个舵机。
3请注意使用Servo库可能会影响Arduino开发板的某些引脚的PWM功能。
4对于除Mega开发板以外的Arduino开发板当使用Servo库时开发板的9号和10号引脚的PWM功能是无法使用的也就是说Arduino程序如果使用了Servo库无论9号和10号引脚上是否连接了舵机这两个引脚都不能使用analogWrite进行控制。
5对于Mega开发板使用12个以下的舵机是不会影响开发板的PWM功能的但如果使用12个以上的舵机那么Mega开发板上的引脚11和引脚12是要受到影响的。
3、Servo库提供的函数
1servo.attach(pin)告知Arduino舵机的数据线连接在引脚pin上。
2servo.write(angle)对于标准舵机write函数会将舵机轴旋转到角度angle相应的位置对于连续旋转类型的舵机write函数可以设置舵机的旋转速度0指示舵机向着一个方向全速旋转180指示舵机向着另一个方向全速旋转90指示舵机静止不动以此类推。
3servo.read()获取当前舵机轴的角度即上一次使用write()函数设置舵机轴的角度信息。
4servo.attached()检查某一个舵机对象是否连接在开发板引脚上如果某一个舵机对象的确连接在开发板上则返回true否则返回false。
5servo.deattach()将舵机对象与Arduino开发板断开连接舵机一旦与Arduino开发板断开连接则引脚9和引脚10的PWM输出analogWrite功能将会恢复。
4、例——舵机自动旋转
1根据上图所示将电路连接好。
2将下面的程序下载到开发板中会发现舵机进行重复的来回旋转。值得注意的是C采用面向对象的编程思想Servo库的编写亦是如此所以可以为Arduino控制的舵机分别创建Servo对象通过Servo对象调用Servo类的成员函数以达到让对象舵机执行相应操作的效果。
#include Servo.h //包含Servo库的头文件Servo myservo; //创建Servo对象用以控制伺服电机
int pos 0; //存储伺服电机角度信息的变量void setup()
{myservo.attach(9); //Servo对象其控制的电机连接在9号引脚 Serial.begin(9600);
}void loop()
{for (pos 0; pos 180; pos 45) //从0度转到180度每一步旋转45度{myservo.write(pos); //舵机旋转轴旋转到pos变量的角度Serial.println(pos);delay(1500); //等待1.5秒以确保伺服电机可以达到目标角度}for (pos 180; pos 0; pos - 45) //从180度转到0度每一步旋转45度{myservo.write(pos); //舵机旋转轴旋转到pos变量的角度Serial.println(pos);delay(1500); //等待1.5秒以确保伺服电机可以达到目标角度}
}二、串口通讯
1、概述
1串行端口用于Arduino和个人电脑或其它设备进行通信若没有特殊说明所提及的串口通信双方均为Arduino与个人电脑所有Arduino控制器都有至少一个串行端口也称为UART或者USART。
2个人电脑可以通过USB端口与Arduino的引脚0RX和引脚1TX进行通信所以当Arduino的引脚0和引脚1用于串行通信功能时Arduino的引脚0和引脚1是不能做其它工作的。引脚RX和引脚TX工作时开发板上会有相应的两盏指示灯分别闪烁。
①开发板上的RX和TX如下图所示。 ②电脑端的RX和TX如下图所示。 ③Arduino和计算机的连接如下图所示计算机可通过TX向Arduino发送以字节为单位的数据Arduino可借助RX接收计算机发送来的数据同理Arduino可通过TX向计算机发送以字节为单位的数据计算机可借助RX接收Arduino发送来的数据。 3串口通信中有一个概念是波特率可认为是数据传输速率通信双方的波特率应相同否则无法正常通信。
4如果想深入了解串口通信的底层原理可以参考课程《计算机网络》虽然该课程不会详细介绍甚至不会介绍串口通信但是通过对通信协议的学习也有助于理解串口通信的原理。
2、例1——串行通讯基本演示
1本例仅用USB线将单片机和个人电脑连接即可。
2begin函数
①该函数的作用是设置电脑与Arduino进行串口通讯时的数据传输速率每秒传输字节数也称波特率可使用300、600、1200、2400、4800、9600、14400、19200、28800、38400、57600或115200也可以根据所使用的设备而设置其它传输速率。
②使用格式为“Serial.begin(speed)”其中参数speed为传输速率。
3available函数
①当计算机给Arduino传输数据时Arduino不一定能及时将该数据接收并处理为了防止数据丢失Arduino设置了串口接收缓存用于存放接收到的数据当然这个缓存不会很大如果不及时将缓存中的数据读走同样会造成数据丢失。另外缓存中的字节数据是以ASCII码的形式存储的比如字符’1’对应的ASCII码为49转换为二进制就是00011001。 ②available函数无函数参数可用于检查设备是否接收到数据该函数将会返回等待读取的数据字节数。
③available函数属于Stream类该函数可被Stream类的子类所使用Stream类的子类继承了Stream类的函数如Serial、WiFiClient、File等本例使用的是Serial.available()用于检查串口接收缓存中是否有未处理的数据。
4read函数
①read函数无参数可用于从设备接收到数据中读取一个字节的数据设备没有接收到数据时返回值为-1设备接收到数据时返回值为接收到的数据流中的1个字符先接收先读取后接收后读取。
②本函数属于Stream类该函数可被Stream类的子类所使用如Serial、WiFiClient、File等本例使用的是Serial.read()用于读取串口接收缓存中的数据。
③一个字节数据被读取走后其在串口接收缓存中随之被移除。 5print函数
①该函数的作用是以人类可读的ASCII码形式向串口发送数据该函数有多种格式。
[1]Serial.print(val)val是要发送的数据可以是任意数据类型。
[2]Serial.print(val, format)val是要发送的数据可以是任意数据类型format是指定数字的基数用于整型数或者小数的位数用于浮点数对于整数这个允许的值为BIN二进制、OCT 八进制、DEC十进制或HEX十六进制对于浮点数该参数可以指定小数点的位数。
②整数的每一数位将以ASCII码形式发送浮点数同样以ASCII码形式发送默认保留小数点后两位字节型数据将以单个字符形式发送字符和字符串会以其相应的形式发送。
③该函数的返回值为发送的字节数一般来说可以摒弃即这个返回值没什么实际用途。
6println函数
①该函数的作用是以人类可读的ASCII码形式向串口发送数据与print函数极其类似不同的是该函数会在数据发送完毕后发送一个换行符。
②该函数的返回值为发送的字节数一般来说也可以摒弃即这个返回值也没什么实际用途。
7将下面的程序下载到开发板中然后开始人工调试。
void setup()
{Serial.begin(9600);Serial.println(Please input serial data.);
}void loop()
{if (Serial.available() 0 ) //检查串口缓存中是否有数据等待读取{Serial.println(); char serialData Serial.read(); //读取串口缓存中等待的一个字符Serial.print(Your serialData: );Serial.print(serialData); //发送刚刚读取到的字符给电脑Serial.println();Serial.print(serialData in DEC );Serial.println(serialData, DEC); //发送刚刚读取到字符的ASCII编码十进制Serial.print(serialData in BIN );Serial.println(serialData, BIN); //发送刚刚读取到字符的ASCII编码二进制Serial.print(serialData in OCT );Serial.println(serialData, OCT); //发送刚刚读取到字符的ASCII编码八进制Serial.print(serialData in HEX );Serial.println(serialData, HEX); //发送刚刚读取到字符的ASCII编码十六进制Serial.println();}
}
①打开Arduino IDE的串口监视器将内容“a”结尾不带换行符发送给ArduinoArduino接收到数据后Serial.available()的返回值为1程序检测到缓存中有数据需要读取然后进行读取操作并将读取到的1字节数据以不同格式通过串口发送给电脑同时附有提示信息。 ②打开Arduino IDE的串口监视器将内容“bc”结尾不带换行符发送给ArduinoArduino接收到数据后Serial.available()的返回值为2程序检测到缓存中有数据需要读取然后进行读取操作首先读取1字节数据——字符’b’并以不同格式通过串口发送给电脑同时附有提示信息再读取1字节数据——字符’c’并以不同格式通过串口发送给电脑同时附有提示信息。 3、例2——利用串行通讯控制一个舵机
1按照下图所示将电路连接好其中Arduino、舵机和电源模块需要共地电源模块选择5V的输出另外需要注意电源模块的正负极不能短接。 2parseInt函数
①parseInt函数没有参数可用于从设备接收到的数据中寻找整数值并将其返回返回值类型为长整型long int若找不到整数数据则返回0。
②本函数属于Stream类可被Stream类的子类所使用本例使用的是Serial.parseInt()。
3parseFloat函数
①parseFloat函数没有参数可用于从设备接收到的数据中寻找浮点数值并将其返回返回值类型为浮点型float。
②本函数属于Stream类可被Stream类的子类所使用本例不使用该函数。
4将下面的程序下载到开发板中然后开始人工调试示例程序没有限定输入数值的取值范围在实际应用中应用if语句对Arduino接收到的数值进行越界判断后再做处理。
#include Servo.hServo myServo; //为舵机创建Servo对象myServo
int dataIndex 0; //创建整数型变量存储输入数据序列号void setup()
{myServo.attach(6); //舵机连接在引脚6上Serial.begin(9600); //启动串口通讯配置传输波特率为9600Serial.println(Please input serial data.);
}void loop()
{ if ( Serial.available() 0 ) // 检查串口缓存是否有数据等待传输{ //处理数据序列号并通过串口监视器显示dataIndex; Serial.print(dataIndex );Serial.print(dataIndex);Serial.print( , ); int pos Serial.parseInt(); //解析串口数据中的整数信息并赋值给变量posSerial.print(Set servo position: );Serial.println(pos); //通过串口发送变量pos数值myServo.write(pos); //使用pos变量数值设置伺服电机delay(15);}
}
①通过串口助手向Arduino发送内容“90”程序检测到串口接收缓存有未处理数据后调用parseInt函数对其中的数据进行处理读取并分析出数据中的内容为整数90接着Arduino通过串口将“90”发回给计算机同时控制舵机旋转至90°的位置。 ②通过串口助手向Arduino发送内容“*#AB45”程序检测到串口接收缓存有未处理数据后调用parseInt函数对其中的数据进行处理读取并分析出数据中的内容含有整数45接着Arduino通过串口将“45”发回给计算机同时控制舵机旋转至45°的位置。 ③通过串口助手向Arduino发送内容“*#AB135CV”程序检测到串口接收缓存有未处理数据后调用parseInt函数对其中的数据进行处理读取并分析出数据中的内容含有整数135“135”之前的字符全部省略“135”之后的字符在本次parseInt函数的调用中不进行读取这部分内容仍存储在缓存中接着Arduino通过串口将“135”发回给计算机同时控制舵机旋转至135°的位置这时串口缓存中还有内容“CV”未处理故程序再次调用parseInt函数对其中的数据进行处理但在剩余内容“CV”中找不到整数数据故返回0Arduino通过串口将“0”发回给计算机同时控制舵机旋转至0°的位置。 ④通过串口助手向Arduino发送内容“*#AB90CV45”程序检测到串口接收缓存有未处理数据后调用parseInt函数对其中的数据进行处理首先parseInt读取到整数数据“90”“90”以后的数据不参与本次读取Arduino控制舵机旋转至90°的位置这时串口接收缓存中还有数据未处理则程序再次调用parseInt函数读取到整数数据“45”Arduino控制舵机旋转至45°的位置。 4、例3——利用串行通讯控制四个舵机
1按照下图所示将电路连接好其中Arduino、舵机和电源模块需要共地电源模块选择5V的输出另外需要注意电源模块的正负极不能短接。 2将下面的程序下载到开发板中然后开始人工调试示例程序没有限定输入数值的取值范围在实际应用中应用if语句对Arduino接收到的数值进行越界判断后再做处理。
#include Servo.hServo base, fArm, rArm, claw; //建立4个电机对象void setup()
{base.attach(11); //base伺服电机连接引脚11 电机代号为brArm.attach(10); //rArm伺服电机连接引脚10 电机代号为rfArm.attach(9); //fArm伺服电机连接引脚9 电机代号为fclaw.attach(6); //claw伺服电机连接引脚6 电机代号为cSerial.begin(9600);Serial.println(Please input serial data.);
}void loop()
{if (Serial.available()) //检查串口缓存是否有数据等待传输{ char servoName Serial.read(); //获取电机指令中电机编号信息Serial.print(servoName );Serial.print(servoName); Serial.print( , ); int data Serial.parseInt(); //获取电机指令中电机角度信息switch(servoName) //根据电机指令中电机信息决定对哪一个电机进行角度设置{case b: //电机编号为b设置base电机的角度base.write(data); Serial.print(Set base servo value: );Serial.println(data); break;case r: //电机编号为r设置rArm电机的角度 rArm.write(data); Serial.print(Set rArm servo value: );Serial.println(data); break;case f: //电机编号为f设置fArm电机的角度 fArm.write(data); Serial.print(Set fArm servo value: );Serial.println(data); break;case c: //电机编号为c设置claw电机的角度 claw.write(data); Serial.print(Set claw servo value: );Serial.println(data); break;}}
}
①通过串口助手向Arduino发送内容“b45”程序检测到缓存中有未处理数据遂进行处理首先获取第一个字节其ASCII码对应的字符’b’为电机编号接着从后续数据中获取到整数数据“45”经过switch语句的逻辑控制将编号为“b”的电机控制旋转至45°。 ②通过串口助手向Arduino发送内容“r90”程序检测到缓存中有未处理数据遂进行处理首先获取第一个字节其ASCII码对应的字符’r’为电机编号接着从后续数据中获取到整数数据“90”经过switch语句的逻辑控制将编号为“r”的电机控制旋转至90°。 ③通过串口助手向Arduino发送内容“f135”程序检测到缓存中有未处理数据遂进行处理首先获取第一个字节其ASCII码对应的字符’f’为电机编号接着从后续数据中获取到整数数据“135”经过switch语句的逻辑控制将编号为“f”的电机控制旋转至135°。 ④通过串口助手向Arduino发送内容“c180”程序检测到缓存中有未处理数据遂进行处理首先获取第一个字节其ASCII码对应的字符’c’为电机编号接着从后续数据中获取到整数数据“180”经过switch语句的逻辑控制将编号为“c”的电机控制旋转至180°。 ⑤如果发送一个非法的电机编号比如“a”四个舵机均不会有任何响应因为switch语句中没有实现对这种异常情况进行处理。
5、更多Serial串行通信函数
1Serial.end()终止串行通讯让RX和TX引脚用于Arduino的输入INPUT或输出OUTPUT功能。可调用Serial.begin()重新打开串行通讯
2Serial.find(target)可用于从设备接收到的数据中寻找指定字符串信息target为被查找字符串允许使用String或char类型当函数找到了指定字符串信息后将会立即结束函数执行并且返回“真”否则将会返回“假”。
3Serial.findUntil(target, terminator)可用于从设备接收到的数据中寻找指定字符串信息当函数找到了指定字符串信息后将会立即结束函数执行并且返回“真”否则将会返回“假”。
①该函数在满足以下任一条件后都会停止函数执行读取到指定终止字符串、找到了指定字符串信息、达到设定时间可使用setTimeout来设置。
②target是被查找字符串允许使用String或char类型terminator是终止字符串用于设置终止函数执行的字符串信息设备在读取数据时一旦读取到此终止字符串将会结束函数执行并返回。
4Serial.flush()让开发板在所有待发数据发送完毕前保持等待状态。
5Serial.peek()从设备接收到的数据中读取一个字节的数据设备没有接收到数据时返回值为-1设备接收到数据时返回值为接收到的数据流中的第1个字符与read函数不同的是使用peek函数读取数据后被读取的数据不会从数据流中消除。
6Serial.readBytes(buffer, length)用于从设备接收的数据中读取信息读取到的数据信息将存放在缓存变量中。
①该函数在读取到指定字节数的信息或者达到设定时间该设定时间可使用setTimeout来设置后都会停止函数执行并返回。
②buffer是缓存变量/数组用于存储读取到的信息允许使用char或者byte类型的变量或数组length是读取字节的数量readBytes函数在读取到length所指定的字节数量后就会停止运行允许使用int类型。
7Serial.readBytesUntil(character, buffer, length)用于从设备接收到数据中读取信息读取到的数据信息将存放在缓存变量中。
①该函数在满足以下任一条件后都会停止函数执行并且返回读取到指定终止字符、读取到指定字节数的信息、达到设定时间可使用setTimeout来设置。
②当函数读取到终止字符后会立即停止函数执行此时buffer缓存变量/数组中所存储的信息为设备读取到终止字符前的字符内容。
③character是终止字符用于设置终止函数执行的字符信息允许使用char类型buffer是缓存变量/数组用于存储读取到的信息允许使用char或者byte类型的变量或数组length是读取字节数量readBytes函数在读取到length所指定的字节数量后就会停止运行允许使用int类型。
8Serial.write有两种形式
①Serial.write(val)将字节数据val通过串口发送val可以是一个字节数据也可以是由一系列字节数据组成的字符串。
②Serial.write(buf, len)将同一系列字节组成的数组buf通过串口发送len为数组长度。
9Serial.readString()用于从设备接收到数据中读取数据信息读取到的信息将以字符串格式返回。
10Serial.readStringUntil(terminator)用于从设备接收到的数据中读取信息读取到的数据信息将以字符串形式返回该函数在读取到指定终止字符terminator或达到设定时间可使用setTimeout来设置时都会停止函数执行并返回。