Arduino C 硬件编程入门
—— 本文献给2023新年里想和孩子一起学习、成长的家长朋友们!
一、Arduino C是什么?
很多人把Arduino编程语言称为Arduino C,大概是因为它的语言是基于C/C++的。Arduino C封装了Arduino各种硬件的API接口,不需要学习底层知识就可以控制Arduino硬件,这样对孩子和硬件入门者都是非常友好的。
经过多年的开源,Arduino C有非常多实用的开源库,可以直接使用,用来方便的控制各类传感器,比如舵机、超声波、红外等,当然你也可以自己编写好用、实用的库,开源给别人使用,这也是Arduino的精神。
二、Arduino C的开发工具是什么?
我是使用官方的Arduino IDE工具开发和调试Arduino程序的,我在头条发过几期短视频《2分钟硬件编程系列》,里面就是使用的Arduino IDE。虽然相对于我工作中经常使用的VS和Eclipse,Arduino IDE的功能过于简单,不够智能化,但对于简单的硬件接口编程来说,已经够用了。
我目前使用的Arduino IDE工具版本是1.8.9,不过arduino.cc已经推出了最新的稳定版本2.0.3,社区反馈不错,我比较看重的是增加了自动纠错和自动补充功能,可以有效减少代码错误并提高效率,等我试用过后,下期单独写一篇文章详细介绍给大家。
IDE工具怎么得到:Arduino IDE官方https://www.arduino.cc/en/software
我的Arduino IDE1.8.9主界面
三、Arduino C的程序结构
我在《2分钟硬件编程系列》中,每个短视频都详细介绍了每一句代码,和我们大学时代学习的C语言相比,Arduino C非常简单,很容易入门,包括10岁左右的孩子。
一个简单而完整的Arduino C程序,只需编写setup和loop函数就可以了。Setup函数里做初始化工作,而loop函数里则是主程序,所以一个完整的Arduino C程序结构就是这样简单:
- 结构第1部分:引入第三方库,定义引脚。
- 结构第2部分:setup()初始化代码,只运行一次。
- 结构第3部分:loop()主程序代码,可反复执行。
四、Arduino C 源码例子详解——超声波避障小车
下面看一段《2分钟硬件编程系列》中超声波小车的源代码,这段代码实现的功能很简单,就是超声波探测到小车前方有障碍物体时,完成自动停车。
源码:
//结构第1部分:
const int leftPin1=5;// 左侧电机引脚
const int leftPin2=6; // 左侧电机引脚
const int rightPin1=11; // 右侧电机引脚
const int rightPin2=3; // 右侧电机引脚
const int trigPin=7; // 超声波trig引脚
const int echoPin=8; // 超声波echo引脚
int disVal=0;//超声波探测距离变量
//问题(1):为什么定义引脚需要const修饰,而定义disVal不需要const修饰呢?我在后面再讲。
//结构第2部分:
void setup() {
//初始化代码,这里只运行一次:
pinMode(leftPin1,OUTPUT);//电机引脚设置为输出模式
pinMode(leftPin2,OUTPUT); //电机引脚设置为输出模式
pinMode(rightPin1,OUTPUT); //电机引脚设置为输出模式
pinMode(rightPin2,OUTPUT); //电机引脚设置为输出模式
pinMode(trigPin,OUTPUT); //超声波trig引脚设置为输出模式
pinMode(echoPin,INPUT); //超声波echo引脚设置为输入模式
}
//结构第3部分:
void loop() {
//主程序代码,会反复运行:
digitalWrite(trigPin,LOW); //超声波trig引脚输出低电平初始化,以便得到干净的高电平。
delayMicroseconds(2); //延时2微秒。
digitalWrite(trigPin,HIGH); //超声波trig引脚输出高电平,触发超声波发射8个40KHz的方波。
delayMicroseconds(10); //延时10微秒。
digitalWrite(trigPin,LOW); //超声波trig引脚输出低电平结束本次触发动作。
disVal = pulseIn(echoPin,HIGH)/58.0;
//问题(2):这里通过一个通用的公式得到超声波探测前方障碍物的距离(单位cm),那么,这个公式原理是什么呢?这个问题也放在后面讲。
//判断前方障碍物的距离
if(disVal >10){
//如果前方障碍物的距离超过10厘米,则执行如下前进操作:
analogWrite(leftPin1,0);
analogWrite(leftPin2,130);//启动左侧电机(带动小车左轮)
analogWrite(rightPin1,0);
analogWrite(rightPin2,130); //启动右侧电机(带动小车右轮)
}else{
//如果前方障碍物的距离不超过10厘米,则执行如下停止操作:
analogWrite(leftPin1,0);
analogWrite(leftPin2,0);//停止
analogWrite(rightPin1,0);
analogWrite(rightPin2,0); //停止
}
}
这样就是一个完整的程序了,Arduino IDE编译完成后,通过串口上传至Arduino主控板即可调试。运行效果:2分钟硬件编程(3):超声波主动避障
我搭建的超声波小车
在前面还留了两个问题:
(1) 为什么定义引脚需要const修饰,而定义disVal不需要const修饰呢?
const作为C语言中的常变量修饰符,一个变量使用const修饰之后,其值将不允许再次被改变,否则编程会出现错误。
比如用const修饰int变量leftPin1(电机引脚):const int leftPin1=5;
这时leftPin1成为了常变量,其引脚值不能在程序中动态修改。
而超声波探测距离是实时在改变着的,所以变量disVal也是需要不停改变的,所以不能用const修饰,直接这样定义即可:int disVal=0;
(2) pulseIn(echoPin,HIGH)/58.0这个公式原理是什么呢?
超声波发射8个40KHz的方波完成探测后,echo引脚会持续输出高电平,持续时间就是方波发射到返回的时间,pulseIn()函数可以得到这个时间(微秒单位)。
那么我们如果把这个时间(微秒)转换成距离(厘米)呢?
方波的速度(也就是声速)是340 米/秒,可以换算为0.034cm/微秒,速度乘以时间就是距离,所以0.034*pulseIn()得到的是方波往返的距离,然后需要除2,才是真正到前方障碍物的距离,因此完整的公式是:
0.034*pulseIn()/2
这个公式可以进一步简化为:
pulseIn()/58
所有人,2023,新年好!
Arduino常见函数讲解
今天马克笔设计留学的程老师继续来跟大家讲解Arduino的相关知识。前面我们介绍了很多Arduino的传感器《 》,那这篇文章我们来讲一下Arduino里面的编程语言,也就是一些常见函数的应用。Arduino 是由 C/C++ 混合编写而成。Arduino 语言也继承了 C/C++ 语言的语法。通常所说的 Arduino 语言,是指 Arduino 核心库文件提供的各种应用程序编程接口(Application Programming Interface,简称API)的集合。Arduino程序基本结构由setup() 和loop() 两个函数组成,那我们就先来看看这两个函数是如何使用的。
Arduino控制器通电或复位后,即会开始执行setup() 函数中的程序,我们一般会把要执行的程序写在中括号里,该部分的程序只会执行一次。通常我们会在setup() 函数中完成Arduino的初始化设置,如配置I/O口状态,初始化串口等操作。
在Setup() 函数中的程序执行完后,Arduino会接着执行Loop() 函数中的程序。而Loop()函数是一个死循环,其中的程序会不断的重复运行。通常我们会在loop() 函数中完成程序的主要功能,如驱动各种模块,采集数据等。我们拿一个最简单的灯泡闪烁这个为例,讲一下LOOP这个函数,中括号里面写的内容我们可以解读为:首先LED小灯泡亮,之后延迟一秒,接着LED小灯泡灭,之后又延迟了一秒,最后反复循环这一段程序,从而实现了小灯泡闪烁的效果。
描述:将程序暂停给定参数的时间量(以毫秒为单位)
- 函数原型:delay(ms)
- 参数:ms – 暂停的毫秒数
- 返回值:无
If else 语句是一种选择结构,可以让代码选择执行。所谓选择执行,就是“某些代码可能执行,也可能不执行,有选择地执行某些代码”。If 语句后面可以跟随一个可选的 else if … else 语句,其对于测试各种条件非常实用。
当使用 if … else if … else 语句时,我们需要记住三个要点:
1)一个 if 可以有0或一个else语句,它必须在所有else if之后。2)if 可以有0到多个else if语句,它们必须在else之前。3)一旦 else if 成功,将不会测试剩余的else if或else语句。
我们来举个例子:
HIGH | LOW 表示数字IO口的高低电平。HIGH 表示高电(1),LOW 表示低电平(0)。
INPUT | OUTPUT 表示数字IO口的方向,INPUT 表示输入(高阻态),OUTPUT 表示输出(AVR单片机能提供5V电压 40mA电流)。Arduino中输出的低电平为0V,输出的高电平为当前Arduino的工作电压。例如Arduino UNO的工作电压为5V,其高电平输出也是5V;Arduino UNO工作电压为3.3V,所以高电平输出也就是3.3V。
没有接触过C语言的同学,可能一上来接受这么多知识会觉得有些困难,其实C语言学起来并不是很难,比较友好。我们可以先从一些简单的语句写起来,用一些简单的函数做一些实验,等真正掌握了各个常见函数的应用场景之后,就可以实现复杂的效果了。还要跟大家强调一点,无论是Arduino电路连接还是C语言学习,都需要不断尝试 ,不断试错,只有这样才能真正学会函数的用法。
文章作者:程雅秋英国皇家艺术学院产品设计硕士擅长产品服务系统设计、用户体验设计和硬件Arduino交互
2023年元旦新篇章——我的Arduino C 硬件编程入门,献给家长朋友们
—— 本文献给2023新年里想和孩子一起学习、成长的家长朋友们!
一、Arduino C是什么?
很多人把Arduino编程语言称为Arduino C,大概是因为它的语言是基于C/C++的。Arduino C封装了Arduino各种硬件的API接口,不需要学习底层知识就可以控制Arduino硬件,这样对孩子和硬件入门者都是非常友好的。
经过多年的开源,Arduino C有非常多实用的开源库,可以直接使用,用来方便的控制各类传感器,比如舵机、超声波、红外等,当然你也可以自己编写好用、实用的库,开源给别人使用,这也是Arduino的精神。
二、Arduino C的开发工具是什么?
我是使用官方的Arduino IDE工具开发和调试Arduino程序的,我在头条发过几期短视频《2分钟硬件编程系列》,里面就是使用的Arduino IDE。虽然相对于我工作中经常使用的VS和Eclipse,Arduino IDE的功能过于简单,不够智能化,但对于简单的硬件接口编程来说,已经够用了。
我目前使用的Arduino IDE工具版本是1.8.9,不过arduino.cc已经推出了最新的稳定版本2.0.3,社区反馈不错,我比较看重的是增加了自动纠错和自动补充功能,可以有效减少代码错误并提高效率,等我试用过后,下期单独写一篇文章详细介绍给大家。
IDE工具怎么得到:Arduino IDE官方 https://www.arduino.cc/en/software
我的Arduino IDE1.8.9主界面
三、Arduino C的程序结构
我在《2分钟硬件编程系列》中,每个短视频都详细介绍了每一句代码,和我们大学时代学习的C语言相比,Arduino C非常简单,很容易入门,包括10岁左右的孩子。
一个简单而完整的Arduino C程序,只需编写setup和loop函数就可以了。Setup函数里做初始化工作,而loop函数里则是主程序,所以一个完整的Arduino C程序结构就是这样简单:
- 结构第1部分:引入第三方库,定义引脚。
- 结构第2部分:setup()初始化代码,只运行一次。
- 结构第3部分:loop()主程序代码,可反复执行。
四、Arduino C 源码例子详解——超声波避障小车
下面看一段《2分钟硬件编程系列》中超声波小车的源代码,这段代码实现的功能很简单,就是超声波探测到小车前方有障碍物体时,完成自动停车。
源码:
//结构第1部分:
const int leftPin1=5;// 左侧电机引脚
const int leftPin2=6; // 左侧电机引脚
const int rightPin1=11; // 右侧电机引脚
const int rightPin2=3; // 右侧电机引脚
const int trigPin=7; // 超声波trig引脚
const int echoPin=8; // 超声波echo引脚
int disVal=0;//超声波探测距离变量
//问题(1):为什么定义引脚需要const修饰,而定义disVal不需要const修饰呢?我在后面再讲。
//结构第2部分:
void setup() {
//初始化代码,这里只运行一次:
pinMode(leftPin1,OUTPUT);//电机引脚设置为输出模式
pinMode(leftPin2,OUTPUT); //电机引脚设置为输出模式
pinMode(rightPin1,OUTPUT); //电机引脚设置为输出模式
pinMode(rightPin2,OUTPUT); //电机引脚设置为输出模式
pinMode(trigPin,OUTPUT); //超声波trig引脚设置为输出模式
pinMode(echoPin,INPUT); //超声波echo引脚设置为输入模式
}
//结构第3部分:
void loop() {
//主程序代码,会反复运行:
digitalWrite(trigPin,LOW); //超声波trig引脚输出低电平初始化,以便得到干净的高电平。
delayMicroseconds(2); //延时2微秒。
digitalWrite(trigPin,HIGH); //超声波trig引脚输出高电平,触发超声波发射8个40KHz的方波。
delayMicroseconds(10); //延时10微秒。
digitalWrite(trigPin,LOW); //超声波trig引脚输出低电平结束本次触发动作。
disVal = pulseIn(echoPin,HIGH)/58.0;
//问题(2):这里通过一个通用的公式得到超声波探测前方障碍物的距离(单位cm),那么,这个公式原理是什么呢?这个问题也放在后面讲。
//判断前方障碍物的距离
if(disVal >10){
//如果前方障碍物的距离超过10厘米,则执行如下前进操作:
analogWrite(leftPin1,0);
analogWrite(leftPin2,130);//启动左侧电机(带动小车左轮)
analogWrite(rightPin1,0);
analogWrite(rightPin2,130); //启动右侧电机(带动小车右轮)
}else{
//如果前方障碍物的距离不超过10厘米,则执行如下停止操作:
analogWrite(leftPin1,0);
analogWrite(leftPin2,0);//停止
analogWrite(rightPin1,0);
analogWrite(rightPin2,0); //停止
}
}
这样就是一个完整的程序了,Arduino IDE编译完成后,通过串口上传至Arduino主控板即可调试。运行效果:
我搭建的超声波小车
在前面还留了两个问题:
(1) 为什么定义引脚需要const修饰,而定义disVal不需要const修饰呢?
const作为C语言中的常变量修饰符,一个变量使用const修饰之后,其值将不允许再次被改变,否则编程会出现错误。
比如用const修饰int变量leftPin1(电机引脚):const int leftPin1=5;
这时leftPin1成为了常变量,其引脚值不能在程序中动态修改。
而超声波探测距离是实时在改变着的,所以变量disVal也是需要不停改变的,所以不能用const修饰,直接这样定义即可:int disVal=0;
(2) pulseIn(echoPin,HIGH)/58.0这个公式原理是什么呢?
超声波发射8个40KHz的方波完成探测后,echo引脚会持续输出高电平,持续时间就是方波发射到返回的时间,pulseIn()函数可以得到这个时间(微秒单位)。
那么我们如果把这个时间(微秒)转换成距离(厘米)呢?
方波的速度(也就是声速)是340 米/秒,可以换算为0.034cm/微秒,速度乘以时间就是距离,所以0.034*pulseIn()得到的是方波往返的距离,然后需要除2,才是真正到前方障碍物的距离,因此完整的公式是:
0.034*pulseIn()/2
这个公式可以进一步简化为:
pulseIn()/58
五、Arduino C 近期一些源码例子推荐
我的红外超声波小车
再有10分钟就是新年了!
2022年注定是所有人刻骨铭心的一年,很多人永远地离开了,包括自己的一些亲人。但我们依旧希望这个世界一年比一年好。
虽然会很难,但”希望“永远是人类存在的价值,我们相信希望,我们带着美好的希望在新的2023年里继续努力,希望可以激发学习和生活的动力,希望可以激发创造的力量,希望可以让文明更进步。
借用《基督山伯爵》的结尾,人生的智慧都集中在两个词,希望与等待。
所有人,2023,新年好!
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。