温度曲线 抽屉

实现天气预报温度曲线绘制及抽屉效果显示:
package com.canvas;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.Toast;

public class AndroidCanvasActivity extends Activity {
private float tempLow[] = {10,24,15,23};
private float tempHigh[] = {33,40,33,34};
private float temp[] = {33,40,33,34,10,24,15,23};

private View view;
private LinearLayout llLayout,llLayout2;
private int screenWith,screenHeight;
float lowDis = 0,highDis = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// view = findViewById(R.id.view);
llLayout = (LinearLayout) findViewById(R.id.content);
llLayout2 = (LinearLayout) findViewById(R.id.ll);

Object object = getSystemService(WINDOW_SERVICE);
WindowManager wm = (WindowManager) object;
screenWith = wm.getDefaultDisplay().getWidth();
screenHeight = wm.getDefaultDisplay().getHeight();

llLayout.addView(new DrawView(this));
llLayout2.addView(new DrawView(this));
}
class DrawView1 extends SurfaceView implements SurfaceHolder.Callback, Runnable{

float circleX = screenWith / 16;//屏幕横向8等分
float circleY = 260.0f*screenHeight/480.0f;
private SurfaceHolder surfaceHolder;
public DrawView1(Context context) {
super(context);
surfaceHolder = this.getHolder();
surfaceHolder.addCallback(this);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
new Thread(this).start();
}

@Override
public void surfaceCreated(SurfaceHolder holder) {

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

}

@Override
public void run() {
while (!Thread.currentThread().interrupted()) {
synchronized (surfaceHolder) {
draw();
}
}
}
private void draw(){
Canvas canvas = null;
Matrix matrix = new Matrix();
if(!Thread.currentThread().interrupted()){
canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.BLUE);
matrix.preTranslate(100f, 100f);

Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Style.FILL);

Paint linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setColor(Color.YELLOW);

Paint textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.WHITE);
textPaint.setTextSize(8.0f);

for (int i = 0; i < tempLow.length; i++) {
canvas.drawCircle(circleX + i*circleX, tempLow[i]*5, 2, paint);
canvas.drawText(tempLow[i]+"°", circleX + i*circleX, tempLow[i]*5-10, textPaint);
if(i < tempLow.length - 1){
canvas.drawLine(circleX + i*circleX,tempLow[i]*5, circleX + (i+1)*circleX, tempLow[i+1]*5, linePaint);
}
}
for (int i = 0; i < tempHigh.length; i++) {
canvas.drawCircle(circleX + i*circleX, tempHigh[i]*5, 2, paint);
canvas.drawText(tempHigh[i]+"°", circleX + i*circleX, tempHigh[i]*5-10, textPaint);
if(i < tempLow.length - 1){
canvas.drawLine(circleX + i*circleX,tempHigh[i]*5, circleX + (i+1)*circleX, tempHigh[i+1]*5, linePaint);
}
}
}
canvas.setMatrix(matrix);
if(canvas != null){

surfaceHolder.unlockCanvasAndPost(canvas);
}
}

}
class DrawView extends View{

float circleX = screenWith / 16;//屏幕横向8等分
float circleY = 260.0f*screenHeight/480.0f;
float[] sortData = sort(temp);
public DrawView(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float highPx = 260.0f*screenHeight/480.0f;
float lowPx = 80.0f*screenHeight/480.0f;

float x0 = screenWith/16;//40.0f
float x1 = 3*x0;
float x2 = 5*x0;
float x3 = 7*x0;

//乘100再除100是未了保留精度
float y0 = highPx - (100*(tempHigh[0]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);
float y1 = highPx - (100*(tempHigh[1]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);
float y2 = highPx - (100*(tempHigh[2]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);
float y3 = highPx - (100*(tempHigh[3]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);

float y00 = highPx - (100*(tempLow[0]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);
float y11 = highPx - (100*(tempLow[1]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);
float y22 = highPx - (100*(tempLow[2]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);
float y33 = highPx - (100*(tempLow[3]-sortData[0])/(sortData[7]-sortData[0])*(highPx-lowPx)/100);


Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);

Paint linePaint = new Paint();
linePaint.setAntiAlias(true);
linePaint.setColor(Color.YELLOW);
linePaint.setTextSize(5.0f);

Paint textPaint = new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.WHITE);
textPaint.setTextSize(10.0f);

float pts1[] = {x0,y0,x1,y1,
x1,y1,x2,y2,
x2,y2,x3,y3
};

float pts2[] = {
x0,y00,x1,y11,
x1,y11,x2,y22,
x2,y22,x3,y33
};

linePaint.setColor(Color.YELLOW );;//
canvas.drawLines(pts1, linePaint);
linePaint.setColor(Color.GREEN);;//
canvas.drawLines(pts2, linePaint);

float radius = 5.0f;
// canvas.drawPoints(pts1, pointPaint);
paint.setColor(Color.WHITE);;//
canvas.drawCircle(x0, y0, radius, paint);
canvas.drawCircle(x1, y1, radius, paint);
canvas.drawCircle(x2, y2, radius, paint);
canvas.drawCircle(x3, y3, radius, paint);
// canvas.drawPoints(pts2, pointPaint);
paint.setColor(Color.WHITE );;//
canvas.drawCircle(x0, y00, radius, paint);
canvas.drawCircle(x1, y11, radius, paint);
canvas.drawCircle(x2, y22, radius, paint);
canvas.drawCircle(x3, y33, radius, paint);

float textWidth = 20.0f;
float textHeight1 = 10.0f*screenHeight/480.0f;

textPaint.setTextSize(20.0f);//
canvas.drawText(tempHigh[0]+"°", x0-textWidth/2, y0-textHeight1, textPaint);
canvas.drawText(tempHigh[1]+"°", x1-textWidth/2, y1-textHeight1, textPaint);
canvas.drawText(tempHigh[2]+"°", x2-textWidth/2, y2-textHeight1, textPaint);
canvas.drawText(tempHigh[3]+"°", x3-textWidth/2, y3-textHeight1, textPaint);

float textHeight2 = 25.0f;

textPaint.setTextSize(20.0f);//
canvas.drawText(tempLow[0]+"°", x0-textWidth/2, y00+textHeight2, textPaint);
canvas.drawText(tempLow[1]+"°", x1-textWidth/2, y11+textHeight2, textPaint);
canvas.drawText(tempLow[2]+"°", x2-textWidth/2, y22+textHeight2, textPaint);
canvas.drawText(tempLow[3]+"°", x3-textWidth/2, y33+textHeight2, textPaint);

float textWidth1 = 40.0f;
textPaint.setTextSize(20.0f);

if(screenHeight == 854){
lowDis = 630f;highDis = 645f;
}else if(screenHeight == 800){
lowDis = 580f;highDis = 595f;
}else if(screenHeight == 480){
lowDis = 290f;highDis = 270f;
}else if(screenHeight == 320){
lowDis = 150f;highDis = 125f;
}
/*for (int i = 0; i < tempLow.length; i++) {
canvas.drawCircle(circleX + i*circleX, screenHeight - tempLow[i]*5 - lowDis, 2, paint);
canvas.drawText(tempLow[i]+"°", circleX + i*circleX, screenHeight - tempLow[i]*5-10 - lowDis, textPaint);
if(i < tempLow.length - 1){
canvas.drawLine(circleX + i*circleX,screenHeight - tempLow[i]*5 - lowDis, circleX + (i+1)*circleX, screenHeight - tempLow[i+1]*5 - lowDis, linePaint);
}
}
for (int i = 0; i < tempHigh.length; i++) {
canvas.drawCircle(circleX + i*circleX, screenHeight - tempHigh[i]*5 - highDis, 2, paint);
canvas.drawText(tempHigh[i]+"°", circleX + i*circleX, screenHeight - tempHigh[i]*5-10 - highDis, textPaint);
if(i < tempLow.length - 1){
canvas.drawLine(circleX + i*circleX,screenHeight - tempHigh[i]*5 - highDis, circleX + (i+1)*circleX, screenHeight - tempHigh[i+1]*5 - highDis, linePaint);
}
}*/
}
}
private float[] sort(float[] data){
for (int i = 1; i < data.length; i++) { // 数组有多长,轮数就有多长
// 将相邻两个数进行比较,较大的数往后冒泡
for (int j = 0; j < data.length - i; j++) {// 每一轮下来会将比较的次数减少
if (data[j] > data[j + 1]) {
// 交换相邻两个数
swap(data, j, j + 1);
}
}
}
return data;
}
private void swap(float[] data, int x, int y) {
float temp = data[x];
data[x] = data[y];
data[y] = temp;
}
}
===========================main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/ll">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绘图"
/>
</LinearLayout>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<SlidingDrawer android:id="@+id/slidingDrawerId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:handle="@+id/handle"
android:content="@+id/content">
<Button
android:id="@+id/handle"
android:layout_width="88dip"
android:layout_height="44dip"
android:background="@drawable/icon"
/>
<LinearLayout
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</LinearLayout>
</SlidingDrawer>
</RelativeLayout>
最外层需要用RelativeLayout包裹
from tkinter import ttk, messagebox from tkinter import * import tkinter as tk import time import binascii import serial.tools.list_ports from time import sleep import threading import matplotlib.pyplot as plt from binascii import unhexlify from crcmod import mkCrcFun #用于CRC校验 plt.rcParams['font.sans-serif'] = ['SimHei'] # 正常显示中文标签 plt.rcParams['axes.unicode_minus'] = False # 正常显示负号 frame_num=0 #全局帧号 ser=serial.Serial( port="COM2", baudrate=38400, bytesize=8, parity=serial.PARITY_NONE, stopbits=1, timeout=0.2) box0=0 box1=0 box2=0 box3=0 box4=0 box5=0 box6=0 box7=0 box8=0 box9=0 "绘制曲线图的温度数据" draw=0 box="0" #2B的锁控位 16进制 box_recv="0" #2B锁控返回位 16进制 press_recv="0" #压缩机工作状态 device_code="FFFFFFFFFF" #设备编码 默认全F device_add="01" #设备地址 缺省为1 post_time ="01" #上传间隔 缺省为1 pressor_start_delay= "1e" #压缩机启动延时 缺省30-》1e Temp="08" #当前温度的16进制字符串 缺省为4 转为8 Temp_pc = "02" #温控偏差 缺省为2 recv="0" Temp_recv=0 #返回的设定温度 Temp_pc_recv=0 #返回的温度控制偏差 press_button=0 #压缩机总开关 0是关 1是开 def draw_temp(): # 绘制温度曲线图 global draw #全局温度变化量 i = 0 t = [] list1 = [] plt.figure(1) plt.xlabel("时间(s)") plt.ylabel("温度(℃)") plt.title("温度实时监控曲线") for m in range(10): #两个for循环控制每次画图的总点数 for x in range(5): list1.append(draw) i = i + 1 t.append(i) plt.scatter(i, draw) #绘图点坐标 温度用全局变量 plt.pause(1.5) plt.plot(t, list1) #连线 plt.plot(t, list1) #总连线 plt.grid() plt.show() time.sleep(2) plt.cla() #清除原图 def xitong(): global frame_num root = Tk() root.title('智能快递柜终端v1.0') root.geometry('800x550') root.maxsize(800, 800) root.minsize(800, 550) ##################工作函数区################### def left_zero_hex1(data): # 1B 16进制左补0 b = data if (len(data) == 1): b = "0" + data # 小于两位 补0 return b def left_zero_hex2(data): # 2B 16进制左补0 b = "0000" if (len(data) == 1): b = "000" + data if (len(data) == 2): b = "00" + data if (len(data) == 3): b = "0" + data if (len(data) == 4): b = data return b def frame_num_re(): # 帧号合法性验证 global frame_num if frame_num > 255: frame_num = 0 def get_crc_value(s, crc16): #crc工作函数 data = s.replace(' ', '') crc_out = hex(crc16(unhexlify(data))) str_list = list(crc_out) if len(str_list) == 5: str_list.insert(2, '0') # 位数不足补0 crc_data = ''.join(str_list[2:]) return crc_data[2:] + crc_data[:2] def crc16_xmodem(s): #xmodem工作函数 crc16 = mkCrcFun(0x11021, rev=False, initCrc=0x0000, xorOut=0x0000) return get_crc_value(s, crc16) def build_frame(length, function, data): # 帧长,功能,数据 global frame_num frame_num=frame_num+1 frame_num_re() f = [] f.append("ffff") f.append(length) # 帧长 f.append(left_zero_hex1(hex(frame_num)[2:])) # 帧号10转16 f.append(device_add) f.append(function) # 功能号 f.append(data) # 数据载荷 ############CRC################# f_crc = ''.join(f) f_crc=crc16_xmodem(f_crc[4:]) #计算生成crc f.append(f_crc) # CRC ############CRC################# f.append("fff7") # 帧结尾标识 f_return = ''.join(f) return f_return ##################工作函数区################### ##################控制函数区################### def paramControl(): #设备参数控制 def build_data_frame(): # 整合设备参数数据部分 global frame_num devide_code = entry1.get() # 长度5B print("设备编码", devide_code) devide_add = left_zero_hex1(hex(int(entry2.get()))[2:]) # 长度1B print("设备地址", devide_add) post_time = left_zero_hex1(hex(int(entry4.get()))[2:]) # 长度1B print("上传间隔", post_time) pressor_start_delay = left_zero_hex1(hex(int(entry5.get()))[2:]) # 长度1B print("延时", pressor_start_delay) Temp = int(entry7.get()) # 1B Temp_2 = '{:06b}'.format(Temp) # 温度转二进制 Temp_2 = '0' + Temp_2 + '0' # 拼成8位二进制 Temp = left_zero_hex1(hex(int(Temp_2, 2))[2:]) # 16进制温度最终数据 print("温度", Temp) Temp_pc = left_zero_hex1(hex(int(entry8.get()))[2:]) # 1B 温度控制偏差 print("偏差", Temp_pc) frame = devide_code + devide_add + "00" + post_time + pressor_start_delay + "0000" + Temp + Temp_pc + "ffff" + "ffff" + "00" frame = build_frame("1c", "05", frame) # 构造参数帧 print(frame) d = bytes.fromhex(frame) ser.write(d) print("帧号:",frame_num) frame_num = frame_num + 1 # 帧号自增1 sleep(0.1) root1 = Toplevel(root) root1.title('设置') root1.geometry('400x400') root1.maxsize(400, 400) root1.minsize(400, 400) '''设备编码''' label1 = Label(root1,text="设备编码:", height=1) label1.place(x=120, y=5) entry1 = Entry(root1, width=20, textvariable='') entry1.place(x=180, y=5) '''设备地址''' label2 = Label(root1,text="设备地址:", height=1) label2.place(x=120, y=30) entry2 = Entry(root1, width=20, textvariable='') entry2.place(x=180, y=30) '''注册帧''' label3 = Label(root1,text="发送注册帧定时时间(s)", height=1) label3.place(x=50, y=60) entry3 = Entry(root1, width=20, textvariable='') entry3.place(x=180, y=60) '''采集时间''' label4 = Label(root1,text="采集时间间隔(s)", height=1) label4.place(x=85, y=90) entry4 = Entry(root1, width=20, textvariable='') entry4.place(x=180, y=90) '''压缩机启动延时''' label5 = Label(root1,text="压缩机启动延时(s)", height=1) label5.place(x=75, y=120) entry5 = Entry(root1, width=20, textvariable='') entry5.place(x=180, y=120) '''设定温度''' label7 = Label(root1,text="设定温度(℃)", height=1) label7.place(x=100, y=180) entry7 = Entry(root1, width=20, textvariable='') entry7.place(x=180, y=180) '''温度控制偏差''' label8 = Label(root1,text="温度控制偏差(℃)", height=1) label8.place(x=80, y=210) entry8 = Entry(root1, width=20, textvariable='') entry8.place(x=180, y=210) root1.Button1 = Button(root1, command=build_data_frame, height=3, width=10, bg="skyblue", text="发送") root1.Button1.place(x=100, y=280) root1.Button2 = Button(root1, command=root1.destroy, height=3, width=10, text="取消") root1.Button2.place(x=200, y=280) root1.mainloop() def openBox(): #抽屉锁控 def build_lock_frame(): # 功能号03 global box,frame_num # 将box转为16进制保存 frame_num_re() #帧号合法性校验 #print("xx",left_zero_hex2(hex(int(box, 2))[2:])) frame = build_frame("0c", "03", left_zero_hex2(hex(int(box, 2))[2:])) d = bytes.fromhex(frame) ser.write(d) frame_num = frame_num + 1 # 帧号自增1 sleep(0.1) class GUI: def __init__(self): self.root2 = tk.Toplevel(root) self.root2.title('抽屉开锁控制') self.root2.geometry("300x100") self.interface() def interface(self): """"界面编写位置""" self.Button0 = tk.Button(self.root2, text="确定", command=self.event) self.Button0.grid(row=4, column=3) self.v1 = tk.IntVar() self.Checkbutton01 = tk.Checkbutton(self.root2, text="1号柜", command=self.Check_box, variable=self.v1) self.Checkbutton01.grid(row=0, column=1) self.v2 = tk.IntVar() self.Checkbutton02 = tk.Checkbutton(self.root2, text="2号柜", command=self.Check_box, variable=self.v2) self.Checkbutton02.grid(row=0, column=2) self.v3 = tk.IntVar() self.Checkbutton03 = tk.Checkbutton(self.root2, text="3号柜", command=self.Check_box, variable=self.v3) self.Checkbutton03.grid(row=0, column=3) self.v4 = tk.IntVar() self.Checkbutton04 = tk.Checkbutton(self.root2, text="4号柜", command=self.Check_box, variable=self.v4) self.Checkbutton04.grid(row=0, column=4) self.v5 = tk.IntVar() self.Checkbutton05 = tk.Checkbutton(self.root2, text="5号柜", command=self.Check_box, variable=self.v5) self.Checkbutton05.grid(row=0, column=5) self.v6 = tk.IntVar() self.Checkbutton06 = tk.Checkbutton(self.root2, text="6号柜", command=self.Check_box, variable=self.v6) self.Checkbutton06.grid(row=1, column=1) self.v7 = tk.IntVar() self.Checkbutton07 = tk.Checkbutton(self.root2, text="7号柜", command=self.Check_box, variable=self.v7) self.Checkbutton07.grid(row=1, column=2) self.v8 = tk.IntVar() self.Checkbutton08 = tk.Checkbutton(self.root2, text="8号柜", command=self.Check_box, variable=self.v8) self.Checkbutton08.grid(row=1, column=3) self.v9 = tk.IntVar() self.Checkbutton09 = tk.Checkbutton(self.root2, text="9号柜", command=self.Check_box, variable=self.v9) self.Checkbutton09.grid(row=1, column=4) self.v10 = tk.IntVar() self.Checkbutton10 = tk.Checkbutton(self.root2, text="10号柜", command=self.Check_box, variable=self.v10) self.Checkbutton10.grid(row=1, column=5) #self.w1 = tk.Text(self.root2, width=20, height=10) #self.w1.grid(row=5, column=0) def event(self): # 绑定到开锁帧生成发送事件 global box '''按钮事件,获取复选框的状态,1表示勾选,0表示未勾选''' box = str(box7) + str(box6) + str(box5) + str(box4) + str(box3) + str(box2) + str(box1) + str( box0) + "000000" + str(box9) + str(box8) # 保存当前锁控16位2进制 #print(box) 检验box序列 build_lock_frame() # 构建开锁帧 def Check_box(self): '''复选框事件''' global box0, box1, box2, box3, box4, box5, box6, box7, box8, box9 if self.v1.get() == 1: box0 = 1 if self.v1.get() == 0: box0 = 0 if self.v2.get() == 1: box1 = 1 if self.v2.get() == 0: box1 = 0 if self.v3.get() == 1: box2 = 1 if self.v3.get() == 0: box2 = 0 if self.v4.get() == 1: box3 = 1 if self.v4.get() == 0: box3 = 0 if self.v5.get() == 1: box4 = 1 if self.v5.get() == 0: box4 = 0 if self.v6.get() == 1: box5 = 1 if self.v6.get() == 0: box5 = 0 if self.v7.get() == 1: box6 = 1 if self.v7.get() == 0: box6 = 0 if self.v8.get() == 1: box7 = 1 if self.v8.get() == 0: box7 = 0 if self.v9.get() == 1: box8 = 1 if self.v9.get() == 0: box8 = 0 if self.v10.get() == 1: box9 = 1 if self.v10.get() == 0: box9 = 0 a = GUI() # a 是 GUI 类 的 一个 实例化 对象 a.root2.mainloop() def tempControl(): def build_temp_frame(): # 功能号04 global frame_num Temp = int(entry4.get()) Temp_2 = '{:06b}'.format(Temp) # 温度转二进制 Temp_2 = '0' + Temp_2 + '0' # 拼成8位二进制 Temp = hex(int(Temp_2, 2))[2:] frame = build_frame("0B", "04", Temp) d = bytes.fromhex(frame) ser.write(d) print("帧号:", frame_num) frame_num = frame_num + 1 # 帧号自增1 sleep(0.1) root3 = tk.Toplevel(root) root3.title('温度控制') root3.geometry('350x300') root3.maxsize(350, 300) root3.minsize(350, 300) '''设备号''' label1 = Label(root3,text="设备号:", height=1) label1.place(x=80, y=30) combo = ttk.Combobox(root3,width=17, height=8, justify=CENTER) combo['values'] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] combo.bind("<<ComboboxSelected>>", lambda event: 'combo_handler(var=varBitrate.get())') combo.current(0) combo.place(x=140, y=30) '''设定温度''' label4 = Label(root3,text="设定温度(℃):", height=1) label4.place(x=60, y=90) entry4 = Entry(root3, width=20, textvariable='') entry4.place(x=140, y=90) root3.Button1 = Button(root3, command=build_temp_frame, height=3, width=10, bg="skyblue", text="发送") root3.Button1.place(x=100, y=150) root3.Button2 = Button(root3, command=root3.destroy, height=3, width=10, text="取消") root3.Button2.place(x=200, y=150) root3.mainloop() def pressorControl(): # 压缩机开启控制 温度偏差36-37 温度设定64-65 采集温度66-67 global draw, Temp_recv,Temp_pc_recv,press_button # 采集温度 设定温度 温度控制偏差 均为int 10进制 直接操作 press_button =1#压缩机总开关 #采集温度±控制偏差 与设定温度不符合则开启压缩机,否则不用开启压缩机 if ((press_button==1)and(draw > Temp_recv + Temp_pc_recv)): # 开启压缩机 frame_num_re() # 帧号合法性校验 frame = build_frame("0b", "02", "01") # 构建发送帧 01表示开启 d = bytes.fromhex(frame) ser.write(d) # 发送帧 if ((press_button==1)and((draw >= Temp_recv - Temp_pc_recv and draw <= Temp_recv + Temp_pc_recv)or(draw < Temp_recv - Temp_pc_recv))): # 在温控范围内 frame_num_re() # 帧号合法性校验 frame = build_frame("0b", "02", "00") # 构建发送帧 00表示关闭 d = bytes.fromhex(frame) ser.write(d) # 发送 def pressorControl2(): # 压缩机关闭控制 global press_button # 压缩机总开关 press_button = 0 frame = "FFFF0B7601020060C8FFF7" d = bytes.fromhex(frame) ser.write(d) ##################控制函数区################### #接收表 columns = ('帧长', '帧号', '地址', '功能号', '数据', '校验码') tv = ttk.Treeview(root, show='headings', columns=columns,height=50) tv.column('帧长', width=80, anchor='center') tv.column('帧号', width=80, anchor='center') tv.column('地址', width=80, anchor='center') tv.column('功能号', width=80, anchor='center') tv.column('数据', width=200, anchor='center') tv.column('校验码', width=80, anchor='center') tv.heading('帧长', text='帧长') tv.heading('帧号', text='帧号') tv.heading('地址', text='地址') tv.heading('功能号', text='功能号') tv.heading('数据', text='数据') tv.heading('校验码', text='校验码') tv.place(x=2,y=5,height=250,width=650) #1号抽屉 b1 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b1.place(x=20, y=320) b11= tk.Label(root,text="抽屉1") b11.place(x=30,y=295) #2号抽屉 b2 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b2.place(x=110, y=320) b22 =tk.Label(root,text="抽屉2") b22.place(x=120,y=295) #3号抽屉 b3 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b3.place(x=200, y=320) b33 =tk.Label(root,text="抽屉3") b33.place(x=210,y=295) #4号抽屉 b4 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b4.place(x=290, y=320) b44 =tk.Label(root,text="抽屉4") b44.place(x=300,y=295) #5号抽屉 b5 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b5.place(x=380, y=320) b55 =tk.Label(root,text="抽屉5") b55.place(x=390,y=295) #6号抽屉 b6 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b6.place(x=20, y=450) b66=tk.Label(root,text="抽屉6") b66.place(x=30,y=425) #7号抽屉 b7 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b7.place(x=110, y=450) b77 =tk.Label(root,text="抽屉7") b77.place(x=120,y=425) #8号抽屉 b8 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b8.place(x=200, y=450) b88 =tk.Label(root,text="抽屉8") b88.place(x=210,y=425) #9号抽屉 b9 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b9.place(x=290, y=450) b99 =tk.Label(root,text="抽屉9") b99.place(x=300,y=425) #10号抽屉 b10 = tk.Label(root, height=3,width=7,bg="red",text="OFF") b10.place(x=380, y=450) b1010 =tk.Label(root,text="抽屉10") b1010.place(x=390,y=425) #压缩机状态 b11 =tk.Label(root,height=9,width=7,bg="red",text="OFF") b11.place(x=480,y=350) b1111 =tk.Label(root,text="压缩机\n状态") b1111.place(x=485,y=310) #温度监控 a1=tk.Label(root,text="【设定温度】") a1.place(x=560,y=360) global Temp_recv,draw,Temp_pc_recv a11=tk.Label(root,text=str(Temp_recv)+'℃') a11.place(x=585,y=380) a2=tk.Label(root,text="【实时温度】") a2.place(x=560,y=410) a22=tk.Label(root,text=str(draw)+'℃') a22.place(x=585,y=430) a3=tk.Label(root,text="【偏差控制】") a3.place(x=560,y=460) a33=tk.Label(root,text=str(Temp_pc_recv)+'℃') a33.place(x=585,y=480) #实时接收函数 def recv_data(): #实时接收数据并更新各项信息 global recv,draw,box_recv,press_recv,Temp_recv,draw,Temp_pc_recv,press_button,frame_num def box_check(): #抽屉总体定时情况更新 state_10 = int(box_recv, 16) data = '{:016b}'.format(state_10) # 补齐16位的进制转换 #print(data) #8+7+6+5+4+3+2+1+000000+10+9 #顺序 #更新主界面抽屉锁状态 if data[7] == '0': b1.config(bg="red",text="OFF") if data[7] == '1': b1.config(bg="green",text="ON") if data[6] == '0': b2.config(bg="red",text="OFF") if data[6] == '1': b2.config(bg="green",text="ON") if data[5] == '0': b3.config(bg="red",text="OFF") if data[5] == '1': b3.config(bg="green",text="ON") if data[4] == '0': b4.config(bg="red",text="OFF") if data[4] == '1': b4.config(bg="green",text="ON") if data[3] == '0': b5.config(bg="red",text="OFF") if data[3] == '1': b5.config(bg="green",text="ON") if data[2] == '0': b6.config(bg="red",text="OFF") if data[2] == '1': b6.config(bg="green",text="ON") if data[1] == '0': b7.config(bg="red",text="OFF") if data[1] == '1': b7.config(bg="green",text="ON") if data[0] == '0': b8.config(bg="red",text="OFF") if data[0] == '1': b8.config(bg="green",text="ON") if data[15] == '0': b9.config(bg="red",text="OFF") if data[15] == '1': b9.config(bg="green",text="ON") if data[14] == '0': b10.config(bg="red",text="OFF") if data[14] == '1': b10.config(bg="green",text="ON") if press_recv == '00':b11.config(bg="red",text="OFF") if press_recv == "01":b11.config(bg="blue",text="预启动") if press_recv == "02":b11.config(bg="green",text="ON") if press_recv == "03":b11.config(bg="yellow",text="故障") ##################实时检测启停压缩机################ if ser.isOpen(): #持续监听函数 print("open") while True: #循环接收数据包 n = ser.inWaiting() if n: sleep(0.1) n = ser.inWaiting() payload = ser.read(n) data = str(binascii.b2a_hex(payload))[2:-1] if(crc16_xmodem(data[4:-8])==data[-8:-4]): #接收的数据进行crc合法性校验 if (len(data) == 88): #上传状态帧 print("上传状态帧:", data) #print("crc计算值",crc) #print("crc切片值",data[-8:-4]) #######数据处理########## box_recv=data[72:76] #用于更新开锁状态 press_recv=data[62:64] #用于更新压缩机状态 #print("press",press_recv) box_check() #更新快递柜状态 data_num=data[6:8] #帧号16转10 data_num = str(int(data_num, 16)) data_add=data[8:10] #设备地址16转10 data_add = str(int(data_add,16)) data_function= "Status" #功能号16转10 data_crc=data[80:84] #crc校验码 data_payload=data[12:30]+"..." #只显示部分数据帧 Temp_pc_recv=int(data[36:38],16) #温度控制偏差返回值 16进制 #print("控制偏差",Temp_pc_recv) #----------采集温度转换------------- #print("采集温度",data[66:68]) drawx='{:08b}'.format(int(data[66:68],16)) if(drawx[0]=='0'): #符号为非负 draw=int(drawx[1:7],2) #可用于画图的采集温度 if(drawx[0]=='1'): #符号为负 draw = int(drawx[1:7], 2) # 可用于画图的采集温度 draw= draw -2*draw #负数取相反数 #print("采集温度",draw) # ----------采集温度转换------------- # ----------设定温度转换------------- #print("设定温度",data[64:66]) Temp_recv='{:08b}'.format(int(data[64:66],16)) Temp_recv = int(Temp_recv[1:7],2) #可用于画图的采集温度 #print("设定温度",Temp_recv) # ----------设定温度转换------------- ##########压缩机控制########### if ((press_button==1)and(draw > Temp_recv + Temp_pc_recv)): # 开启压缩机 frame_num_re() # 帧号合法性校验 frame = build_frame("0b", "02", "01") # 构建发送帧 01表示开启 d = bytes.fromhex(frame) ser.write(d) # 发送帧 if ((press_button==1)and((draw >= Temp_recv - Temp_pc_recv and draw <= Temp_recv + Temp_pc_recv) or ( draw < Temp_recv - Temp_pc_recv))): # 在温控范围内 frame_num_re() # 帧号合法性校验 frame = build_frame("0b", "02", "00") # 构建发送帧 00表示关闭 d = bytes.fromhex(frame) ser.write(d) # 发送 ##########压缩机控制########### ########温度面板更新########### a11.config(text=str(Temp_recv)+'℃') a22.config(text=str(draw)+'℃') a33.config(text=str(Temp_pc_recv)+'℃') ########温度面板更新########### #######数据处理########## tv.insert("", 0, values=("44",data_num,data_add,data_function,data_payload,data_crc)) if (len(data) == 28): #显示ACK帧 print("Ack帧:", data) #######数据处理########## data_num=data[6:8] #帧号16转10 data_num = str(int(data_num, 16)) data_add=data[8:10] #设备地址16转10 data_add = str(int(data_add,16)) data_function= "Ack" #功能号16转10 data_payload=data[12:]+"..." data_crc2 = data[20:24] # crc校验码 #######数据处理########## tv.insert("", 0, values=("28",data_num,data_add,data_function,data_payload,data_crc2)) else: print(" not open") t2=threading.Thread(target=recv_data) #单开线程用于运行while true接收,防止主界面与接收冲突 t2.start() tv.insert("", 0, values=("default", "default", "default", "default", "FFFF0B7601020160C8FFF7")) tv.Button2 = Button(root, text="压缩机控制", command=pressorControl,height=2,width=13) tv.Button2.place(x=670,y=5) tv.Button8 = Button(root, text="压缩机关闭", command=pressorControl2,height=2,width=13) tv.Button8.place(x=670,y=75) tv.Button5 = Button(root, text="打开抽屉 ", command=openBox,height=2,width=13) tv.Button5.place(x=670, y=145) tv.Button6=Button(root,text="设置设备参数",command=paramControl,height=2,width=13) tv.Button6.place(x=670, y=215) tv.Button7=Button(root,text="绘制温度曲线",command=lambda:draw_temp(),height=2,width=13) tv.Button7.place(x=670, y=285) tv.Button4 = Button(root, text="设置温度 ", command=tempControl,height=2,width=13) tv.Button4.place(x=670, y=355) root.mainloop() if __name__ == "__main__": xitong()要求保留原有功能基础上优化功能界面方便使用
06-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值