记录本人使用Arduino的一些经验笔记

  • 如何将Arduino的ino文件分解成多个.h和.cpp工程文件

当用Arduino做复杂工程项目时,程序难免会变得很大。这时候要修改个别参数或函数的时候会变得麻烦,简而言之,项目程序管理难度增高了,程序代码维护会变得困难。这时候,就产生了将一个ino文件分解成多个功能相对独立的源文件,这样就便于针对性的管理代码了。

1. 需要做的准备

不是所有的代码都方便分解成多个cpp文件进行管理的,特别是编程时想到哪编到哪的,代码会异常的凌乱。这意味着,里面的函数关系,逻辑嵌套,变量使用等都是极度凌乱的。这样的代码很难分解开来。因此,如果着手做的是一个相对大的项目,一开始便要有整体规划代码的意识。

一是以功能需求对应各个子函数,尽量一个函数只完成一个功能,避免功能上的嵌套;

二是变量定义要清晰。

在对整体的代码有了比较清晰的规划后,便可以着手分解代码了。

2.功能函数代码的分解

首先,你需要在原来工程文件夹下新建一个头文件,如 config.h,然后将Arduino的硬件接口定义放在这里面。然后,按照功能划分,分别建立各个功能的cpp文件,如 motion.cpp 文件中放置定义了各种运动的函数。然后将各个函数的声明写到 config.h 中。(原来一个ino文件时,软件会自动加函数声明,但现在需要自己加了)如:void trun_left(int, int); 。其他各种功能也是如此。但个函数都划分成多个cpp文件后,就要来处理全局变量的问题了。

3.全局变量的声明

因为在一个地方定义的变量很可能在其他地方使用,因此,全局变量就很关键了。原涞单个ino文件时,只要在 setup() ,上面定义的变量都默认是全局变量,但现在不行了,需要自己在声明。操作方式如下:

在任一cpp中定义你需要的变量,建议定义在最关键的地方。如在motion.cpp中定义了int speed=255; ,而这个变量在其他cpp文件中也要使用到,所以第二步如下:

在config.h 文件中对这个变量进行声明,extern int speed; 这可以跟函数声明一样理解,在这里声明后,在其他地方就可以使用了。

不要想当然的在 config.h 中先定义在声明,这样编译不会出错,但在链接时会出错,显示出现重复定义。(别问我问什么,我这么干失败了)

通过在cpp中定义变量,在头文件中声明该变量的方式便可实现全局变量的使用了。

4. 必要的步骤

在完成上面的步骤后,你还需要除了ino文件外的各个文件里都包含 #include"Arduino.h",否则程序里的HIGH,LOW,OUTPUT,pinMode之类的将无法识别。此外,你的各个cpp文件应该加上头文件 #include“config.h”,不用<>,而用双引号的原因是尖括号引用的是标准库,而这里是自定义的头文件等。最后,你也要在ino文件中包含头文件 #include"config.h"。 ino文件以及头文件中都无需包含cpp文件。

5. 程序的管理

经过上述步骤后,你的程序将由一个包含了setup(),loop()函数的ino文件,一个头文件config.h, 以及许多实现各种功能的cpp文件。 ino文件就是你的主程序了,你想要实现的主干逻辑写在这里面。它通过调用各个cpp里函数来实现你的功能。头文件则包含了你所使用的Arduino的各个接口定义,所有函数的声明,以及全局变量的声明。 而cpp文件则是按照功能类别,将许多子函数集中在一起的源文件。

  • I2C库文件wire

背景
使用 Arduino 例程的时候发现,官方的描述不太详细,走了些弯路。特此,写篇文章记录下。

Arduino 的 I2C 相关函数
Arduino 的封装库真的是非非常的棒,I2C 就只有 10 个 API 函数。I2C 所用的库,称为:Wire Library。详细的描述可以看这个官方地址:

https://www.arduino.cc/en/Reference/Wire

下面我会介绍部分的 API 函数。

begin

begin 函数用于初始化 Wrie Library 并以 Master 或 Slave 的身份加入 I2C 总线上。begin 函数没有返回值。调用 begin 函数有两种形式:

begin():无输入参数,表示以 Master 形式加入总线。
begin( address ):有输入参数,表示以从机形式加入总线,设备地址为address(7-bit)

beginTransmission

beginTransmission 函数用于启动一次 Master write to Slave 操作。值得注意的是这个函数的调用并不会产生 Start 信号 和发送 Slave Address,仅是实现通知 Arduino后面要启动 Master write to Slave 操作。

beginTransmission 函数调用后,(再调用 write 函数进行数据写入), 最后再调用 endTransmission 函数方能产生 Start 信号 和发送 Slave Address 及通讯时序。
beginTransmission 函数调用形式:

beginTransmission(address)
 

write

write 函数用于向 Slave 写入数据。共有 3 种调用形式:

write(value) :写入单字节
write(string) :写入字符串
write(data, length) :写入 length 个字节

endTransmission

endTransmission 函数用于结束一次 Master write to Slave 操作。前面在介绍 beginTransmission 的时候也介绍过了,如果不在后面使用 endTransmission 函数, 总线上不会产生 Master write to Slave 的时序。

endTransmission 函数的调用十分有意思。endTransmission 函数可输入参数。

endTransmission(0):当输入参数为 0 时,将在通讯结束后,不产生 STOP 信号。
endTransmission(!0):当输入参数为 !0 时,在通讯结束后,生成 STOP 信号。(释放总线)
endTransmission():当无输入参数时,在通讯结束后,产生 STOP 信号。(释放总线)
因为我设计的产品程序是使用 DUMMY WRITE 时序,就是这个不产生 STOP 信号卡了我半天的时间(这是我要写本文的原因……)。而官方中,并没有详细介绍这个输入参数…

同时,endTransmission 函数时具有返回值的:

0:success
1:data too long to fit in transmit buffer
2:received NACK on transmit of address
3:received NACK on transmit of data
4:other error
有个地方需要注意的:当通讯过程中,出现异常后,异常后的 write 操作将被终止,直接结束通讯,具体的是否出现异常,只需要看 endTransmission 的返回值即可。

​​​​​​​requestFrom

requestFrom 函数用于实现 Master Read From Slave 操作。调用形式有 2 种:

requestFrom(address, quantity):从 address 设备读取 quantity 个字节,结束后,产生 STOP 信号
requestFrom(address, quantity, stop) :从 address 设备读取 quantity 个字节,结束后,依据 stop 的值确定是否产生 STOP 信号。
stop = 0:不产生 STOP 信号
stop != 0:产生 STOP 信号
requestFrom 函数具有返回值(表示从 address 设备读取到的字节数)。

available


available 函数用于统计 Master Read From Slave 操作后, read 缓存区剩余的字节数。每当缓存区的数据被读走 1 个字节,available 函数的返回值减一。通常 available 函数会搭配着 read 函数使用。

read


read 函数用于在 Master Read From Slave 操作后,读取缓存区的数据。

串口

串口发送数据时,数据的发送顺序取决于计算机的字节序(Endianness)。对于串口通信,数据通常以字节为单位发送,而多字节数据的发送顺序会受到系统是Big-Endian还是Little-Endian的影响:

Little-Endian:在Little-Endian系统中,最低有效字节(Least Significant Byte, LSB)首先发送。如果你在Little-Endian系统中通过串口发送0x12345678,它会先发送78,然后是56,接着是34,最后是12。

Big-Endian:在Big-Endian系统中,最高有效字节(Most Significant Byte, MSB)首先发送。如果你在Big-Endian系统中通过串口发送0x12345678,它会先发送12,然后是34,接着是56,最后是78。

大多数个人电脑和现代操作系统(包括Windows、macOS和Linux)通常都是Little-Endian的。因此,如果你没有特别设置,当你尝试通过这些系统的串口发送0x12345678时,你通常会看到78 56 34 12这样的顺序发送出去。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值