/elec/quadcopter

To get this branch, use:
bzr branch http://bzr.ed.am/elec/quadcopter

« back to all changes in this revision

Viewing changes to test/rc-interface/rc-interface-test

  • Committer: Tim Marston
  • Date: 2014-01-22 23:55:10 UTC
  • Revision ID: tim@ed.am-20140122235510-dcru5aea679wyk7c
added python GTK test program that reads and displays the serial data from the
RC interface software

Show diffs side-by-side

added added

removed removed

 
1
#!/usr/bin/python
 
2
#
 
3
# rc-interface-test
 
4
 
 
5
 
 
6
import pygtk
 
7
pygtk.require( '2.0' );
 
8
import gtk, serial, struct
 
9
from io import BytesIO
 
10
 
 
11
 
 
12
class MainDialogue:
 
13
 
 
14
 
 
15
        # number of channels to read
 
16
        NUM_CHANNELS = 8
 
17
 
 
18
        # maximum channel value
 
19
        MAX_CHANNEL_VALUE = 1000
 
20
 
 
21
        # serial device to use
 
22
        SERIAL_DEVICE = '/dev/ttyACM0'
 
23
 
 
24
 
 
25
        def __init__( self ):
 
26
                self.link = serial.Serial( self.SERIAL_DEVICE, 9600 )
 
27
                self.got_one = False
 
28
                self.channel_values = []
 
29
                self.quit = False
 
30
                self.buffer = bytearray()
 
31
 
 
32
 
 
33
        def setup_window( self ):
 
34
 
 
35
                # create and set up window
 
36
                self.window = gtk.Window( gtk.WINDOW_TOPLEVEL )
 
37
                self.window.connect( "delete_event", self.destroy )
 
38
                self.window.connect( "destroy", self.destroy )
 
39
                self.window.set_title( "Testing rc-interface serial comms" );
 
40
                self.window.set_border_width( 30 )
 
41
                self.window.set_modal( True )
 
42
                self.window.connect( "key-press-event", self.key_press_event )
 
43
 
 
44
                # add widgets
 
45
                table = gtk.Table( self.NUM_CHANNELS, 2 )
 
46
                table.set_row_spacings( 20 )
 
47
                table.set_col_spacings( 10 )
 
48
                self.window.add( table )
 
49
 
 
50
                # add channels
 
51
                self.controls = []
 
52
                for a in range( 0, self.NUM_CHANNELS ):
 
53
 
 
54
                        label = gtk.Label( "Channel %d" % ( a + 1 ) )
 
55
                        table.attach( label, 0, 1, a, a + 1 )
 
56
 
 
57
                        adj = gtk.Adjustment( 0, 0, self.MAX_CHANNEL_VALUE, 1, 0, 0 )
 
58
                        control = gtk.HScale( adj )
 
59
                        control.set_draw_value( False )
 
60
                        control.set_property( 'width-request', 300 )
 
61
                        control.set_sensitive( False )
 
62
                        table.attach( control, 1, 2, a, a + 1 )
 
63
 
 
64
                        self.controls.append( control )
 
65
 
 
66
                # show it
 
67
                self.window.show_all()
 
68
 
 
69
 
 
70
        def key_press_event( self, widget, event ):
 
71
                if event.keyval == gtk.keysyms.Escape:
 
72
                        self.window.destroy()
 
73
                else:
 
74
                        return False
 
75
 
 
76
 
 
77
        def destroy( self, widget, data = None ):
 
78
                self.quit = True
 
79
 
 
80
 
 
81
        def process_serial_data_at( self, pos ):
 
82
                for a in range( 0, self.NUM_CHANNELS ):
 
83
                        at = 2 * a + pos
 
84
                        value = struct.unpack( "h", self.buffer[ at : at + 2 ] )[ 0 ]
 
85
 
 
86
                        # update control
 
87
                        self.controls[ a ].set_value( value )
 
88
 
 
89
 
 
90
        def read_serial( self ):
 
91
 
 
92
                # try and read
 
93
                in_waiting = self.link.inWaiting()
 
94
                if( in_waiting ):
 
95
                        self.buffer.extend( self.link.read( in_waiting ) )
 
96
 
 
97
                        # check buffer for double -1
 
98
                        got = bytearray()
 
99
                        i = 0
 
100
                        while i < len( self.buffer ):
 
101
 
 
102
                                # check foir double -1
 
103
                                if i > 0 and self.buffer[ i ] == 255 and \
 
104
                                                self.buffer[ i - 1 ] == 255:
 
105
 
 
106
                                        # if we've got enough data, process it
 
107
                                        start_index = i - ( self.NUM_CHANNELS * 2 + 1 )
 
108
                                        if start_index >= 0:
 
109
                                                self.process_serial_data_at( start_index )
 
110
 
 
111
                                        # remove everything up to and including this double -1 from
 
112
                                        # the serial buffer
 
113
                                        self.buffer = self.buffer[ i + 1 : ]
 
114
                                        i = 0
 
115
 
 
116
                                else:
 
117
                                        i += 1
 
118
 
 
119
 
 
120
        def main( self ):
 
121
                self.setup_window()
 
122
                while not self.quit:
 
123
 
 
124
                        # update gtk
 
125
                        while gtk.events_pending():
 
126
                                gtk.main_iteration( False )
 
127
 
 
128
                        # check serial interface
 
129
                        self.read_serial()
 
130
 
 
131
 
 
132
MainDialogue().main()