搜索
热搜: ROHM 模拟 车载
查看: 3880|回复: 0

[活动] 【传感器套件试用5-照度接近传感器RPR-0521使用评测】

[复制链接]

该用户从未签到

9

主题

388

帖子

0

精华

高级会员

最后登录
2024-3-25
发表于 2019-8-8 11:26:49 | 显示全部楼层 |阅读模式
本帖最后由 andeyqi 于 2019-8-8 11:26 编辑

RPR-0521RS是将光学式接近传感器和红外LED(IrLED)、数字照度传感器整合在1chip中的模块。
接近传感器 (PS)通过对IrLED发射光线的接近物产生的反射光,检测出人及物体的接近。另外,照度传感器(ALS)可测量从昏暗光线到直射日光的广泛照度。根据照度数据调整LCD显示器及按键的亮度,从而提高组件的节电性能和画面的可视性。

RPR-0521RS系列光学传感器特点:

·兼容I2C BUS接口(支持f/s模式);

·兼容1.8V逻辑接口;

·掉电模式下,电流损耗低;

·有两种ALS输出值:可见光(Data0)对应光谱响应峰值;红外线光(Data1)对应光照度计算。

·能检测到从黑暗环境乃至直接太阳光照的环境范围,具有广泛的照度测量;

·具有抑制(工频)50Hz/60Hz光噪声(ALS功能下);

·光学接近传感探测范围在1~100mm(可通过I2C接口调整);

·内置电流配置的IrLED驱动器;

·提供卷带包装,符合RoHS欧盟标准。


RPR-0521RS系列光学传感器应用:

·智能手机

·移动手机

·数码相机

·便携式游戏机

·摄像—录影一体机

·PDA

·LCD显示屏


模块原理图如下:

0521.png

内部寄存器map如下及框图.

regmap.png

内部框图.png



I2C时序及从机地址(0x38)如下.


i2c.png

寄存器描述:
SYSTEM_CONTROL.png

bit7-设置为1,bit6-设置为0即可,bit5设置脉冲宽度按照默认即可,bit4设置为为默认值bit0-3设定测量时间。

mode_control.png

距离传感器和光照传感器模式设定。
根据官方的测试代码移植到rtthrad,测试代码如下:
  1. #include <rtthread.h>
  2. #include <rtdevice.h>
  3. #include <board.h>
  4. #include <stdio.h>
  5. #include "finsh.h"
  6. #include "i2c_utilise.h"
  7. #include "rpr0521.h"

  8. unsigned short _als_data0_gain;
  9. unsigned short _als_data1_gain;
  10. unsigned short _als_measure_time;

  11. void rpr0521_init(void)
  12. {
  13.         struct rt_i2c_bus_device* bus = NULL;
  14.         rt_uint8_t deviceid = 0,reg = 0,partid = 0;
  15.         rt_uint8_t buff[2] = {0};
  16.         
  17.         unsigned char index;
  18.         unsigned char als_gain_table[] = {1, 2, 64, 128};
  19.         unsigned short als_meas_time_table[] = {0,0,0,0,0,100,100,100,100,100,400,400,50,0,0,0};
  20.         
  21.     bus = rt_i2c_bus_device_find("i2c1");
  22.         if(!bus)
  23.         {
  24.                 rt_kprintf("can't find i2c device\n");
  25.                 return ;
  26.         }
  27.         write_cmd(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_SYSTEM_CONTROL);
  28.         read_reg(bus,RPR0521RS_DEVICE_ADDRESS,1,&partid);
  29.         if((partid&0x3f) != RPR0521RS_PART_ID_VAL)
  30.         {
  31.                 rt_kprintf("partid is not right 0x%x\n",partid);
  32.                 return;
  33.         }
  34.         write_cmd(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_MANUFACT_ID);
  35.         read_reg(bus,RPR0521RS_DEVICE_ADDRESS,1,®);
  36.         if(reg != RPR0521RS_MANUFACT_ID_VAL)
  37.         {
  38.                 rt_kprintf("manufactid is not right 0x%x\n",reg);
  39.                 return;
  40.         }
  41.         /* RPR0521RS_ALS_PS_CONTROL_DATA0_GAIN_X1
  42.            RPR0521RS_ALS_PS_CONTROL_DATA1_GAIN_X1
  43.            RPR0521RS_ALS_PS_CONTROL_LED_CURRENT_100MA
  44.         */
  45.         write_reg(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_ALS_PS_CONTROL,RPR0521RS_ALS_PS_CONTROL_VAL);
  46.         /* set RPR0521RS_PS_CONTROL_PS_GAINX1 */
  47.         write_cmd(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_PS_CONTROL);
  48.         read_reg(bus,RPR0521RS_DEVICE_ADDRESS,1,®);
  49.         rt_kprintf("read RPR0521RS_PS_CONTROL data is 0x%x\n",reg);
  50.         reg |= RPR0521RS_PS_CONTROL_VAL;
  51.         write_reg(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_PS_CONTROL,reg);
  52.         rt_kprintf("write RPR0521RS_PS_CONTROL data is 0x%x\n",reg);
  53.         /*
  54.            RPR0521RS_MODE_CONTROL_MEASTIME_100_100MS
  55.            RPR0521RS_MODE_CONTROL_PS_EN
  56.            RPR0521RS_MODE_CONTROL_ALS_EN
  57.         */
  58.         reg = RPR0521RS_MODE_CONTROL_VAL;
  59.         write_reg(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_MODE_CONTROL,reg);
  60.         
  61.         reg = RPR0521RS_ALS_PS_CONTROL_VAL;
  62.         index = (reg >> 4) & 0x03;
  63.         _als_data0_gain = als_gain_table[index];
  64.         index = (reg >> 2) & 0x03;
  65.         _als_data1_gain = als_gain_table[index];

  66.         index = RPR0521RS_MODE_CONTROL_VAL & 0x0F;
  67.         _als_measure_time = als_meas_time_table[index];
  68. }

  69. void get_rawpsalsval(unsigned char *data)
  70. {
  71.         struct rt_i2c_bus_device* bus = NULL;
  72.         rt_uint8_t status = 0;
  73.         bus = rt_i2c_bus_device_find("i2c1");
  74.         if(!bus)
  75.         {
  76.                 rt_kprintf("can't find i2c device\n");
  77.                 return ;
  78.         }
  79.         write_cmd(bus,RPR0521RS_DEVICE_ADDRESS,RPR0521RS_PS_DATA_LSB);
  80.         read_reg(bus,RPR0521RS_DEVICE_ADDRESS,6,data);
  81. }

  82. float convert_lx(unsigned short *data)
  83. {
  84.   float lx;
  85.   float d0, d1, d1_d0;

  86.   if (_als_data0_gain == 0) {
  87.     return (RPR0521RS_ERROR);
  88.   }

  89.   if (_als_data1_gain == 0) {
  90.     return (RPR0521RS_ERROR);
  91.   }

  92.   if (_als_measure_time == 0) {
  93.     return (RPR0521RS_ERROR);
  94.   } else if (_als_measure_time == 50) {
  95.     if ((data[0] & 0x8000) == 0x8000) {
  96.       data[0] = 0x7FFF;
  97.     }
  98.     if ((data[1] & 0x8000) == 0x8000) {
  99.       data[1] = 0x7FFF;
  100.     }
  101.   }

  102.   d0 = (float)data[0] * (100 / _als_measure_time) / _als_data0_gain;
  103.   d1 = (float)data[1] * (100 / _als_measure_time) / _als_data1_gain;

  104.   if (d0 == 0) {
  105.     lx = 0;
  106.     return (lx);
  107.   }

  108.   d1_d0 = d1 / d0;

  109.   if (d1_d0 < 0.595) {
  110.     lx = (1.682 * d0 - 1.877 * d1);
  111.   } else if (d1_d0 < 1.015) {
  112.     lx = (0.644 * d0 - 0.132 * d1);
  113.   } else if (d1_d0 < 1.352) {
  114.     lx = (0.756 * d0 - 0.243 * d1);
  115.   } else if (d1_d0 < 3.053) {
  116.     lx = (0.766 * d0 - 0.25 * d1);
  117.   } else {
  118.     lx = 0;
  119.   }

  120.   return (lx);
  121. }

  122. void get_psalsval(unsigned short *ps, float *als)
  123. {
  124.   unsigned char val[6];
  125.   unsigned short rawps;
  126.   unsigned short rawals[2];

  127.   get_rawpsalsval(val);

  128.   rawps     = ((unsigned short)val[1] << 8) | val[0];
  129.   rawals[0] = ((unsigned short)val[3] << 8) | val[2];
  130.   rawals[1] = ((unsigned short)val[5] << 8) | val[4];

  131.   *ps  = rawps;
  132.   *als = convert_lx(rawals);
  133. }

  134. unsigned char check_near_far(unsigned short data)
  135. {
  136.   if (data >= RPR0521RS_NEAR_THRESH) {
  137.     return (RPR0521RS_NEAR_VAL);
  138.   } else {
  139.     return (RPR0521RS_FAR_VAL);
  140.   }
  141. }

  142. long rpr0521(void)
  143. {
  144.         static rt_uint8_t isinit = 0;
  145.         rt_uint16_t count = 1000;        
  146.     float data[3] = {0.0};
  147.     char buff[50] = {0};
  148.         
  149.         unsigned short ps_val;
  150.         float als_val;
  151.         unsigned char near_far;
  152.         
  153.         if(!isinit)
  154.         {
  155.                 rpr0521_init();
  156.                 isinit =1;
  157.         }
  158.         while(count--)
  159.         {
  160.                 get_psalsval(&ps_val, &als_val);
  161.                 near_far = check_near_far(ps_val);
  162.                 if (near_far == RPR0521RS_NEAR_VAL)
  163.                 {
  164.                         rt_kprintf(" Near\n");
  165.                 }
  166.                 else
  167.                 {
  168.                         rt_kprintf(" Far\n");
  169.                 }
  170.    
  171.     if (als_val != RPR0521RS_ERROR) {
  172.                 sprintf(buff,"=%.3f",als_val);
  173.                 rt_kprintf(" RPR-0521RS (Ambient Light) %s\n",buff);
  174.                 rt_thread_mdelay(500);
  175.     }
  176.   }
  177.   return 0;
  178. }
  179. FINSH_FUNCTION_EXPORT(rpr0521, show rpr0521 data);
  180. MSH_CMD_EXPORT(rpr0521, show rpr0521 data);
复制代码
测试时发现,靠近的话会输出near,改变光照强度对应的强度值会发生变化,输出如下:
rpr0521.png

程序和芯片手册如下。




rpr-0521rs-e.pdf (926.17 KB, 下载次数: 2)
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /2 下一条

Archiver|手机版|小黑屋|罗姆半导体技术社区

GMT+8, 2024-4-27 02:08 , Processed in 0.088615 second(s), 13 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表