Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@Sg4Dylan
Created June 24, 2019 12:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Sg4Dylan/9c0c0b964443104c65ffec835a9a764e to your computer and use it in GitHub Desktop.
Save Sg4Dylan/9c0c0b964443104c65ffec835a9a764e to your computer and use it in GitHub Desktop.
显示器亮度自动调节套装
import math
import queue
import threading
import serial
from vcp import * # https://github.com/dot-osk/monitor_ctrl
import logging
# Init VCP
try:
monitors = enumerate_monitors()
except OSError as err:
exit(1)
phy_monitors = []
while not phy_monitors:
for i in monitors:
try:
monitor = PhyMonitor(i)
except OSError as err:
logging.error(err)
continue
phy_monitors.append(monitor)
pm = phy_monitors[0]
# Init serial port
connected = False
port = 'COM6'
baud = 9600
try:
serial_port = serial.Serial(port, baud, timeout=0)
except serial.serialutil.SerialException:
logging.error('Can not open serial port.')
# Init lux queue
queue_len = 5
lux_queue = queue.Queue(queue_len)
def handle_data(data):
global lux_queue
if data.startswith('Light') and data.endswith('lx'):
# Parse lux value
brightness_lx = float(data[7:-3])
# Slide window average
if lux_queue.qsize() < queue_len:
lux_queue.put(brightness_lx)
return
else:
lux_queue.get()
lux_queue.put(brightness_lx)
lux_list = list(lux_queue.queue)
lux_centered_average = (sum(lux_list) - max(lux_list) - min(lux_list)) / (len(lux_list) - 2)
# control core
now_brightness = pm.brightness
ctl_factor = math.log(lux_centered_average+1) * 21
final_result = 1
if ctl_factor <= 0:
pass
elif ctl_factor >= 100:
final_result = 100
else:
final_result = math.floor(ctl_factor) + 3
if now_brightness != final_result:
pm.brightness = final_result
print(f'Sensor: {brightness_lx} lx Avg: {lux_centered_average:.2f} lx Factor: {ctl_factor:.2f} Display: {now_brightness}->{final_result}')
def read_from_port(ser):
global connected
while not connected:
connected = True
while True:
while serial_port.in_waiting:
try:
reading = ser.readline().decode().strip()
handle_data(reading)
except KeyboardInterrupt:
ser.close()
thread = threading.Thread(target=read_from_port, args=(serial_port,))
thread.start()
#include <Wire.h>
#include <BH1750.h>
BH1750 lightMeter;
void setup(){
Serial.begin(9600);
// Initialize the I2C bus (BH1750 library doesn't do this automatically)
// On esp8266 devices you can select SCL and SDA pins using Wire.begin(D4, D3);
Wire.begin();
if (lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE)) {
Serial.println(F("BH1750 Advanced begin"));
}
else {
Serial.println(F("Error initialising BH1750"));
}
}
void loop() {
float lux = lightMeter.readLightLevel();
Serial.print("Light: "+lux+"lx");
Serial.print(lux);
Serial.println(" lx");
delay(250);
}
@Sg4Dylan
Copy link
Author

Sg4Dylan commented Jun 24, 2019

硬件需求:

  • 下位机: ESP8266(25 CNY 左右) 或者 STM32F103C8T6(16 CNY 左右(需要另外买一个 USB2TTL))(已安装 STM32duino Bootloader)
  • 传感器: BH1750(5 CNY 包邮)
  • 连接线: microUSB x1、母对母杜邦线 10cm若干
  • 显示器: 支持 DDC/CI 控制亮度

硬件连接:

  • 注意:BH1750 需连接在 STM32F103C8T6 的 I2C1 上(反正就两组,试一下就好了)

程序需要改动的地方:

  1. Python 脚本 L26: 修改为你开发板的 COM 口序号(*inx 系统上不可用(自行将 VCP 换成 ddcutil 即可))
  2. Python 脚本 L53: 21 为我这估算的参数,即最大环境亮度 55lx 时对应最大亮度。算法为:100/(ln(55)+1)+1≈21

执行方法:

  1. 烧录好 Arduino 程序
  2. 将开发板连接 PC,记下 COM 口名称
  3. 修改 Python 脚本
  4. 坐等亮度随环境光变动

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment