这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » [Let'sDo第3期]电子测光表成果帖+模拟相机测光驱动舵机

共3条 1/1 1 跳转至

[Let'sDo第3期]电子测光表成果帖+模拟相机测光驱动舵机

专家
2024-11-29 11:27:42     打赏

在相机中为了完成照相,需要焦距、感光、光圈、快门等互相配合。按照这次活动的内容就是使用舵机、按钮配合BH1750测光模块模拟相机照相动作。在完成这个项目之前,先恶补下感光、光圈、快门和照相之间关系的知识。

相机中的快门、光圈、感光度三个参数的组合决定了一张照片的正确曝光。

图片1.png

快门也叫快门速度,以秒为单位,表示相机感光元件的曝光时间长度,传统机械快门通常以这些数值表示:1s、1/2s、1/4s、1/8s、1/15s、1/30s、1/60s、1/125s、1/250s、1/500s、1/1000s。现代电子快门将快门速度分的更精细,快门速度越快越能凝固被拍对象的动作,反之则会拍出运动物体的拖影。

光圈表示光线通过镜头的通光量,通常以f值表示,但通常所说的数字都是倒数。光圈在照片中决定清晰范围的宽度,也叫景深,照片中的光圈值越大,景深越浅,光圈值越大,景深越大。

图片2.png

感光度也叫iso,表示相机传感器或胶片对光的敏感度,通常表示为:50,100,200,400,800,1600,3200,6400…感光度数值越小,对光的敏感度越低,,反之则越高。但是照片的噪点数量和感光度成正比,感光度高,噪点多,感光度低,噪点少。照片图像质量和感光度成反比,感光度高,质量低,感光度低,质量高。

按照老师提供的课程PPT,这次活动中可以用BH1750测量光强,输出的数据是标定好的 Lux ,直接可以转换成曝光。按照以下公式(在 ISO100 下)计算出EV和快门速度,进而控制驱动舵机动作(模拟快门的动作)。

图片3.png

也就是说,

T=F*F/2^(2-log(LUX/10))

若BH1750测得的结果为400,则EV=2 + log2(160/10)=6。在光圈=4的话,则按照公式T=(4*4)/2^(2 + log2(160/10))=1/4S。为了计算方便,将公式进一步演算为:T = (F * F) / (4 * ( LUX/10 )),这样处理时,就不涉及对数处理。

以下是常见的EV值表(感光度为ISO100前提下)

图片4.png

根据以上资料,按照以下逻辑编程:

图片5.png

整机电路构成:

图片6.png

程序代码如下:


import time  
import math  
import board  
import adafruit_bh1750  
import digitalio  
import terminalio  
from adafruit_display_text import label
import adafruit_imageload
import displayio
import pwmio
#文字尺寸
FONTSCALE = 2
# 文字颜色
TEXT_COLOR = 0xFFFFFF
# 初始化I2C接口,BH1750传感器用
i2c = board.I2C()
sensor = adafruit_bh1750.BH1750(i2c)  
  
# 初始化按钮 D5 和 D6
#模拟启动拍摄
button_start = digitalio.DigitalInOut(board.D5)  
button_start.direction = digitalio.Direction.INPUT  
button_start.pull = digitalio.Pull.UP
#改变光圈
button_GQ = digitalio.DigitalInOut(board.D6)  
button_GQ.direction = digitalio.Direction.INPUT  
button_GQ.pull = digitalio.Pull.UP
 
# D13,PWM输出,控制舵机  
pwm = pwmio.PWMOut(board.D13, duty_cycle=2**15, frequency=50)
# 启动快门  
def start_km(duty_cycle):  
    pwm.duty_cycle = duty_cycle  # 调整 PWM 占空比来控制旋转
#停止马达转动
start_km(0)
# 背景,为了显示汉字标签
display = board.DISPLAY
# 背景
image, palette = adafruit_imageload.load(
    "images/ysqd.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
)
tile_grid = displayio.TileGrid(image, pixel_shader=palette)
# 显示背景
splash = displayio.Group()
splash.append(tile_grid)
board.DISPLAY.root_group = splash
# 光圈参数
label_GQ = label.Label(terminalio.FONT, text="", scale=FONTSCALE)  
label_GQ.x = 80  
label_GQ.y = 15  
splash.append(label_GQ)  
  
#光亮度
label_GL = label.Label(terminalio.FONT, text="", scale=FONTSCALE)  
label_GL.x = 80  
label_GL.y = 50  
splash.append(label_GL)  
#EV,根据光亮度计算出来的数据
label_EV = label.Label(terminalio.FONT, text="", scale=FONTSCALE)  
label_EV.x = 80  
label_EV.y = 85  
splash.append(label_EV)  
#快门,根据EV,光圈计算出来的数据
label_km = label.Label(terminalio.FONT, text="", scale=FONTSCALE)  
label_km.x = 80  
label_km.y = 120  
splash.append(label_km)  
  
# 初始设置
#光圈可选参数
sets_gq = [2, 2.8, 4, 5.6]
#默认光圈初始值为4
index_gq=2
# 主循环  
while True:  
    lux = sensor.lux  # 从传感器读取 Lux 值
    # EV
    ev = 2 + math.log(lux / 10, 2)
    # 快门
    km = (sets_gq[index_gq] * sets_gq[index_gq]) / (4 * (lux / 10))
     
    # 切换光圈(蓝色按钮 D6)  
    if not button_GQ.value:  # D6 蓝色按钮被按下  
        index_gq = (index_gq + 1) % len(sets_gq)
        print("Adjust the aperture")
        time.sleep(0.2)
  
    # 启动拍照(D5,红色按钮)  
    if not button_start.value:
        print("take a photo")
        # 转动马达
        start_km(4000)
        time.sleep(km)
        # 停止转动
        start_km(0)
        time.sleep(0.2)
  
    # 刷新显示  
    label_GQ.text = f"F/{sets_gq[index_gq]}" 
    label_GL.text = f"{lux}"
    label_EV.text = f"{ev:.3f}"  
    label_km.text = f"{km:.3f}"  
  
    time.sleep(0.1)

整机效果:

图片7.png

视频:

链接:https://pan.baidu.com/s/19Ob2yIoUQf8F9UdjG1l6Ow 

提取码:1234

EETV视频链接:https://v.eepw.com.cn/video/play/id/16193 


专家
2024-11-29 15:27:32     打赏
2楼

了解了解


工程师
2024-11-29 17:05:53     打赏
3楼

油get到新知识


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]