Skip to content

Commit 8677f76

Browse files
authored
Merge pull request #13 from arduino/to_ver_030
To ver 030
2 parents b15c502 + 9843ada commit 8677f76

15 files changed

+356
-48
lines changed

arduino_alvik/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .arduino_alvik import *

arduino_alvik.py renamed to arduino_alvik/arduino_alvik.py

+265-8
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
import sys
22
import gc
33
import struct
4-
54
from machine import I2C
6-
from uart import uart
75
import _thread
86
from time import sleep_ms
97

108
from ucPack import ucPack
119

12-
from conversions import *
13-
from pinout_definitions import *
14-
from robot_definitions import *
15-
from constants import *
10+
from .uart import uart
11+
from .conversions import *
12+
from .pinout_definitions import *
13+
from .robot_definitions import *
14+
from .constants import *
1615

1716

1817
class ArduinoAlvik:
1918

2019
_update_thread_running = False
2120
_update_thread_id = None
21+
_touch_events_thread_running = False
22+
_touch_events_thread_id = None
2223

2324
def __new__(cls):
2425
if not hasattr(cls, '_instance'):
@@ -68,6 +69,7 @@ def __init__(self):
6869
self._angular_velocity = None
6970
self._last_ack = ''
7071
self._version = [None, None, None]
72+
self._touch_events = _ArduinoAlvikTouchEvents()
7173

7274
@staticmethod
7375
def is_on() -> bool:
@@ -135,7 +137,7 @@ def _idle(self, delay_=1, check_on_thread=False) -> None:
135137
sys.exit()
136138
except Exception as e:
137139
pass
138-
#print(f'Unable to read SOC: {e}')
140+
# print(f'Unable to read SOC: {e}')
139141
finally:
140142
LEDR.value(1)
141143
LEDG.value(1)
@@ -179,6 +181,9 @@ def begin(self) -> int:
179181
self._idle(1000)
180182
self._begin_update_thread()
181183
sleep_ms(100)
184+
if self._touch_events.has_callbacks():
185+
print('Starting touch events')
186+
self._start_touch_events_thread()
182187
self._reset_hw()
183188
self._flush_uart()
184189
self._snake_robot(1000)
@@ -293,9 +298,12 @@ def stop(self):
293298
# turn off UI leds
294299
self._set_leds(0x00)
295300

296-
# stop the update thrad
301+
# stop the update thread
297302
self._stop_update_thread()
298303

304+
# stop touch events thread
305+
self._stop_touch_events_thread()
306+
299307
# delete _instance
300308
del self.__class__._instance
301309
gc.collect()
@@ -953,6 +961,99 @@ def print_status(self):
953961
continue
954962
print(f'{str(a).upper()} = {getattr(self, str(a))}')
955963

964+
def on_touch_ok_pressed(self, callback: callable, args: tuple = ()) -> None:
965+
"""
966+
Register callback when touch button OK is pressed
967+
:param callback:
968+
:param args:
969+
:return:
970+
"""
971+
self._touch_events.register_callback('on_ok_pressed', callback, args)
972+
973+
def on_touch_cancel_pressed(self, callback: callable, args: tuple = ()) -> None:
974+
"""
975+
Register callback when touch button CANCEL is pressed
976+
:param callback:
977+
:param args:
978+
:return:
979+
"""
980+
self._touch_events.register_callback('on_cancel_pressed', callback, args)
981+
982+
def on_touch_center_pressed(self, callback: callable, args: tuple = ()) -> None:
983+
"""
984+
Register callback when touch button CENTER is pressed
985+
:param callback:
986+
:param args:
987+
:return:
988+
"""
989+
self._touch_events.register_callback('on_center_pressed', callback, args)
990+
991+
def on_touch_up_pressed(self, callback: callable, args: tuple = ()) -> None:
992+
"""
993+
Register callback when touch button UP is pressed
994+
:param callback:
995+
:param args:
996+
:return:
997+
"""
998+
self._touch_events.register_callback('on_up_pressed', callback, args)
999+
1000+
def on_touch_left_pressed(self, callback: callable, args: tuple = ()) -> None:
1001+
"""
1002+
Register callback when touch button LEFT is pressed
1003+
:param callback:
1004+
:param args:
1005+
:return:
1006+
"""
1007+
self._touch_events.register_callback('on_left_pressed', callback, args)
1008+
1009+
def on_touch_down_pressed(self, callback: callable, args: tuple = ()) -> None:
1010+
"""
1011+
Register callback when touch button DOWN is pressed
1012+
:param callback:
1013+
:param args:
1014+
:return:
1015+
"""
1016+
self._touch_events.register_callback('on_down_pressed', callback, args)
1017+
1018+
def on_touch_right_pressed(self, callback: callable, args: tuple = ()) -> None:
1019+
"""
1020+
Register callback when touch button RIGHT is pressed
1021+
:param callback:
1022+
:param args:
1023+
:return:
1024+
"""
1025+
self._touch_events.register_callback('on_right_pressed', callback, args)
1026+
1027+
def _start_touch_events_thread(self) -> None:
1028+
"""
1029+
Starts the touch events thread
1030+
:return:
1031+
"""
1032+
if not self.__class__._touch_events_thread_running:
1033+
self.__class__._touch_events_thread_running = True
1034+
self.__class__._touch_events_thread_id = _thread.start_new_thread(self._update_touch_events, (50,))
1035+
1036+
def _update_touch_events(self, delay_: int = 100):
1037+
"""
1038+
Updates the touch state so that touch events can be generated
1039+
:param delay_:
1040+
:return:
1041+
"""
1042+
while True:
1043+
if self.is_on() and self._touch_byte is not None:
1044+
self._touch_events.update_touch_state(self._touch_byte)
1045+
if not ArduinoAlvik._touch_events_thread_running:
1046+
break
1047+
sleep_ms(delay_)
1048+
1049+
@classmethod
1050+
def _stop_touch_events_thread(cls):
1051+
"""
1052+
Stops the touch events thread
1053+
:return:
1054+
"""
1055+
cls._touch_events_thread_running = False
1056+
9561057

9571058
class _ArduinoAlvikWheel:
9581059

@@ -1065,3 +1166,159 @@ def set_color(self, red: bool, green: bool, blue: bool):
10651166
self._led_state[0] = led_status
10661167
self._packeter.packetC1B(ord('L'), led_status & 0xFF)
10671168
uart.write(self._packeter.msg[0:self._packeter.msg_size])
1169+
1170+
1171+
class _ArduinoAlvikEvents:
1172+
"""
1173+
This is a generic events class
1174+
"""
1175+
1176+
def __init__(self):
1177+
self._callbacks = dict()
1178+
1179+
def register_callback(self, event_name: str, callback: callable, args: tuple = None):
1180+
"""
1181+
Registers a callback to execute on an event
1182+
:param event_name:
1183+
:param callback: the callable
1184+
:param args: arguments tuple to pass to the callable. remember the comma! (value,)
1185+
:return:
1186+
"""
1187+
self._callbacks[event_name] = (callback, args,)
1188+
1189+
def has_callbacks(self) -> bool:
1190+
"""
1191+
True if the _callbacks dictionary has any callback registered
1192+
:return:
1193+
"""
1194+
return bool(self._callbacks)
1195+
1196+
def execute_callback(self, event_name: str):
1197+
"""
1198+
Executes the callback associated to the event_name
1199+
:param event_name:
1200+
:return:
1201+
"""
1202+
if event_name not in self._callbacks.keys():
1203+
return
1204+
self._callbacks[event_name][0](*self._callbacks[event_name][1])
1205+
1206+
1207+
class _ArduinoAlvikTouchEvents(_ArduinoAlvikEvents):
1208+
"""
1209+
This is the event class to handle touch button events
1210+
"""
1211+
1212+
available_events = ['on_ok_pressed', 'on_cancel_pressed',
1213+
'on_center_pressed', 'on_left_pressed',
1214+
'on_right_pressed', 'on_up_pressed',
1215+
'on_down_pressed']
1216+
1217+
def __init__(self):
1218+
self._current_touch_state = 0
1219+
super().__init__()
1220+
1221+
@staticmethod
1222+
def _is_ok_pressed(current_state, new_state) -> bool:
1223+
"""
1224+
True if OK was pressed
1225+
:param current_state:
1226+
:param new_state:
1227+
:return:
1228+
"""
1229+
return not bool(current_state & 0b00000010) and bool(new_state & 0b00000010)
1230+
1231+
@staticmethod
1232+
def _is_cancel_pressed(current_state, new_state) -> bool:
1233+
"""
1234+
True if CANCEL was pressed
1235+
:param current_state:
1236+
:param new_state:
1237+
:return:
1238+
"""
1239+
return not bool(current_state & 0b00000100) and bool(new_state & 0b00000100)
1240+
1241+
@staticmethod
1242+
def _is_center_pressed(current_state, new_state) -> bool:
1243+
"""
1244+
True if CENTER was pressed
1245+
:param current_state:
1246+
:param new_state:
1247+
:return:
1248+
"""
1249+
return not bool(current_state & 0b00001000) and bool(new_state & 0b00001000)
1250+
1251+
@staticmethod
1252+
def _is_up_pressed(current_state, new_state) -> bool:
1253+
"""
1254+
True if UP was pressed
1255+
:param current_state:
1256+
:param new_state:
1257+
:return:
1258+
"""
1259+
return not bool(current_state & 0b00010000) and bool(new_state & 0b00010000)
1260+
1261+
@staticmethod
1262+
def _is_left_pressed(current_state, new_state) -> bool:
1263+
"""
1264+
True if LEFT was pressed
1265+
:param current_state:
1266+
:param new_state:
1267+
:return:
1268+
"""
1269+
return not bool(current_state & 0b00100000) and bool(new_state & 0b00100000)
1270+
1271+
@staticmethod
1272+
def _is_down_pressed(current_state, new_state) -> bool:
1273+
"""
1274+
True if DOWN was pressed
1275+
:param current_state:
1276+
:param new_state:
1277+
:return:
1278+
"""
1279+
return not bool(current_state & 0b01000000) and bool(new_state & 0b01000000)
1280+
1281+
@staticmethod
1282+
def _is_right_pressed(current_state, new_state) -> bool:
1283+
"""
1284+
True if RIGHT was pressed
1285+
:param current_state:
1286+
:param new_state:
1287+
:return:
1288+
"""
1289+
return not bool(current_state & 0b10000000) and bool(new_state & 0b10000000)
1290+
1291+
def update_touch_state(self, touch_state: int):
1292+
"""
1293+
Updates the internal touch state and executes any possible callback
1294+
:param touch_state:
1295+
:return:
1296+
"""
1297+
1298+
if self._is_ok_pressed(self._current_touch_state, touch_state):
1299+
self.execute_callback('on_ok_pressed')
1300+
1301+
if self._is_cancel_pressed(self._current_touch_state, touch_state):
1302+
self.execute_callback('on_cancel_pressed')
1303+
1304+
if self._is_center_pressed(self._current_touch_state, touch_state):
1305+
self.execute_callback('on_center_pressed')
1306+
1307+
if self._is_up_pressed(self._current_touch_state, touch_state):
1308+
self.execute_callback('on_up_pressed')
1309+
1310+
if self._is_left_pressed(self._current_touch_state, touch_state):
1311+
self.execute_callback('on_left_pressed')
1312+
1313+
if self._is_down_pressed(self._current_touch_state, touch_state):
1314+
self.execute_callback('on_down_pressed')
1315+
1316+
if self._is_right_pressed(self._current_touch_state, touch_state):
1317+
self.execute_callback('on_right_pressed')
1318+
1319+
self._current_touch_state = touch_state
1320+
1321+
def register_callback(self, event_name: str, callback: callable, args: tuple = None):
1322+
if event_name not in self.__class__.available_events:
1323+
return
1324+
super().register_callback(event_name, callback, args)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

examples/touch_events.py

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from arduino_alvik import ArduinoAlvik
2+
from time import sleep
3+
import sys
4+
5+
value = 0
6+
7+
8+
def toggle_left_led(custom_text: str = '') -> None:
9+
global value
10+
value = (value + 1) % 2
11+
alvik.left_led.set_color(value, 0, 0)
12+
print(f"RED BLINKS! {custom_text}")
13+
14+
15+
def simple_print(custom_text: str = '') -> None:
16+
print(custom_text)
17+
18+
alvik = ArduinoAlvik()
19+
alvik.on_touch_ok_pressed(toggle_left_led, ("OK WAS PRESSED... THAT'S COOL", ))
20+
alvik.on_touch_center_pressed(simple_print, ("CENTER PRESSED",))
21+
alvik.on_touch_cancel_pressed(simple_print, ("CANCEL PRESSED",))
22+
alvik.on_touch_up_pressed(simple_print, ("UP PRESSED",))
23+
alvik.on_touch_left_pressed(simple_print, ("LEFT PRESSED",))
24+
alvik.on_touch_down_pressed(simple_print, ("DOWN PRESSED",))
25+
alvik.on_touch_right_pressed(simple_print, ("RIGHT PRESSED",))
26+
27+
alvik.begin()
28+
29+
alvik.left_wheel.reset()
30+
alvik.right_wheel.reset()
31+
32+
while True:
33+
try:
34+
alvik.left_wheel.set_position(30)
35+
sleep(2)
36+
print(f'Left wheel degs: {alvik.left_wheel.get_position()}')
37+
print(f'Right wheel degs: {alvik.right_wheel.get_position()}')
38+
39+
alvik.right_wheel.set_position(10)
40+
sleep(2)
41+
print(f'Left wheel degs: {alvik.left_wheel.get_position()}')
42+
print(f'Right wheel degs: {alvik.right_wheel.get_position()}')
43+
44+
alvik.left_wheel.set_position(180)
45+
sleep(2)
46+
print(f'Left wheel degs: {alvik.left_wheel.get_position()}')
47+
print(f'Right wheel degs: {alvik.right_wheel.get_position()}')
48+
49+
alvik.right_wheel.set_position(270)
50+
sleep(2)
51+
print(f'Left wheel degs: {alvik.left_wheel.get_position()}')
52+
print(f'Right wheel degs: {alvik.right_wheel.get_position()}')
53+
54+
except KeyboardInterrupt as e:
55+
print('over')
56+
alvik.stop()
57+
sys.exit()

0 commit comments

Comments
 (0)