感谢您作为业余爱好者程序员提供的任何帮助。我已将Arduino控制器连接到Raspberry Pi。我能够从Arduino接收数据,但Raspberry Pi使用Python,并不总是完全加载数据,直到我点击屏幕的标题栏。我需要有经验的人帮助我弄清楚发生了什么。
Screen will only partially display the data
Screen will update after clicking the title bar
我的Arduino代码:
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println("1//February 1, 2016");
Serial.println("2//19:41:32 CST");
Serial.println("3// 30.092771 N, -95.225553 W");
Serial.println("4//EM22ab");
Serial.println();
}
我的Python代码:
#!/usr/bin python
# -*- coding: UTF-8 -*-
__title__= "GPS Time Clock"
try:
# Enable module-specific functions
import sys, os, time, serial, threading
import pygame
from pygame.locals import *
from datetime import datetime
except ImportError, err:
print("ERROR: {0}...".format(err))
sys.exit()
class Window(object):
# Global color reference
BLACK = ( 0, 0, 0 )
WHITE = ( 255, 255, 255 )
BLUE = ( 0, 46, 179 )
GREEN = ( 66, 179, 27 )
AMBER = ( 217, 162, 0 )
RED = ( 141, 0, 36 )
PURPLE= ( 140, 27, 179 )
# Initialize object
def __init__(self):
self._running = True # trigger for program shutdown
self.screen = None # remember display mode selection
self.font = None # remember font selection
self.windowBackground = self.BLACK # default background color
self.windowForeground = self.WHITE # default foreground color
self.windowWidth = 800 # default display width
self.windowHeight = 480 # default display height
self.fullscreen = False # remember fullscreen status
self.iCounter = 0 # counter used to select color scheme
self._serial_port = serial.Serial() # name instance of serial port
# Initialize screen parameters
def on_init(self):
self._running = True
pygame.init()
pygame.font.init()
pygame.display.set_caption(__title__)
self.font = pygame.font.SysFont("Consolas", 40) # monospaced, fixed-width font
self.screen = pygame.display.set_mode((self.windowWidth, self.windowHeight), pygame.RESIZABLE, 32)
pygame.display.update()
# Respond to keyboard input
def on_event(self, event):
if (event.type == pygame.QUIT): self._running = False
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): self._running = False
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_F9): self.screen_resize()
elif (event.type == pygame.KEYDOWN and event.key == pygame.K_F10):
self.iCounter += 1
if (self.iCounter > 7):
self.iCounter = 1
self.screen_colors(self.iCounter) # change color scheme
pygame.event.pump()
# Open serial port
def serial_open(self):
if (self._serial_port.isOpen() == False): # serial port is not open
pygame.event.pump() # keep program interaction alive
self._serial_port = serial.Serial() # name serial port instance
self._serial_port.port = "COM15" # serial port address used to communicate with the Arduino
self._serial_port.baudrate = 9600
self._serial_port.bytesize = serial.EIGHTBITS
self._serial_port.parity = serial.PARITY_NONE
self._serial_port.stopbits = serial.STOPBITS_ONE
self._serial_port.timeout = 1 # read timeout (seconds)
self._serial_port.xonxoff = False # disable software flow control
self._serial_port.rtscts = False # disable hardware flow control
self._serial_port.dsrdtr = False # disable hardware flow control
self._serial_port.write_timeout = 1 # write timeout (seconds)
print "Searching for Arduino on",
print str(self._serial_port.port) + "...", # look for path inside the Arduio IDE
try:
self._serial_port.open() # try to open serial port
self._serial_port.flush() # clear pre-existing data
print "found!"
except Exception, ex:
print "NOT found!"
print "Error: " + str(ex)
sys.exit(1) # '0' = normal; '1' = abnormal termination
else: # serial port is already open; do nothing
pygame.event.pump() # keep program interaction alive
pass
# Read from serial port
def serial_read(self):
if (self._serial_port.isOpen() == True): # serial port is open
pygame.event.pump() # keep program interaction alive
if (self._serial_port.inWaiting() > 0):
incoming = ""
incoming = self._serial_port.readline(self._serial_port.inWaiting()) # read from serial buffer
incoming = incoming.rstrip() # remove trailing special characters, e.g., crlf
if incoming.find("1//") == 0: # row 1: display the date
incoming = incoming.replace("1//", "")
inDate=incoming
strDate={"Date": inDate}
row1=" Date: {Date}".format(**strDate)
label1= self.font.render(row1, True, self.windowForeground, self.windowBackground)
self.screen.blit(label1, (0,40))
elif incoming.find("2//") == 0: # row 2: display the time
incoming = incoming.replace("2//", "")
inTime=incoming
strTime={"Time": inTime}
row2=" Time: {Time}".format(**strTime)
label2= self.font.render(row2, True, self.windowForeground, self.windowBackground)
self.screen.blit(label2, (0,120))
elif incoming.find("3//") == 0: # row 3: display the GPS coordinates
incoming = incoming.replace("3//", "")
inCoord=incoming
strCoord={"Coords": inCoord}
row3=" Coords: {Coords}".format(**strCoord)
label3= self.font.render(row3, True, self.windowForeground, self.windowBackground)
self.screen.blit(label3, (0,200))
elif incoming.find("4//") == 0: # row 4: display the Maidenhead location
incoming = incoming.replace("4//", "")
inLoc=incoming
strLoc={"Locator": inLoc}
row4=" Locator: {Locator}".format(**strLoc)
label4= self.font.render(row4, True, self.windowForeground, self.windowBackground)
self.screen.blit(label4, (0,280))
else:
incoming = "" # discard unusable data
pygame.display.flip() # refresh display with current data
else: # port is open, but no incoming data; do nothing
pygame.event.pump() # keep program interaction alive
pass
else:
pygame.event.pump() # keep program interaction alive
self.serial_open() # serial port is not open; try to open
# Change screen colors
def screen_colors(self, index):
if index == 1: # color scheme 1
self.windowBackground = self.AMBER
self.windowForeground = self.BLACK
elif index == 2: # color scheme 2
self.windowBackground = self.GREEN
self.windowForeground = self.BLACK
elif index == 3: # color scheme 3
self.windowBackground = self.WHITE
self.windowForeground = self.BLACK
elif index == 4: # color scheme 4
self.windowBackground = self.BLUE
self.windowForeground = self.WHITE
elif index == 5: # color scheme 5
self.windowBackground = self.PURPLE
self.windowForeground = self.WHITE
elif index == 6: # color scheme 6
self.windowBackground = self.RED
self.windowForeground = self.WHITE
elif index == 7: # default color scheme
self.windowBackground = self.BLACK
self.windowForeground = self.WHITE
self.screen.fill(self.windowBackground)
pygame.display.flip()
# Change screen size
def screen_resize(self):
if self.fullscreen == False:
self.fullscreen = True
self.screen = pygame.display.set_mode((self.windowWidth, self.windowHeight),
pygame.FULLSCREEN | pygame.HWSURFACE | pygame.DOUBLEBUF | pygame.NOFRAME, 32)
elif self.fullscreen == True:
self.fullscreen = False
self.screen = pygame.display.set_mode((self.windowWidth, self.windowHeight), pygame.RESIZABLE, 32)
self.screen.fill(self.windowBackground)
pygame.display.flip()
# Execute program
def on_execute(self):
if self.on_init() == False: # execute 'on_init' and get running status
self._running = False
self.serial_open() # open serial port
while(self._running):
for event in pygame.event.get():
self.on_event(event) # check for events
self.serial_read() # read data from serial port
pygame.quit()
sys.exit(0) # '0' = normal; '1' = abnormal termination
if __name__ == "__main__" :
window = Window() # class instantiation automatically invokes __init__()
window.on_execute() # following class instantiation, run 'on_execute()'