如何用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: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);
}
275891381 发表于 2016-9-8 08:15
自己定义个规则每个int16_t 按3个字节发送第一个定义个正负标志第二个高8位第三个 低八位就可以 ...
可以加个qq向您寻求指导吗 我q740237763 本帖最后由 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:19 编辑
kyzo 发表于 2016-9-8 13:16
谢谢你!!我跟着这个思路已经做出来了!
接收端代码:
弄好就行,恭喜了,这样可能会放慢mpu6050的数据速度,还有别的方法 就是用一个字节的8位定义正负 这样 6*2+1个字节就够了 估计能快一点点;
最好再优化下你的程序,不然会慢的很 275891381 发表于 2016-9-8 16:17
弄好就行,恭喜了,这样可能会放慢mpu6050的数据速度,还有别的方法 就是用一个字节的8位定义正负 这样 ...
不太懂 可以详细说一下吗
页:
[1]