1+ import  neopixel 
2+ import  microbit 
3+ import  time 
4+ 
5+ I2C_GET_FIRMWARE_VERSION  =  1 
6+ # I2C_GET_MANUFACTURER = 2 
7+ I2C_GET_BOARD  =  3 
8+ I2C_GET_VOLTAGE_BATTERY  =  4 
9+ I2C_GET_LINE_SENSORS  =  5 
10+ I2C_GET_LIGHT_SENSORS  =  6 
11+ # I2C_GET_MOTOR_STATUS_RIGHT = 7 
12+ # I2C_GET_MOTOR_STATUS_LEFT = 8 
13+ # I2C_SET_MOTOR_POWER = 9 
14+ I2C_SET_MOTOR_POWERS  =  10 
15+ LEFT  =  0 
16+ RIGHT  =  1 
17+ BOTH  =  2 
18+ FORWARD  =  1 
19+ BACKWARD  =  - 1 
20+ DEFAULT_EYE_COLOR  =  (0 , 0 , 10 )
21+ LOW_VOLTAGE_EYE_COLOR  =  (10 , 0 , 0 )
22+ motor_power_left  =  50 
23+ motor_power_right  =  50 
24+ 
25+ def  _write8 (* args , repeat = False ):
26+     buf  =  bytearray (len (args ))
27+     buf [0 ] =  args [0 ]
28+     for  i  in  range (1 , len (args )):
29+         buf [i ] =  (args [i ] &  0xFF )
30+     microbit .i2c .write (0x04 , bytes (buf ), repeat ) 
31+ 
32+ def  _read8 (reg , repeat = False ):
33+     microbit .i2c .write (0x04 , bytes ([reg ]), repeat )
34+     outbuf  =  microbit .i2c .read (0x04 , 1 , repeat )
35+     return_value  =  outbuf [0 ]
36+     return  return_value 
37+ 
38+ def  _read16 (reg , repeat = False ):
39+     microbit .i2c .write (0x04 , bytes ([reg ]), repeat )
40+     outbuf  =  microbit .i2c .read (0x04 , 2 , repeat )
41+     return  outbuf [0 ] *  255  +  outbuf [1 ]
42+ 
43+ def  _get_sensors (reg , repeat = False ):
44+     microbit .i2c .write (0x04 , bytes ([reg ]), repeat )
45+     outbuf  =  []
46+     buf  =  microbit .i2c .read (0x04 , 3 , repeat )
47+     outbuf .append (1023  -  ( buf [0 ] <<  2  |  ((buf [2 ] &  0xC0 ) >>  6 )))
48+     outbuf .append (1023  -  ( buf [1 ] <<  2  |  ((buf [2 ] &  0x30 ) >>  4 )))
49+     return  outbuf 
50+ 
51+ def  volt ():
52+     return  (_read16 (I2C_GET_VOLTAGE_BATTERY )/ 1000 )
53+ 
54+ def  drive (dir = FORWARD , seconds = - 1 ):
55+     _write8 (I2C_SET_MOTOR_POWERS , motor_power_left * dir , motor_power_right * dir )
56+     if  seconds  >=  0 :
57+         time .sleep (seconds )
58+         stop ()
59+ 
60+ def  turn (dir = LEFT , seconds = - 1 ):
61+     if  dir == LEFT :
62+         _write8 (I2C_SET_MOTOR_POWERS , motor_power_left , 0 )
63+     if  dir == RIGHT :
64+         _write8 (I2C_SET_MOTOR_POWERS , 0 , motor_power_right )
65+     if  seconds  >=  0 :
66+         time .sleep (seconds )
67+         stop ()        
68+ 
69+ def  set_speed (power_left , power_right ):
70+     global  motor_power_left , motor_power_right 
71+     motor_power_left  =  power_left 
72+     motor_power_right  =  power_right 
73+ 
74+ def  stop ():
75+         _write8 (I2C_SET_MOTOR_POWERS , 0 , 0 )
76+ 
77+ def  set_servo (which , degrees ):
78+     ''' 
79+     Will set the left/right servo to a value between 0 and 180 
80+     ''' 
81+     us  =  min (2400 , max (600 , 600  +  (1800  *  degrees  //  180 )))
82+     duty  =  round (us  *  1024  *  50  //  1000000 )
83+     if  which  ==  LEFT  or  which  ==  BOTH :
84+         microbit .pin14 .set_analog_period (20 )
85+         microbit .pin14 .write_analog (duty )
86+     if  which  ==  RIGHT  or  which  ==  BOTH :
87+         microbit .pin13 .set_analog_period (20 )
88+         microbit .pin13 .write_analog (duty )
89+         
90+ def  servo_off (which ):
91+     if  which  ==  LEFT  or  which  ==  BOTH :
92+         microbit .pin14 .write_digital (0 )
93+     if  which  ==  RIGHT  or  which  ==  BOTH :
94+         microbit .pin13 .write_digital (0 )
95+     
96+ def  set_smile (R = 25 ,G = 0 ,B = 0 ):
97+     ''' 
98+     Like all neopixel methods, this may return a ValueError if the colors are invalid 
99+     ''' 
100+     for  i  in  range (2 ,9 ):
101+         neopixelstrip [i ] =  (R ,G ,B )
102+     neopixelstrip .show ()
103+ 
104+ def  set_eyes (which = BOTH , R = 0 , G = 0 , B = 10 ):
105+     ''' 
106+     Like all neopixel methods, this may return a ValueError if the colors are invalid 
107+     ''' 
108+     if  which  !=  LEFT :
109+         neopixelstrip [0 ] =  (R ,G ,B )
110+     if  which  !=  RIGHT :
111+         neopixelstrip [1 ]=  (R ,G ,B )
112+     neopixelstrip .show ()
113+ 
114+ def  set_eye_color_on_start ():
115+     if  _read16 (I2C_GET_VOLTAGE_BATTERY ) <  4000 :
116+         neopixelstrip [0 ] =  LOW_VOLTAGE_EYE_COLOR 
117+         neopixelstrip [1 ]=  LOW_VOLTAGE_EYE_COLOR 
118+     else :
119+         neopixelstrip [0 ] =  DEFAULT_EYE_COLOR 
120+         neopixelstrip [1 ]=  DEFAULT_EYE_COLOR 
121+     neopixelstrip .show ()
122+ 
123+ def  read_sensors (which_sensor , which_side ):
124+     if  (which_side  ==  LEFT ):
125+         return  _get_sensors (which_sensor )[0 ]
126+     elif  (which_side  ==  RIGHT ):
127+         return  _get_sensors (which_sensor )[1 ]
128+     else :
129+         return  _get_sensors (which_sensor )
130+ 
131+ def  pixels_off ():
132+     for  i  in  range (9 ):
133+         neopixelstrip [i ] =  (0 ,0 ,0 )
134+     neopixelstrip .show ()
135+   
136+ stop ()
137+ neopixelstrip  =  neopixel .NeoPixel (microbit .pin8 , 9 )
138+ pixels_off ()
139+ eyestrip  =  neopixel .NeoPixel (microbit .pin8 , 2 )
140+ set_eye_color_on_start ()
0 commit comments