乐趣区

关于物联网:LiteOS基于Sensorhub的超声波模组移植

摘要:本文为你带来 LiteOS 基于 Sensorhub 的超声波模组移植的利用。

1、Sensor Hub

LiteOS 传感框架即 Sensor Hub,是一个基于 Huawei LiteOS 物联网操作系统的传感器治理框架。

随着物联网的倒退,物联网终端越来越智能化,例如在集体穿戴、智能家居、家用医疗等终端上将配置越来越多的传感器,来获取更多传感数据,使终端更加智能,使得开发和保护变得复杂和艰难。LiteOS 传感框架将物联网终端设备上例如减速计 (Accelerometer)、陀螺仪(Gyroscope)、气压仪(Barometer)、温湿度计(Humidometer) 等不同类型的传感器对立治理,通过形象不同类型传感器接口,屏蔽其硬件细节,做到“硬件”无关性,十分不便于物联网设施的开发、保护和性能扩大。

LiteOS 传感框架次要包含了 Sensor Manager、BSP manager,Converged Algorithms。

  • Sensor Manager:对立的传感器交互治理,如 Sensor 的配置、采样、上报和治理。
  • BSP Manager:对立的驱动接口,负责 Sensor 驱动治理、电源治理、Sensor 交互治理,如 Sensor 的关上、敞开、读写、数据更新等。
  • Converged Algorithms:交融算法库(算法基于具体的业务模型),依据具体业务模型,在端侧 MCU 进行算法交融,例如环境监测算法、计步算法等,从传统、简略采集算法降级到智能算法,利用间接调用,晋升传感数据的业务精准度,升高数据采集时延。

2、SR04 超声波模组

HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测性能,测距精度可达高到 3mm;模块包含超声波发射器、接收器与控制电路。根本工作原理:(1)采纳 IO 口 TRIG 触发测距,给至多 10us 的高电平信号;(2)模块主动发送 8 个 40khz 的方波,自动检测是否有信号返回;(3)有信号返回,通过 IO 口 ECHO 输入一个高电平,高电平继续的工夫就是超声波从发射到返回的工夫。测试间隔 =(高电平工夫 声速(340M/S))/2;2、实物图:如右图接线,VCC 供 5V 电源,GND 为地线,TRIG 触发管制信号输出,ECHO 回响信号输入等四干线。图一实物图 3、电气参数:电气参数 HC-SR04 超声波模块工作电压 DC 5 V 工作电流 15mA 工作频率 40Hz 最远射程 4m 最近射程 2cm 测量角度 15 度输出触发信号 10uS 的 TTL 脉冲输入回响信号输入 TTL 电平信号,与射程成比例规格尺寸 4520*15mm。

从时序图表明你只须要提供一个 10uS 以上脉冲触发信号,该模块外部将收回 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输入回响信号。回响信号的脉冲宽度与所测的间隔成正比。由此通过发射信号到收到的回响信号工夫距离能够计算失去间隔。公式:uS/58= 厘米或者 uS/148= 英寸;或是:间隔 = 高电平工夫 * 声速(340M/S)/2;倡议测量周期为 60ms 以上,以避免发射信号对回响信号的影响。

3、sensorhub 的 HC-SR04 驱动

通过时序图能够实现一个简略的读取传感器的接管程序:(这里用 GPIOA1 和 GPIOA4 举例)

uint32_t hcsr04_read (void)
{
 local_time=0;
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  // pull the TRIG pin HIGH
 delay(2);  // wait for 2 us


 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);  // pull the TRIG pin HIGH
 delay(10);  // wait for 10 us
 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);  // pull the TRIG pin low

 // read the time for which the pin is high

 while (!(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4)));  // wait for the ECHO pin to go high
 while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4))    // while the pin is high
  {
  local_time++;   // measure time for which the pin is high
  delay (1);
  }
 return local_time * .034/2; 
}

4、将驱动注册到 SensorHub 上

先写 iO 操作,初始化、关上、敞开和读取数据的操作

STATIC INT32 SR04Init(SensorType *sensor)
{(VOID)(sensor);
 
  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin : PD11 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PD12 PD13 PD14 PD15 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    return LOS_OK;
}
STATIC INT32 SR04ReadData(SensorType *sensor)
{PRINTK("read datan");
    INT32 *data = (INT32 *)sensor->sensorData;
    data[0] =  hcsr04_read();
     return LOS_OK;
}
STATIC INT32 SR04Open(SensorType *sensor, OpenParam *para)
{
    UINT32 ret;
    (VOID)(para);

    SR04 *SR04 = (SR04 *)sensor->priv;

    if ((sensor->sensorStat == SENSOR_STAT_OPEN) && (sensor->interval == SR04Period)) {return LOS_OK;}

    if (SR04->gyroTimerId != INVALID_TIMER_ID) {ret = LOS_SwtmrDelete(SR04->gyroTimerId);
        SR04->gyroTimerId = INVALID_TIMER_ID;
        if (ret != LOS_OK) {PRINT_ERR("delete a timer failed!n");
            return LOS_NOK;
        }
    }

    // creat a timer, first parameter is ticks.
    ret = LOS_SwtmrCreate(sensor->interval, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)GypoTimerFunc, &SR04->gyroTimerId, (UINT32)sensor);
    if (ret != LOS_OK) {PRINT_ERR("creat a timer failed!n");
        return LOS_NOK;
    }

    ret = LOS_SwtmrStart(SR04->gyroTimerId);
    if (ret != LOS_OK) {PRINT_ERR("start timer errn");
    }

    SR04Period = sensor->interval;

    PRINTK("SR04 on.n");
    return LOS_OK;
}

STATIC INT32 SR04Close(SensorType *sensor)
{
    UINT32 ret;

    if (sensor->sensorStat == SENSOR_STAT_CLOSE) {PRINT_DEBUG("sr04 has been closedn");
        return LOS_OK;
    }

    __HAL_RCC_GPIOA_CLK_DISABLE();

    PRINTK("SR04 off.n");
    return LOS_OK;
}

而后将设计的驱动注册到框架上

STATIC struct SensorOperation Sr04Ops = {
    .Init = SR04Init,
    .Open = SR04Open,
    .Close = SR04Close,
    .ReadData = SR04ReadData,
};

STATIC SensorType g_sensorSR04 = {
    .sensorOp = &Sr04Ops,
    .sensorData = &g_SR04Data,
    .sensorDataLen = sizeof(g_SR04Data),
    .priv = &g_SR04Priv,
    .tag = TAG_BEGIN,
    .cmd = CMD_CMN_INTERVAL_REQ,
    .interval = DEFAULT_INTERVAL,

};
VOID SR04Register(VOID)
{SensorRegister(&g_sensorSR04);
}

将驱动注册到通用 sensor 驱动模块上。明天的代码移植根本实现,后续有传感器和板子进行验证

总结

这个驱动是有问题,就是这个是读取时阻塞的程序,后面试过,须要设计时采纳定时器和内部中断实现,能够将这个阻塞的程序改成非阻塞的,效率大大晋升,后续解说如何用定时器和内部触发中断实现这个驱动设计。

点击关注,第一工夫理解华为云陈腐技术~

退出移动版