查看: 1103|回复: 3

ROHM模拟传感器资料

[复制链接]

该用户从未签到

发表于 2018-7-5 10:59:59 | 显示全部楼层 |阅读模式
分享到:
 这个套件中有两个传感器是模拟(电压输出)的,读取简单,只用电压表也能测结果。当然用带ADC的单片机是常规做法了。SensorShield要使用模拟通道,我将传感器小板接在 ANALOG_2 的插座位,模拟输出就是 ANA3 了,对应 STM32 Nucleo 上的PA4.

温度传感器 BD1210HFV

  温度传感器可以说是最多的半导体传感器了,最简单的方法用一个二极管就可以测温,不少器件的内部都集成了温度传感器作为附带功能用来作校准等用途。作为单独的一个温度传感器,需要有它的特色,才能在市场占定位置。
  ROHM这个 BD1210HFV 从精度上来看+/- 1.5度的最大误差是不如常用的 DS18B20 的,测温范围 -30~+100 也不如 DS18B20 宽。不过4uA的工作电流是它的强项,可以实现低功耗的在线测量。输出电压和温度的关系在手册中有图给出:

典型是 8.2mV/K 的温度系数,不难写ADC结果的转换公式。用 STM32 的 12-bit ADC 作采样,基准电压是 3.3V 的,传感器工作电压 3.0V,不会有量程问题。我的测试程序:
  1. [mw_shl_code=c,false]void setup_adc(void)
  2. {
  3.     RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
  4.     __NOP();
  5.     ADC->CCR = 0; // default: ADCPRE=0, ADC clock = PCLK/2
  6.     ADC1->CR1 = ADC_CR1_DISCEN|ADC_CR1_EOCIE; // discontinuous mode, EOC interrupt
  7.     ADC1->SQR3 = ADC_SQR3_SQ1&4;  // only 1st conversion in sequence, Ch 4
  8.     ADC1->CR2 = ADC_CR2_ADON|ADC_CR2_EXTEN_0  // enable, trigger rise edge
  9.             |ADC_CR2_EXTSEL_0|ADC_CR2_EXTSEL_1; // Timer2 CC2
  10. }

  11. volatile uint16_t adc_ch4;

  12. int main(void)
  13. {
  14.     int i;
  15.     gpio_config();

  16.     uart_setup();
  17.     uart_wstr("\r\nUSART2 initialized.");

  18.     setup_adc();
  19.     NVIC_EnableIRQ(ADC_IRQn);

  20.     RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;     // enable timer 2
  21.     __NOP();
  22.     TIM2->PSC = 999;        // prescaler
  23.     TIM2->ARR = 199;        // auto reload value
  24.     TIM2->CCR2 = 100;
  25.     TIM2->CCMR1 = TIM_CCMR1_OC2M_0|TIM_CCMR1_OC2M_1|TIM_CCMR1_OC2M_2;
  26.     TIM2->CCER = TIM_CCER_CC2E; // must enable CC2
  27.     TIM2->CR1 = TIM_CR1_URS|TIM_CR1_CEN;    // start counter

  28.     while(1)
  29.     {
  30.         int x=0;
  31.         for(i=0;i<32;i++)
  32.         {
  33.             __WFI();
  34.             x+=adc_ch4;
  35.         }
  36.         double volt=x*3.3f/(32*4096);
  37.         double degree=30-(volt-1.3)/0.0082;
  38.         int d=round(degree*10);
  39.         uart_wstr("\r\nTemperature (degree): ");
  40.         uart_wdec(d/10);
  41.         uart_wstr(".");
  42.         uart_wdec(d%10);
  43.     }
  44. }

  45. void ADC_IRQHandler(void)
  46. {
  47.     adc_ch4=ADC1->DR;   // reading clears flag automatically
  48. }
复制代码
[/code]

  因为 STM32 ADC 的噪声大,用了32次采样结果算平均值之后再进行计算。ADC速度不成问题,我最终输出数据零点几秒钟一次。

  这是在室内的测量,考虑到ADC和Nucleo板子电压基准的误差,结果的波动完全可以接受。因为我没有标定的实验条件,就不评估这个结果的准确度了。

紫外线传感器 ML8511A

  日常防紫外线的用品是不少,测紫外线的功能却很少见到。有了它至少可以做个提醒“注意防晒”装置了。测量范围(我没概念)是 15mW/cm^2,如下图:

  把程序稍加改动就可以读数了:
  1. [mw_shl_code=c,false]    while(1)
  2.     {
  3.         int x=0;
  4.         for(i=0;i<32;i++)
  5.         {
  6.             __WFI();
  7.             x+=adc_ch4;
  8.         }
  9.         double volt=x*3.3f/(32*4096);
  10.         double intensity=(volt-1.0)/1.2*10;
  11.         int i=round(intensity*100);
  12.         if(i<0)
  13.             i=0;
  14.         uart_wstr("\r\nUV Intensity (mW/cm^2): ");
  15.         uart_wdec(i/100);
  16.         uart_wstr(".");
  17.         if(i%100<10)
  18.             uart_wstr("0");
  19.         uart_wdec(i%100);
  20.     }
复制代码
[/code]
  数据输出次数和上一个程序一样。在室内,读数几乎就是0。今天外面有阳光照射,在窗口的地方有阳光射进来,于是可以做一些测试。

这是隔着窗玻璃的结果(双层玻璃,上面还有严重的擦不掉的污渍):

已经有明显的紫外线了。然后把窗推开呢?

紫外线强了几倍。有趣的是,在阳光直射下这个数字也会变,有云过来的时候明显会降低。试了下一把太阳伞,隔了伞之后降到0.3的样子。

突然想到我的墨镜了,拿出来试!




墨镜果然厉害!

28.png
25.png
27.png
26.jpg
23.jpg
24.png
29.png
30.png
31.jpg
32.png
回复

使用道具 举报

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

本版积分规则

关闭

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



手机版|小黑屋|与非网

GMT+8, 2024-11-15 10:53 , Processed in 0.149838 second(s), 25 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.