本科毕设通信模块,首次嵌入式工程尝试,集CSDN众多大家之成果,期间依旧遇坑无数,在此Mark,以便后续参考。
通信过程大致描述如下:树莓派通过2.4GHz廉价模块nrf24l01,发送无线数据给同样连接nrf24l01模块的Arduino模块,Arduino通过串口蓝牙将数据转发给安卓手机。
本文将分别记录以上通信实现过程,着重描述遇到的问题与解决方法。期间参考前辈教程攻略如下:
NF库:https://github.com/TMRh20/RF24.git
树莓派与Arduino通信 http://shumeipai.nxez.com/2017/03/20/communication-between-arduino-and-raspberry-pi.html
安卓蓝牙编程 https://blog.csdn.net/qq_30379689/article/details/52621769
树莓派波特率的修改 https://www.cnblogs.com/mengfanrong/p/4272038.html
以下雷区,请避开:
1、 便宜的Arduino常常存在各种各样的问题,不要图便宜,请使用正版Arduino
2、 便宜的nRF24L01模块(价格在10元附近),传输距离有时只有数米甚至更短。
如果想要完成类似本项目的百米无线通信,需要选用带有PA+LNA的模块,其理论通信距离甚至可以达到千米,其价格在单只20元左右。
做项目请不要图便宜。
序号 | nRF24L01 | 树莓派 | Arduino UNO | 蓝牙2.0 |
---|---|---|---|---|
1 | VCC |
1 | 3.3V(接5v 烧坏) | |
2 | GND | 9 | GND | |
3 | CE | 15 | 7(按照程序自定义) | |
4 | CSN | 24 | 8(按照程序自定义) | |
5 | SCK | 23 | 13 | |
6 | MOSI | 19 | 11 | |
7 | MISO | 21 | 12 | |
8 | TX | RX | ||
9 | RX | TX | ||
10 | 5V | +5V |
||
11 | GND | GND |
nRF24L01的管脚参考下图,参考模块上印的格子,参照点是角落着重标出的接地线方格。
树莓派管脚图如下(图片来自网络)
此部分参考直接引用http://shumeipai.nxez.com/2017/03/20/communication-between-arduino-and-raspberry-pi.html
1)RF库安装
将https://github.com/TMRh20/RF24.git上的RF24库复制到树莓派(或通过git直接获取)。进入RF24目录后执行如下命令,进行编译和安装(选择SPI方式)
1 2 |
|
2) 修改系统配置
1 2 3 4 5 |
|
reboot重启树莓派后,/dev下会新增spidev0.0和spidev0.1两个设备文件。
3)代码修改
修改RF24/example_linux/GettingStarted.cpp文件,
由于设备的一些原因,树莓派不能及时收到ack信号,但是数据均可正确发送。在要求不严格的情况下,不妨先删掉检测ack的相关代码,待发送的数据来自程序外I/O输入。更改后输入模式下的代码如下所示:
if (role == role_ping_out){
// First, stop listening so we can talk.
radio.stopListening();
printf("Now sending...\n");
unsigned long time = millis();
// 将程序外输入的数据发送出去
string tmp_input;
getline(cin, tmp_input);
const char* input_str = tmp_input.c_str();
count++;
bool ok = radio.write( input_str, strlen(input_str) );
printf("Have sent: %s\n", input_str);
sleep(1);
}
(修改后的代码可以参考https://github.com/iAlexKai/Raspberry2Arduino_send/blob/master/examples_linux/gettingstarted.cpp)
在当前目录下执行make后,生成GettingStarted的二进制文件。
4)运行
使用sudo ./ GettingStarted执行,并输入1进入发送模式。
1. 将从https://github.com/TMRh20/RF24.git下载来的代码,直接复制到Arduino安装目录的libraries目录下,启动ArduinoIDE,从示例中找到RF24 -> gettingStarted
2. 将代码中radioNumber 0 改为 1 :
bool radioNumber = 0;
->
bool radioNumber = 1;
注意,Arduino和树莓派的radioNumber必须一个为0,一个为1,表示建立通道的两个端
3. 由于我们将蓝牙模块接入了Arduino的输入输出端,蓝牙通信属于串口通信。代码中的Serial.println()发出的数据均可通过蓝牙发送。因此设备连接上此蓝牙模块后即可收到Arduino发出的数据。
(接收端代码可参考https://github.com/iAlexKai/Raspberry2Arduino_recv)
1. 蓝牙模块需要接入Arduino的5v管脚,在程序从电脑上传到Arduino板子上时需要拔掉此5v接线,否则由于并联的关系会导致程序无法上传。
2.两个模块进行数据收发时,要保证波特率一致。由于最终接收终端是安卓手机,安卓端并不提供更改波特率的接口,因此需要修改蓝牙模块以及树莓派的波特率为9600Baud,从而适应蓝牙模块。
Arduino可以通过直接修改代码中串口初始化参数即可更改波特率
Serial.begin(9600);
树莓派的波特率更改方式参考:https://www.cnblogs.com/mengfanrong/p/4272038.html
需要改动/boot/cmdline.txt文件删除原始的console=ttyAMA0,115200 kgdboc=ttyAMA0,115200
改动 /etc/inittab注释掉最后一行-L ttyAMA0 115200 vt100
通过apt-get安装minicom,root账户后输入minicom -s,找到波特率修改项,更改为9600Baud