OPT101 光电传感器实战:附Arduino/ESP32 /STM32F103C8T6 三平台驱动代码
- 一、 OPT101 简介
- 二、 内部功能框图
- 三、 引脚定义
- 三、项目接线
- 四、驱动代码
- 4.1-- Arduino
- 4.2-- ESP32
- 4.3 STM32F103C8T6 驱动代码
- 五、总结
摘要:本文以优信电子的 OPT101 模块为例,介绍这款 TI 光电二极管与跨阻放大器集成器件的工作原理与实战用法。文章首先讲解 OPT101 的模拟电压输出特性及其关键参数,随后给出引脚定义与项目接线方式,最后分别提供 Arduino、ESP32 和 STM32F103C8T6 三个平台的完整驱动代码,帮助读者快速上手并验证模块功能。
一、 OPT101 简介
文章测试使用优信电子的OPT101模块,OPT101 是 TI 的一款光电二极管 + 跨阻放大器集成器件。
它和 BH1750、TSL2561 这类数字光照传感器不同:不需要 I2C / SPI通讯,检测到光照变化直接转换成模拟电压输出变化,MCU 只需要使用 ADC 读取电压即可,光越强,输出电压越高。OPT101 内部集成约1MΩ 反馈电阻。在 650nm 红光条件下,典型电压响应度约为:0.45 V/μW,也就是说,照射到芯片上的光功率增加时,输出电压基本线性增加。
| 参数 | 典型值 |
|---|---|
| 工作电压 | 2.7V ~ 36V |
| 内置反馈电阻 | 1MΩ |
| 光敏面积 | 2.29mm × 2.29mm |
| 650nm 光响应度 | 0.45A/W |
| 650nm 电压响应度 | 约 0.45V/μW |
| 1MΩ反馈时带宽 | 约 14kHz |
| 暗态输出 | 典型约 7.5mV |
本文为了兼容 ESP32 和 STM32 ADC,统一给 OPT101 使用3.3V 供电。
二、 内部功能框图
三、 引脚定义
OPT101芯片的引脚定义:
文章使用模块的原理图如下:
模块的引脚定义没有做特殊处理,芯片和模块引脚区别在于
1.-IN:模块没有单独引出,放在板子背面丝印-IN的跳线焊盘
2.GND:模块单独引出的地引脚,单电源供电情况下可以不用,也可以背面跳线焊盘短接到V-/COM
3.NC:悬空,模块无引出
4.其他引脚定义同芯片引脚定义
三、项目接线
| 引脚 | 单片机 |
|---|---|
| VCC | 3.3V |
| -V和COM短接 | MCU GND |
| Output和1M短接 | A0(arduino) / GPIO34(ESP32) / PA0(STM32F103C8T6) |
| GND | 悬空不接 |
实物接线
这里的GND是板子另外引出的定义,项目用的是单电源供电,所以直接在芯片的-V引脚接地即可。
四、驱动代码
4.1-- Arduino
constintOPT101_PIN=A0;// 板子AREF接到3.3VconstfloatADC_REF=3.3f;voidsetup(){Serial.begin(115200);}voidloop(){intraw=analogRead(OPT101_PIN);floatvoltage=raw*ADC_REF/1023.0f;Serial.print("ADC = ");Serial.print(raw);Serial.print(" Voltage = ");Serial.print(voltage,3);Serial.println(" V");delay(100);}串口输出现象
4.2-- ESP32
constintOPT101_PIN=34;voidsetup(){Serial.begin(115200);analogReadResolution(12);// 扩大 ADC 输入范围,适合读取 OPT101 输出analogSetPinAttenuation(OPT101_PIN,ADC_11db);}voidloop(){intraw=analogRead(OPT101_PIN);// Arduino-ESP32 可直接读取校准后的毫伏值uint32_tmv=analogReadMilliVolts(OPT101_PIN);Serial.print("ADC = ");Serial.print(raw);Serial.print(" Voltage = ");Serial.print(mv);Serial.println(" mV");delay(100);}串口输出现象
4.3 STM32F103C8T6 驱动代码
mian.c
#include"stm32f10x.h"// Device header#include"Delay.h"#include"OLED.h"#include"AD.h"#include<stdio.h>voidUSART1_Init(uint32_tbaudrate);//串口1初始化函数uint16_tADValue;//定义AD值变量floatVoltage;//定义电压变量//print重定向intfputc(intch,FILE*f){USART_SendData(USART1,(uint8_t)ch);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);returnch;}/* 主函数 */intmain(void){/*模块初始化*/OLED_Init();//OLED初始化AD_Init();//AD初始化USART1_Init(115200);//串口初始化/*显示静态字符串*/OLED_ShowString(1,1,"ADValue:");OLED_ShowString(2,1,"Voltage:0.00V");while(1){ADValue=AD_GetValue();//获取AD转换的值Voltage=(float)ADValue/4095*3.3;//将AD值线性变换到0~3.3的范围,表示电压//串口输出printf("ADValue:%d Voltage:%.3f V\r\n ",ADValue,Voltage);//OLED显示OLED_ShowNum(1,9,ADValue,4);//显示AD值OLED_ShowNum(2,9,Voltage,1);//显示电压值的整数部分OLED_ShowNum(2,11,(uint16_t)(Voltage*100)%100,2);//显示电压值的小数部分Delay_ms(100);//延时100ms,手动增加一些转换的间隔时间}}/* ** USART1 初始化 ** 参数:串口波特率 */voidUSART1_Init(uint32_tbaudrate){GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* 开启 GPIOA 和 USART1 时钟 */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);/* PA9 -> USART1_TX */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);/* PA10 -> USART1_RX */GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_InitStructure);/* USART1 参数 */USART_InitStructure.USART_BaudRate=baudrate;USART_InitStructure.USART_WordLength=USART_WordLength_8b;USART_InitStructure.USART_StopBits=USART_StopBits_1;USART_InitStructure.USART_Parity=USART_Parity_No;USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;USART_Init(USART1,&USART_InitStructure);USART_Cmd(USART1,ENABLE);}输出现象
五、总结
OPT101 可以直接输出模拟电压来展示光强的变化,不需要复杂的通讯,如果是快速测试模块的好坏可以按上面接线,万用表接out输出引脚测电压变化去看模块在不同光强下输出电压是否变化。
需要模块验证代码的可以评论区留言邮箱!!!