實作部分

pyserial

因為要從樹梅派的USB到3D列印機的Arduino控制系統,必須做出一套橋梁,來做兩端的溝通,採用的方式是使用pyserial,由python第三方模組支援的串列通訊溝通,由官方提供的方法可以import pyserial後,就可以進行serial.open(Value),開啟兩端的連接後,接者進行資料的傳送和溝通,利用3Dprinter裡面的指令,就可以下指令到3D列印機中控制他(例如:G01、M105…),利用這樣的方式,就可以傳送基本指令控制3D列印機。 以下為串列傳輸程式碼: (包含解字、切字、utf-8、執行緒)

#!/usr/bin/python3

import serial
import sys
import numpy as np
import tkinter
from matplotlib import pyplot, rcParams

port = serial.Serial('COM6', 9600, timeout=1)

# Tkinter canvas
top = tkinter.Tk()
top.title("Tkinter + matplotlib")

# Create flag to work with indefinite while loop
flag = tkinter.BooleanVar(top)
flag.set(True)


def cleanText(data):
    data = data.replace("\r\n", "")
    return data


def onStartButtonPress():
    while True:
        if flag.get():
            line = port.readline().decode('UTF-8')
            reading = line.split(':')
        #    print (reading)
            if len(reading) == 2:
                for i in range(2):
                    if reading[0] == "temperature":
                        TempLabel.config(text=cleanText(reading[1]))
                        TempUnitLabel.config(text="C")
                        TempUnitLabel.update_idletasks()
  #                  if reading[0] == "Temperature(F)":
 #                       TempLabel.config(text=cleanText(reading[1]))
 #                       TempUnitLabel.config(text="F")
#                        TempUnitLabel.update_idletasks()
                    if reading[0] == "Humidity":
                        HumdLabel.config(text=cleanText(reading[1]))
                        pData.append(float(reading[1]))
                        del pData[0]
#                    if reading[0] == "Light(lx)":
  #                      LighLabel.config(text=cleanText(reading[1]))
                    if reading[0] == "Flag":
#                        print (reading[1])
                        if int(reading[1]) == 1:
                            try:
                                print ("In flag")
                                print ("In flag -> if ")
                                l1.set_xdata(np.arange(len(pData)))
                                l1.set_ydata(pData)  # update the data
                                pyplot.ylim([0, 100])
                                pyplot.draw()  # update the plot
                            except:
                                print ("In flag except")
                                pyplot.figure()
                                pyplot.title('Humidity')
                                ax1 = pyplot.axes()
                                l1, = pyplot.plot(pData)
                                pyplot.ylim([0, 100])
                        if int(reading[1]) == 0:
                            try:
                                pyplot.close('all')
                                l1 = None
                            except:
                                continue
            port.flushInput()
            top.update()
        else:
            flag.set(True)
            break


def onExitButtonPress():
    print ("Exiting....")
    flag.set(False)
    port.close()
    top.quit()
    top.destroy()
    print ("Done.")
    sys.exit()

pyplot.ion()
rcParams['toolbar'] = 'None'
pData = [0] * 25

tkinter.Label(top, text="Temperature").grid(column=1, row=1)
tkinter.Label(top, text="Humidity").grid(column=1, row=2)
tkinter.Label(top, text="Light").grid(column=1, row=3)

TempLabel = tkinter.Label(top, text=" ")
TempLabel.grid(column=2, row=1)
HumdLabel = tkinter.Label(top, text=" ")
HumdLabel.grid(column=2, row=2)
LighLabel = tkinter.Label(top, text=" ")
LighLabel.grid(column=2, row=3)

TempUnitLabel = tkinter.Label(top, text=" ")
TempUnitLabel.grid(column=3, row=1)
HumdUnitLabel = tkinter.Label(top, text="%")
HumdUnitLabel.grid(column=3, row=2)
LighUnitLabel = tkinter.Label(top, text="lx")
LighUnitLabel.grid(column=3, row=3)

# Create Start button and associate with onStartButtonPress method
StartButton = tkinter.Button(top,
                             text="Start",
                             command=onStartButtonPress)
StartButton.grid(column=1, row=4)

# Create Exit button and destroy the window
ExitButton = tkinter.Button(top,
                            text="Exit",
                            command=onExitButtonPress)
ExitButton.grid(column=2, row=4)

top.mainloop()

Flask

這邊我們選用的框架是flask,因為它輕巧、且具有大量的可擴充性,因此選用,相較於python其他兩個,他擁有比較小的空間和核心,較符合Raspberrypi的系統。 底下為利用flask看通訊端得到的資料


import flask
import serial
from time import sleep

app = flask.Flask(__name__)
app.debug = True

def event_barcode():
    messageid = 0
    ser = serial.Serial()
    ser.port = COM^
    ser.baudrate = 9600
    ser.bytesize = 8
    ser.parity = serial.PARITY_NONE
    ser.stopbits = serial.STOPBITS_ONE
    ser.timeout = 0
    try:
        ser.open()
    except serial.SerialException as e:
         yield 'event:error\n' + 'data:' + 'Serial port error({0}): {1}\n\n'.format(e.errno, e.strerror)
         messageid = messageid + 1
    str_list = []
    while True:
        sleep(0.01)
        nextchar = ser.read()
        if nextchar:
            str_list.append(nextchar)
        else:
            if len(str_list) > 0:
                yield 'id:' + str(messageid) + '\n' + 'data:' + ''.join(str_list) + '\n\n'
                messageid = messageid + 1
                str_list = []

@app.route('/barcode')
def barcode():
    newresponse = flask.Response(event_barcode(), mimetype="text/event-stream")
    newresponse.headers.add('Access-Control-Allow-Origin', '*')
    newresponse.headers.add('Cache-Control', 'no-cache')
    return newresponse

if __name__ == '__main__':
    app.run(port=5000, threaded=True)

OctoPrint

我們在找相關資料的時候,發現到其實已經有人將我們實作的部分寫成一份套件包,只需要從新編譯過,就可以符合我們使用,而且他是屬於OpenSource,不會有版權上的問題,他將程式碼公開,讓我們這些後輩人學習,真的非常感動,我們照著他的code一路走,看到每個人針對他所想要走所設計的不同,看到不一樣的寫法,因此感謝他的幫助好讓我們可以有參考資料。主要他用的方法是使用我們看到的flask+js+nginx+pyserial+oprint+yaml,非常的複雜,但是在flask底下,可以很清楚的知道,每個py檔的作用和功能,可以讓我們比較好了解如何使用。


Comments

comments powered by Disqus