赞
踩
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
腰带的主要功能是跌倒判断和LORA通信。我们通过MPU6050传感器获取运动数据,结合跌倒检测算法判断佩戴者是否发生跌倒。同时,我们使用JS跳频算法实现LORA自组网通信,腰带能够把检测数据通过LORA传输到网关,能够在不同环境中实现应急通信,给跌倒者给予尽快的救助。
我们采用Hi3861芯片作为腰带的主控芯片, Hi3861V100是一款高度集成的2.4GHz SoC WiFi芯片,集成IEEE 802.11b/g/n基带和RF电路,RF电路包括功率放大器PA、低 噪声放大器LNA、RF balun、天线开关以及电源管理等模块;支持20MHz标准带宽和5MHz/10MHz窄带宽,提供最大72.2Mbit/s 物理层速率。 Hi3861V100 WiFi基带支持正交频分复用(OFDM)技术,并向下兼容直接序列扩频(DSSS)和补码键控(CCK)技术,支 持IEEE 802.11 b/g/n协议的各种数据速率。 Hi3861V100芯片集成高性能32bit微处理器、硬件安全引擎以及丰富的外设接口,外设接口包括SPI、UART、I2C、PWM、 GPIO和多路ADC,同时支持高速SDIO2.0 Slave接口,最高时钟可达50MHz;芯片内置SRAM和Flash,可独立运行,并支持 在Flash上运行程序。 Hi3861V100支持HUAWEI LiteOS和第三方组件,并配套提供开放、易用的开发和调试运行环境。 Hi3861V100芯片适应于智能家电等物联网智能终端领域。
为了确保系统良好的通信质量(例如,鲁棒性和永久性) ,我们将跳频信道集成到 LoRa 中,并应用了我们之前的工作,即Jump-Stay(JS)跳频算法[1]。JS算法允许节点(终端或网关)在网络中通过特定的信道跳转序列在不同的信道之间跳转。JS中的信道跳转序列由多个回合组成,每个回合由一个“跳转模式”和一个“停止模式”组成。每个节点可以在跳跃模式下连续跳转到不同的可用通道,但是在停止模式下保持在一个通道中。因此,JS算法可以帮助多个节点同时通过不同的通道进行通信,从而提高通信效率。
我们选择的LoRa模块为正点原子ATK-LORA-02,该模块采用高效的ISM 频段射频SX1278 扩频芯片,模块的工作频率在410Mhz~441Mhz,以1Mhz 频率为步进信道,共32 个信道。可通过AT 指令在线修改串口速率,发射功率,空中速率,工作模式等各种参数。
MPU6050 是 InvenSense 公司推出的整合性 6 轴运动处理组件,其内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个IIC 接口, 可用于连接外部磁力传感器,并利用自带的数字运动处理器(DMP: Digital Motion Processor) 硬件加速引擎,通过主 IIC 接口,向应用端输出完整的 9 轴融合演算数据。
为了减少主板面积方便使用者佩戴,PCB板采用双层板设计,顶层主要放置Hi3861WiFi芯片模块(Hi-12F)和MPU6050传感器组件。传感器和主控芯片之间使用I2C串口进行连接通信。此外,我们在主板上设计了稳压电路,稳定电压,减少干扰。
主板底层主要放置LORA模块和EPPROM。LORA模块和主控芯片之间使用UART串口通信,LORA模块的MD0和AUX引脚连接到主控芯片的GPIO引脚,从而实现LORA通信时的JS信道跳跃。存储器则连接I2C,保证即使主板掉电后数据不会丢失。
实物图如下:
代码如下(示例):
- #define SEED 1346354787//随机种子
- #define N 32//全局信道数
- /**可用信道数改变时需改变下面代码**/
- #define U 32//当前可用信道数
- char *Ck[32]={"0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16",
- "17","18","19","20","21","22","23","24","25","26","27","28","29","30","31"};//可用信道集合
- /**********************************/
- int M=U;//所有可用信道的数量
- int P=17;//大于M的最小素数,在每一轮算法中保持不变
- int r=1;//跳跃步长,是[1,M]的中一个数
- int i=0;//信道索引,是[1,P]中的一个数
- int t=0;//时隙计数器,每个时隙为20ms。1s=1000000
- int s=0;//随机数
-
- //判断是否为质数
- int isPrime(int num){
- if (num<2) return 0;
- int k=2;
- int s=sqrt(num);
- while(k<=s){
- if(num%k==0) return 0;
- k++;
- }
- return 1;
- }
-
- //得到一个大于M的最小素数
- int getLargestPrime(int M){
- int isPrime(int num);
- int k=M+1;
- int flag=1;
- while(flag){
- if (isPrime(k)){
- return k;
- }
- k++;
- }
- return 0;
- }
-
- //获取时隙t时的调频信道
- int JSHopping (int M,int P,int r,int i,int t){
- int j=0;//可用信道
- t%=(3*P);
- if (t<(2*P)) j=(i+(t*r)-1)%P+1;
- else j=r;
- if(j>M) j=(j-1)%M+1;
- return j;//返回可用信道
- }
-
- //连接字符串
- char *join(char *a, char *b) {
- char *c = (char *) malloc(strlen(a) + strlen(b) + 1);
- //局部变量,用malloc申请内存,strlen不算'\0',所以需要+1
- if (c == NULL) exit (1);
- char *tempc = c; //把首地址存下来
- while (*a != '\0') {
- *c++ = *a++;
- }
- while ((*c++ = *b++) != '\0') {
- ;
- }
- return tempc;
- }
-
- //发送AT指令进行JS跳信道
- void JS_2(void){
- GPIO(0);//设置为配置模式
-
- uint32_t ret;
- WifiIotUartAttribute uart_attr = {
-
- //baud_rate: 115200
- .baudRate = 115200,
-
- //data_bits: 8bits
- .dataBits = 8,
- .stopBits = 1,
- .parity = 0,
- };
- //Initialize uart driver
- ret = UartInit(WIFI_IOT_UART_IDX_1, &uart_attr, NULL);
- if (ret != WIFI_IOT_SUCCESS)
- {
- printf("Failed to init uart! Err code = %d\n", ret);
- return;
- }
- int r0,i0;
- P=getLargestPrime(M);
- r0=rand()%M+1;//随机选取
- i0=rand()%P+1;//随机选取
- int n=t/(3*P);
- int m=t/(3*M*P);
- r=((r0+n-1)%M)+1;
- i=((i0+m-1)%P);
- int c=JSHopping (M,P,r,i,t);
- t++;
- char *aa="AT+WLRATE=";
- char *bb=",5\r\n";
- char *packed=join(join(aa,(char *)Ck[c]),bb);//AT+WLRATE=Ck[c],5\r\n
- UartWrite(WIFI_IOT_UART_IDX_1, (unsigned char *)packed, strlen(packed));
- printf("(更换信道中)发送的数据: %s\r\n", (unsigned char *)packed);
- usleep(500000);
- }
代码如下(示例):
- static void AXIS_Task(void)
- {
- E53_SC2_Init();
- short *gyroData;
- while (1)
- {
- int sum_x=0,sum_y=0,sum_z=0;
- int gyro_x=0,gyro_y=0,gyro_z=0;
- int count = 10;//取10次的均值
- for(int i=count;i>0;i--)//均值滤波
- {
- E53_SC2_Read_Data();
- MPU6050ReadGyro(*gyroData);
- sum_x += (int)E53_SC2_Data.Accel[0];
- sum_y += (int)E53_SC2_Data.Accel[1];
- sum_z += (int)E53_SC2_Data.Accel[2];
- gyro_x += (int)gyroData[0];
- gyro_y += (int)gyroData[1];
- gyro_z += (int)gyroData[2];
- }
- Temperature = (int)E53_SC2_Data.Temperature;
- x = sum_x/count/2048*G;
- y = sum_x/count/2048*G;
- z = sum_x/count/2048*G;
- dx = gyro_x/count;
- dy = gyro_y/count;
- dz = gyro_z/count;
-
- smv = sqrt(x*x+y*y+z*z);
- //printf("x=%d\ty=%d\tz=%d\tm/s^2\n",x,y,z);
- //printf("三轴加速度和:%lf m/s^2\r\n",smv);
-
-
- if(smv < 5 || smv >13)
- {
- FALL = 1;
- f = 1;
- osThreadYield();
- LED_D1_StatusSet(OFF);
- LED_D2_StatusSet(ON);
-
- itoa(x+99900,str_x);
- X_axisdata = str_x;
- itoa(y+88800,str_y);
- Y_axisdata = str_y;
- itoa(z+77700,str_z);
- Z_axisdata = str_z;
- itoa(Temperature+66600,str_t);
- Temperaturedata = str_t;
- }
- else
- {
- if(FALL==0)
- {
- itoa(x+99900,str_x);
- X_axisdata = str_x;
- itoa(y+88800,str_y);
- Y_axisdata = str_y;
- itoa(z+77700,str_z);
- Z_axisdata = str_z;
- itoa(Temperature+66600,str_t);
- Temperaturedata = str_t;
- }
- f = 0;
- LED_D1_StatusSet(ON);
- LED_D2_StatusSet(OFF);
- }
-
- osDelay(100);
- }
- }
该腰带仍处于开发调试阶段,更多功能也在逐步添加完善,本篇文章记录当前开发进度。
参考文献
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。