Created
June 18, 2013 15:26
-
-
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…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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