这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【成果贴】DIY电子测光笔成果展

共2条 1/1 1 跳转至

【成果贴】DIY电子测光笔成果展

菜鸟
2024-11-30 14:25:40     打赏

简单来说,在完成了阶段的过程,对每一个模块的驱动后,终于可以开始我们的项目的设计。


主要设计了一个曝光控制系统,可以通过不同的曝光模式(光圈优先和快门优先)来调整相机的曝光参数。能够根据环境光线强度(LUX)和传感器数据实时计算适当的曝光值(EV),并通过按键调节光圈、快门速度和ISO。


项目目标
  1. 实现基于光圈优先(AV)和快门优先(TV)模式的曝光控制系统。

  2. 根据实时环境光强(LUX)计算曝光值(EV)。

  3. 提供用户友好的操作界面,通过按键调节光圈、快门速度和ISO。

  4. 显示当前曝光模式、光圈值、ISO、快门速度和EV,帮助用户了解当前相机状态。


曝光模式选择

  • 光圈优先模式(AV优先):用户选择光圈大小,系统自动调整快门速度。

  • 快门优先模式(TV优先):用户选择快门速度,系统自动调整光圈值。

使用显示屏实时展示当前的曝光参数,包括曝光模式、光圈、快门速度、ISO和曝光值。

import time
import board
from digitalio import DigitalInOut, Direction, Pull
import terminalio
import math
import adafruit_bh1750
import displayio
from adafruit_display_text import label

# 初始化 I2C 总线
i2c = board.I2C()

# 创建 BH1750 传感器对象
sensor = adafruit_bh1750.BH1750(i2c)

# display
BORDER = 20
TEXT_HIGH = 26
FONTSCALE = 2

TEXT_COLOR = 0x00ff00        # 
TEXT_COLOR_WHITE = 0xFFFFFF  # White
# 假设 AV, SV, TV 是预定义的列表
Mode = [  
    'AV   ',  
    'TV   ',  
]  
 
#FLAG
current_mode = "TV优先"

#光圈优先情况下,
def calculate_shutter_speed(EV, aperture, ISO):
    aperture = float(aperture)
    ISO = int(ISO)
   
    return aperture ** 2 / (2 ** EV * ISO / 100)

# 根据 EV 调整 ISO 值的函数
def adjust_iso(EV, aperture, shutter_speed):
    return int((100 * aperture ** 2) / (shutter_speed * (2 ** EV)))

#快门优先情况下
# 根据 EV 计算光圈值
def calculate_aperture(EV, shutter_speed, ISO):
    ISO = int(ISO)
    return math.sqrt(shutter_speed * (2 ** EV) * (ISO / 100))

# 根据 EV 调整 ISO

def adjust_iso(EV, shutter_speed, aperture):
    return int((100 * aperture ** 2) / (shutter_speed * (2 ** EV)))

ISO = [  
    '100   ',  
    '200   ',  
    '400   ',  
    '800   ',  
    '1600  ',  
    '3200  ',  
    '6400  ',  
    '12800 ',  
]  
 
F = [  
    '1  ',  
    '1.4',  
    '2  ',  
    '2.8',  
    '4  ',  
    '5.6',  
    '8  ',  
    '11 ',  
    '16 ',  
    '22 ',  
    '32 '  
]  
T = [  
    '32    ',  
    '16    ',  
    '8     ',  
    '4     ',  
    '2     ',  
    '1     ',  
    '1/2   ',  
    '1/4   ',  
    '1/8   ',  
    '1/15  ',  
    '1/30  ',  
    '1/60  ',  
    '1/125 ',  
    '1/250 ',  
    '1/500 ',  
    '1/1000'  
]


# 定义按键值
KEY_NULL = 0
KEY_D0   = 1
KEY_D1   = 2
KEY_D2   = 4
KEY_D3   = 8
KEY_D4   = 16

# 定义按键 GPIO 引脚
key0 = DigitalInOut(board.BOOT0)  # BOOT0 按键
key1 = DigitalInOut(board.A1)     # A1 按键
key2 = DigitalInOut(board.A2)     # A2 按键
key3 = DigitalInOut(board.A4)     # A2 按键
key4 = DigitalInOut(board.A5)     # A2 按键

# 按键初始化
def keyInit():
    key0.direction = Direction.INPUT
    key0.pull = Pull.UP  # BOOT0 使用上拉
    key1.direction = Direction.INPUT
    key1.pull = Pull.DOWN  # A1 使用下拉
    key2.direction = Direction.INPUT
    key2.pull = Pull.DOWN  # A2 使用下拉
    key3.direction = Direction.INPUT
    key3.pull = Pull.DOWN  # 11 使用下拉
    key4.direction = Direction.INPUT
    key4.pull = Pull.DOWN  # 9 使用下拉

# 按键检测
def keyDetect():
    key_value = KEY_NULL
    if key0.value == 0:  # 判断 BOOT0 是否按下
        key_value += KEY_D0
    if key1.value:       # 判断 A1 是否按下
        key_value += KEY_D1
    if key2.value:       # 判断 A2 是否按下
        key_value += KEY_D2
    if key3.value:       # 判断 11 是否按下
        key_value += KEY_D3
    if key4.value:       # 判断 9 是否按下
        key_value += KEY_D4
    return key_value

# 检查按键是否按下
def isKeyPressed():
    key_value = keyDetect()
    if key_value:  # 如果检测到按键被按下
        time.sleep(0.01)  # 防抖
        if key_value == keyDetect():  # 再次确认按键状态
            return key_value
    return 0  # 没有按键按下


def menu0():
    # 设置文本
    text1 = "Hello EEPW & DigiKey"
    text2 = "LeslieZhuang"

    # 获取屏幕的宽度和高度
    screen_width = board.DISPLAY.width
    screen_height = board.DISPLAY.height

    # 使用 terminalio 中的默认字体
    font = terminalio.FONT

    # 创建文本标签,并设置颜色为绿色
    text_area1 = label.Label(font, text=text1, color=0x00FF00)
    text_area2 = label.Label(font, text=text2, color=0x00FF00)

    # 将字体的尺寸进行放大
    text_area1.scale = 2  # 放大1倍
    text_area2.scale = 2  # 放大1倍

    # 计算文本的高度
    text1_height = text_area1.bounding_box[1]
    text2_height = text_area2.bounding_box[1]

    # 设置文本的垂直位置
    text_area1.x = 0  
    text_area2.x = 0  

    text_area1.y = screen_height // 4 - text1_height // 2
    text_area2.y = 3 * screen_height // 4 - text2_height // 2

    # 创建显示组
    group = displayio.Group()
    group.append(text_area1)
    group.append(text_area2)

    # 显示内容
    board.DISPLAY.root_group = group
   
# 默认模式和索引
# global svIdx, avIdx, shutter_speed_idx
# svIdx = 2  # 默认 ISO 索引
# avIdx = 3  # 默认 光圈 (AV) 索引
# shutter_speed_idx = 5  # 默认快门速度 (索引)
svIdx = 2  # 默认 ISO 索引
avIdx = 3  # 默认 光圈 (AV) 索引
shutter_speed_idx = 5  # 默认快门速度 (索引)
modeIdx = 0

lux = sensor.lux  # 获取光强值
if lux <= 0:
    lux = 0.1  # 防止 lux 为零,避免 log(0) 错误
   
ev = math.floor(2 + math.log(lux / 10) / math.log(2))  # 计算 EV
ISO_value = int(ISO[svIdx].strip())  # 获取 ISO,转换为整数
aperture_value = float(F[avIdx].strip())  # 获取光圈值,转换为浮动点数
shutter_speed = int(T[shutter_speed_idx].split()[0])  # 获取快门速度值
   

def menu1(svIdx: int, avIdx: int, shutter_speed_idx: int):
    global modeIdx
    svIdx, avIdx, shutter_speed_idx  # 声明为全局变量
   

    display = board.DISPLAY
    splash = displayio.Group()
    display.root_group = splash

    # 计算每行的高度,避免超出屏幕
    line_height = TEXT_HIGH  # 每行文本的高度

    # 缩小字体大小


      # 显示模式
    if modeIdx == 0:
        mode_text = "Mode: AV"
    else:
        mode_text = "Mode: TV"
       
    mode_area = label.Label(terminalio.FONT, text=mode_text, color=TEXT_COLOR, scale=FONTSCALE)
    mode_group = displayio.Group(x=0, y=TEXT_HIGH // 2)
    mode_group.append(mode_area)
    splash.append(mode_group)

    # 合成 LUX 和 EV 文字,并显示在同一行
    lux_ev_text = "LUX: %0.2f   EV: %d" % (lux, ev)
    lux_ev_area = label.Label(terminalio.FONT, text=lux_ev_text, color=TEXT_COLOR, scale=FONTSCALE)
    lux_ev_group =  displayio.Group(x=0, y=TEXT_HIGH * 2 - TEXT_HIGH // 2)  # 第2行,强制转换为整数
    lux_ev_group.append(lux_ev_area)
    splash.append(lux_ev_group)

    # 显示光圈 F (AV) 值
    text_Line2 = "F/TV: " + F[avIdx]
    text_Line2_area = label.Label(terminalio.FONT, text=text_Line2, color=TEXT_COLOR, scale=FONTSCALE)
    text_Line2_group = displayio.Group(x=0, y=TEXT_HIGH * 3 - TEXT_HIGH // 2)  # 第3行,强制转换为整数
    text_Line2_group.append(text_Line2_area)
    splash.append(text_Line2_group)

    # 显示 ISO 值
    text_Line3 = "ISO/AV: " + ISO[svIdx]
    text_Line3_area = label.Label(terminalio.FONT, text=text_Line3, color=TEXT_COLOR, scale=FONTSCALE)
    text_Line3_group = displayio.Group(x=0, y=TEXT_HIGH * 4 - TEXT_HIGH // 2)  # 第4行,强制转换为整数
    text_Line3_group.append(text_Line3_area)
    splash.append(text_Line3_group)

    shutter_speed_idx = max(0, min(shutter_speed_idx, len(T) - 1))  # 限制索引范围在 0 到 len(T) - 1 之间

    text_Line4 = "S: " + T[shutter_speed_idx]  
    text_Line4_area = label.Label(terminalio.FONT, text=text_Line4, color=TEXT_COLOR, scale=FONTSCALE)
    text_Line4_group = displayio.Group(x=0, y=TEXT_HIGH * 5 - TEXT_HIGH // 2) # 第5行,强制转换为整数
    text_Line4_group.append(text_Line4_area)
    splash.append(text_Line4_group)



def main():
    # 初始化按键
    global modeIdx
    global ev
    global lux
    global svIdx, avIdx, shutter_speed_idx
#     ev = math.floor(2 + math.log(lux / 10) / math.log(2))  # 计算 EV

   
    keyInit()
    key_value = 0
    # 初始化显示,首先显示menu0
    menu0()
   
    modeIdx = 0
   

    while True:
        key_value = isKeyPressed()  # 检测是否有按键按下
       
       
        if key_value:
            menu1(svIdx, avIdx, shutter_speed_idx)
           
        if key_value == KEY_D0:
            modeIdx = 1 - modeIdx
            menu1(svIdx, avIdx, shutter_speed_idx)
            print(f"modeIdx is now: {modeIdx}")
       
        elif key_value == KEY_D2:  # 增加光圈 / 快门速度
            if modeIdx == 0:  # 光圈优先
                if avIdx < len(F) - 1:
                    avIdx += 1
                shutter_speed = calculate_shutter_speed(ev, F[avIdx], ISO_value)
            else:  # 快门优先
                if shutter_speed_idx < len(T) - 1:
                    shutter_speed_idx += 1
                    print(f"shutter_speed_idx  = {shutter_speed_idx}")

#                 aperture = calculate_aperture(ev, int(T[shutter_speed_idx].split()[0]), ISO_value)
       
        elif key_value == KEY_D1:  # 增加光圈 / 快门速度
            if modeIdx == 0:  # 光圈优先
                if avIdx > 0:
                    avIdx -= 1
                shutter_speed = calculate_shutter_speed(ev, F[avIdx], ISO_value)
            else:  # 快门优先
                if shutter_speed_idx > 0:
                    shutter_speed_idx -= 1
                    print(f"shutter_speed_idx  = {shutter_speed_idx}")
#                 aperture = calculate_aperture(ev, int(T[shutter_speed_idx].split()[0]), ISO_value)
           
           
        time.sleep(0.1)  # 延时,防止按键过于频繁
       
main()


视频展示

 https://www.bilibili.com/video/BV19xzEYLEtR/share_source=copy_web&vd_source=8ec8a0cb875921c69ae671711837bd63





关键词: 成果     电子     光笔    

专家
2024-11-30 23:37:45     打赏
2楼

效果不错


共2条 1/1 1 跳转至

回复

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