AIoT应用创新大赛-基于TencentOS Tiny的智能车钥匙

2022-03-12 22:00:09 浏览数 (1)

智能车钥匙.pptx

项目背景

UWB数字钥匙是全新的无钥匙进入系统,在接近车辆时,根据距离车辆会自动首先开启迎宾灯,然后随着距离的接近,会自动调整座椅位置等,然后靠近车门时,则自动解锁;当远离车辆时,也能够自动根据位置变化来自动锁车。解决车辆电子钥匙中继攻击的安全漏洞。UWB钥匙的优点在于,它是一项具有近距离精确空间感知能力的技术;准确性高,感应智能手机位置的准确性约为现有产品的 5 倍。

本设计主要是基于UWB定位技术实现智能车钥匙的测距功能,结合TencentosTiny实时操作系统完成初步的功能实现。由于时间紧迫,这里只实现了UWB智能车钥匙的部分功能,后期再慢慢完善。

硬件设计

我采用的是研创物联家的DWM1000-SMA芯片分别与小熊派STM32L431和比赛用的最新一代物联网开发板连接实现测距功能。

硬件框图硬件框图

开发板不断的通过SPI读取DWM1000的时序和回传消息,计算出两个板的距离然后再通过ESP8266上传到云端。

当实测距离小于1m时,将一个信号量置1,大于1m后置0

TencentOS Tiny开发板

TencentOS Tiny开发板端TencentOS Tiny开发板端

小熊派开发板

小熊派用户端小熊派用户端

ESP8266模块

DWM1000-SMA

UWB技术

UWB是Ultra Wide-Band缩写,UWB技术中文名为超宽带无线通信技术,它来源于很久之前的脉冲通信技术,是一种无载波通信技术,UWB不使用载波,而是使用短的能量脉冲序列,并通过正交频分调制或直接排序将脉冲扩展到一个频率范围内。这是我论文里的调查部分,可以看到UWB在功耗,定位,安全,精度等方面都优于其它技术。

UWB基本测距原理

TOF:Time Of Flight飞行时间测距法,主要利用信号在两个异步收发机(Transceiver)之间飞行时间来测量节点间的距离。双向飞行时间法(TW-TOF, two way-time of flight)每个模块从启动开始即会生成一条独立的时间戳 。模块A的发射机在其时间戳上的Ta1发射请求性质的脉冲信号,模块B在Tb2时刻发射一个响应性质的信号,被模块A在自己的时间戳Ta2时刻接收。有次可以计算出脉冲信号在两个模块之间的飞行时间,从而确定飞行距离S。

但是单纯的TOF算法有一个比较严格的约束:发送设备和接收设备必须始终同步。这是一个比较棘手的问题,但是一种Double-sided Two-way Ranging的算法巧妙的避开了这个问题,它即利用了TOF测距的优良特点,同时又极大的去除了TOF的同步问题,从而为TOF的实用化扫清了道路。

双向飞行时间原理双向飞行时间原理

软件开发

UWB驱动文件的移植

  1. decadriver文件夹,是DW1000中的寄存器定义及各种操作,与平台无关,属于通用文件,无需进行大的修改;
  2. platform文件夹下:
  • deca_mutex.c:提供平台相关的互斥锁操作适配实现,裸机中用开关中断实现,RTOS中用互斥量实现;
  • deca_slepp.c:提供平台相关的延时函数实现,用系统提供的tos_task_delay延时函数;
  • deca_spi.c:提供平台相关的SPI通信函数实现,直接使用系统的API实现即可,可以参考一下官方例程库中的demo_apps lpspi_loopback

3. dw1000.c和dw1000.h文件,这两个文件主要为了定义一些DW1000所使用的控制引脚,实现DW1000中断引脚所连接的EXTI功能初始化,DW1000复位功能等。

4. example_ds_twr_init.c该文件将程序打包为一个程序入口,以方便系统调用

这部分主要参考了MCULover666大佬的博客:DW1000开发笔记(三)基于STM32 HAL库裸机工程移植DW1000官方驱动

测距程序入口

代码语言:javascript复制
void DEMO_SSTWR_INITIATOR( void )
{
  uint32_t status;

  uint8_t tagAddress = tagAddr[1];
  uint8_t anchorAddress = 0;

  float32_t distance[4] = {0};

  UWB_SetRxAfterTxDelay(UWB_POLL_TX_TO_RESP_RX_DLY_UUS);
  UWB_SetRxTimeout(UWB_RESP_RX_TIMEOUT_UUS);

  while (1) {
    for (uint8_t i = 0; i < 4; i  ) {
      anchorAddress = anchorAddr[i];
      status = UWB_Ranging(tagAddress, &anchorAddress, &distance[i]);
      if (status == KS_OK) {
        printf(" [X] [OK] .7f mrn", anchorAddress, distance[i]);
      }
      else {
        printf(" [X] [ER] .7f mrn", anchorAddress, distance[i]);
      }
    }
    printf("rn");
    tos_task_delay(100);
  }
}

测距主程序

代码语言:javascript复制
uint32_t UWB_Ranging( const uint8_t tagAddress, uint8_t *anchorAddress, float32_t *distance )
{
  uint32_t status;

  uint8_t buffer[RANGING_LENS   6] = {0};   // PACKET   TIME (4)   CHECK SUM (2)
  uint8_t address[2] = {tagAddress, *anchorAddress};

  uint8_t type;
  uint16_t lens;

  int32_t t_init, t_resp;

//  *distance = 0;

  kSerial_Pack(buffer, address, NULL, 0, KS_NTYPE);
  UWB_SendPacket(buffer, RANGING_LENS   2, UWB_RANGING | UWB_IMMEDIATE | UWB_TX_RESPONSE);

  status = UWB_RecvPacket(buffer, RANGING_LENS   6, UWB_RX_CONTINUE);
  if (status == KS_OK) {
    status = kSerial_Unpack(buffer, address, NULL, &lens, &type);
    if (status == KS_OK) {
      if ((address[1] == tagAddress) || (address[1] == 0)) {
        if (*anchorAddress == 0) {
          *anchorAddress = address[0];
        }
        else if (address[0] != *anchorAddress) {
          return KS_ERROR;
        }

        t_init = UWB_GetInitiatorTime();
        t_resp = UWB_GetReplyTime(&buffer[RANGING_LENS]);

        *distance = UWB_GetDistance(t_init, t_resp);
        return KS_OK;
      }
    }
  }

  return KS_ERROR;
}

MQTT上云

代码语言:javascript复制
void mqttclient_task(void)
{
    int error;
    int k=0;
    int distences = 1;
    
    mqtt_client_t *client = NULL;
    
    mqtt_message_t msg;
    
    k_event_flag_t match_flag;
    
    char  host_ip[20];
    
    memset(&msg, 0, sizeof(msg));
    
#ifdef USE_ESP8266 
    esp8266_sal_init(esp8266_port);
    esp8266_join_ap("dashengbeyond", "88888888");
#endif


#ifdef USE_EC600S
    ec600s_sal_init(HAL_UART_PORT_0);
#endif

    mqtt_log_init();

    client = mqtt_lease();
    
    tos_event_create(&report_result_event, (k_event_flag_t)0u);
    
    /* Domain Format: <your product ID>.iotcloud.tencentdevices.com */
    tos_sal_module_parse_domain("YSR3V1LY80.iotcloud.tencentdevices.com",host_ip,sizeof(host_ip));
    
    /*
        These infomation is generated by mqtt_config_gen.py tool in "TencentOS-tinytools" directory.
    */
    mqtt_set_port(client, "1883");
    mqtt_set_host(client, host_ip);
    mqtt_set_client_id(client, "YSR3V1LY80dev01");
    mqtt_set_user_name(client, "YSR3V1LY80dev01;21010406;12365;4294967295");
    mqtt_set_password(client, "cdb70911879d695b7ef68cd6caa74f6848b5a245;hmacsha1");
    mqtt_set_clean_session(client, 1);

    error = mqtt_connect(client);
    
    MQTT_LOG_D("mqtt connect error is %#0x", error);
    
    error = mqtt_subscribe(client, "$thing/down/property/YSR3V1LY80/dev01", QOS0, tos_topic_handler);
    
    MQTT_LOG_D("mqtt subscribe error is %#0x", error);
    
    while (1) {
        memset(&msg, 0, sizeof(msg));

        if (distences>=150)
        {
        	k=1;
        	 tos_task_delay(3000);
        }

       if (distences > 100) {
        	 g_pinSet = 1;//识别钥匙标志位
        	 GPIO_PinWrite(BOARD_USER_LED_GPIO,BOARD_USER_LED_GPIO_PIN,LOGIC_LED_ON);
         }
       if (distences < 100) {
        	 g_pinSet = 0;
        	 GPIO_PinWrite(BOARD_USER_LED_GPIO,BOARD_USER_LED_GPIO_PIN,LOGIC_LED_OFF);
         }

         snprintf(report_buf, sizeof(report_buf), REPORT_DATA_TEMPLATE, distences);
        msg.qos = QOS0;
        msg.payload = (void *) report_buf;
        
        error = mqtt_publish(client, "$thing/up/property/YSR3V1LY80/dev01", &msg);
        
        MQTT_LOG_D("mqtt publish error is %#0x", error);
        
        tos_event_pend(&report_result_event, 
                       report_success|report_fail,
                       &match_flag,
                       TOS_TIME_FOREVER,
                       TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR);
        
        if (match_flag == report_success) {
            printf("report to Tencent IoT Explorer successrn");
        
        }else if (match_flag == report_fail){
            printf("report to Tencent IoT Explorer failrn");
        }        
        tos_task_delay(1000);
    }
}

程序运行

串口打印

云端数据

这里我是想加一个远程开锁的,但是时间不够了,我对MQTT还不是很熟悉,后面再接着完善吧

微信小程序(腾讯连连)

演示视频

视频内容

总结与展望

第一次接触实时操作系统,什么都需要去学习,时间很紧,做的很粗超,还有一些功能没有实现,再加上过年舒服了好长时间,直到开学才开始加班做,有点累,但这两周过的很充实。因为开始的晚,有很多大家已经解决的问题我还在问,感觉有被讨厌,但真的很感谢大家给我的帮助。能参加这次比赛真的很开心。

后面我会接着做这个方案,比如一些很实用的功能:

  • 远程开车门
  • 多标签识别--多把钥匙看是谁开的车
  • 多基站三维定位--识别人在车内还是车外

最后感谢TencentOS Tiny AIoT应用创新大赛给了我这次学习的机会,再次感谢各位大佬给我提供的帮助,感谢!

0 人点赞