python控制两台光源控制器

工作中碰见两台单通道的大功率光源控制器,但是没有找到该控制器的手册.

一看牌子和厂家名称,突然发现这个和上次同事发给我的多通道手册是一个牌子.

于是插上串口线用串口助手测一下果然 指令兼容的;

厂家名不说了省事,只看串口参数,截图放在下方.

本来是打算C#做,但是python不甘心,于是就python;控制光源控制器.

一共80行两个滑动条,不废话贴程序.

import tkinter as tk
from tkinter import messagebox
import time
import serial
serL=serial.Serial("COM2",19200,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,timeout=0.5) #winsows系统使用com口连接串行口
serR=serial.Serial("COM3",19200,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,timeout=0.5) #winsows系统使用com口连接串行口
if (serL.isOpen()):print("serLdone!")
if (serR.isOpen()):print("serRdone!")
def portL_close():
    serL.close()
    if (serL.isOpen()):
        print("关闭失败")
def portR_close():
    serR.close()
    if (serR.isOpen()):
        print("关闭失败")     
def Lsend(send_data):
    if (serL.isOpen()):
        serL.write(send_data.encode('utf-8'))  #utf-8 编码发送
        #ser.write(binascii.a2b_hex(send_data))  #Hex发送
        print("发送成功",send_data)
def Rsend(send_data):
    if (serR.isOpen()):
        serR.write(send_data.encode('utf-8'))  #utf-8 编码发送
        #ser.write(binascii.a2b_hex(send_data))  #Hex发送
        print("发送成功",send_data)
win = tk.Tk();win.title("滑动条控制光源")
try:
    win.iconbitmap('th.ico')   
except:
    pass
r"""
COM2 是左光源
COM3 是右光源
串口配置:
波特率:19200 数据位:8 停止位:1 校验位:NONE
19200 8 N 1 
光源控制器本就单通道:不存在多通道操作:
发送字符串:
设置亮度:200
	发送:SA0200#
	返回:
亮度查询:
	发送:SA#
	返回:a0200
"""
def select_price_L(value):
    Lsend(f"SA0{value}#")
    print(value,"L") 
def select_price_R(value):
    Rsend(f"SA0{value}#")
    print(value,"R")   
Scale1=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='左侧光源' , #滑动条的标签:不写则不显示.
command=select_price_L)
Scale1.pack()
Scale1.set(255)#初始位置100
Scale2=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='右侧光源' , #滑动条的标签:不写则不显示.
command=select_price_R)
Scale2.pack()
Scale2.set(255)#初始位置100
def QueryWindow():
    if messagebox.askokcancel("窗口关闭?")==True:
        portL_close();portR_close()
        win.destroy()
win.protocol('WM_DELETE_WINDOW', QueryWindow)
win.mainloop()

算然自己电脑有python环境但是工控机没python更没有第三方库,于是需要打包成exe.

开始: 新建个打包程序 如下:

import os,sys
def cmd(s="pause"):
    os.system(s)
    pass
打包的文件名="光源控制滑动条002"
生成单一EXE=" -F "
指定图标="-i th.ico"
不显示命令行="--noconsole"
cmd(f"pyinstaller {打包的文件名}.py {生成单一EXE} {指定图标}  {不显示命令行} ")

新建一个文件夹: 这个程序和上面那个还有图标放在里面.运行打包程序.

dist里面就会出现打包成exe的python程序将同名图标复制进去就可以自定义图标.

不过没有加防多开,第一个没关运行二次会报串口打不开. 然后这个打包的exe 经常报毒就很奇怪.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

仔细观察的同学已经发现,上面的程序有好几个毛病,0.不能多开前面已经说过了.1.程序重新打开的时候光源亮度会回到255,2.不知道是控制器问题还是程序问题设置亮度低于100时就写不起作用了.

这次手上有一台海康de4通道光源控制器.控制方式竟然和上次那个一模一样.

附图为证:

.

四通道:贴程序看看.

import tkinter as tk
from tkinter import messagebox
import time,serial
ser=serial.Serial("COM4",19200,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,timeout=0.1) 
if (ser.isOpen()):print("serdone!")
def port_close():#关闭串口
    ser.close()
    if (ser.isOpen()):
        print("关闭失败")     
def read(S=""):
    if (ser.isOpen()):
        r = ser.read().decode('utf-8')
        if (r==S):
            print(f"{S}")
        else:
            print(f"{S}W>>失败!")     
def send(send_data):
    if (ser.isOpen()):
        ser.write(send_data.encode('utf-8'))  #utf-8 编码发送
        print(">>",send_data)
CH1=0
CH2=0
CH3=0
CH4=0
def readCH_value():
    global CH1,CH2,CH3,CH4 
    if (ser.isOpen()):
        send(f"SA#");r1 = ser.readall().decode('utf-8');
        send(f"SB#");r2 = ser.readall().decode('utf-8');
        send(f"SC#");r3 = ser.readall().decode('utf-8');
        send(f"SD#");r4 = ser.readall().decode('utf-8');
    print(f"**************************************************");
    if (len(r1)==5):
        print(f"{len(r1)} {r1} {r1[2:]}");CH1=r1[2:]
    if (len(r2)==5):
        print(f"{len(r2)} {r2} {r2[2:]}");CH2=r2[2:]
    if (len(r3)==5):
        print(f"{len(r3)} {r3} {r3[2:]}");CH3=r3[2:]
    if (len(r4)==5):
        print(f"{len(r4)} {r4} {r4[2:]}");CH4=r4[2:]
    print(f"**************************************************");   
    Scale1.set(CH1)
    Scale2.set(CH2)
    Scale3.set(CH3)
    Scale4.set(CH4)
win = tk.Tk();win.title("滑动条控制光源")
def select_price1(value):
    send(f"SA0{value}#")
    read("A")
Scale1=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道1' , #滑动条的标签:不写则不显示.
command=select_price1)
Scale1.pack()
def select_price2(value):
    send(f"SB0{value}#")
    read("B")
Scale2=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道2' , #滑动条的标签:不写则不显示.
command=select_price2)
Scale2.pack()
def select_price3(value):
    send(f"SC0{value}#")
    read("C")
Scale3=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道3' , #滑动条的标签:不写则不显示.
command=select_price3)
Scale3.pack()
def select_price4(value):
    send(f"SD0{value}#")
    read("D")
Scale4=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道4' , #滑动条的标签:不写则不显示.
command=select_price4)
Scale4.pack()
readCH_value()
def QueryWindow():
    if messagebox.askokcancel("窗口关闭?")==True:
        try:
            port_close(); 
        except:
            pass
        win.destroy()
win.protocol('WM_DELETE_WINDOW', QueryWindow)
win.mainloop()
r"""
COM4 是光源
串口配置:
波特率:19200 数据位:8 停止位:1 校验位:NONE
19200 8 N 1 
通道操作:
    A:1通道
    B:2通道
    C:3通道
    D:4通道
发送字符串:
设置亮度:200
	发送:SA0200#
	返回:
    发送成功 SD0255#
    D
    发送成功 SC0255#
    C
    发送成功 SB0255#
    B
    发送成功 SA0255#
    A
亮度查询:
	发送:SA#
	返回:a0200
    发送成功 SA#
    a0255
    发送成功 SB#
    b0255
    发送成功 SC#
    c0255
    发送成功 SD#
    d0255	
"""

这次增加了,亮度读取,不会出现重启程序亮度回到255的情况.

1.亮度不能低于100的情况依然存在>依然不知道是哪里出了问题(从现象看应该是控制器的问题).

2.多开的问题也没解决.>>实际上还有个端口记忆和端口扫描的问题.

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

偶然机缘巧合和大姐大说了一下第一个情况,大姐大瞄了一眼,就找到:这行:说你这个value哪来的???我木讷的思量了一下说是这是进度条传进来的.只见大姐大说,那肯定是你输入格式错了.

并指出可以控制进度条value的格式.

def select_price1(value):
    send(f"SA0{value}#")

原来根本没有仔细看手册,手册只有短短一页. 回头一看亮度等级是(0000-0255).而不是自己想当然的(00-0255).  好了.问题发现了现在该优化了.               大姐大的精髓没学会.控制格式咱也不会.就简单粗暴的改一下吧.

#笨蛋办法 判断value长度决定前面有几个0 4通道进度条改成如下
def select_price1(value):
    if(len(value)==3):
        send(f"SA0{value}#")
    if(len(value)==2):
        send(f"SA00{value}#")
    if(len(value)==1):
        send(f"SA000{value}#")     
    read("A")

def select_price2(value):
    if(len(value)==3):
        send(f"SB0{value}#")
    if(len(value)==2):
        send(f"SB00{value}#")
    if(len(value)==1):
        send(f"SB000{value}#")  
    read("B")

def select_price3(value):
    if(len(value)==3):
        send(f"SC0{value}#")
    if(len(value)==2):
        send(f"SC00{value}#")
    if(len(value)==1):
        send(f"SC000{value}#")  
    read("C")

def select_price4(value):
    if(len(value)==3):
        send(f"SD0{value}#")
    if(len(value)==2):
        send(f"SD00{value}#")
    if(len(value)==1):
        send(f"SD000{value}#")  
    read("D")

完整程序如下:

import tkinter as tk
from tkinter import messagebox
import time,serial
ser=serial.Serial("COM1",19200,bytesize=serial.EIGHTBITS,parity=serial.PARITY_NONE,stopbits=serial.STOPBITS_ONE,timeout=0.1) 
if (ser.isOpen()):print("serdone!")
def port_close():#关闭串口
    ser.close()
    if (ser.isOpen()):
        print("关闭失败")     
def read(S=""):
    if (ser.isOpen()):
        r = ser.read().decode('utf-8')
        if (r==S):
            print(f"{S}")
        else:
            print(f"{S}W>>失败!")     
def send(send_data):
    if (ser.isOpen()):
        ser.write(send_data.encode('utf-8'))  #utf-8 编码发送
        print(">>",send_data)
CH1=0
CH2=0
CH3=0
CH4=0
def readCH_value():
    global CH1,CH2,CH3,CH4 
    if (ser.isOpen()):
        send(f"SA#");r1 = ser.readall().decode('utf-8');
        send(f"SB#");r2 = ser.readall().decode('utf-8');
        send(f"SC#");r3 = ser.readall().decode('utf-8');
        send(f"SD#");r4 = ser.readall().decode('utf-8');
    print(f"**************************************************");
    if (len(r1)==5):
        print(f"{len(r1)} {r1} {r1[2:]}");CH1=r1[2:]
    if (len(r2)==5):
        print(f"{len(r2)} {r2} {r2[2:]}");CH2=r2[2:]
    if (len(r3)==5):
        print(f"{len(r3)} {r3} {r3[2:]}");CH3=r3[2:]
    if (len(r4)==5):
        print(f"{len(r4)} {r4} {r4[2:]}");CH4=r4[2:]
    print(f"**************************************************");   
    Scale1.set(CH1)
    Scale2.set(CH2)
    Scale3.set(CH3)
    Scale4.set(CH4)
win = tk.Tk();win.title("滑动条控制光源")
def select_price1(value):
    if(len(value)==3):
        send(f"SA0{value}#")
    if(len(value)==2):
        send(f"SA00{value}#")
    if(len(value)==1):
        send(f"SA000{value}#")     
    read("A")
Scale1=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道1' , #滑动条的标签:不写则不显示.
command=select_price1)
Scale1.pack()
def select_price2(value):
    if(len(value)==3):
        send(f"SB0{value}#")
    if(len(value)==2):
        send(f"SB00{value}#")
    if(len(value)==1):
        send(f"SB000{value}#")  
    read("B")
Scale2=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道2' , #滑动条的标签:不写则不显示.
command=select_price2)
Scale2.pack()
def select_price3(value):
    if(len(value)==3):
        send(f"SC0{value}#")
    if(len(value)==2):
        send(f"SC00{value}#")
    if(len(value)==1):
        send(f"SC000{value}#")  
    read("C")
Scale3=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道3' , #滑动条的标签:不写则不显示.
command=select_price3)
Scale3.pack()
def select_price4(value):
    if(len(value)==3):
        send(f"SD0{value}#")
    if(len(value)==2):
        send(f"SD00{value}#")
    if(len(value)==1):
        send(f"SD000{value}#")  
    read("D")
Scale4=tk.Scale(win,orient=tk.HORIZONTAL, 
from_=0,            #从0开始
to=255,             #到255结束
resolution =1,      #单步步长.
length =300,        #控件长度 
sliderlength= 20,  #滑动块尺寸
tickinterval=50,    #指示刻度
label ='通道4' , #滑动条的标签:不写则不显示.
command=select_price4)
Scale4.pack()
readCH_value()
def QueryWindow():
    if messagebox.askokcancel("窗口关闭?")==True:
        try:
            port_close(); 
        except:
            pass
        win.destroy()
win.protocol('WM_DELETE_WINDOW', QueryWindow)
win.mainloop()

好,现在可以随意拖拽进度条控制4通道,光源控制器亮度了.

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值