1010
1111 import pyboard
1212 pyb = pyboard.Pyboard('/dev/ttyACM0')
13+
14+ Or:
15+
16+ pyb = pyboard.Pyboard('192.168.1.1')
17+
18+ Then:
19+
1320 pyb.enter_raw_repl()
1421 pyb.exec('pyb.LED(1).on()')
1522 pyb.exit_raw_repl()
3138
3239import sys
3340import time
34- import serial
3541
3642def stdout_write_bytes (b ):
3743 sys .stdout .buffer .write (b )
@@ -40,9 +46,76 @@ def stdout_write_bytes(b):
4046class PyboardError (BaseException ):
4147 pass
4248
49+ class TelnetToSerial :
50+ def __init__ (self , ip , user , password , read_timeout = None ):
51+ import telnetlib
52+ self .tn = telnetlib .Telnet (ip , timeout = 15 )
53+ self .read_timeout = read_timeout
54+ if b'Login as:' in self .tn .read_until (b'Login as:' , timeout = read_timeout ):
55+ self .tn .write (bytes (user , 'ascii' ) + b"\r \n " )
56+
57+ if b'Password:' in self .tn .read_until (b'Password:' , timeout = read_timeout ):
58+ # needed because of internal implementation details of the telnet server
59+ time .sleep (0.2 )
60+ self .tn .write (bytes (password , 'ascii' ) + b"\r \n " )
61+
62+ if b'for more information.' in self .tn .read_until (b'Type "help()" for more information.' , timeout = read_timeout ):
63+ # login succesful
64+ from collections import deque
65+ self .fifo = deque ()
66+ return
67+
68+ raise PyboardError ('Failed to establish a telnet connection with the board' )
69+
70+ def __del__ (self ):
71+ self .close ()
72+
73+ def close (self ):
74+ try :
75+ self .tn .close ()
76+ except :
77+ # the telnet object might not exist yet, so ignore this one
78+ pass
79+
80+ def read (self , size = 1 ):
81+ while len (self .fifo ) < size :
82+ timeout_count = 0
83+ data = self .tn .read_eager ()
84+ if len (data ):
85+ self .fifo .extend (data )
86+ timeout_count = 0
87+ else :
88+ time .sleep (0.25 )
89+ if self .read_timeout is not None and timeout_count > 4 * self .read_timeout :
90+ break
91+ timeout_count += 1
92+
93+ data = b''
94+ while len (data ) < size and len (self .fifo ) > 0 :
95+ data += bytes ([self .fifo .popleft ()])
96+ return data
97+
98+ def write (self , data ):
99+ self .tn .write (data )
100+ return len (data )
101+
102+ def inWaiting (self ):
103+ n_waiting = len (self .fifo )
104+ if not n_waiting :
105+ data = self .tn .read_eager ()
106+ self .fifo .extend (data )
107+ return len (data )
108+ else :
109+ return n_waiting
110+
43111class Pyboard :
44- def __init__ (self , serial_device , baudrate = 115200 ):
45- self .serial = serial .Serial (serial_device , baudrate = baudrate , interCharTimeout = 1 )
112+ def __init__ (self , device , baudrate = 115200 , user = 'micro' , password = 'python' ):
113+ if device and device [0 ].isdigit () and device [- 1 ].isdigit () and device .count ('.' ) == 3 :
114+ # device looks like an IP address
115+ self .serial = TelnetToSerial (device , user , password , read_timeout = 10 )
116+ else :
117+ import serial
118+ self .serial = serial .Serial (device , baudrate = baudrate , interCharTimeout = 1 )
46119
47120 def close (self ):
48121 self .serial .close ()
@@ -155,85 +228,28 @@ def get_time(self):
155228 t = str (self .eval ('pyb.RTC().datetime()' ), encoding = 'utf8' )[1 :- 1 ].split (', ' )
156229 return int (t [4 ]) * 3600 + int (t [5 ]) * 60 + int (t [6 ])
157230
158- def execfile (filename , device = '/dev/ttyACM0' ):
159- pyb = Pyboard (device )
231+ def execfile (filename , device = '/dev/ttyACM0' , baudrate = 115200 , user = 'micro' , password = 'python' ):
232+ pyb = Pyboard (device , baudrate , user , password )
160233 pyb .enter_raw_repl ()
161234 output = pyb .execfile (filename )
162235 stdout_write_bytes (output )
163236 pyb .exit_raw_repl ()
164237 pyb .close ()
165238
166- def run_test (device ):
167- pyb = Pyboard (device )
168- pyb .enter_raw_repl ()
169- print ('opened device {}' .format (device ))
170-
171- pyb .exec ('import pyb' ) # module pyb no longer imported by default, required for pyboard tests
172- print ('seconds since boot:' , pyb .get_time ())
173-
174- pyb .exec ('def apply(l, f):\r \n for item in l:\r \n f(item)\r \n ' )
175-
176- pyb .exec ('leds=[pyb.LED(l) for l in range(1, 5)]' )
177- pyb .exec ('apply(leds, lambda l:l.off())' )
178-
179- ## USR switch test
180-
181- pyb .exec ('switch = pyb.Switch()' )
182-
183- for i in range (2 ):
184- print ("press USR button" )
185- pyb .exec ('while switch(): pyb.delay(10)' )
186- pyb .exec ('while not switch(): pyb.delay(10)' )
187-
188- print ('USR switch passed' )
189-
190- ## accel test
191-
192- if True :
193- print ("hold level" )
194- pyb .exec ('accel = pyb.Accel()' )
195- pyb .exec ('while abs(accel.x()) > 10 or abs(accel.y()) > 10: pyb.delay(10)' )
196-
197- print ("tilt left" )
198- pyb .exec ('while accel.x() > -10: pyb.delay(10)' )
199- pyb .exec ('leds[0].on()' )
200-
201- print ("tilt forward" )
202- pyb .exec ('while accel.y() < 10: pyb.delay(10)' )
203- pyb .exec ('leds[1].on()' )
204-
205- print ("tilt right" )
206- pyb .exec ('while accel.x() < 10: pyb.delay(10)' )
207- pyb .exec ('leds[2].on()' )
208-
209- print ("tilt backward" )
210- pyb .exec ('while accel.y() > -10: pyb.delay(10)' )
211- pyb .exec ('leds[3].on()' )
212-
213- print ('accel passed' )
214-
215- print ('seconds since boot:' , pyb .get_time ())
216-
217- pyb .exec ('apply(leds, lambda l:l.off())' )
218-
219- pyb .exit_raw_repl ()
220- pyb .close ()
221-
222239def main ():
223240 import argparse
224241 cmd_parser = argparse .ArgumentParser (description = 'Run scripts on the pyboard.' )
225- cmd_parser .add_argument ('--device' , default = '/dev/ttyACM0' , help = 'the serial device of the pyboard' )
242+ cmd_parser .add_argument ('--device' , default = '/dev/ttyACM0' , help = 'the serial device or the IP address of the pyboard' )
243+ cmd_parser .add_argument ('-b' , '--baudrate' , default = 115200 , help = 'the baud rate of the serial device' )
244+ cmd_parser .add_argument ('-u' , '--user' , default = 'micro' , help = 'the telnet login username' )
245+ cmd_parser .add_argument ('-p' , '--password' , default = 'python' , help = 'the telnet login password' )
226246 cmd_parser .add_argument ('--follow' , action = 'store_true' , help = 'follow the output after running the scripts [default if no scripts given]' )
227- cmd_parser .add_argument ('--test' , action = 'store_true' , help = 'run a small test suite on the pyboard' )
228247 cmd_parser .add_argument ('files' , nargs = '*' , help = 'input files' )
229248 args = cmd_parser .parse_args ()
230249
231- if args .test :
232- run_test (device = args .device )
233-
234250 for filename in args .files :
235251 try :
236- pyb = Pyboard (args .device )
252+ pyb = Pyboard (args .device , args . baudrate , args . user , args . password )
237253 pyb .enter_raw_repl ()
238254 with open (filename , 'rb' ) as f :
239255 pyfile = f .read ()
@@ -251,7 +267,7 @@ def main():
251267
252268 if args .follow or len (args .files ) == 0 :
253269 try :
254- pyb = Pyboard (args .device )
270+ pyb = Pyboard (args .device , args . baudrate , args . user , args . password )
255271 ret , ret_err = pyb .follow (timeout = None , data_consumer = stdout_write_bytes )
256272 pyb .close ()
257273 except PyboardError as er :
0 commit comments