极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 16931|回复: 5

如何用NRF24l01同时发送多组有正负的数字?

[复制链接]
发表于 2016-9-7 22:51:14 | 显示全部楼层 |阅读模式
本帖最后由 kyzo 于 2016-12-14 21:31 编辑

如题
我想用NRF24l01模块发送  MPU6050陀螺仪接收到的数据
ax, ay, az, gx, gy, gz;

看教程说只能以byte字节形式发送, 可是字节是无符号的

然后我将数据转成十六进制再发送, 还是不成功。

本人c语言比较菜, 如有菜鸟错误请原谅!!
程序是根据别人的程序改的, 备注部分没有改过来。
望有能人帮我解决解决~

下面是发送端代码
  1. /*
  2. nRF24L01 Arduino发送端

  3. 引脚接法:
  4. nRF24L01   Arduino UNO
  5. VCC        <->        3.3V
  6. GND        <->        GND
  7. CE        <->        D9
  8. CSN        <->        D10
  9. MOSI<->        D11
  10. MISO<->        D12
  11. SCK        <->        D13
  12. IRQ        <->        不接
  13. */

  14. #include "Wire.h"
  15. #include "I2Cdev.h"
  16. #include "MPU6050.h"
  17. MPU6050 accelgyro;

  18. int16_t ax, ay, az;
  19. int16_t gx, gy, gz;
  20. char adata[] = {0,0,0,0,0,0};

  21. #include <SPI.h>
  22. #include <Mirf.h>
  23. #include <nRF24L01.h>
  24. #include <MirfHardwareSpiDriver.h>
  25. void setup()
  26. {
  27.     Wire.begin();
  28.     Serial.begin(9600);
  29.     accelgyro.initialize();

  30.     Mirf.cePin = 9;                //设置CE引脚为D9
  31.     Mirf.csnPin = 10;        //设置CE引脚为D10
  32.     Mirf.spi = &MirfHardwareSpi;
  33.     Mirf.init();  //初始化nRF24L01               

  34.         //设置接收标识符"Sen01"
  35.     Mirf.setRADDR((byte *)"Sen01");
  36.     //设置一次收发的字节数,这里发一个整数,写sizeof(unsigned int),实际等于2字节
  37.     Mirf.payload = sizeof(char);
  38.     //发送通道,可以填0~128,收发必须一致。
  39.     Mirf.channel = 5;
  40.     Mirf.config();

  41.         //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
  42.         //这里标识写入了Sender.ino
  43.     Serial.println("I'm Sender...");
  44. }
  45. //int adata = 0;
  46. void loop()
  47. {
  48.         //读取A0值到adata
  49.     //adata = analogRead(A0);
  50.     accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  51.     /*ax= ax/16384;
  52.     ay= ay/16384;
  53.     az= az/16384;
  54.     gx= gx/131;
  55.     gy= gy/131;
  56.     gz= gz/131; */

  57.     /*adata[0] = ax/16384;
  58.     adata[1] = ay/16384;
  59.     adata[2] = az/16384;
  60.     adata[3] = gx/131;
  61.     adata[4] = gy/131;
  62.     adata[5] = gz/131;  */

  63.     adata[0] = (ax/16384,HEX);
  64.     adata[1] = (ay/16384,HEX);
  65.     adata[2] = (az/16384,HEX);
  66.     adata[3] = (gx/131,HEX);
  67.     adata[4] = (gy/131,HEX);
  68.     adata[5] = (gz/131,HEX);

  69.     //由于nRF24L01只能以byte单字节数组形式发送Mirf.payload个数据,
  70.     //所以必须将所有需要传输的数据拆成byte。
  71.     //下面定义byte数组,存放待发数据,因为Mirf.payload = sizeof(unsigned int);
  72.     //实际下面等于byte data[2];
  73.     byte data0[Mirf.payload];
  74.     byte data1[Mirf.payload];
  75.     byte data2[Mirf.payload];
  76.     byte data3[Mirf.payload];
  77.     byte data4[Mirf.payload];
  78.     byte data5[Mirf.payload];

  79.     //adata是unsigned int双字节数据,必须拆开。
  80.     //将adata高低八位拆分:
  81.     data0[0] = adata[0] & 0xFF;                //低八位给data[0],
  82.     data0[1] = adata[0] >> 8;                //高八位给data[1]。
  83.     data1[0] = adata[1] & 0xFF;
  84.     data1[1] = adata[1] >> 8;
  85.     data2[0] = adata[2] & 0xFF;
  86.     data2[1] = adata[2] >> 8;
  87.     data3[0] = adata[3] & 0xFF;
  88.     data3[1] = adata[3] >> 8;
  89.     data4[0] = adata[4] & 0xFF;
  90.     data4[1] = adata[4] >> 8;
  91.     data5[0] = adata[5] & 0xFF;
  92.     data5[1] = adata[5] >> 8;
  93.    
  94.     //data

  95.     //设置向"serv1"发送数据
  96.     Mirf.setTADDR((byte *)"Rec01");
  97.     Mirf.send(data0);
  98.     Mirf.send(data1);
  99.     Mirf.send(data2);
  100.     Mirf.send(data3);
  101.     Mirf.send(data4);
  102.     Mirf.send(data5);
  103.    

  104.     /*Serial.print(adata[0]); Serial.print("\t");
  105.     Serial.print(adata[1]); Serial.print("\t");
  106.     Serial.print(adata[2]); Serial.print("\t");
  107.     Serial.print(adata[3]); Serial.print("\t");
  108.     Serial.print(adata[4]); Serial.print("\t");
  109.     Serial.println(adata[5]);  */  
  110.     //while死循环等待发送完毕,才能进行下一步操作。
  111.     while(Mirf.isSending()) {}
  112.     delay(20);
  113. }
复制代码


下面是接收端代码:
  1. /*
  2. nRF24L01 Arduino Receiver接收端

  3. 引脚接法:
  4. nRF24L01   Arduino UNO
  5. VCC <-> 3.3V
  6. GND <-> GND
  7. CE  <-> D9
  8. CSN <-> D10
  9. MOSI<-> D11
  10. MISO<-> D12
  11. SCK <-> D13
  12. IRQ <-> 不接
  13. */

  14. #include <SPI.h>
  15. #include <Mirf.h>
  16. #include <nRF24L01.h>
  17. #include <MirfHardwareSpiDriver.h>

  18.     //定义一个变量adata存储最终结果,oldadata存储旧结果,防止相同结果刷屏。
  19.     int adata[]= {0,0,0,0,0,0};
  20.     int olddata[] = {0,0,0,0,0,0};
  21.     int adata0 =0, adata1 = 0, adata2 =0, adata3 = 0, adata4= 0, adata5 =0;

  22. void setup()
  23. {
  24.     Serial.begin(9600);

  25.     //---------初始化部分,不可随时修改---------
  26.     Mirf.cePin = 9;     //设置CE引脚为D9
  27.     Mirf.csnPin = 10;   //设置CE引脚为D10
  28.     Mirf.spi = &MirfHardwareSpi;
  29.     Mirf.init();  //初始化nRF24L01

  30.     //---------配置部分,可以随时修改---------
  31.     //设置接收标识符"Rev01"
  32.     Mirf.setRADDR((byte *)"Rec01");
  33.     //设置一次收发的字节数,这里发一个整数,
  34.     //写sizeof(unsigned int),实际等于2字节
  35.     Mirf.payload = sizeof(char);
  36.     //发送通道,可以填0~128,收发必须一致。
  37.     Mirf.channel = 5;
  38.     Mirf.config();

  39.     //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
  40.     //这里用来辨别写入了Receiver.ino程序
  41.     Serial.println("I'm Receiver...");
  42. }

  43. void loop()
  44. {
  45.     //定义一个暂存数组,大小为Mirf.payload。
  46.     byte data0[Mirf.payload];
  47.     byte data1[Mirf.payload];
  48.     byte data2[Mirf.payload];
  49.     byte data3[Mirf.payload];
  50.     byte data4[Mirf.payload];
  51.     byte data5[Mirf.payload];
  52.     if(Mirf.dataReady())    //等待接收数据准备好
  53.     {
  54.         Mirf.getData(data0);    //接收数据到data数组
  55.         Mirf.getData(data1);
  56.         Mirf.getData(data2);
  57.         Mirf.getData(data3);
  58.         Mirf.getData(data4);
  59.         Mirf.getData(data5);
  60.         
  61.         //data[1]<左移8位与data[0]并,重组数据。
  62.         // adata = (unsigned int)((data[1] << 8) | data[0]);

  63.         //int("adata");
  64.         adata0 = (unsigned int)((data0[1] << 8) | data0[0]);
  65.         adata1 = (unsigned int)((data1[1] << 8) | data1[0]);
  66.         adata2 = (unsigned int)((data2[1] << 8) | data2[0]);
  67.         adata3 = (unsigned int)((data3[1] << 8) | data3[0]);
  68.         adata4 = (unsigned int)((data4[1] << 8) | data4[0]);
  69.         adata5 = (unsigned int)((data5[1] << 8) | data5[0]);

  70.         /*adata[0] = adata0;
  71.         adata[1] = adata1;
  72.         adata[2] = adata2;
  73.         adata[3] = adata3;
  74.         adata[4] = adata4;
  75.         adata[5] = adata5; */

  76.         adata[0] = (adata0,DEC);
  77.         adata[1] = (adata1,DEC);
  78.         adata[2] = (adata2,DEC);
  79.         adata[3] = (adata3,DEC);
  80.         adata[4] = (adata4,DEC);
  81.         adata[5] = (adata5,DEC);
  82.         
  83.       

  84.         //与上一次结果比较,避免相同结果刷屏,降低串口流量
  85.         if(adata != olddata)
  86.         {
  87.             olddata[0] = adata[0]; //本次结果作为历史结果。
  88.             olddata[1] = adata[1];
  89.             olddata[2] = adata[2];
  90.             olddata[3] = adata[3];
  91.             olddata[4] = adata[4];
  92.             olddata[5] = adata[5];
  93.             
  94.             //Serial.print输出数据
  95.             //Serial.print("A0=");
  96.             //Serial.println(adata);
  97.             //也可以输出双字节数据   
  98.     Serial.print(adata[0]); Serial.print("\t");
  99.     Serial.print(adata[1]); Serial.print("\t");
  100.     Serial.print(adata[2]); Serial.print("\t");
  101.     Serial.print(adata[3]); Serial.print("\t");
  102.     Serial.print(adata[4]); Serial.print("\t");
  103.     Serial.println(adata[5]);
  104.             //Serial.write(data[1]);
  105.             //Serial.write(data[0]);
  106.        }

  107.     }
  108. }
复制代码
回复

使用道具 举报

发表于 2016-9-8 08:15:17 | 显示全部楼层
本帖最后由 275891381 于 2016-9-8 08:41 编辑

自己定义个规则  每个int16_t 按3个字节发送  第一个定义个正负标志  第二个高8位  第三个 低八位  就可以了      例如符号位用0x0f 代表负   0xf0 代表 正    -12345=0x0f  0x48 0f69

  1. /*
  2. nRF24L01 Arduino发送端

  3. 引脚接法:
  4. nRF24L01   Arduino UNO
  5. VCC        <->        3.3V
  6. GND        <->        GND
  7. CE        <->        D9
  8. CSN        <->        D10
  9. MOSI<->        D11
  10. MISO<->        D12
  11. SCK        <->        D13
  12. IRQ        <->        不接
  13. */

  14. #include "Wire.h"
  15. #include "I2Cdev.h"
  16. #include "MPU6050.h"
  17. MPU6050 accelgyro;
  18. int16_t data[6];
  19. int num=0;
  20. int16_t ax, ay, az;
  21. int16_t gx, gy, gz;
  22. char adata[] = {0,0,0,0,0,0};

  23. #include <SPI.h>
  24. #include <Mirf.h>
  25. #include <nRF24L01.h>
  26. #include <MirfHardwareSpiDriver.h>
  27. void setup()
  28. {
  29.     Wire.begin();
  30.     Serial.begin(9600);
  31.     accelgyro.initialize();

  32.     Mirf.cePin = 9;                //设置CE引脚为D9
  33.     Mirf.csnPin = 10;        //设置CE引脚为D10
  34.     Mirf.spi = &MirfHardwareSpi;
  35.     Mirf.init();  //初始化nRF24L01               

  36.         //设置接收标识符"Sen01"
  37.     Mirf.setRADDR((byte *)"Sen01");
  38.     //设置一次收发的字节数,这里发一个整数,写sizeof(unsigned int),实际等于2字节
  39.     Mirf.payload = 18;
  40.    
  41.     //发送通道,可以填0~128,收发必须一致。
  42.     Mirf.channel = 5;
  43.     Mirf.config();

  44.         //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
  45.         //这里标识写入了Sender.ino
  46.     Serial.println("I'm Sender...");
  47. }
  48. //int adata = 0;
  49. void loop()
  50. {
  51.         //读取A0值到adata
  52.     //adata = analogRead(A0);
  53.     accelgyro.getMotion6(&data[0], &data[1], &data[2], &data[3], &data[4], &data[5]);
  54.     byte adata[Mirf.payload];
  55.     for(int i=0;i<6;i++)
  56.     {
  57.           if(data[i]< 0){adata[3*i+0]=0x0f;adata[3*i+1]=(0-data[i])/255;adata[3*i+2]=(0-data[i])%255;}
  58.           if(data[i]>=0){adata[3*i+0]=0xf0;adata[3*i+1]=(0+data[i])/255;adata[3*i+2]=(0+data[i])%255;}
  59.     }

  60.     //设置向"serv1"发送数据
  61.     Mirf.setTADDR((byte *)"Rec01");
  62.     Mirf.send(adata);

  63.     /*Serial.print(adata[0]); Serial.print("\t");
  64.     Serial.print(adata[1]); Serial.print("\t");
  65.     Serial.print(adata[2]); Serial.print("\t");
  66.     Serial.print(adata[3]); Serial.print("\t");
  67.     Serial.print(adata[4]); Serial.print("\t");
  68.     Serial.println(adata[5]);  */  
  69.     //while死循环等待发送完毕,才能进行下一步操作。
  70.     while(Mirf.isSending()) {}
  71.     delay(20);
  72. }
复制代码




回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-9-8 11:12:38 | 显示全部楼层
275891381 发表于 2016-9-8 08:15
自己定义个规则  每个int16_t 按3个字节发送  第一个定义个正负标志  第二个高8位  第三个 低八位  就可以 ...

可以加个qq向您寻求指导吗 我q740237763
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-8 13:16:03 | 显示全部楼层
本帖最后由 kyzo 于 2016-9-8 13:23 编辑
275891381 发表于 2016-9-8 08:15
自己定义个规则  每个int16_t 按3个字节发送  第一个定义个正负标志  第二个高8位  第三个 低八位  就可以 ...


谢谢你!!我跟着这个思路已经做出来了!

接收端代码:
  1. /*
  2. nRF24L01 Arduino Receiver接收端

  3. Ansifa
  4. 2015/3/7

  5. 引脚接法:
  6. nRF24L01   Arduino UNO
  7. VCC <-> 3.3V
  8. GND <-> GND
  9. CE  <-> D9
  10. CSN <-> D10
  11. MOSI<-> D11
  12. MISO<-> D12
  13. SCK <-> D13
  14. IRQ <-> 不接
  15. */

  16. #include <SPI.h>
  17. #include <Mirf.h>
  18. #include <nRF24L01.h>
  19. #include <MirfHardwareSpiDriver.h>

  20.     //定义一个变量adata存储最终结果,oldadata存储旧结果,防止相同结果刷屏。
  21.     int16_t data[6];
  22.     int16_t olddata[6];
  23.    // int adata0 =0, adata1 = 0, adata2 =0, adata3 = 0, adata4= 0, adata5 =0;

  24. void setup()
  25. {
  26.     Serial.begin(9600);

  27.     //---------初始化部分,不可随时修改---------
  28.     Mirf.cePin = 9;     //设置CE引脚为D9
  29.     Mirf.csnPin = 10;   //设置CE引脚为D10
  30.     Mirf.spi = &MirfHardwareSpi;
  31.     Mirf.init();  //初始化nRF24L01

  32.     //---------配置部分,可以随时修改---------
  33.     //设置接收标识符"Rev01"
  34.     Mirf.setRADDR((byte *)"Rec01");
  35.     //设置一次收发的字节数,这里发一个整数,
  36.     //写sizeof(unsigned int),实际等于2字节
  37.     Mirf.payload = 18;//sizeof(char);
  38.     //发送通道,可以填0~128,收发必须一致。
  39.     Mirf.channel = 5;
  40.     Mirf.config();

  41.     //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
  42.     //这里用来辨别写入了Receiver.ino程序
  43.     Serial.println("I'm Receiver...");
  44. }

  45. void loop()
  46. {
  47.     //定义一个暂存数组,大小为Mirf.payload。
  48.     byte adata[Mirf.payload];
  49.    
  50.     if(Mirf.dataReady())    //等待接收数据准备好
  51.     {
  52.         Mirf.getData(adata);    //接收数据到data数组
  53.         
  54.         
  55.         //data[1]<左移8位与data[0]并,重组数据。
  56.         // adata = (unsigned int)((data[1] << 8) | data[0]);

  57.         //int("adata");
  58.         for(int i=0;i<6;i++)
  59.     {
  60.           if(adata[3*i+0]==0x0f){data[i] =( (-1)*((adata[3*i+1]*255) + (adata[3*i + 2])));}
  61.           if(adata[3*i+0]==0xf0){data[i] =( ( 1)*((adata[3*i+1]*255) + (adata[3*i + 2])));}
  62.     }

  63.         /*adata[0] = adata0;
  64.         adata[1] = adata1;
  65.         adata[2] = adata2;
  66.         adata[3] = adata3;
  67.         adata[4] = adata4;
  68.         adata[5] = adata5; */

  69.         //与上一次结果比较,避免相同结果刷屏,降低串口流量
  70.         if(data != olddata)
  71.         {
  72.             olddata[0] = data[0]; //本次结果作为历史结果。
  73.             olddata[1] = data[1];
  74.             olddata[2] = data[2];
  75.             olddata[3] = data[3];
  76.             olddata[4] = data[4];
  77.             olddata[5] = data[5];
  78.             
  79.             //Serial.print输出数据
  80.             //Serial.print("A0=");
  81.             //Serial.println(adata);
  82.             //也可以输出双字节数据   
  83.     Serial.print(data[0]); Serial.print("\t");
  84.     Serial.print(data[1]); Serial.print("\t");
  85.     Serial.print(data[2]); Serial.print("\t");
  86.     Serial.print(data[3]); Serial.print("\t");
  87.     Serial.print(data[4]); Serial.print("\t");
  88.     Serial.println(data[5]);
  89.             //Serial.write(data[1]);
  90.             //Serial.write(data[0]);
  91.        }

  92.     }
  93. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2016-9-8 16:17:04 | 显示全部楼层
本帖最后由 275891381 于 2016-9-8 16:19 编辑
kyzo 发表于 2016-9-8 13:16
谢谢你!!我跟着这个思路已经做出来了!

接收端代码:


弄好就行,恭喜了,这样可能会放慢mpu6050的数据速度,还有别的方法 就是用一个字节的8位定义正负 这样 6*2+1个字节就够了 估计能快一点点;

最好再优化下你的程序,不然会慢的很
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-9-9 08:52:29 | 显示全部楼层
275891381 发表于 2016-9-8 16:17
弄好就行,恭喜了,这样可能会放慢mpu6050的数据速度,还有别的方法 就是用一个字节的8位定义正负 这样 ...

不太懂 可以详细说一下吗
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-5-4 22:19 , Processed in 0.040951 second(s), 19 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表