码迷,mamicode.com
首页 > 其他好文 > 详细

BLE和2.4G实现通信

时间:2018-04-29 11:57:30      阅读:1498      评论:0      收藏:0      [点我收藏+]

标签:packet   一个   format   左移   ==   get   NPU   特征   冗余   

1. 背景

    客户的项目是无线控制灯具,目前采用2.4G芯片,一端是2.4G遥控器,一端是2.4G灯具。现在客户的需求是在不增加成本的条件下增加手机APP控制。因为BLE芯片一般会比纯2.4G芯片价格高,所以客户不想用BLE芯片替代掉2.4G芯片,毕竟省下的钱都进了客户自己的腰包。

2. 项目评估

   BLE和2.4G都工作在2.4GHz频段,所以让他们互相通信在物理层上理论是可行的。在物理层之上只要手机BLE发送的数据包能被2.4G芯片解析就可以达到目的,所以本项目的技术点就转换到手机BLE模拟2.4G的数据包发送数据。

3. 技术实现

   频移键控(FSK)接收机的一个特点:其接收连续相同比特的能力很差,当接收机收到一连串的“0000000000”时,会认为发射机的频率向左移了,进而导致频率失锁,以致导致数据接收失败。所以为了避免数据传输中出现一连串的全0或者全1,BLE设备会对数据做白化处理。

   白化这个词,可能在深度学习领域比较常遇到,挺起来就是高大上的名词,然而其实白化是一个比PCA稍微高级一点的算法而已,所以如果熟悉PCA,那么其实会发现这是一个非常简单的算法。白化的目的是去除输入数据的冗余信息。假设训练数据是图像,由于图像中相邻像素之间具有很强的相关性,所以用于训练时输入是冗余的;白化的目的就是降低输入的冗余性。
输入数据集X,经过白化处理后,新的数据X‘满足两个性质:
(1)特征之间相关性较低;
(2)所有特征具有相同的方差。
    其实我们之前学的PCA算法中,可能PCA给我们的印象是一般用于降维操作。然而其实PCA如果不降维,而是仅仅使用PCA求出特征向量,然后把数据X映射到新的特征空间,这样的一个映射过程,其实就是满足了我们白化的第一个性质:除去特征之间的相关性。因此白化算法的实现过程,第一步操作就是PCA,求出新特征空间中X的新坐标,然后再对新的坐标进行方差归一化操作。

   然而手机端的白化处理是无法直接通过软件接口关掉的,所以在发送时就需要做反白化处理。另外,2.4G芯片接收机的特点是:从空中抓取2.4GHz信道的数据包,逐BIT对比,硬件过滤掉不是自己想要的数据包(不是只对比数据包头)。

   手机端APP的实现原理如下:

文档中包头部分(Header)是指必须在手机端APP里添加的头,并非标准BLE的包头。
Packet Format:
                                                                |---------------------------------------------------------------------------|
|---------------------------------------------------------------|----------------------------------------|   |---------------------------|  |
|                                                               |                                        |   |                           |  |
| |---------------|   |-----------------|    |---------------|  | |--------------|   |-----------------| |   |  |---------------------|  |  |
| | Pdu_head(2B)  | + | Mac_address(6B) | +  | Menu_head(4B) | +| | Preamble(3B) | + | Dev_address(4B) | | + |  | Payload(Max is 18B) |  |  |
| |---------------|   |-----------------|    |---------------|  | |--------------|   |-----------------| |   |  |---------------------|  |  |
|                                                               |                                        |   |                           |  |
|----------------------------------------Header Format----------|----------------------------------------|   |------2.4G Control---------|  |
                                                                |                                                                           |
                                                                |-----------------------2.4G Packet Format----------------------------------|

                                                                
Pdu_head:   标准BLE数据包的PDU head(BLE协议规定),此值可通过Android API设置。
Mac_address: BLE设备的MAC 地址(BLE协议规定),此字段可通过Android API设置。
Menu_head:   Menufacture data head(BLE协议规定), 此字段占4个字节。目前设置为1E FF F0 FF,此值是通过Android API设置的。
Preamble:    引导码,此字段占3个字节。此字段必须设置为2.4G接收芯片端规定的值,2.4G接收芯片端规定此值为0x710F55,Android端发送值见下。
Dev_address:设备地址,此字段占4个字节。此字段也必须和2.4G接收端确认。
Payload:     有效数据,此字段最大为18个字节。用于2.4G应用控制数据包,此字段用于应用控制协议,若应用控制协议大于18Byte需另做说明。
//以下代码可以直接编译、运行,然后直接查看最后结果
#include <stdio.h>
/**数据准备:
定义一个37字节的数组(标准BLE广播数据包最大的payload为37字节),BLE数据包LSB发送在前。
根据Header Format结构,可得到data[11] - data[13]为Preamble字段,data[14] - data[17]为Dev_address字段。
而且Preamble和Dev_address必须进行比特的反转。
Example:
2.4G接收端Preamble为:    0x71  0x0F  0x55
                            |    |      |
那么,对应Android端为:   0x8E  0xF0   0xAA

2.4G接收端Dev_address为:    0xC0   0xC1   0xC2   0xC3
                               |      |      |      |
那么,对应Android端为:      0x03   0x83   0x43   0xC3
*/
int data[37] = {0,0,0,0,0,0,0,0,0,0,0,0,0x8E, 0xF0, 0xAA, 0x03, 0x83, 0x43, 0xc3, 0};
int whitening_reg[8] = {0};
int data_re = 0void whitening_init(int channel_index)
{
    int i = 0;
    whitening_reg[0] = 1;
    
    for (i = 1; i < 7; i++)
    {
        whitening_reg[i] = (channel_index >> (6 - i)) & 0x01;
    }
}

int whitening_output(void)
{
    int temp = whitening_reg[3] ^ whitening_reg[6];
    
    whitening_reg[3] = whitening_reg[2];
    whitening_reg[2] = whitening_reg[1];
    whitening_reg[1] = whitening_reg[0];
    whitening_reg[0] = whitening_reg[6];
    whitening_reg[6] = whitening_reg[5];
    whitening_reg[5] = whitening_reg[4];
    whitening_reg[4] = temp;
    
    return whitening_reg[0];
}

int whitening_decode(int *data, int length)
{
    int data_index = 0;
    
    for (data_index = 0; data_index < length; data_index++)
    {
        int data_input = data[data_index];
        int data_bit = 0;
        int data_output = 0;
        
        for (int bit_index = 0; bit_index < 8; bit_index++)
        {
            data_bit = (data_input >> (bit_index)) & 0x01;
            
            data_bit ^= whitening_output();
            
            data_output += (data_bit << (bit_index));
        }
        
        data_re = data_output;
        //此处可以得到最后转换完成的数据
        if(data_index > 11 && data_index < 20)
        {
            printf("Result == %x\n", data_re);
        }
    }
   
   return data_re;
}

int main(int argc, char * argv[])
{
   int result = 0;
   //37代表传输在2402频点, 38代表传输在2426频点, 39代表传输在2480频点, 参数只能为这3个值其中一个,需和2.4G接收端协调一致。
   whitening_init(37);
   //此处可以对data数组index=20以后赋值,赋值即为2.4G控制协议字段
   //whitening_decode(*,*)函数第二个参数代表要转换的数组个数
   result =  whitening_decode(data, 20);
   
    getchar();
    return 0;
}

该实现方式缺点:

1. 无法实现跳频,如果BLE的37/38/39某个频点严重拥堵的话可能会造成接受成功率低


 
 
 


 
 
 

BLE和2.4G实现通信

标签:packet   一个   format   左移   ==   get   NPU   特征   冗余   

原文地址:https://www.cnblogs.com/lweleven/p/bleto24g.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!