Arduino通过nrf24l01与树莓派通信,并通过蓝牙转发给安卓手机

本科毕设通信模块,首次嵌入式工程尝试,集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元左右。

       做项目请不要图便宜。

 

二、树莓派/Arduino UNO/蓝牙2.0模块/nRF24L01相互连接

序号 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的管脚参考下图,参考模块上印的格子,参照点是角落着重标出的接地线方格。

Arduino通过nrf24l01与树莓派通信,并通过蓝牙转发给安卓手机_第1张图片

树莓派管脚图如下(图片来自网络)

Arduino通过nrf24l01与树莓派通信,并通过蓝牙转发给安卓手机_第2张图片

三、代码与实现

1.树莓派端发送代码 gettingstarted.cpp

 此部分参考直接引用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

./configure --driver=SPIDEV

sudo make install -B

2) 修改系统配置

1

2

3

4

5

修改/etc/modprobe.d/raspi-blacklist.conf,如果其中存在

blacklist spi-bcm2708,将其注释。

 

修改/etc/modules文件,在其中追加一行,开启SPI。

spidev

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进入发送模式。

2.Arduino接收端代码

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)

3.实现细节

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

你可能感兴趣的:(嵌入式工程,nRF24L01,树莓派,Arduino,蓝牙)