Skip to content

Instantly share code, notes, and snippets.

@michalzielanski
Created June 18, 2013 15:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michalzielanski/5806325 to your computer and use it in GitHub Desktop.
Save michalzielanski/5806325 to your computer and use it in GitHub Desktop.
Port do Pythona 3.x i Gtk+ 3.x aplikacji prezentującej dane z akcelerometru ADXL345. Testowane pod Python 3.2, pygobject 3.4.2, pyserial 2.6 Źródło oryginalnej aplikacji: http://starter-kit.nettigo.pl/2012/02/akcelerometry-zyroskopy-i-kompasy-czyli-badanie-polozenia-z-arduino-cz-1/ http://static.nettigo.pl/code/adxl345.zip Autor: sprae (http://s…
import serial
from serial.tools import list_ports
from gi.repository import Gtk, GObject
import widgets
ACC_PORT = None
for port in serial.tools.list_ports.comports():
p_name, p_desc, p_hw_id = port
if p_hw_id != 'n/a':
ACC_PORT = p_name
break
class ADXL (object):
def __init__(self):
self.device = serial.Serial(ACC_PORT, 57600, timeout=0.5)
def read_last_line(self):
line = ''
while self.device.inWaiting() > 0:
line = self.device.readline()
return line
def parse_args(self, line):
try:
data = [float(v) for v in line[5:].strip().split(b',')]
except ValueError:
return 0, 0, 0, 0, 0
return data
def read(self):
line = self.read_last_line()
while line[:5] != b'#ACC=':
line = self.read_last_line()
data = self.parse_args(line)
if len(data) == 5:
return data
return 0, 0, 0, 0, 0
class App (object):
def __init__(self):
self.window = Gtk.Window()
self.gforce = widgets.GForce()
self.horizon = widgets.Horizon()
self.level = widgets.Level()
self.hbox = Gtk.HBox()
self.hbox.pack_start(self.gforce, True, True, 0)
self.hbox.pack_start(self.horizon, True, True, 0)
self.vbox = Gtk.VBox()
self.vbox.pack_start(self.hbox, True, True, 0)
self.vbox.pack_start(self.level, True, True, 0)
self.window.add(self.vbox)
self.window.set_title('Accelerometer ADXL345')
self.window.show_all()
self.window.connect('destroy', self.on_destroy)
self.device = ADXL()
self.timer_id = GObject.timeout_add(33, self.on_timer)
Gtk.main()
def on_timer(self):
x, y, z, roll, pitch = self.device.read()
self.horizon.set_horizon(pitch, roll)
self.gforce.set_accel(x, y, z)
self.level.set_angle(roll)
return True
def on_destroy(self, widget, data=None):
GObject.source_remove(self.timer_id)
Gtk.main_quit()
if __name__ == '__main__':
App()
from gi.repository import Gtk, Gdk
import cairo
import math
class Image (object):
def __init__(self, filename):
self.surface = cairo.ImageSurface.create_from_png(filename)
def draw(self, cr):
cr.save()
cr.set_source_surface(self.surface)
cr.paint()
cr.restore()
class Widget (Gtk.DrawingArea):
def __init__(self):
Gtk.DrawingArea.__init__(self)
self.set_size_request(300, 300)
self.connect('draw', self.on_draw)
def refresh(self):
rect = Gdk.Rectangle()
allocation = self.get_allocation()
rect.x, rect.y, rect.width, rect.height = 0, 0, allocation.width, allocation.height
win = self.get_window()
win.invalidate_rect(rect, True)
win.process_updates(True)
def on_draw(self, widget, cr, data=None):
cr.set_source_rgb(0, 0, 0)
cr.paint()
self.draw(cr)
def draw(self, cr):
pass
class Compass (Widget):
def __init__(self):
Widget.__init__(self)
self.background = Image('compass-background.png')
self.face = Image('compass-face.png')
self.glass = Image('compass-glass.png')
self.angle = 0.0
def set_azimuth(self, azimuth):
self.angle = -math.radians(azimuth)
self.refresh()
def draw(self, cr):
cr.save()
self.background.draw(cr)
cr.save()
cr.translate(150, 150)
cr.rotate(self.angle)
cr.translate(-150, -150)
self.face.draw(cr)
cr.restore()
self.glass.draw(cr)
cr.restore()
class Horizon (Widget):
def __init__(self):
Widget.__init__(self)
self.face = Image('horizon-face.png')
self.background = Image('horizon-background.png')
self.hand_shadow = Image('horizon-hand-shadow.png')
self.hand = Image('horizon-hand.png')
self.glass = Image('horizon-glass.png')
self.pitch = 0.0
self.roll = 0.0
def set_horizon(self, pitch, roll):
self.pitch = pitch * 4
self.roll = math.radians(roll)
self.refresh()
def draw_face(self, cr):
cr.save()
cr.arc(150, 150, 150, 0, 2*math.pi)
cr.clip()
cr.translate(0, -742-self.pitch)
cr.translate(150, 892+self.pitch)
cr.rotate(self.roll)
cr.translate(-150, -892-self.pitch)
self.face.draw(cr)
cr.restore()
def draw_hand(self, cr):
cr.save()
cr.translate(150, 150)
cr.rotate(self.roll)
cr.translate(-150, -150)
self.hand.draw(cr)
cr.restore()
def draw_hand_shadow(self, cr):
cr.save()
cr.translate(3, 3)
cr.translate(150, 150)
cr.rotate(self.roll)
cr.translate(-150, -150)
self.hand_shadow.draw(cr)
cr.restore()
def draw(self, cr):
cr.save()
self.draw_face(cr)
self.background.draw(cr)
self.draw_hand_shadow(cr)
self.draw_hand(cr)
self.glass.draw(cr)
cr.restore()
class GForce (Widget):
def __init__(self):
Widget.__init__(self)
self.face = Image('gforce-face.png')
self.progress = [0, 0, 0, 0, 0, 0]
def set_accel(self, x, y, z):
if x > 0:
self.progress[0] = x * 48.5
self.progress[1] = 0
else:
self.progress[0] = 0
self.progress[1] = -x * 48.5
if y > 0:
self.progress[2] = y * 48.5
self.progress[3] = 0
else:
self.progress[2] = 0
self.progress[3] = -y * 48.5
if z > 0:
self.progress[4] = z * 48.5
self.progress[5] = 0
else:
self.progress[4] = 0
self.progress[5] = -z * 48.5
self.refresh()
def draw(self, cr):
cr.save()
self.face.draw(cr)
cr.set_source_rgb(0.937, 0.161, 0.161)
cr.rectangle(130, 125, 40, -self.progress[2])
cr.fill()
cr.set_source_rgb(0.451, 0.824, 0.086)
cr.rectangle(130, 175, 40, self.progress[3])
cr.fill()
cr.set_source_rgb(0.929, 0.831, 0.000)
cr.rectangle(125, 130, -self.progress[1], 40)
cr.fill()
cr.rectangle(175, 130, self.progress[0], 40)
cr.fill()
cr.set_source_rgb(0.447, 0.624, 0.812)
cr.rectangle(232, 125, 40, -self.progress[5])
cr.fill()
cr.rectangle(232, 175, 40, self.progress[4])
cr.fill()
cr.restore()
class Level (Widget):
def __init__(self):
Widget.__init__(self)
self.level = 0
self.background = Image('level-background.png')
self.hand = Image('level-hand.png')
self.glass = Image('level-glass.png')
def set_angle(self, angle):
self.level = angle * 8
self.refresh()
def draw(self, cr):
cr.save()
cr.translate(22, 118)
cr.arc(32, 32, 32, math.pi*0.5, math.pi*1.5)
cr.rel_line_to(192, 0)
cr.arc(224, 32, 32, math.pi*1.5, math.pi*0.5)
cr.close_path()
cr.clip()
self.background.draw(cr)
cr.save()
cr.translate(86-self.level, 2)
self.hand.draw(cr)
cr.restore()
self.glass.draw(cr)
cr.restore()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment