基于树莓派的蓄电池控制系统

基于树莓派的蓄电池控制系统

总概:

(1)使用 Raspberry 4B作为主控芯片,通过不同模块采集信息。

(2)搭建BP神经网络模型并训练,根据采集信息算出蓄电池的补水量。

(3)使用PyQT编写人机交互界面。

硬件准备:

Raspberry Pi 4B

基于树莓派的蓄电池控制系统

PT1000 温度传感器

基于树莓派的蓄电池控制系统

MAX31865 放大器

基于树莓派的蓄电池控制系统

超声波测距传感器

基于树莓派的蓄电池控制系统

模数转换器

基于树莓派的蓄电池控制系统

比重检测模块

基于树莓派的蓄电池控制系统

总体连接图

基于树莓派的蓄电池控制系统

环境配置:

树莓派新板子配置可以看我之前的博客,有详细介绍树莓派开机

蓝牙配置

以下是DM35密度仪蓝牙配置及数据传输

基于树莓派的蓄电池控制系统

Blueman插件

基于树莓派的蓄电池控制系统

在树莓派上将所需依赖安装上

sudo apt update && sudo apt upgrade

sudo apt install bluetooth pi-bluetooth bluez blueman

基于树莓派的蓄电池控制系统

基于树莓派的蓄电池控制系统

之后右上角就出线了蓝牙的图标,可以通过GUI点击蓝牙配对比重仪并且信任该设备,或者通过以下命令行:

sudo bluetoothctl

scan on

pair XX:XX:XX:XX:XX:XX

connect XX:XX:XX:XX:XX:XX

exit

当比重仪点击发送数据后,树莓派就能接受到数据

基于树莓派的蓄电池控制系统

发送的是一个Iso8859编码格式的txt文件

基于树莓派的蓄电池控制系统

这里使用正则表达式将比重、温度、密度等需要信息提取出来

基于树莓派的蓄电池控制系统

基于树莓派的蓄电池控制系统

屏幕驱动

基于树莓派的蓄电池控制系统

可以上LCDWIKI找到具体的LCD信号及其驱动文件。

基于树莓派的蓄电池控制系统

按照步骤一步一步配置即可,注意的是有些触摸板上是power和touch接口,并不是下图这种双power接口,所以接线时除了HDMI还需要接touch线而不接power线。

基于树莓派的蓄电池控制系统

软件编写

写得很烂,完全没有去耦合,能跑就行

#用到的python解释库导入
import re
from PyQt5.QtWidgets import QLabel,QLineEdit
from PyQt5.QtCore import QTimer,QDateTime, QSize, Qt
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QComboBox
from PyQt5.QtGui import *

import sys
import os

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from openpyxl.styles.builtins import output
import time
import board
import digitalio
import adafruit_max31865
import ADS1263.ADS1263 as AD
import RPi.GPIO as GPIO

os.environ["QT_IM_MODULE"] = "qtvirtualkeyboard"

#接下来这部分是BP神经网络的内容

#定义每一层之间用到的传递函数
def sigmoid(x):
    # 第一层到第二层的激活函数
    return 1 / (1 + np.exp(-x))

def deriv_sigmoid(x):
    # 第一层到第二层的激活函数的求导函数
    fx = sigmoid(x)
    return fx * (1 - fx)

def mse_loss(y_true, y_pred):
    # 使用方差作为损失函数
return ((y_true - y_pred) ** 2).mean()

#开始神经网络的建立过程
class OurNeuralNetwork:

    def __init__(self):
        # 第一层到第二层的权重初始值设置
        self.w11 = np.random.normal()
        self.w12 = np.random.normal()
        self.w13 = np.random.normal()
        self.w14 = np.random.normal()
        self.w21 = np.random.normal()
        self.w22 = np.random.normal()
        self.w23 = np.random.normal()
        self.w24 = np.random.normal()
        # 第二层到第三层的权重初始值设置
        self.w1 = np.random.normal()
        self.w2 = np.random.normal()
        # 每一层截距项的初始值设置,Biases
        self.b1 = np.random.normal()
        self.b2 = np.random.normal()
        self.b3 = np.random.normal()

     # 前向传播学习函数
    def feedforward(self, x):
        h1 = sigmoid(self.w11 * x[0] + self.w12 * x[1] + self.w13 * x[2] + self.w14 * x[3] + self.b1)
        h2 = sigmoid(self.w21 * x[0] + self.w22 * x[1] + self.w23 * x[2] + self.w24 * x[3] + self.b1)
        o1 = self.w1 * h1 + self.w2 * h2 + self.b3
        return o1
     #训练函数
    def train(self, data, all_y_trues):
        learn_rate = 0.001  # 学习率
        epochs = 1000  # 训练的次数
        # 画图数据
        self.loss = np.zeros(100)
        self.sum = 0
        # 开始训练
        for epoch in range(epochs):
            for x, y_true in zip(data, all_y_trues):
                # 计算h1
                h1 = sigmoid(self.w11 * x[0] + self.w12 * x[1] + self.w13 * x[2] + self.w14 * x[3] + self.b1)
                # 计算h2
                h2 = sigmoid(self.w21 * x[0] + self.w22 * x[1] + self.w23 * x[2] + self.w24 * x[3] + self.b2)
                #计算输出节点
                y_pred = self.w1 * h1 + self.w2 * h2 + self.b3
                # 反向传播计算导数
                d_L_d_ypred = -2 * (y_true - y_pred)
                d_ypred_d_w1 = h1
                d_ypred_d_w2 = h2
                d_ypred_d_b3 = 0
                d_ypred_d_h1 = self.w1
                d_ypred_d_h2 = self.w2
                sum_1=self.w11 * x[0] + self.w12 * x[1] + self.w13 * x[2] + self.w14 * x[3] + self.b1
                d_h1_d_w11 = x[0] * deriv_sigmoid(sum_1)
                d_h1_d_w12 = x[1] * deriv_sigmoid(sum_1)
                d_h1_d_w13 = x[2] * deriv_sigmoid(sum_1)
                d_h1_d_w14 = x[3] * deriv_sigmoid(sum_1)
                d_h1_d_b1 = deriv_sigmoid(sum_1)
                sum_2 = self.w21 * x[0] + self.w22 * x[1] + self.w23 * x[2] + self.w24 * x[3] + self.b2
                d_h1_d_w21 = x[0] * deriv_sigmoid(sum_2)
                d_h1_d_w22 = x[1] * deriv_sigmoid(sum_2)
                d_h1_d_w23 = x[2] * deriv_sigmoid(sum_2)
                d_h1_d_w24 = x[3] * deriv_sigmoid(sum_2)
                d_h1_d_b2 = deriv_sigmoid(sum_2)

                # 梯度下降法
                self.w11 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w11
                self.w12 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w12
                self.w13 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w13
                self.w14 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_w14
                self.b1 -= learn_rate * d_L_d_ypred * d_ypred_d_h1 * d_h1_d_b1
                self.w21 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w21
                self.w22 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w22
                self.w23 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w23
                self.w24 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_w24
                self.b2 -= learn_rate * d_L_d_ypred * d_ypred_d_h2 * d_h1_d_b2
                self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_w1
                self.w1 -= learn_rate * d_L_d_ypred * d_ypred_d_w2
                self.b3 -= learn_rate * d_L_d_ypred * d_ypred_d_b3

            if epoch % 10 == 0:
                y_preds = np.apply_along_axis(self.feedforward, 1, data)
                loss = mse_loss(all_y_trues, y_preds)
                print("Epoch %d loss: %.3f" % (epoch, loss))
                self.loss[self.sum] = loss
                self.sum = self.sum + 1

训练数据文件导入
FILENAME = "/home/pi/Downloads/data.xlsx"
禁用科学计数法
pd.set_option('float_format', lambda x: '%.3f' % x)
np.set_printoptions(suppress=True,threshold=sys.maxsize)
得到的DataFrame分别为补水量、密度、电压、高度、温度
data = pd.read_excel(FILENAME, header=0, usecols="A,B,C,D,E")
DataArray = data.values
Y = DataArray[:, 0]
X = DataArray[:, 1:5]
X = np.array(X)#转化为array,自变量
Y = np.array(Y)#转化为array,因变量

处理数据
data = np.array(X)
data_mean = np.sum(data, axis=0) / np.size(data, 0)
data = (data - data_mean) / np.max(data)
all_y_trues = np.array(Y)
all_y_trues_mean = np.sum(all_y_trues) / np.size(all_y_trues)
all_y_trues = (all_y_trues - all_y_trues_mean) / np.max(all_y_trues)

训练数据
network = OurNeuralNetwork()
network.train(data, all_y_trues)

输出神经网络参数
print("w11-->%.3f" % network.w11)
print("w12-->%.3f" % network.w12)
print("w13-->%.3f" % network.w13)
print("w14-->%.3f" % network.w14)
print("w21-->%.3f" % network.w21)
print("w22-->%.3f" % network.w22)
print("w23-->%.3f" % network.w23)
print("w24-->%.3f" % network.w24)
print("w1-->%.3f" % network.w1)
print("w2-->%.3f" % network.w2)
print("b1-->%.3f" % network.b1)
print("b2-->%.3f" % network.b2)
print("b3-->%.3f" % network.b3)

#这部分是人机界面的建立过程
class Stats():
    def __init__(self):
        #主窗口设计参数
        self.window = QMainWindow()
        self.window.showFullScreen()
        self.window.move(0, 0)
        self.window.setWindowTitle('测控界面')
        self.window.setWindowFlags(Qt.FramelessWindowHint)
        self.window.setObjectName("MainWindow")
        self.window.setStyleSheet("#MainWindow{border-image:url(bg.jpg)}")
        self.state = True

        self.wendu = QLabel('温度(°)', self.window)                  # 温度按钮
        self.wendu.setGeometry(80, 200, 150, 60)  # (x坐标,y坐标,宽,高)

        self.tem = 0
        self.Label1 = QLineEdit(f'{self.tem}', self.window)               # 单文本框1:温度显示值
        self.Label1.setGeometry(250, 200, 150, 60)  # (x坐标,y坐标,宽,高)
        self.Label1.setAlignment(Qt.AlignCenter)                             # 设置文本框中内容居中

        self.bizhong = QLabel('密度(g/cm3)', self.window)                     # 比重按钮
        self.bizhong.setGeometry(80, 350, 150, 60)  # (x坐标,y坐标,宽,高)

        self.midu = 0
        self.Label4 = QLineEdit(f'{self.midu}', self.window)               # 单文本框4:比重显示值
        self.Label4.setGeometry(250, 350, 150, 60)  # (x坐标,y坐标,宽,高)
        self.Label4.setAlignment(Qt.AlignCenter)                             # 设置文本框中内容居中

        self.gaodu = QLabel('高度(cm)', self.window)                   # 高度按钮
        self.gaodu.setGeometry(640, 200, 150, 60)  # (x坐标,y坐标,宽,高)

        self.hei = 0
        self.Label2 = QLineEdit(f'{self.hei}', self.window)           # 单文本框2:高度显示值
        self.Label2.setGeometry(810, 200, 150, 60)  # (x坐标,y坐标,宽,高)
        self.Label2.setAlignment(Qt.AlignCenter)                             # 设置文本框中内容居中

        self.bushui = QLabel('水量(ml)', self.window)               # 补水量按钮
        self.bushui.setGeometry(640, 350, 150, 60)  # (x坐标,y坐标,宽,高)

        self.shui = 0
        self.Label3 = QLineEdit(f'{self.shui}', self.window)           # 单文本框3:补水量显示值
        self.Label3.setGeometry(810, 350, 150, 60)  # (x坐标,y坐标,宽,高)
        self.Label3.setAlignment(Qt.AlignCenter)                             # 设置文本框中内容居中

        self.ceshi = QPushButton('刷新', self.window)                   # 开始按钮,点击来对此时测量量进行显示以及赋值
        self.ceshi.setGeometry(100, 100, 60, 30)  # (x坐标,y坐标,宽,高)
        self.ceshi.clicked.connect(self.handleCalc)

        self.caculate_out_label = QLabel('补水量',self.window)
        self.caculate_out_label.setGeometry(100, 50, 60, 30)  # (x坐标,y坐标,宽,高)
        self.caculate_out_label.setAlignment(Qt.AlignCenter)

        self.Ncalculate_data=0
        self.caculate_outData_label = QLabel(f'{self.Ncalculate_data}',self.window)                           # 在self.window窗口添加一个标签time_label
        self.caculate_outData_label.setGeometry(180, 50, 60, 30)  # (x坐标,y坐标,宽,高)
        self.caculate_outData_label.setAlignment(Qt.AlignCenter)

        self.state_label = QLabel(f'OK',self.window)                           # 在self.window窗口添加一个标签time_label
        self.state_label.setGeometry(250, 50, 60, 30)  # (x坐标,y坐标,宽,高)
        self.state_label.setAlignment(Qt.AlignCenter)

        self.time_label = QLabel(self.window)                           # 在self.window窗口添加一个标签time_label
        self.time_label.setGeometry(700, 0, 300, 200)  # (x坐标,y坐标,宽,高)
        self.time_label.setAlignment(Qt.AlignCenter)                    # 函数setAlignment()主要将是消除布局中的空隙,让两个控件紧紧挨在一起
        self.Timer = QTimer()                                           # 创建定时器
        self.Timer.start(500)                                           # 定时器每500ms工作一次
        self.Timer.timeout.connect(self.TimeUpdate)                     # 500指的是500ms,即每500ms调用一下这个TimeUpdate函数
                                                                        # 建立定时器连接通道  注意这里调用TimeUpdate方法,不是方法返回的的结果,所以不能带括号, # 写成self.TimeUpdate()是不对的,带括号代表返回值

        self.setup = QPushButton('设置', self.window)                    # 设置按钮:点击进入下一界面
        self.setup.setGeometry(300, 100, 60, 30)  # (x坐标,y坐标,宽,高)
        self.setup.clicked.connect(self.call_dialog)

        self.Ncalculate = QPushButton('计算', self.window)                   # 开始按钮,点击来对此时测量量进行显示以及赋值
        self.Ncalculate.setGeometry(200, 100, 60, 30)  # (x坐标,y坐标,宽,高)
        self.Ncalculate.clicked.connect(self.Ncalculate_handle)

        # 电池类型选择:模式一,模式二,模式三分别代表不同的电池组类型
        self.moshi = QComboBox(self.window)
        self.moshi.setGeometry(400, 100, 110, 30)  # (x坐标,y坐标,宽,高)
        self.moshi.addItem("模式1")
        self.moshi.addItem("模式2")
        self.moshi.addItem("模式3")

    # 下面是前面用到的函数功能定义总结
    # 函数一:用于变量显示
    def handleCalc(self):                                                # 开始按钮对应的函数  def handleCalc(self):

通过SPI通讯读取MAX31865上面的数据(读取热电偶输出值)
            spi = board.SPI()
            cs = digitalio.DigitalInOut(board.D5)  # Chip select of the MAX31865 board.

            sensor = adafruit_max31865.MAX31865(spi, cs, rtd_nominal=1000.0, ref_resistor=4300.0, wires=4)
            print("Temperature: {0:0.3f}C".format(sensor.temperature))
            print("resistance: {0:0.3f} Ohms".format(sensor.resistance))
            self.tem = round(sensor.temperature,2)
            self.temperature=sensor.temperature
通过SPI通讯分时复用读取ADS1263上面的数据(读取超声波传感器上输出值)
            REF = 5.08  # Modify according to actual voltage
            try:
                ADC = AD.ADS1263()
                if (ADC.ADS1263_init_ADC1('ADS1263_7200SPS') == -1):
                    exit()
                ADC.ADS1263_SetMode(0)
                self.ADC_Value = ADC.ADS1263_GetAll()  # get ADC1 value
                self.height = self.ADC_Value[1] * REF / 0x7fffffff
                print("ADC1 IN1 = %lf" % self.height)  # 32bit
                self.hei=round(self.height, 2)
            except IOError as e:
                print(e)

            self.buttonLabel1 = f'{self.tem}'
            self.Label1.setText(self.buttonLabel1)                         # 改变标签1的函数,给标签1赋当前温度值

            self.buttonLabel2 = f'{self.hei}'
            self.Label2.setText(self.buttonLabel2)                        # 改变标签1的函数,给标签2赋当前温度值

            try:
                f = open('./measureLog_export.txt',encoding='iso8859')
            except:
                self.Density=0
                print(f'bluetooth error:not file')
                self.state = False
            else:
                read_data_line=f.readlines()
                f.close()
                read_data_line_count=len(read_data_line)
                os.remove("./measureLog_export.txt")

                regex = re.compile("[0-9]+.*[0-9]")
                search_data=regex.search(read_data_line[read_data_line_count-6])
                SampleID=str(search_data.group())
                print(f'SampleID is {SampleID}')

                regex = re.compile("[0-9]+.*[0-9]")
                search_data=regex.search(read_data_line[read_data_line_count-5])
                self.Density=float(search_data.group())
                print(f'Density is {self.Density}')

                regex = re.compile("[0-9]+.*[0-9]")
                search_data=regex.search(read_data_line[read_data_line_count-3])
                SG=float(search_data.group())
                print(f'SG is {SG}')
                self.state = True

            self.midu=round(self.Density, 2)

            self.buttonLabel4 = f'{self.midu}'
            self.Label4.setText(self.buttonLabel4)

            info = self.moshi.currentText()                              # 提取模式多组合选择里面的文本出来,此时文本包括字符串以及数字
            salary = re.sub("\D", "", info)                              # 提取info里面的数字出来

            if int(salary) == 1:                                         # 根据模式不同,赋给按钮6补水量的值也有所不同
                    self.shui = 10
                    self.buttonLabel3 = f'{self.shui}'
                    self.Label3.setText(self.buttonLabel3)              # 改变按钮6标签的函数
            if int(salary) == 2:
                    self.shui = 20
                    self.buttonLabel3 = f'{self.shui}'
                    self.Label3.setText(self.buttonLabel3)  # 改变按钮6标签的函数
            if int(salary) == 3:
                    self.shui = 30
                    self.buttonLabel3 = f'{self.shui}'
                    self.Label3.setText(self.buttonLabel3)  # 改变按钮6标签的函数

    # 函数二:用于时间刷新,实时时间显示:目前是调用当前电脑上时间
    def TimeUpdate(self):
        self.time_label.setText(QDateTime.currentDateTime().toString('yyyy-MM-dd hh:mm:ss dddd'))
        if self.state == False :
            self.state_label.setText('Error')
        else :
            self.state_label.setText('OK')

    def is_number(self,s):
        pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
        result = pattern.match(s)
        if result:
            return True
        else:
            return False

    def Ncalculate_handle(self):

        calculate_data_Density=self.Label4.text()
        if not self.is_number(calculate_data_Density):
            calculate_data_Density = 0
            print('Density input is not number')
            self.Label4.setText('0')
            self.state = False
        else :
            calculate_data_Density = float(calculate_data_Density)
        if  calculate_data_Density==self.midu :
            calculate_data_Density=self.Density
        else :
            self.state = True

        calculate_data_temperature=self.Label1.text()
        if not self.is_number(calculate_data_temperature):
            calculate_data_temperature = 0
            print('Temperature input is not number')
            self.state = False
            self.Label1.setText('0')
        else :
            calculate_data_temperature = float(calculate_data_temperature)
        if  calculate_data_temperature==self.tem :
            calculate_data_temperature=self.temperature

        calculate_data_shui=self.Label3.text()
        if not self.is_number(calculate_data_shui):
            calculate_data_shui = 0
            print('Water input is not number')
            self.state = False
            self.Label3.setText('0')
        else :
            calculate_data_shui = float(calculate_data_shui)
        if  calculate_data_shui==self.shui :
            calculate_data_shui=self.shui

        calculate_data_height=self.Label2.text()
        if not self.is_number(calculate_data_height):
            calculate_data_height = 0
            print('Height input is not number')
            self.state = False
            self.Label2.setText('0')
        else :
            calculate_data_height = float(calculate_data_height)
        if  calculate_data_height==self.hei :
            calculate_data_height=self.height

        self.k1 = calculate_data_Density
        self.k2 = calculate_data_height
        self.k3 = calculate_data_shui
        self.k4 = calculate_data_temperature
        z = [self.k1, self.k2, self.k3, self.k4]
        z = (z - data_mean) / np.max(data)
        z1 = z[0]
        z2 = z[1]
        z3 = z[2]
        z4 = z[3]

        self.h1 = sigmoid(network.w11 * z1 + network.w12 * z2 + network.w13 * z3 + network.w14 * z4 + network.b1)
        self.h2 = sigmoid(network.w21 * z1 + network.w22 * z2 + network.w23 * z3 + network.w24 * z4 + network.b2)
        self.output = network.w1 * self.h1 + network.w2 * self.h2 + network.b3
        self.output = self.output * np.max(all_y_trues) + all_y_trues_mean
        self.d1 = round(self.output, 2)  # 0.0005 is changed as 0.05

        self.Ncalculate_data=self.d1
        self.caculate_outData_label.setText(f'{self.Ncalculate_data}')

        print(f'Neural Networks OutPut is {self.d1}')

    # 函数三:点击设置按钮后用于主界面的关闭与子界面1的打开
    def call_dialog(self):
        self.childwindow = QMainWindow()                                 # 子界面childwindow的设置
        self.childwindow.resize(400, 300)
        self.childwindow.move(300, 100)
        self.childwindow.setWindowTitle('设置界面')

        self.save = QPushButton('返回', self.childwindow)                 # 存储按钮
        self.save.move(80, 200)
        self.save.clicked.connect(self.back)

        self.language = QPushButton('语言', self.childwindow)             # 语言按钮
        self.language.move(80, 40)
        self.language.clicked.connect(self.call_dialog2)

        self.test = QPushButton('校零', self.childwindow)                 # 校零按钮
        self.test.move(80, 120)
        self.test.clicked.connect(self.backzero)

        self.childwindow.show()

        # 函数四 语言按钮的子窗口2
    def call_dialog2(self):
        self.childwindow2 = QMainWindow()                                 # 子界面childwindow的设置
        self.childwindow2.resize(400, 300)
        self.childwindow2.move(300, 100)
        self.childwindow2.setWindowTitle('语言界面')

        self.foreign = QPushButton('英语', self.childwindow2)                 # 存储按钮
        self.foreign.move(80, 40)
        self.foreign.clicked.connect(self.English)

        self.china = QPushButton('中文', self.childwindow2)             # 语言按钮
        self.china.move(80, 120)
        self.china.clicked.connect(self.Chinese)

        self.childwindow.close()
        self.childwindow2.show()

    def English(self):
        self.wendu.setText('Temeratiure')
        self.gaodu.setText('Height')
        self.ceshi.setText('Begin')
        self.bizhong.setText('Density')
        self.setup.setText('Setting')
        self.save.setText('Save')
        self.language.setText('Language')
        self.test.setText('Test')
        self.foreign.setText('English')
        self.china.setText('Chinese')
        self.save.setText('Save')

        self.childwindow2.close()
        self.childwindow.show()

    def Chinese(self):
        self.wendu.setText('温度')
        self.gaodu.setText('高度')
        self.ceshi.setText('刷新')
        self.bizhong.setText('密度')
        self.setup.setText('设置')
        self.save.setText('存储')
        self.language.setText('语言')
        self.test.setText('校零')
        self.foreign.setText('英语')
        self.china.setText('中文')
        self.save.setText('返回')

        self.childwindow2.close()
        self.childwindow.show()

    # 函数五:点击返回按钮后用于子界面1的关闭与主界面的打开
    def back(self):
        self.childwindow.close()
        self.window.show()

    # 函数六:点击返回按钮后用于子界面1的关闭与主界面的打开
    def backzero(self):

        self.shui = 0
        self.buttonLabel1 = f'{self.shui}c'
        self.Label1.setText(self.buttonLabel1)                         # 改变单文本框1标签的函数,给赋当前温度值
        self.buttonLabel2 = f'{self.shui}cm'
        self.Label2.setText(self.buttonLabel2)                         # 改变单文本框2标签的函数,赋当前高度值
        self.buttonLabel3 = f'{self.shui}ml'
        self.Label3.setText(self.buttonLabel3)                         # 改变单文本框3标签的函数
        self.buttonLabel4 = f'{self.shui}ml'
        self.Label4.setText(self.buttonLabel4)                         # 改变单文本框4标签的函数
        self.childwindow.close()
        self.window.show()

app = QApplication([])
stats = Stats()
stats.window.show()
app.exec_()

基于树莓派的蓄电池控制系统

基于树莓派的蓄电池控制系统

基于树莓派的蓄电池控制系统

为方便调试、测量数据,编写两套启动脚本

auto_start_test.sh:不含神经网络计算,只为测量、调试,启动、运行更快

auto_start.sh:含神经网络计算部分,先将测量后的数据进行训练学习,利用模型得出计算量

Original: https://blog.csdn.net/qq_41495871/article/details/127809293
Author: PeepFuture橙子
Title: 基于树莓派的蓄电池控制系统

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/656665/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球