APDS9960传感器在Hi3861上的移植和使用 原创 精华

再见南丫岛
发布于 2022-5-18 09:32
浏览
3收藏

1、APDS9960简介

APDS9960是一款多功能传感器。它可以在光线下检测手势、环境光和RGB值。该传感器还可用作接近传感器,主要用于智能手机,以便在通话时禁用触摸屏。该传感器由四个光电二极管组成。这些光电二极管检测由板载LED传输的反射IR能量。因此,无论何时执行任何手势,该IR能量都被阻挡并反射回传感器,现在传感器检测到关于手势的信息(方向、速度)并将其转换为数字信息。该传感器可用于通过检测反射的IR光来测量障碍物的距离。它具有用于检测RGB颜色的UV和IR阻挡滤光器,并为每种颜色生成16位数据。
官方介绍资料:https://www.sparkfun.com/products/12787

2、代码移植

官方提供了Arduino版本的源代码:https://github.com/sparkfun/APDS-9960_RGB_and_Gesture_Sensor
代码移植的核心为两部分:1)Arduino代码的转成标准C语言。2)修改I2C的驱动,适配openharmony。
这里介绍一下I2C的部分代码。其他代码,会放在附件中。

/*******************************************************************************
 * Raw I2C Reads and Writes
 ******************************************************************************/

/**
 * @brief Writes a single byte to the I2C device (no register)
 *
 * @param[in] val the 1-byte value to write to the I2C device
 * @return True if successful write operation. False otherwise.
 */
bool APDS9960_wireWriteByte(uint8_t val)
{
	uint8_t write_data[2] = {val};
    hi_i2c_data i2c_data = {0};
    i2c_data.send_buf = write_data;
    i2c_data.send_len = 1;
 
    uint32_t result = hi_i2c_write(apds_i2c_channel, (APDS9960_I2C_ADDR<<1), &i2c_data);
    if(result == 0){
        return true;
    }
	return false;
}

/**
 * @brief Writes a single byte to the I2C device and specified register
 *
 * @param[in] reg the register in the I2C device to write to
 * @param[in] val the 1-byte value to write to the I2C device
 * @return True if successful write operation. False otherwise.
 */
bool APDS9960_wireWriteDataByte(uint8_t reg, uint8_t val)
{
	uint8_t write_data[3] = {reg,val};
    hi_i2c_data i2c_data = {0};
    i2c_data.send_buf = write_data;
    i2c_data.send_len = 2;
 
    uint32_t result = hi_i2c_write(apds_i2c_channel, (APDS9960_I2C_ADDR<<1), &i2c_data);
    if(result == 0){
        return true;
    }
	return false;
}

/**
 * @brief Writes a block (array) of bytes to the I2C device and register
 *
 * @param[in] reg the register in the I2C device to write to
 * @param[in] val pointer to the beginning of the data byte array
 * @param[in] len the length (in bytes) of the data to write
 * @return True if successful write operation. False otherwise.
 */
bool APDS9960_wireWriteDataBlock(  uint8_t reg,
                                        uint8_t *val,
                                        unsigned int len)
{
    return true;
}

/**
 * @brief Reads a single byte from the I2C device and specified register
 *
 * @param[in] reg the register to read from
 * @param[out] the value returned from the register
 * @return True if successful read operation. False otherwise.
 */
bool APDS9960_wireReadDataByte(uint8_t reg, uint8_t *val)
{
    hi_i2c_data i2c_data = {0};
    uint8_t  buffer[1] = {0x00};
    buffer[0] = reg;
    i2c_data.send_buf = buffer;
    i2c_data.send_len = 1;
    i2c_data.receive_buf = val;
    i2c_data.receive_len = 1;
    int res = hi_i2c_writeread(apds_i2c_channel, (APDS9960_I2C_ADDR<<1), &i2c_data);
    if(res == 0)//成功
    {
        return true;
    }
    else
    {
        return false;
    }
}

/**
 * @brief Reads a block (array) of bytes from the I2C device and register
 *
 * @param[in] reg the register to read from
 * @param[out] val pointer to the beginning of the data
 * @param[in] len number of bytes to read
 * @return Number of bytes read. -1 on read error.
 */
int APDS9960_wireReadDataBlock(uint8_t reg,uint8_t *val,unsigned int len)
{
    hi_i2c_data i2c_data = {0};
    uint8_t  buffer[1] = {0x00};
    buffer[0] = reg;
    i2c_data.send_buf = buffer;
    i2c_data.send_len = 1;
    i2c_data.receive_buf = val;
    i2c_data.receive_len = len;
    int res = hi_i2c_writeread(apds_i2c_channel, (APDS9960_I2C_ADDR<<1), &i2c_data);
    if(res == 0)//成功
    {
        return len;
    }
    else
    {
        return -1;
    }
}
  • 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.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.

3、功能使用

实际的使用,也比较简单。官方也有其使用方法。这里介绍手势识别的使用方法。

1)I2C初始化

这里不做介绍,就是使用openharmony标准的方法即可。

2)手势检测模式初始化

// Start running the APDS-9960 gesture sensor engine
if (APDS9960_enableGestureSensor(true))
{
    DEBUG_printf("Gesture sensor is now running\r\n");
}
else
{
    DEBUG_printf("Something went wrong during gesture sensor init!\r\n");
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

3)测试使用

STATIC mp_obj_t machine_gesture_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
{
    int gesture = 0;
    if (APDS9960_isGestureAvailable())
    {
        switch (APDS9960_readGesture())
        {
        case DIR_UP:
            DEBUG_printf("UP\r\n");
            gesture = DIR_UP;
            break;
        case DIR_DOWN:
            DEBUG_printf("DOWN\r\n");
            gesture = DIR_DOWN;
            break;
        case DIR_LEFT:
            DEBUG_printf("LEFT\r\n");
            gesture = DIR_LEFT;
            break;
        case DIR_RIGHT:
            DEBUG_printf("RIGHT\r\n");
            gesture = DIR_RIGHT;
            break;
        case DIR_NEAR:
            DEBUG_printf("NEAR\r\n");
            gesture = DIR_NEAR;
            break;
        case DIR_FAR:
            DEBUG_printf("FAR\r\n");
            gesture = DIR_FAR;
            break;
        default:
            DEBUG_printf("NONE\r\n");
            gesture = 0;
            break;
        }
    }

    //return mp_obj_new_int(gesture);
    return mp_const_none;
}
  • 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.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.

根据手势的不同方向,可以检测不同的状态,比如,向上挥手,向做挥手等等。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
apds资料.zip 719.23K 30次下载
APDS-9960_RGB_and_Gesture_Sensor-master.zip 3.98M 31次下载
APDS-9960四合一传感器.pdf 957.1K 25次下载
3
收藏 3
回复
举报
3
1
3
1条回复
按时间正序
/
按时间倒序
wx62944dace922b
wx62944dace922b

作者,你好,请问一下没有可以烧录的.bin文件嘛?

回复
2023-5-3 21:37:16


回复
    相关推荐