sudo apt-get update
sudo apt-get install python3-tk
sudo mkdir -m a+x ./battery_status_code
cd ./battery_status_code
sudo nano ./battery_status_GUI_app.py
import tkinter as tk
from tkinter import PhotoImage
import smbus
import time
import threading
device_address = 0x36
VCELL = 0x02
SOC = 0x04
SOC1 = 0x05
MODE = 0x06
VERSION = 0x08
CONFIG = 0x0C
COMMAND = 0xFE
bus = smbus.SMBus(1)
def read_custom_bits(device_address, register, num_bits):
num_bytes = (num_bits + 7) // 8 # 计算所需的字节数
# 从设备中读取指定字节数的数据
data = bus.read_i2c_block_data(device_address, register, num_bytes)
# 将字节数据转换为位串
bit_string = ''.join(format(byte, '08b') for byte in data)
# 从位串中提取指定位数的数据
result = int(bit_string[:num_bits], 2)
return result
def update_data():
while True:
VCELL_data = read_custom_bits(device_address, VCELL, 12)
SOC_data = bus.read_byte_data(device_address, SOC)
SOC1_data = bus.read_byte_data(device_address, SOC1)
# MODE_data = bus.read_byte_data(device_address, MODE)
# VERSION_data = bus.read_byte_data(device_address, VERSION)
# CONFIG_data = bus.read_byte_data(device_address, CONFIG)
# COMMAND_data = bus.read_byte_data(device_address, COMMAND)
# 更新标签文本
vcell_label.config(text=f"Battery voltage: {VCELL_data * 0.00125:.4f} V")
soc_label.config( text=f"Battery level: {SOC_data + (SOC1_data / 256):.2f} %")
# vcell_label.config(text=f"VCELL: {VCELL_data * 0.00125:.4f} V")
# soc_label.config(text=f"SOC: {SOC_data + (SOC1_data / 256):.2f} %")
# mode_label.config(text=f"MODE: {MODE_data}")
# version_label.config(text=f"VERSION: {VERSION_data}")
# config_label.config(text=f"CONFIG: {CONFIG_data}")
# command_label.config(text=f"COMMAND: {COMMAND_data}")
time.sleep(0.5)
def start_update_thread():
threading.Thread(target=update_data, daemon=True).start()
root = tk.Tk()
root.title("I2C Data Monitor")
root.attributes("-fullscreen", True)
# 添加Logo
logo = PhotoImage(file="/home/pi/battery_status_code/logo.png")
logo_label = tk.Label(root, image=logo)
logo_label.pack(pady=10)
vcell_label = tk.Label(root, text="Battery voltage: ", font=("Helvetica", 16))
vcell_label.pack(pady=10)
soc_label = tk.Label(root, text="Battery level: ", font=("Helvetica", 16))
soc_label.pack(pady=10)
#vcell_label = tk.Label(root, text="VCELL: ", font=("Helvetica", 16))
#vcell_label.pack(pady=10)
#soc_label = tk.Label(root, text="SOC: ", font=("Helvetica", 16))
#soc_label.pack(pady=10)
#mode_label = tk.Label(root, text="MODE: ", font=("Helvetica", 16))
#mode_label.pack(pady=10)
#version_label = tk.Label(root, text="VERSION: ", font=("Helvetica", 16))
#version_label.pack(pady=10)
#config_label = tk.Label(root, text="CONFIG: ", font=("Helvetica", 16))
#config_label.pack(pady=10)
#command_label = tk.Label(root, text="COMMAND: ", font=("Helvetica", 16))
#command_label.pack(pady=10)
button = tk.Button(root, text="Close", command=root.quit, font=("Helvetica", 16))
button.pack(pady=20)
# 启动更新数据的线程
start_update_thread()
# 绑定按键事件,按F11键切换全屏模式,按Esc键退出全屏模式
root.bind("<F11>", lambda event: root.attributes("-fullscreen", not root.attributes("-fullscreen")))
root.bind("<Escape>", lambda event: root.attributes("-fullscreen", False))
root.mainloop()
NOTE:注意logo图片的路径要以实际路径保持一致
sudo python3 ./battery_status_GUI_app.py
NOTE:要在GUI环境执行该程序,如果只在ssh执行则会报“无法访问图形环境”的错误
NOTE:因为该程序必须在GUI环境才能正常启动,所以在/etc/rc.local自启动脚本的方法是无效的,得使用服务的方法实现自启动;
编译一个Tkinter程序的Python脚本,如上述程序“/home/pi/battery_status_code/battery_status_GUI_app.py”
创建一个systemd服务文件】
创建一个名为"gui_app.service"的文件,该文件定义了Tkinter GUI应用程序作为服
务的行为,并在终端中运行以下命令
sudo nano /etc/systemd/system/gui_app.service
[Unit]
Description=Tkinter GUI Application
After=graphical.target
[Service]
User=pi
Environment=DISPLAY=:0
ExecStart=/usr/bin/python3 /home/pi/battery_status_code/battery_status_GUI_app.py
Restart=always
[Install]
WantedBy=graphical.target
运行以下命令以重新加载systemd配置文件,使其识别新的服务文件
sudo systemctl daemon-reload
运行以下命令以启用并启动服务,这样它将在系统启动时自动运行:
sudo systemctl enable gui_app.service
sudo systemctl start gui_app.service
使用以下命令检查服务的状态
sudo systemctl status gui_app.service
如果服务运行正常,会看到服务的状态为`active(running)'。
sudo mkdir -m a+x ./battery_status_code
cd ./battery_status_code
sudo nano ./battery_status_command_app.py
import smbus
import time
import sys
device_address = 0x36
VCELL = 0x02
SOC = 0x04
SOC1 = 0x05
MODE = 0x06
VERSION = 0x08
CONFIG = 0x0C
COMMAND = 0xFE
bus = smbus.SMBus(1)
def read_custom_bits(device_address, register, num_bits):
num_bytes = (num_bits + 7) // 8 # 计算所需的字节数
# 从设备中读取指定字节数的数据
data = bus.read_i2c_block_data(device_address, register, num_bytes)
# 将字节数据转换为位串
bit_string = ''.join(format(byte, '08b') for byte in data)
# 从位串中提取指定位数的数据
result = int(bit_string[:num_bits], 2)
return result
def clear_screen():
# 清除屏幕并将光标移动到起始位置
sys.stdout.write("\033[H\033[J")
sys.stdout.flush()
while True:
clear_screen()
VCELL_data = read_custom_bits(device_address, VCELL, 12)
SOC_data = bus.read_byte_data(device_address, SOC)
SOC1_data = bus.read_byte_data(device_address, SOC1)
MODE_data = bus.read_byte_data(device_address, MODE)
VERSION_data = bus.read_byte_data(device_address, VERSION)
CONFIG_data = bus.read_byte_data(device_address, CONFIG)
COMMAND_data = bus.read_byte_data(device_address, COMMAND)
# 打印读取的数据
print(" Battery status \n")
print("Battery voltage:", (VCELL_data * 0.00125))
print("Battery level :", SOC_data + (SOC1_data / 256), "%")
print()
time.sleep(1)
sudo python3 ./battery_status_command_app.py
周一-周五(9:30-6:30)周六(9:30-5:30)
手机:13434470212
邮箱:services04@spotpear.cn
QQ:202004841