@@ -11,22 +11,38 @@ class ComponentPins(Enum):
11
11
ANALOG_WRITE = 4
12
12
RGB_LED_STRIP = 5
13
13
SERVO = 6
14
+ LED_MATRIX = 7
15
+ DIGITAL_DISPLAY_TM = 8
16
+ MOTOR = 9
17
+ PASSIVE_BUZZER = 10
18
+ STEPPER_MOTOR = 11
19
+ BUTTON = 12
20
+ IR_REMOTE = 13
21
+ DIGITAL_READ = 14
22
+ JOYSTICK = 16
23
+ ULTRASONIC_SENSOR = 17
24
+ RFID = 18
14
25
15
26
class ElectroBlocks :
16
27
17
28
last_sense_data = ""
18
29
verbose = False
19
30
pins = {}
20
31
32
+
33
+
21
34
def __init__ (self , baudrate = 115200 , timeout = 2 , verbose = False ):
22
35
self .ser = self ._auto_connect (baudrate , timeout )
23
36
self .verbose = verbose
24
37
self ._wait_for_ready ()
25
-
38
+ self ._cache = None
39
+ self ._cache_time = 0
40
+ self ._cache_ttl = 0.08 # 80 milliseconds
41
+
26
42
def _auto_connect (self , baudrate , timeout ):
27
43
ports = list (serial .tools .list_ports .comports ())
28
44
for p in ports :
29
- if ( p .vid == 9025 and p .pid in (67 , 16 )) or ( p . vid == 6790 ): # Arduino Uno or Mega and Indian Arduino UNO
45
+ if p .vid in ( 9025 , 6790 , 4292 ) or p .pid in (67 , 16 , 60000 ): # Arduino Uno or Mega and Indian Arduino UNO
30
46
try :
31
47
ser = serial .Serial (p .device , baudrate , timeout = timeout )
32
48
time .sleep (2 ) # Give Arduino time to reset
@@ -63,12 +79,26 @@ def _wait_for_message(self, message):
63
79
return ""
64
80
65
81
def _get_sensor_str (self ):
82
+ now = time .monotonic ()
83
+
84
+ # If cached value is still fresh, return it
85
+ if self ._cache and (now - self ._cache_time ) < self ._cache_ttl :
86
+ if self .verbose :
87
+ print ("Using cached sensor message" )
88
+ return self ._cache
89
+
90
+ # Otherwise fetch new data
66
91
self .ser .write (b"sense|" )
67
92
message = self ._wait_for_message ("SENSE_COMPLETE" )
68
93
if self .verbose :
69
- print (f"FULL SENSOR MESSSAGE : { message } " )
94
+ print (f"FULL SENSOR MESSAGE : { message } " )
70
95
message = message .replace ("SENSE_COMPLETE" , "" )
71
96
sensorsStr = message .split (";" )
97
+
98
+ # Update cache
99
+ self ._cache = sensorsStr
100
+ self ._cache_time = now
101
+
72
102
return sensorsStr
73
103
74
104
# return the result of pin read that is being sensed
@@ -93,45 +123,84 @@ def _send(self, cmd):
93
123
94
124
# Digital Write Method
95
125
def config_digital_read (self , pin ):
96
- self ._send (f"config:b={ pin } " )
126
+ self ._add_pin (ComponentPins .DIGITAL_READ , pin )
127
+ self ._send (f"register::dr::{ pin } " )
97
128
98
129
def digital_read (self , pin ):
99
130
return self ._find_sensor_str (pin , "dr" ) == "1"
100
131
101
132
# RFID
102
133
def config_rfid (self , rxPin , txPin ):
103
- self ._send (f"config:rfid={ rxPin } ,{ txPin } " )
134
+ self ._add_pin (ComponentPins .RFID , rxPin )
135
+ self ._add_pin (ComponentPins .RFID , txPin )
136
+ self ._send (f"register::rfi::{ rxPin } ::{ txPin } ::9600" )
104
137
105
138
def rfid_tag_number (self ):
106
- return self ._find_sensor_str ("0" , "rfid" )
139
+ pin = self .pins [ComponentPins .RFID ][0 ]
140
+ tag = self ._find_sensor_str (pin , "rfi" )
141
+ if tag == "0" :
142
+ return ""
143
+ else :
144
+ return tag
107
145
108
146
def rfid_sensed_card (self ):
109
- return len (self ._find_sensor_str ("0" , "rfid" )) > 0
147
+ pin = self .pins [ComponentPins .RFID ][0 ]
148
+ return self ._find_sensor_str (pin , "rfi" ) != "0"
110
149
150
+ # Joysick
151
+ def config_joystick (self , x , y , sw ):
152
+ self ._send (f"register::js::{ x } ::{ y } ::{ sw } " )
153
+ self ._add_pin (ComponentPins .JOYSTICK , x )
154
+ self ._add_pin (ComponentPins .JOYSTICK , y )
155
+ self ._add_pin (ComponentPins .JOYSTICK , sw )
156
+
157
+ def joystick_angle (self ):
158
+ pin = self .pins [ComponentPins .JOYSTICK ][0 ]
159
+ [pressed , angle , engaged ] = self ._find_sensor_str (pin , "js" )
160
+ return angle
161
+
162
+ def is_joystick_button_pressed (self ):
163
+ pin = self .pins [ComponentPins .JOYSTICK ][0 ]
164
+ [pressed , angle , engaged ] = self ._find_sensor_str (pin , "js" )
165
+ return pressed
166
+
167
+ def is_joystick_engaged (self ):
168
+ pin = self .pins [ComponentPins .JOYSTICK ][0 ]
169
+ [pressed , angle , engaged ] = self ._find_sensor_str (pin , "js" )
170
+ return pressed
171
+
172
+
111
173
#IR Remote
112
174
113
175
def config_ir_remote (self , pin ):
114
- self ._send (f"config:ir={ pin } " )
176
+ self ._send (f"register::ir::{ pin } " )
177
+ self ._add_pin (ComponentPins .IR_REMOTE , pin )
115
178
116
179
def ir_remote_has_sensed_code (self ):
117
- return len (self ._find_sensor_str ("0" , "ir" )) > 0
180
+ pin = self .pins [ComponentPins .IR_REMOTE ][0 ]
181
+ return len (self ._find_sensor_str (pin , "ir" )) > 0
118
182
119
183
def ir_remote_get_code (self ):
120
- return self ._find_sensor_str ("0" , "ir" )
184
+ pin = self .pins [ComponentPins .IR_REMOTE ][0 ]
185
+ return self ._find_sensor_str (pin , "ir" )
121
186
122
187
# Motion Sensors
123
188
def config_motion_sensor (self , echoPin , trigPin ):
124
- self ._send (f"config:m={ echoPin } ,{ trigPin } " )
189
+ self ._add_pin (ComponentPins .ULTRASONIC_SENSOR , trigPin )
190
+ self ._add_pin (ComponentPins .ULTRASONIC_SENSOR , echoPin )
191
+ self ._send (f"register::ul::{ trigPin } ::{ echoPin } " )
125
192
126
193
def motion_distance_cm (self ):
127
- return self ._find_sensor_str ("0" , "m" )
194
+ pin = self .pins [ComponentPins .ULTRASONIC_SENSOR ][0 ]
195
+ return self ._find_sensor_str (pin , "ul" )
128
196
129
197
# Button Methods
130
198
def config_button (self , pin ):
131
- self ._send (f"config:b={ pin } " )
199
+ self ._send (f"register:bt::{ pin } " )
200
+ self ._add_pin (ComponentPins .BUTTON , pin )
132
201
133
202
def is_button_pressed (self , pin ):
134
- return self ._find_sensor_str (pin , "b " ) == "0"
203
+ return self ._find_sensor_str (pin , "bt " ) == "0"
135
204
136
205
# Servo Methods
137
206
def config_servo (self , pin ):
@@ -197,6 +266,69 @@ def analog_config(self, pin):
197
266
self ._send (f"register::aw::{ pin } " )
198
267
self ._add_pin (ComponentPins .ANALOG_WRITE , pin )
199
268
269
+ # LED MATRIX
270
+
271
+ def config_led_matrix (self , data_pin , cs_pin , clk_pin ):
272
+ self ._add_pin (ComponentPins .LED_MATRIX , data_pin )
273
+ self ._add_pin (ComponentPins .LED_MATRIX , cs_pin )
274
+ self ._add_pin (ComponentPins .LED_MATRIX , clk_pin )
275
+ self ._send (f"register::ma::{ data_pin } ::{ cs_pin } ::{ clk_pin } " )
276
+
277
+ def set_led_matrix_led (self , row , col , isOn ):
278
+ pin = self .pins [ComponentPins .LED_MATRIX ][0 ]
279
+ isLedOnNumber = "1" if isOn else "0"
280
+ self ._send (f"write::ma::{ pin } ::1::{ col - 1 } ::{ 8 - row } ::{ isLedOnNumber } " )
281
+
282
+ # TM Digital Display
283
+
284
+ def config_digital_display (self , dio , clk ):
285
+ self ._add_pin (ComponentPins .DIGITAL_DISPLAY_TM , dio )
286
+ self ._add_pin (ComponentPins .DIGITAL_DISPLAY_TM , clk )
287
+ self ._send (f"register::tm::{ dio } ::{ clk } " )
288
+
289
+ def set_digital_display (self , colonOn , message ):
290
+ pin = self .pins [ComponentPins .DIGITAL_DISPLAY_TM ][0 ]
291
+ colon = "1" if colonOn else "0"
292
+ self ._send (f"write::tm::{ pin } ::{ colon } ::{ message } " )
293
+
294
+ # Stepper Motors
295
+
296
+ def config_stepper_motor (self , pin1 , pin2 , pin3 , pin4 , steps , speed ):
297
+ self ._add_pin (ComponentPins .STEPPER_MOTOR , pin1 )
298
+ self ._add_pin (ComponentPins .STEPPER_MOTOR , pin2 )
299
+ self ._add_pin (ComponentPins .STEPPER_MOTOR , pin3 )
300
+ self ._add_pin (ComponentPins .STEPPER_MOTOR , pin4 )
301
+ self ._send (f"register::ste::{ pin1 } ::{ pin2 } ::{ pin3 } ::{ pin4 } ::{ steps } ::{ speed } " )
302
+
303
+ def move_stepper_motor (self , steps ):
304
+ pin = self .pins [ComponentPins .STEPPER_MOTOR ][0 ]
305
+ self ._send (f"write::ste::{ pin } ::{ steps } " )
306
+
307
+
308
+ # Motors
309
+
310
+ def config_motor (self , en1 , in1 , in2 , en2 = None , in3 = None , in4 = None ):
311
+ self ._add_pin (ComponentPins .MOTOR , en1 )
312
+ self ._add_pin (ComponentPins .MOTOR , in1 )
313
+ self ._add_pin (ComponentPins .MOTOR , in2 )
314
+ if en2 == None or in3 == None or in4 == None :
315
+ self ._send (f"register::mo::{ en1 } ::{ in1 } ::{ in2 } " )
316
+ else :
317
+ self ._add_pin (ComponentPins .MOTOR , en2 )
318
+ self ._add_pin (ComponentPins .MOTOR , in3 )
319
+ self ._add_pin (ComponentPins .MOTOR , in4 )
320
+ self ._send (f"register::mo::{ en1 } ::{ in1 } ::{ in2 } ::{ en2 } ::{ in3 } ::{ in4 } " )
321
+
322
+ def move_motor (self , which_motor , direction , speed ):
323
+ pin = self .pins [ComponentPins .MOTOR ][0 ]
324
+ direction_num = "1" if direction == "clockwise" else "2"
325
+ self ._send (f"write::mo::{ pin } ::{ which_motor } ::{ speed } ::{ direction_num } " )
326
+
327
+
328
+ def stop_motor (self , which_motor ):
329
+ pin = self .pins [ComponentPins .MOTOR ][0 ]
330
+ self ._send (f"write::mo::{ pin } ::{ which_motor } ::0::3" )
331
+
200
332
# NEO PIXELS
201
333
202
334
def config_rgb_strip (self , pin , count , colorOrderString , brightness ):
@@ -223,6 +355,18 @@ def rgb_strip_show_all(self):
223
355
pin = self .pins [ComponentPins .RGB_LED_STRIP ][0 ]
224
356
self ._send (f"write::leds::{ pin } ::1" )
225
357
358
+ # Passive Buzzer
359
+
360
+ def config_passive_buzzer (self , pin ):
361
+ self ._add_pin (ComponentPins .PASSIVE_BUZZER , pin )
362
+ self ._send (f"register::bu::{ pin } " )
363
+
364
+ def play_passive_buzzer (self , pin , note ):
365
+ self ._send (f"write::bu::{ pin } ::{ note } " )
366
+
367
+ def turn_off_buzzer (self , pin ):
368
+ self ._send (f"write::bu::{ pin } ::0" )
369
+
226
370
# Helpers
227
371
228
372
def rgb_to_hex (self , red , green , blue ):
0 commit comments