求助:Arduino nano + nrf24l01实现遥控舵机中遇到问题:同时传输模拟量与数字量
首先,非常感谢网友(ID:pqy39)分享的程序,已实现双摇杆控制四个舵机的功能。但是现在有一个需要功能无法实现:摇杆按下(Z轴),实现开关功能,如何通过nrf24l01传送到接收端,控制相应设备(开关功能即可),请大神指教!先谢谢了!附程序:
/* 发射端程序,感谢网友(ID:pqy39),空端口:D0~D6,D9、D10,A4~A7 */
#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>
#include <nRF24L01.h>
/* nRF24L01接线方式:
* MISO -> 12
* MOSI -> 11
* SCK-> 13
* CE -> 8
* CSN-> 7
* 摇杆接线方式:
* ps11电机电调(Y轴) -> A0
* ps12车体转向(X轴) -> A1
* ps21云台俯仰(Y轴) -> A2
* ps22云台转向(X轴) -> A3
*/
int a;
int aa;
int b;
int bb;
int c;
int cc;
int d;
int dd;
void setup()
{
Mirf.spi = &MirfHardwareSpi; // 加载24L01SPI
Mirf.init(); // 开始
Mirf.setTADDR((byte *)"serv1"); // 发送到"接收地址"
Mirf.payload = sizeof(int); // 数据类型(整数)
Mirf.config(); // 发送通道
Serial.begin(9600);
}
void loop()
{
a = analogRead(A0); // 读取摇杆ps11输出电平(0至1023)
b = analogRead(A1);
c = analogRead(A2);
d = analogRead(A3);
a = map(a,0,1023,0,999) ;
b = map(b,0,1023,1000,1999) ;
c = map(c,0,1023,2000,2999) ;
d = map(d,0,1023,3000,3999) ;
Serial.print(a);
Serial.print(" ");
Serial.print(b);
Serial.print(" ");
Serial.print(c);
Serial.print(" ");
Serial.println(d);
if (a != aa)
{
Mirf.send((byte *)&a); // 发送电机电调(Y轴)信号
while(Mirf.isSending())
{} // 等待或继续发送
aa = a;
}
if (b != bb)
{
Mirf.send((byte *)&b); // 发送车体转向(X轴)信号
while(Mirf.isSending())
{} // 等待或继续发送
bb = b;
}
if (c != cc)
{
Mirf.send((byte *)&c); // 发送云台俯仰(Y轴)信号
while(Mirf.isSending())
{ } // 等待或继续发送
cc = c;
}
if (d != dd)
{
Mirf.send((byte *)&d); // 发送云台转向(X轴)信号
while(Mirf.isSending())
{ } // 等待或继续发送
dd = d;
}
delay(20); // 等待0.02秒
}
/* 接收端程序,感谢网友(ID:pqy39),空端口:D0、1、3、9、10,A0~A7 */
#include <Mirf.h>
#include <MirfHardwareSpiDriver.h>
#include <MirfSpiDriver.h>
#include <nRF24L01.h>
#include <Servo.h>
/* nRF24L01接线方式:
* MISO -> 12
* MOSI -> 11
* SCK-> 13
* CE -> 8
* CSN-> 7
* 舵机接线方式:
* 电机电调 -> 2
* 车体转向 -> 4
* 云台俯仰 -> 5
* 云台转向 -> 6
*/
Servo myservo1; // 创建电机电调(Y轴)对象
Servo myservo2; // 创建车体转向(X轴)舵机对象
Servo myservo3; // 创建云台俯仰(Y轴)舵机对象
Servo myservo4; // 创建云台转向(X轴)舵机对象
int data;
int a;
int b;
int c;
int d;
int pin1 = 2; // 定义电机电调信号线接口
int pin2 = 4; // 定义车体转向舵机信号线接口
int pin3 = 5; // 定义云台俯仰舵机信号线接口
int pin4 = 6; // 定义云台转向舵机信号线接口
void setup()
{
myservo1.attach(pin1,1000,2000); // 定义舵机管脚号与脉宽
myservo2.attach(pin2,1000,2000); // min 默认544,max 默认2400
myservo3.attach(pin3,1000,2000);
myservo4.attach(pin4,1000,2000);
Mirf.spi = &MirfHardwareSpi; // 加载24L01SPI
Mirf.init();
Mirf.setRADDR((byte *)"serv1"); // 接收地址"serv1"
Mirf.payload = sizeof(int); // 数据类型(整数)
Mirf.config();
Serial.begin(9600);
}
void loop()
{
if (Mirf.dataReady()) //如果接收到数据则执行
{
Mirf.getData((byte *)&data); //接收数据
if (data>=0&&data<=999)
{
a = map(data,0,999,1000,2000); // 设置舵机主轴角度,1000是逆时针位置,2000是顺时针位置,1500在中间(即1.5ms)
myservo1.writeMicroseconds(a);// 写入一个微秒单位的数值(uS)到舵机
}
if (data>=1000&&data<=1999)
{
b = map(data,1000,1999,1000,2000);
myservo2.writeMicroseconds(b);
}
if (data>=2000&&data<=2999)
{
c = map(data,2000,2999,1000,2000);
myservo3.writeMicroseconds(c);
}
if (data>=3000&&data<=3999)
{
d = map(data,3000,3999,1000,2000);
myservo4.writeMicroseconds(d);
}
Serial.print(a);
Serial.print(" ");
Serial.print(b);
Serial.print(" ");
Serial.print(c);
Serial.print(" ");
Serial.println(d);
Mirf.rxFifoEmpty(); // 清理nRF24L01援存
}
}
每次传输的时候不要只传输一个int那么大小的payload,可以一次性传送至多32字节,如果你要发送5个int型的变量,那么实际上可以一次性发送 5 x 2 = 10byte的数据,设置payload=10
Mirf.payload = 10; //这一行替换掉原来的sizeof(int)
然后假设你每次发送的数据分别是 int v0,v1,v2,v3,v4;这5个数据
那么你可以将这5个int分别放到一个unsigned char values;的数组中然后使用NRF传输出去这10个字节
接受的时候也是接受10个字节放到数组中
unsigned int v0,v1,v2,v3,v4;
unsigned char values={0};
//下面是你对v0到v4进行赋值的一些操作 ,省略
......
//将五个变量放到数组中
*(unsigned int *)(values+0) = v0;
*(unsigned int *)(values+2) = v1;
*(unsigned int *)(values+4) = v2;
*(unsigned int *)(values+6) = v3;
*(unsigned int *)(values+8) = v4;
//然后你就可以发送values了
Mirf.send(values);
对于接收端 无非就是接受数据的那一步倒过来完成
unsigned char values={0};
unsigned int rv0,rv1,rv2,rv3,rv4;
Mirf.getData(values);
rv0 = *(unsigned int *)(values+0);
rv1 = *(unsigned int *)(values+2);
rv2 = *(unsigned int *)(values+4);
rv3 = *(unsigned int *)(values+6);
rv4 = *(unsigned int *)(values+8);
这样子接收端的rv0~rv4中就存放着发送端发过来的v0~v4了。
L.anrist 发表于 2017-11-16 17:26
每次传输的时候不要只传输一个int那么大小的payload,可以一次性传送至多32字节,如果你要发送5个int型的变 ...
多谢多谢,您提出的思路我以前没想到,我好好钻研一下,再次感谢!! L.anrist 发表于 2017-11-16 17:26
每次传输的时候不要只传输一个int那么大小的payload,可以一次性传送至多32字节,如果你要发送5个int型的变 ...
按照你的思路,功能已实现,多谢多谢 Mirf.spi = &MirfHardwareSpi; // 加载24L01SPI
Mirf.init(); // 开始
Mirf.setTADDR((byte *)"serv1"); // 发送到"接收地址"
Mirf.payload = sizeof(int); // 数据类型(整数)
Mirf.config(); // 发送通道
请问在使用nRF24L01通讯的时候这几段代码都需要使用吗? x1179047899 发表于 2018-4-14 14:33
Mirf.spi = &MirfHardwareSpi; // 加载24L01SPI
Mirf.init(); // 开 ...
都要,设定地址和数据长度 joyduino 发表于 2018-4-14 20:31
请问用的是哪种摇杆 麻烦上几个图片
网上能买到的最便宜那种,5针的
页:
[1]