所以我买了这款便宜的四轴飞行器,实际上是3种不同的型号(此,此和该,并且三个型号的原理都相同)
所有型号都使用BK2423无线电,应该是与NRF24l01空气兼容-这就是我所拥有的。
因此,由于我在网上发现(令人惊讶地)有关此问题的信息很少,因此我在遥控器的MPU和BK2423之间放置了一些探针,并使用Saleae Logic Analyzer读取了SPI总线上运行的通信两者之间。我发现它有3个主要阶段:Config,Search / Bind和Command,在这两个阶段之间,MCU会执行一些调整,如下所述。
在Config阶段,正在设置一些寄存器,例如Rx的管道编号以及地址,RF通道等。这是配置捕获的一部分:
因此初始Tx(和Rx)地址为5个字节:0xCCCCCCCCCC。
初始RF通道为0x2D。
这两个芯片的默认地址长度为5个字节,并且由于遥控器不更改它,因此该长度应保持5个字节。在该阶段,远程设备反复发送基本相同的数据,并且仅更改RF通道。这是最后一个搜索数据包:
因此,在使用不同的RF通道进行多次传输之后,发生了一些奇怪的事情。遥控器为四轴飞行器找到了正确的RF通道,但是我无法弄清楚他是如何理解的,因为状态寄存器(在MISO通道上)在最后一个搜索数据包中保持不变。此处,远程控制MCU告诉BK2423更改RF通道,而周围没有其他证据:
然后,MCU通知BK2423将地址和RF通道更改为正确的地址和RF通道。由于四轴飞行器会做出正确反应,因此它必须是正确的。我无法正确地通过搜索阶段。
我使用了该项目的一些代码(摘自本页),并更改了HCD.cpp以匹配我的嗅探。这只是我更改过的两种方法(该文件中的其余代码保持不变):
void HCD::bind(unsigned char *ID)
{
for(unsigned char i=0;i<4;i++)
noteID[i]=ID[i];
state=HS_CONNECT;
radio.offline();
radio.txbuf[0] = 0x3F;
radio.txbuf[1] = 0x4C;
radio.txbuf[2] = 0x84;
radio.txbuf[3] = 0x6F;
radio.txbuf[4] = 0x9C;
radio.txbuf[5] = 0x20;
radio.sendBuffer(6);
radio.txbuf[0] = 0x3E;
radio.txbuf[1] = 0xC9;
radio.txbuf[2] = 0x9A;
radio.txbuf[3] = 0xB0;
radio.txbuf[4] = 0x61;
radio.txbuf[5] = 0xBB;
radio.txbuf[6] = 0xAB;
radio.txbuf[7] = 0x9C;
radio.sendBuffer(8);
radio.txbuf[0] = 0x39;
radio.txbuf[1] = 0x0B;
radio.txbuf[2] = 0xDF;
radio.txbuf[3] = 0xC4;
radio.txbuf[4] = 0xA7;
radio.txbuf[5] = 0x03;
radio.sendBuffer(6);
radio.txbuf[0] = 0x30;
radio.txbuf[1] = 0xCC;
radio.txbuf[2] = 0xCC;
radio.txbuf[3] = 0xCC;
radio.txbuf[4] = 0xCC;
radio.txbuf[5] = 0xCC;
radio.sendBuffer(6);
radio.txbuf[0] = 0x2A;
radio.txbuf[1] = 0xCC;
radio.txbuf[2] = 0xCC;
radio.txbuf[3] = 0xCC;
radio.txbuf[4] = 0xCC;
radio.txbuf[5] = 0xCC;
radio.sendBuffer(6);
radio.txbuf[0] = 0xE1;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0] = 0xE2;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0] = 0x27;
radio.txbuf[1] = 0x70;
radio.sendBuffer(2);
radio.txbuf[0] = 0x21;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0] = 0x22;
radio.txbuf[1] = 0x01;
radio.sendBuffer(2);
radio.txbuf[0] = 0x23;
radio.txbuf[1] = 0x03;
radio.sendBuffer(2);
radio.txbuf[0] = 0x25;
radio.txbuf[1] = 0x2D;
radio.sendBuffer(2);
radio.txbuf[0] = 0x24;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0] = 0x31;
radio.txbuf[1] = 0x09;
radio.sendBuffer(2);
radio.txbuf[0] = 0x26;
radio.txbuf[1] = 0x07;
radio.sendBuffer(2);
radio.txbuf[0] = 0x50;
radio.txbuf[1] = 0x73;
radio.sendBuffer(2);
radio.txbuf[0] = 0x3C;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0] = 0x3D;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0] = 0x31;
radio.txbuf[1] = 0x09;
radio.sendBuffer(2);
radio.txbuf[0] = 0x1D;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
}
void HCD::update(unsigned char *payload)
{
Serial.print("Sending, state: ");
Serial.print(state);
Serial.print(" Channel: ");
Serial.println(channel);
unsigned char c=0;
switch(state)
{
case HS_CONNECT:
radio.offline();
radio.txbuf[0] = 0x27;
radio.txbuf[1] = 0x70;
radio.sendBuffer(2);
radio.txbuf[0] = 0xE1;
radio.txbuf[1] = 0x00;
radio.sendBuffer(2);
radio.txbuf[0]=0x25;
radio.txbuf[1]= channel; //0x2A;
radio.sendBuffer(2); //-Chan
//radio.block(baseAddress);
//radio.block(flushTX);
radio.txbuf[0]=0xA0;
radio.txbuf[1]=0x20;
radio.txbuf[2]=0x14;
radio.txbuf[3]=0x03;
radio.txbuf[4]=0x25;
radio.txbuf[5]=0x1F; //noteID[0];
radio.txbuf[6]=0xC3; //noteID[1];
radio.txbuf[7]=0x00; //noteID[2];
radio.txbuf[8]=0xE2; //noteID[3];
radio.txbuf[8]=0xAA; //noteID[3];
radio.sendBuffer(9); //-tx data
//radio.block(PTX);
radio.online();
while(!c)
c=radio.getStatus();
radio.clrStatus();
Serial.print("Status: " );
Serial.println(c);
if(c&0x10) //MRT
{
state=HS_UNINITIALIZED;
Serial.println("Uninitializing :( Connecting");
}
if(c&0x20) //ACK
{
Serial.println("ACK Connecting");
state=HS_CONNECTED;
}
break;
case HS_CONNECTED:
radio.offline();
radio.txbuf[0]=0x25;
radio.txbuf[1]=channel;
radio.sendBuffer(2); //-Chan
radio.txbuf[0]=0x2a;
radio.txbuf[1]=noteID[0];
radio.txbuf[2]=noteID[1];
radio.txbuf[3]=noteID[2];
radio.txbuf[4]=noteID[3];
radio.txbuf[5]=0xCC;
radio.sendBuffer(6); //-tx data
radio.txbuf[0]=0x30;
radio.txbuf[1]=noteID[0];
radio.txbuf[2]=noteID[1];
radio.txbuf[3]=noteID[2];
radio.txbuf[4]=noteID[3];
radio.txbuf[5]=0xAA;
radio.sendBuffer(6); //-tx data
radio.online();
radio.block(flushTX);
radio.txbuf[0]=0xA0;
radio.txbuf[1]=payload[0];
radio.txbuf[2]=payload[1];
radio.txbuf[3]=payload[2];
radio.txbuf[4]=payload[3];
radio.txbuf[5]=payload[4];
radio.txbuf[6]=payload[5];
radio.txbuf[7]=payload[6];
radio.txbuf[8]=payload[7];
radio.sendBuffer(9); //-tx data
radio.txbuf[0]=0x20;
radio.txbuf[1]=0x7A; //-TX
radio.sendBuffer(2);
while(!c)
c=radio.getStatus();
radio.clrStatus();
if(c&0x10) //MRT
{
Serial.println("MRT - connected");
}
if(c&0x20) //ACK
{
Serial.println("ACK - connected");
}
break;
}
}
这些方法(这是上述项目中INO文件的修改版本): 。
如果有人在我的问题上提到这条线,我将感谢他/她可以提供的任何帮助。
#1 楼
在您的代码中有一些我无法理解的项目:在初始的“绑定”例程中,有命令0x3F,0x3E,0x39,它们对应于寄存器1F,1E,19如果我了解这项权利。这些没有记录在NRF24l01数据表中(顺便说一句,您的链接不起作用)。
使用正确的命令0xA0发送有效载荷。但是,您总共发送了9个字节,包括命令。这是否意味着您要发送的有效负载仅包含八个字节?在其中一个有效载荷发送命令中,将txbuf [8]放置了两次。也许您的意思是第二次txbuf [9]?
作为最后一条命令,您发送了0x20。如果我做对了,这就是“写入配置”。
否则,我对四旋翼机一无所知(只是亚马逊想使用它们...)
评论
感谢您的发言! 1.正确-我只是复制了逻辑分析器捕获的内容。 2.再次正确。第二[8]是个错误。 3.这与原始代码相同,基本上也可以在此阶段出现,对此寄存器可以在流中的何处进行配置没有限制,所以我想应该可以。
–
15年7月12日在12:58
但是,由于有效载荷大小已设置为9,因此您不应该总共发送10个字节吗?当包含命令时,您还将在逻辑分析器中捕获10个字节。
–乔什
15年7月12日在13:29
对。默认有效负载为8字节,他们没有更改。但是在其他所有方法都失败之后,我决定完全复制捕获的内容。我知道这没有意义,与不存在的寄存器1F和1E一样,但这是我几次嗅探的内容。有这种差异的经验吗?
–
15年7月12日在13:45
对不起,我没听懂。在“绑定”例程中,将有效载荷长度设置为9个字节(命令0x31),但是随后仅发送8个字节的有效载荷。为什么?但是也许我让您完全错了,而我们正在谈论的是不同的话题。我对微控制器的经验有限。
–乔什
2015年7月12日14:11
我想你又对了。我错过了。在某个阶段,我只是复制了字节,实际上0x31后跟0x9意味着有效负载设置为9个字节。修复双“ txbuf [8]”的错误也应反映出来(意味着包括命令在内总共10个字节)。我应该执行此修复程序并更新问题(谁知道,也许这是问题所在!! ...)
–
15年7月12日在14:34
评论
恐怕我不具备帮助您的知识,但是我希望对RE.SE的更多问题得到充分的研究和撰写。已发表。