diff --git a/README.md b/README.md
index 55915a6..0efb38f 100644
--- a/README.md
+++ b/README.md
@@ -106,7 +106,7 @@ Each color allows to run a different demo as following:
To run a demo, press the `OK touch button`, after selecting the right demo color.
-To run a different demo, turn the robot off and on again or reset the Arduino® Nano ESP32.
+To run a different demo, press the `CANCEL touch button` and you will be redirected to the main menu.
### 1. Touch mode example (RED)
This example starts with the red leds on.
@@ -125,6 +125,7 @@ The leds will blink in red.
To start the sequence, press the `OK touch button`.
Pressing the `CANCEL touch button` at any time stops the robot and resets the sequence.
+Pressing the `CANCEL touch button` two times during sequence programming you will be redirected to the main menu.
@@ -167,4 +168,4 @@ __WARNING: do not open bin files with Arduino Lab for Micropython 0.8.0 because
## Useful links
- [Arduino_Alvik](https://github.com/arduino-libraries/Arduino_Alvik): Arduino library required to program Alvik
- [Arduino_AlvikCarrier](https://github.com/arduino-libraries/Arduino_AlvikCarrier): Arduino library required to build the firmware
-- [Arduino Alvik product page](https://store.arduino.cc/pages/alvik)
\ No newline at end of file
+- [Arduino Alvik product page](https://store.arduino.cc/pages/alvik)
diff --git a/arduino_alvik/__init__.py b/arduino_alvik/__init__.py
index 50fb7db..bb92f05 100644
--- a/arduino_alvik/__init__.py
+++ b/arduino_alvik/__init__.py
@@ -4,8 +4,8 @@
__author__ = "Lucio Rossi , Giovanni Bruno "
__license__ = "MPL 2.0"
-__version__ = "1.1.0"
+__version__ = "1.1.4"
__maintainer__ = "Lucio Rossi , Giovanni Bruno "
-__required_firmware_version__ = "1.1.0"
+__required_firmware_version__ = "1.1.1"
from .arduino_alvik import *
diff --git a/arduino_alvik/arduino_alvik.py b/arduino_alvik/arduino_alvik.py
index d83305a..d1a5629 100644
--- a/arduino_alvik/arduino_alvik.py
+++ b/arduino_alvik/arduino_alvik.py
@@ -1,5 +1,3 @@
-import sys
-import gc
import struct
from machine import I2C
import _thread
@@ -17,18 +15,79 @@
from .__init__ import __required_firmware_version__
+def writes_uart(method):
+ def wrapper(*args, **kwargs):
+ with ArduinoAlvik._write_lock:
+ return method(*args, **kwargs)
+
+ return wrapper
+
+
+def reads_uart(method):
+ def wrapper(*args, **kwargs):
+ with ArduinoAlvik._read_lock:
+ return method(*args, **kwargs)
+
+ return wrapper
+
+
+class _AlvikRLock:
+ def __init__(self):
+ """Alvik re-entrant Lock implementation"""
+ self._lock = _thread.allocate_lock()
+ self._owner = None
+ self._count = 0
+
+ def acquire(self):
+ tid = _thread.get_ident()
+
+ if self._owner == tid:
+ self._count += 1
+ return True
+
+ self._lock.acquire()
+ self._owner = tid
+ self._count = 1
+ return True
+
+ def release(self):
+ tid = _thread.get_ident()
+
+ if self._owner != tid:
+ raise RuntimeError("Cannot release an unowned lock")
+
+ self._count -= 1
+ if self._count == 0:
+ self._owner = None
+ self._lock.release()
+
+ def locked(self):
+ return self._lock.locked()
+
+ def __enter__(self):
+ self.acquire()
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self.release()
+
+
class ArduinoAlvik:
_update_thread_running = False
_update_thread_id = None
_events_thread_running = False
_events_thread_id = None
+ _write_lock = _AlvikRLock()
+ _read_lock = _AlvikRLock()
+
def __new__(cls):
if not hasattr(cls, '_instance'):
cls._instance = super(ArduinoAlvik, cls).__new__(cls)
return cls._instance
- def __init__(self):
+ def __init__(self, stack_size = THREAD_STACK_SIZE):
+ _thread.stack_size(stack_size)
self.i2c = _ArduinoAlvikI2C(A4, A5)
self._packeter = ucPack(200)
self.left_wheel = _ArduinoAlvikWheel(self._packeter, ord('L'), alvik=self)
@@ -84,6 +143,14 @@ def __init__(self):
self._move_events = _ArduinoAlvikMoveEvents()
self._timer_events = _ArduinoAlvikTimerEvents(-1)
+ def __del__(self):
+ """
+ This method is a stub. __del__ is not implemented in MicroPython (https://docs.micropython.org/en/latest/genrst/core_language.html#special-method-del-not-implemented-for-user-defined-classes)
+ :return:
+ """
+ ...
+ # self.__class__._instance = None
+
@staticmethod
def is_on() -> bool:
"""
@@ -100,16 +167,20 @@ def _print_battery_status(percentage: float, is_charging) -> None:
:param is_charging: True if the battery is charging
:return:
"""
- sys.stdout.write(bytes('\r'.encode('utf-8')))
+ print("\033[2K\033[1G", end='\r')
if percentage > 97:
marks_str = ' \U0001F50B'
else:
marks_str = ' \U0001FAAB'
- charging_str = f' \U0001F50C' if is_charging else ' \U000026A0WARNING: battery is discharging!'
- word = marks_str + f" {percentage}%" + charging_str + " \t"
- sys.stdout.write(bytes((word.encode('utf-8'))))
+ if is_charging:
+ charging_str = ' \U0001F50C '
+ else:
+ charging_str = ' \U000026A0 WARNING: battery is discharging!'
+ word = marks_str + f" {percentage}% {charging_str} \t"
+ print(word, end='')
- def _lenghty_op(self, iterations=10000000) -> int:
+ @staticmethod
+ def _lengthy_op(self, iterations=10000000) -> int:
result = 0
for i in range(1, iterations):
result += i * i
@@ -124,7 +195,7 @@ def _idle(self, delay_=1, check_on_thread=False, blocking=False) -> None:
self.i2c.set_single_thread(True)
if blocking:
- self._lenghty_op(50000)
+ self._lengthy_op(50000)
else:
sleep_ms(500)
led_val = 0
@@ -147,7 +218,7 @@ def _idle(self, delay_=1, check_on_thread=False, blocking=False) -> None:
self._battery_perc = abs(soc_perc)
self._print_battery_status(round(soc_perc), self._battery_is_charging)
if blocking:
- self._lenghty_op(10000)
+ self._lengthy_op(10000)
else:
sleep_ms(delay_)
if soc_perc > 97:
@@ -159,13 +230,16 @@ def _idle(self, delay_=1, check_on_thread=False, blocking=False) -> None:
led_val = (led_val + 1) % 2
self.i2c.set_single_thread(False)
if self.is_on():
- print("********** Alvik is on **********")
- except KeyboardInterrupt:
+ print("\n********** Alvik is on **********")
+ except KeyboardInterrupt as e:
self.stop()
- sys.exit()
+ raise e
+ except OSError as e:
+ print(f'\nUnable to read SOC: {e}')
+ raise e
except Exception as e:
- pass
- print(f'Unable to read SOC: {e}')
+ print(f'\nUnhandled exception: {e} {type(e)}')
+ raise e
finally:
LEDR.value(1)
LEDG.value(1)
@@ -187,18 +261,14 @@ def _snake_robot(duration: int = 1000):
frame = ''
for i in range(0, cycles):
- sys.stdout.write(bytes('\r'.encode('utf-8')))
+ print("\033[2K\033[1G", end='\r')
pre = ' ' * i
between = ' ' * (i % 2 + 1)
post = ' ' * 5
frame = pre + snake + between + robot + post
- sys.stdout.write(bytes(frame.encode('utf-8')))
+ print(frame, end='')
sleep_ms(200)
- sys.stdout.write(bytes('\r'.encode('utf-8')))
- clear_frame = ' ' * len(frame)
- sys.stdout.write(bytes(clear_frame.encode('utf-8')))
-
def begin(self) -> int:
"""
Begins all Alvik operations
@@ -218,15 +288,15 @@ def begin(self) -> int:
self._snake_robot(1000)
self._wait_for_ack()
if not self._wait_for_fw_check():
- print('\n********** PLEASE UPDATE ALVIK FIRMWARE (required: '+'.'.join(map(str,self._required_fw_version))+')! Check documentation **********\n')
- sys.exit(-2)
+ self.stop()
+ raise Exception('\n********** PLEASE UPDATE ALVIK FIRMWARE (required: '+'.'.join(map(str,self._required_fw_version))+')! Check documentation **********\n')
self._snake_robot(2000)
self.set_illuminator(True)
self.set_behaviour(1)
self.set_behaviour(2)
self._set_color_reference()
if self._has_events_registered():
- print('Starting events thread')
+ print('\n********** Starting events thread **********\n')
self._start_events_thread()
self.set_servo_positions(90, 90)
return 0
@@ -254,26 +324,32 @@ def _wait_for_ack(self) -> None:
sleep_ms(20)
self._waiting_ack = None
- def _wait_for_fw_check(self) -> bool:
+ def _wait_for_fw_check(self, timeout=5) -> bool:
"""
Waits until receives version from robot, check required version and return true if everything is ok
+ :param timeout: wait for fw timeout in seconds
:return:
"""
+ start = ticks_ms()
while self._fw_version == [None, None, None]:
sleep_ms(20)
+ if ticks_diff(ticks_ms(), start) > timeout * 1000:
+ print("Could not get FW version")
+ return False
+
if self.check_firmware_compatibility():
return True
else:
return False
@staticmethod
+ @reads_uart
def _flush_uart():
"""
Empties the UART buffer
:return:
"""
- while uart.any():
- uart.read(1)
+ uart.read(uart.any())
def _begin_update_thread(self):
"""
@@ -302,6 +378,7 @@ def _wait_for_target(self, idle_time):
# print(self._last_ack)
sleep_ms(100)
+ @writes_uart
def is_target_reached(self) -> bool:
"""
Returns True if robot has sent an M or R acknowledgment.
@@ -319,6 +396,7 @@ def is_target_reached(self) -> bool:
return True
return False
+ @writes_uart
def set_behaviour(self, behaviour: int):
"""
Sets the behaviour of Alvik
@@ -328,6 +406,7 @@ def set_behaviour(self, behaviour: int):
self._packeter.packetC1B(ord('B'), behaviour & 0xFF)
uart.write(self._packeter.msg[0:self._packeter.msg_size])
+ @writes_uart
def rotate(self, angle: float, unit: str = 'deg', blocking: bool = True):
"""
Rotates the robot by given angle
@@ -344,6 +423,7 @@ def rotate(self, angle: float, unit: str = 'deg', blocking: bool = True):
if blocking:
self._wait_for_target(idle_time=(angle / MOTOR_CONTROL_DEG_S))
+ @writes_uart
def move(self, distance: float, unit: str = 'cm', blocking: bool = True):
"""
Moves the robot by given distance
@@ -377,10 +457,6 @@ def stop(self):
# stop touch events thread
self._stop_events_thread()
- # delete _instance
- del self.__class__._instance
- gc.collect()
-
@staticmethod
def _reset_hw():
"""
@@ -401,6 +477,7 @@ def get_wheels_speed(self, unit: str = 'rpm') -> (float | None, float | None):
"""
return self.left_wheel.get_speed(unit), self.right_wheel.get_speed(unit)
+ @writes_uart
def set_wheels_speed(self, left_speed: float, right_speed: float, unit: str = 'rpm'):
"""
Sets left/right motor speed
@@ -420,12 +497,13 @@ def set_wheels_speed(self, left_speed: float, right_speed: float, unit: str = 'r
self._packeter.packetC2F(ord('J'), left_speed, right_speed)
uart.write(self._packeter.msg[0:self._packeter.msg_size])
+ @writes_uart
def set_wheels_position(self, left_angle: float, right_angle: float, unit: str = 'deg', blocking: bool = True):
"""
Sets left/right motor angle
:param left_angle:
:param right_angle:
- :param unit: the speed unit of measurement (default: 'rpm')
+ :param unit: the speed unit of measurement (default: 'deg')
:param blocking:
:return:
"""
@@ -483,6 +561,7 @@ def get_line_sensors(self) -> (int | None, int | None, int | None):
return self._left_line, self._center_line, self._right_line
+ @writes_uart
def drive(self, linear_velocity: float, angular_velocity: float, linear_unit: str = 'cm/s',
angular_unit: str = 'deg/s'):
"""
@@ -523,6 +602,7 @@ def get_drive_speed(self, linear_unit: str = 'cm/s', angular_unit: str = 'deg/s'
return convert_speed(self._linear_velocity, 'mm/s', linear_unit), angular_velocity
+ @writes_uart
def reset_pose(self, x: float, y: float, theta: float, distance_unit: str = 'cm', angle_unit: str = 'deg'):
"""
Resets the robot pose
@@ -552,6 +632,7 @@ def get_pose(self, distance_unit: str = 'cm', angle_unit: str = 'deg') \
convert_distance(self._y, 'mm', distance_unit),
convert_angle(self._theta, 'deg', angle_unit))
+ @writes_uart
def set_servo_positions(self, a_position: int, b_position: int):
"""
Sets A/B servomotor angle
@@ -579,10 +660,16 @@ def get_ack(self) -> str:
"""
return self._last_ack
- # def send_ack(self):
- # self._packeter.packetC1B(ord('X'), ACK_)
- # uart.write(self._packeter.msg[0:self._packeter.msg_size])
+ @writes_uart
+ def send_ack(self, ack: str = 'K'):
+ """
+ Sends an ack message on UART
+ :return:
+ """
+ self._packeter.packetC1B(ord('X'), ord(ack))
+ uart.write(self._packeter.msg[0:self._packeter.msg_size])
+ @writes_uart
def _set_leds(self, led_state: int):
"""
Sets the LEDs state
@@ -641,21 +728,23 @@ def _update(self, delay_=1):
self.set_behaviour(2)
if not ArduinoAlvik._update_thread_running:
break
- if self._read_message():
- self._parse_message()
+ self._read_message()
sleep_ms(delay_)
- def _read_message(self) -> bool:
+ @reads_uart
+ def _read_message(self) -> None:
"""
Read a message from the uC
:return: True if a message terminator was reached
"""
- while uart.any():
- b = uart.read(1)[0]
- self._packeter.buffer.push(b)
- if b == self._packeter.end_index and self._packeter.checkPayload():
- return True
- return False
+ buf = bytearray(uart.any())
+ uart.readinto(buf)
+ if len(buf):
+ uart.readinto(buf)
+ for b in buf:
+ self._packeter.buffer.push(b)
+ if b == self._packeter.end_index and self._packeter.checkPayload():
+ self._parse_message()
def _parse_message(self) -> int:
"""
@@ -820,6 +909,13 @@ def get_shake(self) -> bool:
"""
return bool(self._move_bits & 0b00000001)
+ def get_lifted(self) -> bool:
+ """
+ Returns true if Alvik is lifted
+ :return:
+ """
+ return bool(self._move_bits & 0b00000010)
+
def get_tilt(self) -> str:
"""
Returns the tilt string eg: "X", "-Z" etc
@@ -1251,6 +1347,24 @@ def on_shake(self, callback: callable, args: tuple = ()) -> None:
"""
self._move_events.register_callback('on_shake', callback, args)
+ def on_lift(self, callback: callable, args: tuple = ()) -> None:
+ """
+ Register callback when Alvik is lifted
+ :param callback:
+ :param args:
+ :return:
+ """
+ self._move_events.register_callback('on_lift', callback, args)
+
+ def on_drop(self, callback: callable, args: tuple = ()) -> None:
+ """
+ Register callback when Alvik is dropped
+ :param callback:
+ :param args:
+ :return:
+ """
+ self._move_events.register_callback('on_drop', callback, args)
+
def on_x_tilt(self, callback: callable, args: tuple = ()) -> None:
"""
Register callback when Alvik is tilted on X-axis
@@ -1513,7 +1627,6 @@ def writeto_mem(self, addr, memaddr, buf, addrsize=8) -> None:
return i2c.writeto_mem(addr, memaddr, buf, addrsize=addrsize)
-
class _ArduinoAlvikServo:
def __init__(self, packeter: ucPack, label: str, servo_id: int, position: list[int | None]):
@@ -1521,7 +1634,8 @@ def __init__(self, packeter: ucPack, label: str, servo_id: int, position: list[i
self._label = label
self._id = servo_id
self._position = position
-
+
+ @writes_uart
def set_position(self, position):
"""
Sets the position of the servo
@@ -1550,7 +1664,8 @@ def __init__(self, packeter: ucPack, label: int, wheel_diameter_mm: float = WHEE
self._speed = None
self._position = None
self._alvik = alvik
-
+
+ @writes_uart
def reset(self, initial_position: float = 0.0, unit: str = 'deg'):
"""
Resets the wheel reference position
@@ -1562,6 +1677,7 @@ def reset(self, initial_position: float = 0.0, unit: str = 'deg'):
self._packeter.packetC2B1F(ord('W'), self._label & 0xFF, ord('Z'), initial_position)
uart.write(self._packeter.msg[0:self._packeter.msg_size])
+ @writes_uart
def set_pid_gains(self, kp: float = MOTOR_KP_DEFAULT, ki: float = MOTOR_KI_DEFAULT, kd: float = MOTOR_KD_DEFAULT):
"""
Set PID gains for Alvik wheels
@@ -1581,6 +1697,7 @@ def stop(self):
"""
self.set_speed(0)
+ @writes_uart
def set_speed(self, velocity: float, unit: str = 'rpm'):
"""
Sets the motor speed
@@ -1617,6 +1734,7 @@ def get_position(self, unit: str = 'deg') -> float | None:
"""
return convert_angle(self._position, 'deg', unit)
+ @writes_uart
def set_position(self, position: float, unit: str = 'deg', blocking: bool = True):
"""
Sets left/right motor speed
@@ -1647,6 +1765,7 @@ def __init__(self, packeter: ucPack, label: str, led_state: list[int | None], rg
self._rgb_mask = rgb_mask
self._led_state = led_state
+ @writes_uart
def set_color(self, red: bool, green: bool, blue: bool):
"""
Sets the LED's r,g,b state
@@ -1957,7 +2076,7 @@ class _ArduinoAlvikMoveEvents(_ArduinoAlvikEvents):
Event class to handle move events
"""
- available_events = ['on_shake', 'on_x_tilt', 'on_y_tilt', 'on_z_tilt',
+ available_events = ['on_shake', 'on_lift', 'on_drop', 'on_x_tilt', 'on_y_tilt', 'on_z_tilt',
'on_nx_tilt', 'on_ny_tilt', 'on_nz_tilt']
NZ_TILT = 0x80
@@ -1984,6 +2103,26 @@ def _is_shaken(current_state, new_state) -> bool:
"""
return not bool(current_state & 0b00000001) and bool(new_state & 0b00000001)
+ @staticmethod
+ def _is_lifted(current_state, new_state) -> bool:
+ """
+ True if Alvik was lifted
+ :param current_state:
+ :param new_state:
+ :return:
+ """
+ return not bool(current_state & 0b00000010) and bool(new_state & 0b00000010)
+
+ @staticmethod
+ def _is_dropped(current_state, new_state) -> bool:
+ """
+ True if Alvik was dropped
+ :param current_state:
+ :param new_state:
+ :return:
+ """
+ return bool(current_state & 0b00000010) and not bool(new_state & 0b00000010)
+
@staticmethod
def _is_x_tilted(current_state, new_state) -> bool:
"""
@@ -2057,6 +2196,12 @@ def update_state(self, state: int | None):
if self._is_shaken(self._current_state, state):
self.execute_callback('on_shake')
+ if self._is_lifted(self._current_state, state):
+ self.execute_callback('on_lift')
+
+ if self._is_dropped(self._current_state, state):
+ self.execute_callback('on_drop')
+
if self._is_x_tilted(self._current_state, state):
self.execute_callback('on_x_tilt')
@@ -2096,6 +2241,19 @@ def update_firmware(file_path: str):
STM32_eraseMEM,
STM32_writeMEM, )
+ def flash_toggle():
+ i = 0
+
+ while True:
+ if i == 0:
+ LEDR.value(1)
+ LEDG.value(0)
+ else:
+ LEDR.value(0)
+ LEDG.value(1)
+ i = (i + 1) % 2
+ yield
+
if CHECK_STM32.value() is not 1:
print("Turn on your Alvik to continue...")
while CHECK_STM32.value() is not 1:
@@ -2112,8 +2270,13 @@ def update_firmware(file_path: str):
STM32_eraseMEM(0xFFFF)
print("\nWRITING MEM")
- STM32_writeMEM(file_path)
+ toggle = flash_toggle()
+ STM32_writeMEM(file_path, toggle)
+
print("\nDONE")
print("\nLower Boot0 and reset STM32")
+ LEDR.value(1)
+ LEDG.value(1)
+
STM32_endCommunication()
diff --git a/arduino_alvik/robot_definitions.py b/arduino_alvik/robot_definitions.py
index 26a2e51..c0a0864 100644
--- a/arduino_alvik/robot_definitions.py
+++ b/arduino_alvik/robot_definitions.py
@@ -12,3 +12,6 @@
# Robot params
ROBOT_MAX_DEG_S = 6*(2*MOTOR_MAX_RPM*WHEEL_DIAMETER_MM)/WHEEL_TRACK_MM
+
+# Thread stack size
+THREAD_STACK_SIZE = 8*1024
diff --git a/arduino_alvik/stm32_flash.py b/arduino_alvik/stm32_flash.py
index 89522c6..83b3ff2 100644
--- a/arduino_alvik/stm32_flash.py
+++ b/arduino_alvik/stm32_flash.py
@@ -1,5 +1,4 @@
import os
-import sys
from time import sleep_ms
from machine import UART, Pin
@@ -296,7 +295,7 @@ def STM32_readMEM(pages: int):
_incrementAddress(readAddress)
-def STM32_writeMEM(file_path: str):
+def STM32_writeMEM(file_path: str, toggle: "Generator" = None):
with open(file_path, 'rb') as f:
print(f"Flashing {file_path}\n")
@@ -322,10 +321,13 @@ def STM32_writeMEM(file_path: str):
print(f"STM32 ERROR FLASHING PAGE: {writeAddress}")
return
- sys.stdout.write('\r')
- sys.stdout.write(f"{int((i/file_pages)*100)}%")
+ percentage = int((i / file_pages) * 100)
+ print("\033[2K\033[1G", end='\r')
+ print(f"Flashing STM32: {percentage:>3}%", end='')
i = i + 1
_incrementAddress(writeAddress)
+ if toggle is not None:
+ next(toggle)
def _STM32_standardEraseMEM(pages: int, page_list: bytearray = None):
diff --git a/examples/actuators/leds_setting.py b/examples/actuators/leds_setting.py
index cceb6c4..3ea1020 100644
--- a/examples/actuators/leds_setting.py
+++ b/examples/actuators/leds_setting.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -34,4 +34,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/actuators/move_wheels.py b/examples/actuators/move_wheels.py
index d6f6e7e..94537a3 100644
--- a/examples/actuators/move_wheels.py
+++ b/examples/actuators/move_wheels.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -33,4 +33,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/actuators/pose_example.py b/examples/actuators/pose_example.py
index 11b675a..465a635 100644
--- a/examples/actuators/pose_example.py
+++ b/examples/actuators/pose_example.py
@@ -1,82 +1,80 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
-while True:
- try:
+try:
+
+ alvik.move(100.0, 'mm')
+ print("on target after move")
+
+ alvik.move(50.0, 'mm')
+ print("on target after move")
+
+ alvik.rotate(90.0, 'deg')
+ print("on target after rotation")
- alvik.move(100.0, 'mm')
- print("on target after move")
+ alvik.rotate(-45.00, 'deg')
+ print("on target after rotation")
- alvik.move(50.0, 'mm')
- print("on target after move")
+ x, y, theta = alvik.get_pose()
+ print(f'Current pose is x(cm)={x}, y(cm)={y}, theta(deg)={theta}')
- alvik.rotate(90.0, 'deg')
- print("on target after rotation")
+ alvik.reset_pose(0, 0, 0)
- alvik.rotate(-45.00, 'deg')
- print("on target after rotation")
+ x, y, theta = alvik.get_pose()
+ print(f'Updated pose is x(cm)={x}, y(cm)={y}, theta(deg)={theta}')
+ sleep_ms(500)
- x, y, theta = alvik.get_pose()
- print(f'Current pose is x(cm)={x}, y(cm)={y}, theta(deg)={theta}')
+ print("___________NON-BLOCKING__________________")
- alvik.reset_pose(0, 0, 0)
+ alvik.move(50.0, 'mm', blocking=False)
- x, y, theta = alvik.get_pose()
- print(f'Updated pose is x(cm)={x}, y(cm)={y}, theta(deg)={theta}')
+ while not alvik.is_target_reached():
+ alvik.left_led.set_color(1, 0, 0)
+ sleep_ms(500)
+ alvik.left_led.set_color(0, 0, 0)
+ sleep_ms(500)
+ print("on target after move")
+
+ alvik.rotate(45.0, 'deg', blocking=False)
+ while not alvik.is_target_reached():
+ alvik.left_led.set_color(1, 0, 0)
+ sleep_ms(500)
+ alvik.left_led.set_color(0, 0, 0)
sleep_ms(500)
+ print("on target after rotation")
- print("___________NON-BLOCKING__________________")
-
- alvik.move(50.0, 'mm', blocking=False)
-
- while not alvik.is_target_reached():
- alvik.left_led.set_color(1, 0, 0)
- sleep_ms(500)
- alvik.left_led.set_color(0, 0, 0)
- sleep_ms(500)
- print("on target after move")
-
- alvik.rotate(45.0, 'deg', blocking=False)
- while not alvik.is_target_reached():
- alvik.left_led.set_color(1, 0, 0)
- sleep_ms(500)
- alvik.left_led.set_color(0, 0, 0)
- sleep_ms(500)
- print("on target after rotation")
-
- alvik.move(100.0, 'mm', blocking=False)
- while not alvik.is_target_reached():
- alvik.left_led.set_color(1, 0, 0)
- sleep_ms(500)
- alvik.left_led.set_color(0, 0, 0)
- sleep_ms(500)
- print("on target after move")
-
- alvik.rotate(-90.00, 'deg', blocking=False)
- while not alvik.is_target_reached():
- alvik.left_led.set_color(1, 0, 0)
- sleep_ms(500)
- alvik.left_led.set_color(0, 0, 0)
- sleep_ms(500)
- print("on target after rotation")
-
- x, y, theta = alvik.get_pose()
- print(f'Current pose is x(cm)={x}, y(cm)={y}, theta(deg)={theta}')
-
- alvik.reset_pose(0, 0, 0)
-
- x, y, theta = alvik.get_pose()
- print(f'Updated pose is x={x}, y={y}, theta(deg)={theta}')
+ alvik.move(100.0, 'mm', blocking=False)
+ while not alvik.is_target_reached():
+ alvik.left_led.set_color(1, 0, 0)
sleep_ms(500)
+ alvik.left_led.set_color(0, 0, 0)
+ sleep_ms(500)
+ print("on target after move")
+
+ alvik.rotate(-90.00, 'deg', blocking=False)
+ while not alvik.is_target_reached():
+ alvik.left_led.set_color(1, 0, 0)
+ sleep_ms(500)
+ alvik.left_led.set_color(0, 0, 0)
+ sleep_ms(500)
+ print("on target after rotation")
+
+ x, y, theta = alvik.get_pose()
+ print(f'Current pose is x(cm)={x}, y(cm)={y}, theta(deg)={theta}')
+
+ alvik.reset_pose(0, 0, 0)
+
+ x, y, theta = alvik.get_pose()
+ print(f'Updated pose is x={x}, y={y}, theta(deg)={theta}')
+ sleep_ms(500)
- alvik.stop()
- sys.exit()
+except KeyboardInterrupt as e:
+ print('Test interrupted')
- except KeyboardInterrupt as e:
- print('over')
- alvik.stop()
- sys.exit()
+finally:
+ alvik.stop()
+ print("END of pose example")
\ No newline at end of file
diff --git a/examples/actuators/set_servo.py b/examples/actuators/set_servo.py
index b4e9084..48720c1 100644
--- a/examples/actuators/set_servo.py
+++ b/examples/actuators/set_servo.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -19,4 +19,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/actuators/wheels_position.py b/examples/actuators/wheels_position.py
index 6f3a151..fc521c6 100644
--- a/examples/actuators/wheels_position.py
+++ b/examples/actuators/wheels_position.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep, sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -62,4 +62,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/actuators/wheels_speed.py b/examples/actuators/wheels_speed.py
index 1919f27..3a54340 100644
--- a/examples/actuators/wheels_speed.py
+++ b/examples/actuators/wheels_speed.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -21,4 +21,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/arduino-runtime/blink.py b/examples/arduino-runtime/blink.py
new file mode 100644
index 0000000..920838f
--- /dev/null
+++ b/examples/arduino-runtime/blink.py
@@ -0,0 +1,28 @@
+from time import sleep_ms
+
+from arduino import start
+from arduino_alvik import ArduinoAlvik
+
+
+alvik = ArduinoAlvik()
+
+
+def setup():
+ alvik.begin()
+
+
+def loop():
+ print('blinking LEDs')
+ alvik.left_led.set_color(0, 0, 1)
+ alvik.right_led.set_color(0, 0, 1)
+ sleep_ms(500)
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(1, 0, 0)
+ sleep_ms(500)
+
+
+def cleanup():
+ alvik.stop()
+
+
+start(setup=setup, loop=loop, cleanup=cleanup)
diff --git a/examples/arduino-runtime/line_follower.py b/examples/arduino-runtime/line_follower.py
new file mode 100644
index 0000000..cf6c861
--- /dev/null
+++ b/examples/arduino-runtime/line_follower.py
@@ -0,0 +1,64 @@
+from time import sleep_ms
+
+from arduino import start
+from arduino_alvik import ArduinoAlvik
+
+
+alvik = ArduinoAlvik()
+
+
+def calculate_center(left: int, center: int, right: int):
+ centroid = 0
+ sum_weight = left + center + right
+ sum_values = left + 2 * center + 3 * right
+ if sum_weight != 0:
+ centroid = sum_values / sum_weight
+ centroid = 2 - centroid
+ return centroid
+
+
+def run_line_follower(alvik):
+
+ kp = 50.0
+ line_sensors = alvik.get_line_sensors()
+ print(f' {line_sensors}')
+
+ error = calculate_center(*line_sensors)
+ control = error * kp
+
+ if control > 0.2:
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ elif control < -0.2:
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ else:
+ alvik.left_led.set_color(0, 1, 0)
+ alvik.right_led.set_color(0, 1, 0)
+
+ alvik.set_wheels_speed(30 - control, 30 + control)
+ sleep_ms(100)
+
+
+def setup():
+ alvik.begin()
+ alvik.left_led.set_color(0, 0, 1)
+ alvik.right_led.set_color(0, 0, 1)
+
+
+def loop():
+ while not alvik.get_touch_ok():
+ alvik.left_led.set_color(0, 0, 1)
+ alvik.right_led.set_color(0, 0, 1)
+ alvik.brake()
+ sleep_ms(100)
+
+ while not alvik.get_touch_cancel():
+ run_line_follower(alvik)
+
+
+def cleanup():
+ alvik.stop()
+
+
+start(setup=setup, loop=loop, cleanup=cleanup)
diff --git a/examples/arduino-runtime/read_tof.py b/examples/arduino-runtime/read_tof.py
new file mode 100644
index 0000000..63fb76d
--- /dev/null
+++ b/examples/arduino-runtime/read_tof.py
@@ -0,0 +1,26 @@
+from time import sleep_ms
+
+from arduino import start
+from arduino_alvik import ArduinoAlvik
+
+
+alvik = ArduinoAlvik()
+
+
+def setup():
+ alvik.begin()
+
+
+def loop():
+ L, CL, C, CR, R = alvik.get_distance()
+ T = alvik.get_distance_top()
+ B = alvik.get_distance_bottom()
+ print(f'T: {T} | B: {B} | L: {L} | CL: {CL} | C: {C} | CR: {CR} | R: {R}')
+ sleep_ms(100)
+
+
+def cleanup():
+ alvik.stop()
+
+
+start(setup=setup, loop=loop, cleanup=cleanup)
diff --git a/examples/communication/i2c_scan.py b/examples/communication/i2c_scan.py
index a246787..6f1ed45 100644
--- a/examples/communication/i2c_scan.py
+++ b/examples/communication/i2c_scan.py
@@ -1,5 +1,5 @@
from time import sleep_ms
-import sys
+
from arduino_alvik import ArduinoAlvik
@@ -22,4 +22,4 @@
sleep_ms(100)
except KeyboardInterrupt as e:
alvik.stop()
- sys.exit()
\ No newline at end of file
+ break
\ No newline at end of file
diff --git a/examples/communication/modulino.py b/examples/communication/modulino.py
index bf1e8e2..e5950d7 100644
--- a/examples/communication/modulino.py
+++ b/examples/communication/modulino.py
@@ -1,11 +1,12 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
+
try:
from modulino import ModulinoPixels
except ImportError as e:
- print("ImportError: ModulinoPixels not installed")
- sys.exit(-1)
+ print("\nImportError: ModulinoPixels not installed")
+ raise e
alvik = ArduinoAlvik()
alvik.begin()
@@ -13,8 +14,7 @@
pixels = ModulinoPixels(alvik.i2c)
if not pixels.connected:
- print("🤷 No pixel modulino found")
- sys.exit(-2)
+ raise Exception("🤷 No pixel modulino found")
while True:
try:
@@ -32,4 +32,4 @@
except KeyboardInterrupt as e:
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/demo/demo.py b/examples/demo/demo.py
index 931aa47..f1b283d 100644
--- a/examples/demo/demo.py
+++ b/examples/demo/demo.py
@@ -1,6 +1,10 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
+from line_follower import run_line_follower
+from touch_move import run_touch_move
+from hand_follower import run_hand_follower
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -27,12 +31,21 @@ def update_led_status(val):
try:
if alvik.get_touch_ok():
- if menu_status == 0:
- import line_follower
- elif menu_status == 1:
- import hand_follower
- elif menu_status == -1:
- import touch_move
+ alvik.left_led.set_color(0, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ sleep_ms(500)
+ while not alvik.get_touch_cancel():
+ if menu_status == 0:
+ run_line_follower(alvik)
+ elif menu_status == 1:
+ run_hand_follower(alvik)
+ elif menu_status == -1:
+ if run_touch_move(alvik) < 0:
+ break
+ alvik.left_led.set_color(0, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ sleep_ms(500)
+ alvik.brake()
if alvik.get_touch_up() and menu_status < 1:
menu_status += 1
@@ -50,4 +63,4 @@ def update_led_status(val):
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/demo/hand_follower.py b/examples/demo/hand_follower.py
index fcdc41e..1b784b5 100644
--- a/examples/demo/hand_follower.py
+++ b/examples/demo/hand_follower.py
@@ -1,38 +1,43 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
-alvik = ArduinoAlvik()
-alvik.begin()
-reference = 10.0
+def run_hand_follower(alvik):
+ reference = 10.0
+ alvik.left_led.set_color(0, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ L, CL, C, CR, R = alvik.get_distance()
+ print(f'C: {C}')
+ error = C - reference
+ alvik.set_wheels_speed(error * 10, error * 10)
+ sleep_ms(100)
-alvik.left_led.set_color(0, 1, 0)
-alvik.right_led.set_color(0, 1, 0)
-while alvik.get_touch_ok():
- sleep_ms(50)
+if __name__ == "__main__":
-while not alvik.get_touch_ok():
- sleep_ms(50)
+ alvik = ArduinoAlvik()
+ alvik.begin()
+
+ alvik.left_led.set_color(0, 1, 0)
+ alvik.right_led.set_color(0, 1, 0)
+
+ while alvik.get_touch_ok():
+ sleep_ms(50)
+
+ while not alvik.get_touch_ok():
+ sleep_ms(50)
-try:
while True:
- while not alvik.get_touch_cancel():
- alvik.left_led.set_color(0, 0, 0)
- alvik.right_led.set_color(0, 0, 0)
- L, CL, C, CR, R = alvik.get_distance()
- print(f'C: {C}')
- error = C - reference
- alvik.set_wheels_speed(error*10, error*10)
- sleep_ms(100)
-
- while not alvik.get_touch_ok():
- alvik.left_led.set_color(0, 1, 0)
- alvik.right_led.set_color(0, 1, 0)
- alvik.brake()
- sleep_ms(100)
-except KeyboardInterrupt as e:
- print('over')
- alvik.stop()
- sys.exit()
+ try:
+ while not alvik.get_touch_cancel():
+ run_hand_follower(alvik)
+
+ while not alvik.get_touch_ok():
+ alvik.left_led.set_color(0, 1, 0)
+ alvik.right_led.set_color(0, 1, 0)
+ alvik.brake()
+ sleep_ms(100)
+ except KeyboardInterrupt as e:
+ print('over')
+ alvik.stop()
+ break
diff --git a/examples/demo/line_follower.py b/examples/demo/line_follower.py
index 041faf6..c61f3c4 100644
--- a/examples/demo/line_follower.py
+++ b/examples/demo/line_follower.py
@@ -1,6 +1,5 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
def calculate_center(left: int, center: int, right: int):
@@ -13,52 +12,54 @@ def calculate_center(left: int, center: int, right: int):
return centroid
-alvik = ArduinoAlvik()
-alvik.begin()
+def run_line_follower(alvik):
+ kp = 50.0
+ line_sensors = alvik.get_line_sensors()
+ print(f' {line_sensors}')
-error = 0
-control = 0
-kp = 50.0
+ error = calculate_center(*line_sensors)
+ control = error * kp
-alvik.left_led.set_color(0, 0, 1)
-alvik.right_led.set_color(0, 0, 1)
+ if control > 0.2:
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ elif control < -0.2:
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ else:
+ alvik.left_led.set_color(0, 1, 0)
+ alvik.right_led.set_color(0, 1, 0)
-while alvik.get_touch_ok():
- sleep_ms(50)
+ alvik.set_wheels_speed(30 - control, 30 + control)
+ sleep_ms(100)
-while not alvik.get_touch_ok():
- sleep_ms(50)
-try:
+if __name__ == "__main__":
+
+ alvik = ArduinoAlvik()
+ alvik.begin()
+
+ alvik.left_led.set_color(0, 0, 1)
+ alvik.right_led.set_color(0, 0, 1)
+
+ while alvik.get_touch_ok():
+ sleep_ms(50)
+
+ while not alvik.get_touch_ok():
+ sleep_ms(50)
+
while True:
- while not alvik.get_touch_cancel():
-
- line_sensors = alvik.get_line_sensors()
- print(f' {line_sensors}')
-
- error = calculate_center(*line_sensors)
- control = error * kp
-
- if control > 0.2:
- alvik.left_led.set_color(1, 0, 0)
- alvik.right_led.set_color(0, 0, 0)
- elif control < -0.2:
- alvik.left_led.set_color(1, 0, 0)
- alvik.right_led.set_color(0, 0, 0)
- else:
- alvik.left_led.set_color(0, 1, 0)
- alvik.right_led.set_color(0, 1, 0)
-
- alvik.set_wheels_speed(30 - control, 30 + control)
- sleep_ms(100)
-
- while not alvik.get_touch_ok():
- alvik.left_led.set_color(0, 0, 1)
- alvik.right_led.set_color(0, 0, 1)
- alvik.brake()
- sleep_ms(100)
-
-except KeyboardInterrupt as e:
- print('over')
- alvik.stop()
- sys.exit()
+ try:
+ while not alvik.get_touch_cancel():
+ run_line_follower(alvik)
+
+ while not alvik.get_touch_ok():
+ alvik.left_led.set_color(0, 0, 1)
+ alvik.right_led.set_color(0, 0, 1)
+ alvik.brake()
+ sleep_ms(100)
+
+ except KeyboardInterrupt as e:
+ print('over')
+ alvik.stop()
+ break
diff --git a/examples/demo/touch_move.py b/examples/demo/touch_move.py
index b51e4ca..728cc03 100644
--- a/examples/demo/touch_move.py
+++ b/examples/demo/touch_move.py
@@ -1,17 +1,8 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
-alvik = ArduinoAlvik()
-alvik.begin()
-alvik.left_led.set_color(1, 0, 0)
-alvik.right_led.set_color(1, 0, 0)
-
-movements = []
-
-
-def blink():
+def blink(alvik):
alvik.left_led.set_color(1, 0, 1)
alvik.right_led.set_color(1, 0, 1)
sleep_ms(200)
@@ -19,27 +10,25 @@ def blink():
alvik.right_led.set_color(1, 0, 0)
-def add_movement():
- global movements
-
+def add_movement(alvik, movements):
if alvik.get_touch_up():
movements.append('forward')
- blink()
+ blink(alvik)
while alvik.get_touch_up():
sleep_ms(100)
if alvik.get_touch_down():
movements.append('backward')
- blink()
+ blink(alvik)
while alvik.get_touch_down():
sleep_ms(100)
if alvik.get_touch_left():
movements.append('left')
- blink()
+ blink(alvik)
while alvik.get_touch_left():
sleep_ms(100)
if alvik.get_touch_right():
movements.append('right')
- blink()
+ blink(alvik)
while alvik.get_touch_right():
sleep_ms(100)
if alvik.get_touch_cancel():
@@ -53,7 +42,7 @@ def add_movement():
sleep_ms(100)
-def run_movement(movement):
+def run_movement(alvik, movement):
if movement == 'forward':
alvik.move(10, blocking=False)
if movement == 'backward':
@@ -70,33 +59,45 @@ def run_movement(movement):
alvik.right_led.set_color(0, 0, 0)
sleep_ms(100)
-while alvik.get_touch_ok():
- sleep_ms(50)
-while not (alvik.get_touch_ok() and len(movements) != 0):
- add_movement()
- sleep_ms(50)
+def run_touch_move(alvik) -> int:
+ movements = []
+ while not (alvik.get_touch_ok() and len(movements) != 0):
+ if alvik.get_touch_cancel():
+ if len(movements) == 0:
+ return -1
+ movements.clear()
+ blink(alvik)
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(1, 0, 0)
+ alvik.brake()
+ add_movement(alvik, movements)
+ sleep_ms(100)
-try:
- while True:
- alvik.left_led.set_color(0, 0, 0)
- alvik.right_led.set_color(0, 0, 0)
- for move in movements:
- run_movement(move)
- if alvik.get_touch_cancel():
- break
+ alvik.left_led.set_color(0, 0, 0)
+ alvik.right_led.set_color(0, 0, 0)
+ for move in movements:
+ run_movement(alvik, move)
+ if alvik.get_touch_cancel():
+ movements.clear()
+ blink(alvik)
+ sleep_ms(100)
+ return 1
- movements = []
- while not (alvik.get_touch_ok() and len(movements) != 0):
- alvik.left_led.set_color(1, 0, 0)
- alvik.right_led.set_color(1, 0, 0)
- alvik.brake()
- add_movement()
- sleep_ms(100)
-except KeyboardInterrupt as e:
- print('over')
- alvik.stop()
- sys.exit()
+if __name__ == "__main__":
+ alvik = ArduinoAlvik()
+ alvik.begin()
+
+ alvik.left_led.set_color(1, 0, 0)
+ alvik.right_led.set_color(1, 0, 0)
+
+ while True:
+ try:
+ run_touch_move(alvik)
+ except KeyboardInterrupt as e:
+ print('over')
+ alvik.stop()
+ break
diff --git a/examples/events/hot_wheels.py b/examples/events/hot_wheels.py
new file mode 100644
index 0000000..7ce9894
--- /dev/null
+++ b/examples/events/hot_wheels.py
@@ -0,0 +1,44 @@
+from arduino_alvik import ArduinoAlvik
+from time import sleep_ms
+
+
+def stop_when_up(alvik):
+ print("lift")
+ alvik.set_wheels_speed(0, 0)
+
+
+def run_when_down(alvik):
+ print("drop")
+ alvik.set_wheels_speed(20, 20)
+
+
+alvik = ArduinoAlvik()
+alvik.on_lift(stop_when_up, (alvik,))
+alvik.on_drop(run_when_down, (alvik,))
+alvik.begin()
+color_val = 0
+
+
+def blinking_leds(val):
+ alvik.left_led.set_color(val & 0x01, val & 0x02, val & 0x04)
+ alvik.right_led.set_color(val & 0x02, val & 0x04, val & 0x01)
+
+
+while not alvik.get_touch_ok():
+ sleep_ms(100)
+
+alvik.set_wheels_speed(20, 20)
+
+while not alvik.get_touch_cancel():
+
+ try:
+ blinking_leds(color_val)
+ color_val = (color_val + 1) % 7
+ sleep_ms(500)
+
+ except KeyboardInterrupt as e:
+ print('over')
+ alvik.stop()
+ break
+
+alvik.stop()
diff --git a/examples/events/motion_events.py b/examples/events/motion_events.py
index f7edf01..f8ea953 100644
--- a/examples/events/motion_events.py
+++ b/examples/events/motion_events.py
@@ -1,6 +1,5 @@
from arduino_alvik import ArduinoAlvik
from time import sleep
-import sys
def toggle_value():
@@ -32,6 +31,8 @@ def simple_print(custom_text: str = '') -> None:
alvik = ArduinoAlvik()
alvik.on_shake(toggle_left_led, ("ALVIK WAS SHAKEN... YOU MAKE ME SHIVER :)", toggle_value(), ))
+alvik.on_lift(simple_print, ("ALVIK WAS LIFTED",))
+alvik.on_drop(simple_print, ("ALVIK WAS DROPPED",))
alvik.on_x_tilt(simple_print, ("TILTED ON X",))
alvik.on_nx_tilt(simple_print, ("TILTED ON -X",))
alvik.on_y_tilt(simple_print, ("TILTED ON Y",))
@@ -49,4 +50,4 @@ def simple_print(custom_text: str = '') -> None:
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/events/timer_one_shot_events.py b/examples/events/timer_one_shot_events.py
index 8ab8a99..487c4fb 100644
--- a/examples/events/timer_one_shot_events.py
+++ b/examples/events/timer_one_shot_events.py
@@ -1,17 +1,5 @@
from arduino_alvik import ArduinoAlvik
from time import sleep
-import sys
-
-
-def toggle_value():
- """
- This function yields a generator object that toggles values between 0 and 1.
- :return:
- """
- value = 0
- while True:
- yield value % 2
- value += 1
def toggle_left_led(custom_text: str, val) -> None:
@@ -21,13 +9,12 @@ def toggle_left_led(custom_text: str, val) -> None:
:param val: a toggle signal generator
:return:
"""
- led_val = next(val)
- alvik.left_led.set_color(led_val, 0, 0)
- print(f"RED {'ON' if led_val else 'OFF'}! {custom_text}")
+ alvik.left_led.set_color(val, 0, 0)
+ print(f"LEFT LED -> RED {'ON' if val else 'OFF'}! {custom_text}")
alvik = ArduinoAlvik()
-alvik.set_timer('one_shot', 10000, toggle_left_led, ("10 seconds have passed... I won't do this again", toggle_value(), ))
+alvik.set_timer('one_shot', 10000, toggle_left_led, ("10 seconds have passed... I won't do this again", 1, ))
alvik.begin()
@@ -68,4 +55,4 @@ def toggle_left_led(custom_text: str, val) -> None:
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
\ No newline at end of file
diff --git a/examples/events/timer_periodic_events.py b/examples/events/timer_periodic_events.py
index fd5aa28..d56e90c 100644
--- a/examples/events/timer_periodic_events.py
+++ b/examples/events/timer_periodic_events.py
@@ -1,6 +1,5 @@
from arduino_alvik import ArduinoAlvik
from time import sleep
-import sys
def toggle_value():
@@ -67,4 +66,4 @@ def toggle_left_led(custom_text: str, val) -> None:
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/events/touch_events.py b/examples/events/touch_events.py
index 9ef35e3..db0d6c1 100644
--- a/examples/events/touch_events.py
+++ b/examples/events/touch_events.py
@@ -1,6 +1,5 @@
from arduino_alvik import ArduinoAlvik
from time import sleep
-import sys
def toggle_value():
@@ -67,4 +66,4 @@ def simple_print(custom_text: str = '') -> None:
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/flash_firmware.py b/examples/flash_firmware.py
index a3327da..b98fba8 100644
--- a/examples/flash_firmware.py
+++ b/examples/flash_firmware.py
@@ -1,4 +1,18 @@
-# from machine import reset
+import sys
+
+
+def reload_modules():
+ to_be_reloaded = []
+
+ for m in sys.modules:
+ to_be_reloaded.append(m)
+ del sys.modules[m]
+
+ for m in to_be_reloaded:
+ exec(f'import {m}')
+
+
+reload_modules()
from arduino_alvik import update_firmware
# this is a patch to fix possible running threads on Alvik
@@ -6,5 +20,4 @@
alvik = ArduinoAlvik()
alvik.stop()
-update_firmware('./firmware.bin')
-# reset()
\ No newline at end of file
+update_firmware('/firmware.bin')
diff --git a/examples/reload_modules.py b/examples/reload_modules.py
new file mode 100644
index 0000000..bd5108a
--- /dev/null
+++ b/examples/reload_modules.py
@@ -0,0 +1,14 @@
+import sys
+
+def reload_modules():
+ to_be_reloaded = []
+
+ for m in sys.modules:
+ to_be_reloaded.append(m)
+ del sys.modules[m]
+
+ for m in to_be_reloaded:
+ exec(f'import {m}')
+
+
+reload_modules()
\ No newline at end of file
diff --git a/examples/sensors/read_color_sensor.py b/examples/sensors/read_color_sensor.py
index 462826c..0c92871 100644
--- a/examples/sensors/read_color_sensor.py
+++ b/examples/sensors/read_color_sensor.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -15,4 +15,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/sensors/read_imu.py b/examples/sensors/read_imu.py
index 3c6589b..7c0d984 100644
--- a/examples/sensors/read_imu.py
+++ b/examples/sensors/read_imu.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -14,4 +14,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/sensors/read_orientation.py b/examples/sensors/read_orientation.py
index 23cf006..33b0113 100644
--- a/examples/sensors/read_orientation.py
+++ b/examples/sensors/read_orientation.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -13,4 +13,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/sensors/read_tof.py b/examples/sensors/read_tof.py
index 990bf63..20d37f0 100644
--- a/examples/sensors/read_tof.py
+++ b/examples/sensors/read_tof.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -15,4 +15,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/sensors/read_touch.py b/examples/sensors/read_touch.py
index 21c5ebb..6a627df 100644
--- a/examples/sensors/read_touch.py
+++ b/examples/sensors/read_touch.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -27,4 +27,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/tests/message_reader.py b/examples/tests/message_reader.py
index 7ae24e1..d2eb283 100644
--- a/examples/tests/message_reader.py
+++ b/examples/tests/message_reader.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -25,5 +25,5 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/tests/test_idle.py b/examples/tests/test_idle.py
index f65625a..1c26a97 100644
--- a/examples/tests/test_idle.py
+++ b/examples/tests/test_idle.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
@@ -19,5 +19,5 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
+ break
diff --git a/examples/tests/test_meas_units.py b/examples/tests/test_meas_units.py
index 468073d..3938a56 100644
--- a/examples/tests/test_meas_units.py
+++ b/examples/tests/test_meas_units.py
@@ -1,124 +1,122 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
alvik.begin()
-while True:
- try:
-
- # -- LINEAR MOVEMENTS --
-
- print("Move fw 0.05 m")
- alvik.move(0.05, unit='m')
- sleep_ms(2000)
-
- print("Move fw 10 cm")
- alvik.move(5, unit='cm')
- sleep_ms(2000)
-
- print("Move bw 100 mm")
- alvik.move(-100, unit='mm')
- sleep_ms(2000)
-
- print("Move fw 1 inch")
- alvik.move(1, unit='in')
- sleep_ms(2000)
-
- print(f"Current position: {alvik.get_pose()}")
- alvik.reset_pose(0, 0, theta=3.1415, angle_unit='rad')
- sleep_ms(2000)
-
- print(f"Current position: {alvik.get_pose()}")
-
- # -- WHEEL ROTATIONS --
- alvik.right_wheel.reset()
- sleep_ms(2000)
- curr_pos = alvik.right_wheel.get_position()
- print(f'R wheel pos: {curr_pos}')
- sleep_ms(2000)
-
- print("Rotate right wheel 25% fw")
- alvik.right_wheel.set_position(25, unit='%')
- sleep_ms(2000)
- curr_pos = alvik.right_wheel.get_position()
- print(f'R wheel pos: {curr_pos}')
-
- print("Rotate right wheel 90 deg bw")
- alvik.right_wheel.set_position(-90, unit='deg')
- sleep_ms(2000)
- curr_pos = alvik.right_wheel.get_position()
- print(f'R wheel pos: {curr_pos}')
-
- print("Rotate right wheel pi rad fw")
- alvik.right_wheel.set_position(3.14, unit='rad')
- sleep_ms(2000)
- curr_pos = alvik.right_wheel.get_position()
- print(f'R wheel pos: {curr_pos}')
-
- print("Rotate right wheel a quarter revolution bw")
- alvik.right_wheel.set_position(-0.25, unit='rev')
- sleep_ms(2000)
- curr_pos = alvik.right_wheel.get_position()
- print(f'R wheel pos: {curr_pos}')
-
- # -- WHEELS SPEED --
- print("Set speed 50% max_rpm (35.0 rpm)")
- alvik.set_wheels_speed(50, 50, '%')
- sleep_ms(1000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- print("Set speed 12 rpm (1 rev in 5 sec)")
- alvik.set_wheels_speed(12, 12, 'rpm')
- sleep_ms(1000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- print("Set speed -pi rad/s (1 back rev in 2 sec)")
- alvik.set_wheels_speed(-3.1415, -3.1415, 'rad/s')
- sleep_ms(1000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- print("Set speed 180 deg/s (1 back rev in 2 sec)")
- alvik.set_wheels_speed(180, 180, 'deg/s')
- sleep_ms(1000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- # -- DRIVE --
- print("Driving at 10 mm/s (expecting approx 5.6 rpm 64 deg/s)")
- alvik.drive(10, 20, linear_unit='mm/s', angular_unit='%')
- sleep_ms(2000)
- print(f"Current speed is {alvik.get_drive_speed()} (mm/s, deg/s))")
-
- print("Driving at 10 mm/s (expecting approx 5.6 rpm)")
- alvik.drive(10, 0, linear_unit='mm/s')
- sleep_ms(2000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- print("Driving at 2 cm/s (expecting approx 11.2 rpm)")
- alvik.drive(2, 0, linear_unit='cm/s')
- sleep_ms(2000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- print("Driving at 1 in/s (expecting approx 14 rpm)")
- alvik.drive(1, 0, linear_unit='in/s')
- sleep_ms(2000)
- print(f"Current speed is {alvik.get_wheels_speed()} rpm")
-
- print("Driving at 5 mm/s (expecting approx 5.6 rpm) pi/8 rad/s (22.5 deg/s)")
- alvik.drive(5, 3.1415/8, linear_unit='mm/s', angular_unit='rad/s')
- sleep_ms(2000)
- print(f"Current speed is {alvik.get_drive_speed()} (mm/s) (rpm)")
-
- print("Driving at 5 mm/s (expecting approx 5.6 rpm) 1/8 rev/s (45 deg/s)")
- alvik.drive(5, 1/8, linear_unit='mm/s', angular_unit='rev/s')
- sleep_ms(2000)
- print(f"Current speed is {alvik.get_drive_speed()} (mm/s) (rpm)")
-
- alvik.stop()
- sys.exit()
-
- except KeyboardInterrupt as e:
- print('over')
- alvik.stop()
- sys.exit()
+try:
+
+ # -- LINEAR MOVEMENTS --
+
+ print("Move fw 0.05 m")
+ alvik.move(0.05, unit='m')
+ sleep_ms(2000)
+
+ print("Move fw 10 cm")
+ alvik.move(5, unit='cm')
+ sleep_ms(2000)
+
+ print("Move bw 100 mm")
+ alvik.move(-100, unit='mm')
+ sleep_ms(2000)
+
+ print("Move fw 1 inch")
+ alvik.move(1, unit='in')
+ sleep_ms(2000)
+
+ print(f"Current position: {alvik.get_pose()}")
+ alvik.reset_pose(0, 0, theta=3.1415, angle_unit='rad')
+ sleep_ms(2000)
+
+ print(f"Current position: {alvik.get_pose()}")
+
+ # -- WHEEL ROTATIONS --
+ alvik.right_wheel.reset()
+ sleep_ms(2000)
+ curr_pos = alvik.right_wheel.get_position()
+ print(f'R wheel pos: {curr_pos}')
+ sleep_ms(2000)
+
+ print("Rotate right wheel 25% fw")
+ alvik.right_wheel.set_position(25, unit='%')
+ sleep_ms(2000)
+ curr_pos = alvik.right_wheel.get_position()
+ print(f'R wheel pos: {curr_pos}')
+
+ print("Rotate right wheel 90 deg bw")
+ alvik.right_wheel.set_position(-90, unit='deg')
+ sleep_ms(2000)
+ curr_pos = alvik.right_wheel.get_position()
+ print(f'R wheel pos: {curr_pos}')
+
+ print("Rotate right wheel pi rad fw")
+ alvik.right_wheel.set_position(3.14, unit='rad')
+ sleep_ms(2000)
+ curr_pos = alvik.right_wheel.get_position()
+ print(f'R wheel pos: {curr_pos}')
+
+ print("Rotate right wheel a quarter revolution bw")
+ alvik.right_wheel.set_position(-0.25, unit='rev')
+ sleep_ms(2000)
+ curr_pos = alvik.right_wheel.get_position()
+ print(f'R wheel pos: {curr_pos}')
+
+ # -- WHEELS SPEED --
+ print("Set speed 50% max_rpm (35.0 rpm)")
+ alvik.set_wheels_speed(50, 50, '%')
+ sleep_ms(1000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ print("Set speed 12 rpm (1 rev in 5 sec)")
+ alvik.set_wheels_speed(12, 12, 'rpm')
+ sleep_ms(1000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ print("Set speed -pi rad/s (1 back rev in 2 sec)")
+ alvik.set_wheels_speed(-3.1415, -3.1415, 'rad/s')
+ sleep_ms(1000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ print("Set speed 180 deg/s (1 back rev in 2 sec)")
+ alvik.set_wheels_speed(180, 180, 'deg/s')
+ sleep_ms(1000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ # -- DRIVE --
+ print("Driving at 10 mm/s (expecting approx 5.6 rpm 64 deg/s)")
+ alvik.drive(10, 20, linear_unit='mm/s', angular_unit='%')
+ sleep_ms(2000)
+ print(f"Current speed is {alvik.get_drive_speed()} (mm/s, deg/s))")
+
+ print("Driving at 10 mm/s (expecting approx 5.6 rpm)")
+ alvik.drive(10, 0, linear_unit='mm/s')
+ sleep_ms(2000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ print("Driving at 2 cm/s (expecting approx 11.2 rpm)")
+ alvik.drive(2, 0, linear_unit='cm/s')
+ sleep_ms(2000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ print("Driving at 1 in/s (expecting approx 14 rpm)")
+ alvik.drive(1, 0, linear_unit='in/s')
+ sleep_ms(2000)
+ print(f"Current speed is {alvik.get_wheels_speed()} rpm")
+
+ print("Driving at 5 mm/s (expecting approx 5.6 rpm) pi/8 rad/s (22.5 deg/s)")
+ alvik.drive(5, 3.1415/8, linear_unit='mm/s', angular_unit='rad/s')
+ sleep_ms(2000)
+ print(f"Current speed is {alvik.get_drive_speed()} (mm/s) (rpm)")
+
+ print("Driving at 5 mm/s (expecting approx 5.6 rpm) 1/8 rev/s (45 deg/s)")
+ alvik.drive(5, 1/8, linear_unit='mm/s', angular_unit='rev/s')
+ sleep_ms(2000)
+ print(f"Current speed is {alvik.get_drive_speed()} (mm/s) (rpm)")
+
+except KeyboardInterrupt as e:
+ print('Test interrupted')
+
+finally:
+ alvik.stop()
+ print('END of measurement units test')
diff --git a/examples/tests/test_version.py b/examples/tests/test_version.py
index 1682316..52c0660 100644
--- a/examples/tests/test_version.py
+++ b/examples/tests/test_version.py
@@ -1,6 +1,6 @@
from arduino_alvik import ArduinoAlvik
from time import sleep_ms
-import sys
+
alvik = ArduinoAlvik()
@@ -16,4 +16,4 @@
except KeyboardInterrupt as e:
print('over')
alvik.stop()
- sys.exit()
\ No newline at end of file
+ break
\ No newline at end of file
diff --git a/examples/update_firmware.py b/examples/update_firmware.py
new file mode 100644
index 0000000..96845fe
--- /dev/null
+++ b/examples/update_firmware.py
@@ -0,0 +1,8 @@
+from arduino_alvik import update_firmware
+
+# this is a patch to fix possible running threads on Alvik
+from arduino_alvik import ArduinoAlvik
+alvik = ArduinoAlvik()
+alvik.stop()
+
+update_firmware('/firmware.bin')
\ No newline at end of file
diff --git a/install.bat b/install.bat
index efbd576..f8a4830 100644
--- a/install.bat
+++ b/install.bat
@@ -30,6 +30,7 @@ python -m mpremote %port_string% fs cp arduino_alvik/uart.py :lib/arduino_alvik/
echo Installing dependencies
python -m mpremote %port_string% mip install github:arduino/ucPack-mpy
+python -m mpremote %port_string% mip install github:arduino/arduino-runtime-mpy
python -m mpremote %port_string% reset
exit /b 0
diff --git a/install.sh b/install.sh
index e606f57..837f7fd 100644
--- a/install.sh
+++ b/install.sh
@@ -55,5 +55,6 @@ $python_command -m mpremote $connect_string fs cp arduino_alvik/uart.py :lib/ard
echo "Installing dependencies"
$python_command -m mpremote $connect_string mip install github:arduino/ucPack-mpy
+$python_command -m mpremote $connect_string mip install github:arduino/arduino-runtime-mpy
$python_command -m mpremote $connect_string reset
diff --git a/package.json b/package.json
index 8c829cb..d09a258 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,8 @@
["arduino_alvik/stm32_flash.py", "github:arduino/arduino-alvik-mpy/arduino_alvik/stm32_flash.py"]
],
"deps": [
- ["github:arduino/ucPack-mpy", "0.1.6"]
+ ["github:arduino/ucPack-mpy", "0.1.7"],
+ ["github:arduino/arduino-runtime-mpy", "0.4.0"]
],
- "version": "1.1.0"
+ "version": "1.1.4"
}