kyzo 发表于 2016-9-7 22:51:14

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

本帖最后由 kyzo 于 2016-12-14 21:31 编辑

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

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

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

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

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

引脚接法:
nRF24L01   Arduino UNO
VCC      <->      3.3V
GND      <->      GND
CE      <->      D9
CSN      <->      D10
MOSI<->      D11
MISO<->      D12
SCK      <->      D13
IRQ      <->      不接
*/

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
MPU6050 accelgyro;

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

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
void setup()
{
    Wire.begin();
    Serial.begin(9600);
    accelgyro.initialize();

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

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

      //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
      //这里标识写入了Sender.ino
    Serial.println("I'm Sender...");
}
//int adata = 0;
void loop()
{
      //读取A0值到adata
    //adata = analogRead(A0);
    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
    /*ax= ax/16384;
    ay= ay/16384;
    az= az/16384;
    gx= gx/131;
    gy= gy/131;
    gz= gz/131; */

    /*adata = ax/16384;
    adata = ay/16384;
    adata = az/16384;
    adata = gx/131;
    adata = gy/131;
    adata = gz/131;*/

    adata = (ax/16384,HEX);
    adata = (ay/16384,HEX);
    adata = (az/16384,HEX);
    adata = (gx/131,HEX);
    adata = (gy/131,HEX);
    adata = (gz/131,HEX);

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

    //adata是unsigned int双字节数据,必须拆开。
    //将adata高低八位拆分:
    data0 = adata & 0xFF;                //低八位给data,
    data0 = adata >> 8;                //高八位给data。
    data1 = adata & 0xFF;
    data1 = adata >> 8;
    data2 = adata & 0xFF;
    data2 = adata >> 8;
    data3 = adata & 0xFF;
    data3 = adata >> 8;
    data4 = adata & 0xFF;
    data4 = adata >> 8;
    data5 = adata & 0xFF;
    data5 = adata >> 8;
   
    //data

    //设置向"serv1"发送数据
    Mirf.setTADDR((byte *)"Rec01");
    Mirf.send(data0);
    Mirf.send(data1);
    Mirf.send(data2);
    Mirf.send(data3);
    Mirf.send(data4);
    Mirf.send(data5);
   

    /*Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.println(adata);*/
    //while死循环等待发送完毕,才能进行下一步操作。
    while(Mirf.isSending()) {}
    delay(20);
}


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

引脚接法:
nRF24L01   Arduino UNO
VCC <-> 3.3V
GND <-> GND
CE<-> D9
CSN <-> D10
MOSI<-> D11
MISO<-> D12
SCK <-> D13
IRQ <-> 不接
*/

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

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

void setup()
{
    Serial.begin(9600);

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

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

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

void loop()
{
    //定义一个暂存数组,大小为Mirf.payload。
    byte data0;
    byte data1;
    byte data2;
    byte data3;
    byte data4;
    byte data5;
    if(Mirf.dataReady())    //等待接收数据准备好
    {
      Mirf.getData(data0);    //接收数据到data数组
      Mirf.getData(data1);
      Mirf.getData(data2);
      Mirf.getData(data3);
      Mirf.getData(data4);
      Mirf.getData(data5);
      
      //data<左移8位与data并,重组数据。
      // adata = (unsigned int)((data << 8) | data);

      //int("adata");
      adata0 = (unsigned int)((data0 << 8) | data0);
      adata1 = (unsigned int)((data1 << 8) | data1);
      adata2 = (unsigned int)((data2 << 8) | data2);
      adata3 = (unsigned int)((data3 << 8) | data3);
      adata4 = (unsigned int)((data4 << 8) | data4);
      adata5 = (unsigned int)((data5 << 8) | data5);

      /*adata = adata0;
      adata = adata1;
      adata = adata2;
      adata = adata3;
      adata = adata4;
      adata = adata5; */

      adata = (adata0,DEC);
      adata = (adata1,DEC);
      adata = (adata2,DEC);
      adata = (adata3,DEC);
      adata = (adata4,DEC);
      adata = (adata5,DEC);
      
      

      //与上一次结果比较,避免相同结果刷屏,降低串口流量
      if(adata != olddata)
      {
            olddata = adata; //本次结果作为历史结果。
            olddata = adata;
            olddata = adata;
            olddata = adata;
            olddata = adata;
            olddata = adata;
            
            //Serial.print输出数据
            //Serial.print("A0=");
            //Serial.println(adata);
            //也可以输出双字节数据   
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.println(adata);
            //Serial.write(data);
            //Serial.write(data);
       }

    }
}

275891381 发表于 2016-9-8 08:15:17

本帖最后由 275891381 于 2016-9-8 08:41 编辑

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

/*
nRF24L01 Arduino发送端

引脚接法:
nRF24L01   Arduino UNO
VCC      <->      3.3V
GND      <->      GND
CE      <->      D9
CSN      <->      D10
MOSI<->      D11
MISO<->      D12
SCK      <->      D13
IRQ      <->      不接
*/

#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
MPU6050 accelgyro;
int16_t data;
int num=0;
int16_t ax, ay, az;
int16_t gx, gy, gz;
char adata[] = {0,0,0,0,0,0};

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>
void setup()
{
    Wire.begin();
    Serial.begin(9600);
    accelgyro.initialize();

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

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

      //注意一个Arduino写Sender.ino,另一个写Receiver.ino。
      //这里标识写入了Sender.ino
    Serial.println("I'm Sender...");
}
//int adata = 0;
void loop()
{
      //读取A0值到adata
    //adata = analogRead(A0);
    accelgyro.getMotion6(&data, &data, &data, &data, &data, &data);
    byte adata;
    for(int i=0;i<6;i++)
    {
          if(data< 0){adata=0x0f;adata=(0-data)/255;adata=(0-data)%255;}
          if(data>=0){adata=0xf0;adata=(0+data)/255;adata=(0+data)%255;}
    }

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

    /*Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.print(adata); Serial.print("\t");
    Serial.println(adata);*/
    //while死循环等待发送完毕,才能进行下一步操作。
    while(Mirf.isSending()) {}
    delay(20);
}




kyzo 发表于 2016-9-8 11:12:38

275891381 发表于 2016-9-8 08:15
自己定义个规则每个int16_t 按3个字节发送第一个定义个正负标志第二个高8位第三个 低八位就可以 ...

可以加个qq向您寻求指导吗 我q740237763

kyzo 发表于 2016-9-8 13:16:03

本帖最后由 kyzo 于 2016-9-8 13:23 编辑

275891381 发表于 2016-9-8 08:15
自己定义个规则每个int16_t 按3个字节发送第一个定义个正负标志第二个高8位第三个 低八位就可以 ...

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

接收端代码:
/*
nRF24L01 Arduino Receiver接收端

Ansifa
2015/3/7

引脚接法:
nRF24L01   Arduino UNO
VCC <-> 3.3V
GND <-> GND
CE<-> D9
CSN <-> D10
MOSI<-> D11
MISO<-> D12
SCK <-> D13
IRQ <-> 不接
*/

#include <SPI.h>
#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

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

void setup()
{
    Serial.begin(9600);

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

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

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

void loop()
{
    //定义一个暂存数组,大小为Mirf.payload。
    byte adata;
   
    if(Mirf.dataReady())    //等待接收数据准备好
    {
      Mirf.getData(adata);    //接收数据到data数组
      
      
      //data<左移8位与data并,重组数据。
      // adata = (unsigned int)((data << 8) | data);

      //int("adata");
      for(int i=0;i<6;i++)
    {
          if(adata==0x0f){data =( (-1)*((adata*255) + (adata)));}
          if(adata==0xf0){data =( ( 1)*((adata*255) + (adata)));}
    }

      /*adata = adata0;
      adata = adata1;
      adata = adata2;
      adata = adata3;
      adata = adata4;
      adata = adata5; */

      //与上一次结果比较,避免相同结果刷屏,降低串口流量
      if(data != olddata)
      {
            olddata = data; //本次结果作为历史结果。
            olddata = data;
            olddata = data;
            olddata = data;
            olddata = data;
            olddata = data;
            
            //Serial.print输出数据
            //Serial.print("A0=");
            //Serial.println(adata);
            //也可以输出双字节数据   
    Serial.print(data); Serial.print("\t");
    Serial.print(data); Serial.print("\t");
    Serial.print(data); Serial.print("\t");
    Serial.print(data); Serial.print("\t");
    Serial.print(data); Serial.print("\t");
    Serial.println(data);
            //Serial.write(data);
            //Serial.write(data);
       }

    }
}

275891381 发表于 2016-9-8 16:17:04

本帖最后由 275891381 于 2016-9-8 16:19 编辑

kyzo 发表于 2016-9-8 13:16
谢谢你!!我跟着这个思路已经做出来了!

接收端代码:

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

最好再优化下你的程序,不然会慢的很

kyzo 发表于 2016-9-9 08:52:29

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

不太懂 可以详细说一下吗
页: [1]
查看完整版本: 如何用NRF24l01同时发送多组有正负的数字?