天天看點

一起玩轉樹莓派(8)——樹莓派模數/數模轉換實踐(四)

 2.編寫代碼

對于本實驗來說,有涉及到UI開發,我們依然采用Python自帶的Tkinter庫,其有很好的移植性,并且其提供了Canvas畫布,我們可以靈活的渲染所需要的圖形。示例代碼如下:

#coding:utf-8

# 導入UI子產品

import tkinter as Tkinter

#SMBus (System Management Bus,系統管理總線)

import smbus   #在程式中導入“smbus”子產品

import RPi.GPIO as GPIO # 導入樹莓派GPIO子產品

import time # 導入定時器子產品

import threading

# 首頁面設定

top = Tkinter.Tk()

top.geometry('500x300')

top.title("操縱杆控制圓球")

# 目前圓球的坐标

currentX = 0

currentY = 0

# 目前圓球的顔色是否紅色

currentColor = True

# 進行視窗的初始化

canvas = Tkinter.Canvas(top, width=500, height=300, borderwidth=0, highlightthickness=0)

canvas.grid()

# 進化畫布的初始化

circle = canvas.create_oval(currentX, currentY, 100, 100, fill="red", outline="")

# 定義移動圓球的方法

def moveCircle(c, x, y):

   global currentX, currentY

   moveX = x

   moveY = y

   if x >= 0:

       if x + currentX > 400:

           moveX = 400 - currentX

           currentX = 400

       else:

           currentX += x

   else:

       if x + currentX < 0:

           moveX = -currentX

           currentX = 0

   if y >= 0:

       if y + currentY > 200:

           moveY = 200 - currentY

           currentY = 200

           currentY += y

       if y + currentY < 0:

           moveY = -currentY

           currentY = 0

           currentY += y

   canvas.move(c, moveX, moveY)

# 定義改變圓球顔色的方法

def changeColor(c):

   global currentColor

   canvas.itemconfig(c, fill= 'red' if currentColor else 'blue')

   currentColor = not currentColor

bus = smbus.SMBus(1)         #建立一個smbus執行個體

# 通過PCF8591讀取模拟信号

# 搖杆X引腳的模拟資料

def readX():

   #發送一個控制位元組到裝置 表示要讀取AIN0通道的資料

   bus.write_byte(0x48,0x40)  

   bus.read_byte(0x48)         # 空讀一次,消費掉無效資料

   return bus.read_byte(0x48)  # 傳回某通道輸入的模拟值A/D轉換後的數字值

# 搖杆Y引腳的模拟資料

def readY():

#發送一個控制位元組到裝置 表示要讀取AIN1通道的資料

   bus.write_byte(0x48,0x41)  

# 通過GPIO讀取數字信号

# 設定使用的引腳編碼模式

GPIO.setmode(GPIO.BOARD)

# 按鍵使用引腳 BCM 17

BTN = 11

# 引腳初始化 設定下拉高電平

GPIO.setup(BTN, GPIO.IN, pull_up_down=GPIO.PUD_UP)

# 建立定時器函數,用來檢查搖杆動作

def fun_timer():

   global timer

   x = readX()

   y = readY()

   press = GPIO.input(BTN)

   print('X:', x)

   print('Y:', y)

   print('按鈕:', press)

   if x <= 10:

       moveCircle(circle, -10, 0)

   if x >= 245:

       moveCircle(circle, 10, 0)

   if y <= 10:

       moveCircle(circle, 0, -10)

   if y >= 245:

       moveCircle(circle, 0, 10)

   timer = threading.Timer(0.2, fun_timer)

   timer.start()

timer = threading.Timer(0.2, fun_timer)

timer.start()

# 定義GPIO輸入端口的回調

def btnCallback(channel):

   if not GPIO.input(channel):

       changeColor(circle)

# 添加輸入引腳電平變化的回調函數

GPIO.add_event_detect(BTN, GPIO.FALLING, callback=btnCallback, bouncetime=200)

top.mainloop()

上面的代碼有些長,但是有詳盡的注釋,關于UI開發方面的内容不是我們本系列部落格的重點,這裡我們不做過多介紹。moveCircle函數是核心的圓球移動函數,内部通過邊界判定邏輯可以確定圓球不會移動到視圖界面外。changeColor方法用來修改圓球的顔色,這裡我們讓每次按鍵後在紅綠顔色間進行切換。readX和readY函數我們無需做過多介紹了,其通過PCF8591的AIN0和AIN1來傳輸搖杆的橫縱坐标信号。GPIO的相關操作我們也非常熟悉了,我們通過注冊回調函數來監聽操作杆按鈕按下的行為。

在樹莓派上運作上面的代碼,嘗試操作下,感受下使用操縱杆控制頁面元素的喜悅吧。

3.一點擴充

觀察上面的示例代碼,你會發現,我們使用了一些臨界值來作為觸發方向動作的門檻值,例如10,245這種,這是因為PCF8591是8位的數模轉換子產品,即其轉換出的數字量在0-255之間(包括0和255),對于本實驗來說,我們并沒有讓搖杆元件傳輸的模拟量發揮正真的作用,想一下,你是否能夠根據操作杆的旋轉程度來調整圓球移動的速度呢?動手試試吧!