在经历了充满趣味与挑战的 DigiKey Let's do 第 3 期电子测光表 DIY 活动后,我们成功打造出了一款功能丰富且实用的相机测光表。通过运用 CircuitPython,这款测光表具备了一系列令人满意的功能,下面就来展示一下我的一部分代码吧。
本来想一点点说的,但是又怕写乱了,我直接复制代码进来大家看我的代码注释就能明白我的意思
import board # 导入板载库(内置的) import displayio # 导入displayio库(内置的) import time # 导入时间库(内置的) import digitalio # 导入io库(内置的) import math # 导入数学计算库(内置的) import pwmio # 导入PWM控制库 from adafruit_motor import servo # 导入舵机控制库 import adafruit_bh1750 # 导入外部库adafruit_bh1750 import adafruit_imageload # 导入外部库adafruit_imageload,如果没有就在帖子附件下载 import terminalio # 导入官方字体显示设置 from adafruit_display_text import bitmap_label # 引用文本标签库 # 初始化 I2C 总线和光照传感器 i2c = board.I2C() # 使用板载的 SCL 和 SDA 引脚 guangxian = adafruit_bh1750.BH1750(i2c) # 为光线传感器赋予名称 pwm = pwmio.PWMOut(board.D10, frequency=50) # 给D10口设置pwmio输出50m赫兹 motor_servo = servo.ContinuousServo(pwm) motor_servo.throttle = 0 # 取值范围 -1 ~ 1,负1正转,正1逆时针旋转 def kacha(): # 定义一个舵机按快门的动作 motor_servo.throttle = -1 time.sleep(0.54) motor_servo.throttle = 1 time.sleep(0.48) motor_servo.throttle = 0 display = board.DISPLAY # 使用固件自带的屏幕设备,不需要另行初始化屏幕参数 display.brightness = 0.5 # 更改屏幕亮度 display.rotation = 0 # 更改显示方向,0为横屏,90为竖屏 group_hello = displayio.Group() # 创建本代码里的欢迎图像组 group_2 = displayio.Group() # 创建本代码里的第二图像组 image, palette = adafruit_imageload.load("/png/bjtp.png") # 加载图片 palette.make_transparent(34) # 是否开启png透明,当前完全不透明,取值范围0~34 bjtp = displayio.TileGrid(image, pixel_shader=palette) # 创建图片布局 group_hello.append(bjtp) # 将图片布局添加到图像组,由于是第一个添加的,默认是最下层 image, palette = adafruit_imageload.load("/png/bjtp3.png") # 加载图片 palette.make_transparent(34) # 是否开启png透明,当前完全不透明,取值范围0~34 bjtp2 = displayio.TileGrid(image, pixel_shader=palette) # 创建图片布局 group_2.append(bjtp2) # 将图片布局添加到图像组,由于是第一个添加的,默认是最下层 text = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "\n EEPW&&DigiKey \n Let's do!", # 显示的文本 x = 10 , # 文本的起始X坐标 y = 2 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0x000000 ) # 设置文字颜色为黑色 group_hello.append(text) # 将文字布局添加到图像group_hello组 text_ISO = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "ISO=", # 显示的文本 x = 0 , # 文本的起始X坐标 y = 15 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_ISO) # 将文字布局添加到图像group_2组 text_iso_date = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "iso_date", # 显示的文本,文字区域已被my_iso[iso_lest_state_num]占用,无需填入文字 x = 54 , # 文本的起始X坐标 y = 15 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_iso_date) text_lux = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "LUX=", # 显示的文本 x = 120 , # 文本的起始X坐标 y = 15 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_lux) text_lux_date = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "lux_date", # 显示的文本,文字区域已被lux_date数据占用,无需填入文字也可 x = 170 , # 文本的起始X坐标 y = 15 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_lux_date) text_F = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "GQ =", # 显示的文本 x = 0 , # 文本的起始X坐标 y = 35 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_F) text_f_date = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "f_zhi", # 显示的文本,文字区域已被lux_date数据占用,无需填入文字也可 x = 54 , # 文本的起始X坐标 y = 35 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_f_date) text_km = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "T =", # 显示的文本 x = 120 , # 文本的起始X坐标 y = 35 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_km) text_km_date = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "km_date", # 显示的文本,文字区域已被lux_date数据占用,无需填入文字也可 x = 170 , # 文本的起始X坐标 y = 35 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_km_date) text_ev = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "EV =", # 显示的文本 x = 0 , # 文本的起始X坐标 y = 55 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_ev) text_ev_date = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "ev_date", # 显示的文本,文字区域已被 ev 数据占用,无需填入文字也可 x = 54 , # 文本的起始X坐标 y = 55 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_ev_date) text_duoji = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "SE =", # 显示的文本 x = 120 , # 文本的起始X坐标 y = 55 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_duoji) text_time = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "", # 显示的文本,文字区域已被占用,无需填入文字 x = 25 , # 文本的起始X坐标 y = 115 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_time) text_test2 = bitmap_label.Label( font = terminalio.FONT, # 你需要指定一个字体对象,我用的自带字体 text = "", # 显示的文本,文字区域已被占用,无需填入文字 x = 170 , # 文本的起始X坐标 y = 55 , # 文本的起始Y坐标 scale = 2, # 设置文字大小 color = 0xFFFFFF ) # 设置文字颜色为白色 group_2.append(text_test2) def Show_huanying(): # 定义欢迎页为:Show_huanying() display.root_group = group_hello Show_huanying() # 显示修改后的欢迎页组 print(" 欢迎使用电子测光表! \n 当前显示欢迎页") led = digitalio.DigitalInOut(board.LED) # 给板载led灯定义名称 led.direction = digitalio.Direction.OUTPUT # 设置led输出 button = digitalio.DigitalInOut(board.BUTTON) # 给板载boot按键定义名称 button.switch_to_input(pull=digitalio.Pull.UP) # 设置按键上拉 anjian_lan = digitalio.DigitalInOut(board.D12) # 给外接按键蓝色按钮定义名称 anjian_lan.switch_to_input(pull=digitalio.Pull.UP) # 设置按键上拉 anjian_hong = digitalio.DigitalInOut(board.D11) # 给外接按键红色按钮定义名称 anjian_hong.switch_to_input(pull=digitalio.Pull.UP) # 设置按键上拉 my_iso = [100,200,400,800,1600,3200,6400,12800] # ISO列表,可替换为你需要选择数值的实际列表 iso_lest_state_num = 0 # 初始ios选中的索引,指向列表中的第一个元素 my_f_guangquan_daxiao = [1,1.4,2,2.8,4,5.6,8,11] # f光圈列表 f_guangquan_daxiao_lest_state_num = 0 # 初始光圈选中的索引,指向列表中的第一个元素 my_km = [ 1,1/2,1/4,1/8,1/15,1/30,1/60,1/125,1/250,1/500,1/1000] # km速度列表 km_sudu_num = 0 # 初始快门速度选中的索引,指向列表中的第一个元素 last_button_state = True # 记录boot上一次按键状态,初始为未按下(高电平) last_anjian_lan_state = True # 记录外接蓝色按键上一次按键状态,初始为未按下(高电平) last_anjian_hong_state = True # 记录外接红色按键上一次按键状态,初始为未按下(高电平) debounce_delay = 0.03 # 消抖延时时间,单位:秒,可根据实际调整,一般几十毫秒 button_kz = 0 # 创建boot按键的计数控制 while True: current_time = time.localtime() # 定义时间方法 formatted_time = "{:02d}:{:02d}:{:02d}".format(current_time.tm_hour, current_time.tm_min, current_time.tm_sec) #print("%.2f Lux" % guangxian.lux) # 向控制台打印lux数据 # 蓝色按键控制iso值 anjian_lan_state = anjian_lan.value # 获取蓝色按键当前按键状态 if anjian_lan_state != last_anjian_lan_state: # 检测到按键状态改变 #time.sleep(debounce_delay) # 进行延时消抖 anjian_lan_state != anjian_lan.value # 再次获取按键状态确认 if anjian_lan_state != last_anjian_lan_state: # 如果状态确实改变了 if anjian_lan_state == False: # 按键按下(变为低电平) led.value = True # 为led赋值高电平,让led亮起 print("蓝键按下了") iso_lest_state_num += 1 # iso列表索引加1,选择下一个元素 if iso_lest_state_num == len(my_iso): # 判断是否未达到列表末尾 if iso_lest_state_num >= 7: iso_lest_state_num = 0 print("清空iso_lest_one_num列表的位置计数,重新开始") print("当前iso数字为:",my_iso[iso_lest_state_num],"在列表的第",iso_lest_state_num,"位") else: # 按键松开(变回高电平) print("蓝键被松开了") # 可添加按键松开相关操作代码 led.value = False # 取消led亮起状态 last_anjian_lan_state = anjian_lan_state # 更新上一次按键状态记录 anjian_hong_state = anjian_hong.value # 获取红色按键当前按键状态 if anjian_hong_state != last_anjian_hong_state: # 检测到按键状态改变 #time.sleep(debounce_delay) # 进行延时消抖 anjian_hong_state != anjian_hong.value # 再次获取按键状态确认 if anjian_hong_state != last_anjian_hong_state: # 如果状态确实改变了 if anjian_hong_state == False: # 按键按下(变为低电平) led.value = True # 为led赋值高电平,让led亮起 print("红色键按下了") f_guangquan_daxiao_lest_state_num += 1 # f 光圈列表索引加1,选择下一个元素 if f_guangquan_daxiao_lest_state_num == len(my_f_guangquan_daxiao): # 判断是否未达到列表末尾 if f_guangquan_daxiao_lest_state_num >= 7: f_guangquan_daxiao_lest_state_num = 0 print("清空f_guangquan_daxiao_lest_state_num列表的位置计数,重新开始") print("当前光圈大小为:",my_f_guangquan_daxiao[f_guangquan_daxiao_lest_state_num],"在列表的第",f_guangquan_daxiao_lest_state_num,"位") else: # 按键松开(变回高电平) print("红色键被松开了") # 可添加按键松开相关操作代码 led.value = False # 取消led亮起状态 last_anjian_hong_state = anjian_hong_state # 更新上一次按键状态记录 ev = math.floor(2 + math.log((guangxian.lux+0.01) / (my_iso[iso_lest_state_num] / 10)) / math.log(2)) #print("EV值为=",ev) km1 = (math.pow(my_f_guangquan_daxiao[f_guangquan_daxiao_lest_state_num],2)*250) / ((guangxian.lux + 0.000001) * my_iso[iso_lest_state_num]) #print("快门值为=",km1) button_state = button.value # 获取当前按键状态 if button_state != last_button_state: # 检测到按键状态改变 #time.sleep(debounce_delay) # 进行延时消抖 button_state = button.value # 再次获取按键状态确认 if button_state!= last_button_state: # 如果状态确实改变了 if button_state == False: # 按键按下(变为低电平) led.value = True # 为led赋值高电平 print("\nboot按键被按下了") # 输出信息 # 这里可以添加按键按下后要执行的具体操作代码,比如切换显示组等 button_kz += 1 # button_kz boot按键控制计数加1 print("这是按下的第",button_kz,"次") #motor_servo.throttle = -1 kacha() if button_kz != 0: # 如果boot按键的计数控制不等于0 display.root_group = group_2 # 切换到显示组2 else: # 按键松开(变回高电平) print("boot按键被松开了") # 可添加按键松开相关操作代码 #button_kz = 0 # 清空boot按键计数控制 motor_servo.throttle = 0 led.value = False # 取消led亮起状态 #文字数据传递区域 text_test2.text = f"{button_kz}" # 向 text_test2 文字标签传递参数 text_iso_date.text = f"{my_iso[iso_lest_state_num]}" # 向 text_iso _date 光圈数据文字标签传递参数 text_lux_date.text = f"{int(guangxian.lux)}" # 向 text_lux_date 文字标签传递参数 text_time.text = f"time = {formatted_time}" # 向 text_time.text 文字标签传递时间参数 text_f_date.text = f"{my_f_guangquan_daxiao[f_guangquan_daxiao_lest_state_num]}" # 向 text_f_date 文字标签传递参数 text_km_date.text = f"{km1}" # 向 text_km_date 文字标签传递参数 text_ev_date.text = f"{ev}" # 向 text_ev_date 文字标签传递参数 last_button_state = button_state # 更新上一次按键状态记录 time.sleep(0.1) # 适当延时,减少循环对资源的占用 while True: # 死循环,显示当前所有代码不会退出 pass
【电子测光表基础任务视频】 https://www.bilibili.com/video/BV13hzrY3EsM/?share_source=copy_web&vd_source=5991d36362262775e81fd5dbdacc3dc5
源代码和支持库 直接复制到开发板上即可运行.zip