Arduino ALVIK

Introducción

Introducción

Qué es Arduino Alvik

Es un robot con las siguientes características :

datasheet_connectors.png

prj-00-robot-illustration.webp
prj-00-components.webp
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Programas predefinidos

select-examples.gif

Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Introducción

Hola mundo

El lenguaje de programación que han elegido es de tipo CODIGO concretamente el lenguaje MICROPYTHON, de momento Arduino Alvik no esta disponible en programación con bloques. Al ser hardware libre, si se convierte popular, no es de extrañar que lo incorporen los diferentes programadores de entornos de lenguaje en bloques para ser más accesible a niveles educativos de primaria.

Tal y como dice la página https://docs.arduino.cc/micropython/ hay dos editores para cargar MicroPython en el Arduino Alvik

Nosotros en este curso elegimos Arduino Lab for Micropython por su sencillez y adaptación al Arduino Alvik

Una vez cargado el programa, apagamos Arduino Alvik

robot-on.webp
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Luego lo conectamos por cable

connecting-final.gif
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Lo encendemos

robot-on.webp
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

En el programa Arduino Lab for MicroPython ponemos este programa:

from time import sleep

print("Hola mundo, soy un robot que me gusta chatear, ¿cual es tu nombre? ")
student_name = input("Tu nombre : ")
print("Mucho gusto , " + student_name + "! ¿ Cómo quieres llamarme?")
robot_name = input("Mi nombre ? : ")

print(f"{robot_name} es un fantástico nombre. Ya me siento un poco más humano.")

sleep(2) # Use sleep() to make interaction feel more natural
print(f"Okay, {student_name}, voy a ponerte a prueba:")
sleep(2)
print("¿ Has oido hablar que puedo nadar ?")
sleep(4)
print("Je je, es broma..... :D")
sleep(5)

Adaptado de  https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Pulsamos a conectar, nos pregunta por el puerto

2024-06-14 23_20_41-Arduino Lab for MicroPython.png

Runeamos y vamos contestando a sus preguntas

2024-06-14 23_22_58-Arduino Lab for MicroPython.png

 

Introducción

Brush up MicroPython

Brush up = repasar, refrescar. Con esta página NO se quiere realizar un curso de MicroPython pues excede de los propósitos del curso, pero sí una visión rápida de las diferentes instrucciones que se dan en el curso.
Este repaso es inspirado en el tutorial MicroPython Basics autora Francesca Sanfilippo & Karl Söderby

Lo básico

Hemos visto la función print visualiza un mensaje en la cónsola :

print('Hola mundo !')

Podemos introducir una variable, frase que contenga el texto, la función time.sleep(segundos) que hace una pausa, (para utilizar esta función se necesita importar la librería time con import time ) y dentro de un bucle while que se ejecuta mientras sea verdadero lo que le sigue, en este caso while True se ejecutará siempre:

import time    
frase = "Hola mundo !!"
 
while True:
   print(frase)   
   time.sleep(1)

Aquí se utiliza

import time

frase = "Hola mundo "
contador = 0

def funcion_contar():
    global contador
    contador = contador + 1

while True:
    funcion_contar()
    print(frase, contador)
    time.sleep(1)

El resultado:

2024-06-15 07_32_00-Arduino Lab for MicroPython.png

Aquí utilizamos el condicional if  con su auxiliar  else y la función exit para acabar el programa:

import time

frase = "Hola mundo "
contador = 0
maximo = 20

def funcion_contar():
    global contador
    contador = contador + 1

while True:
    funcion_contar()
    if contador>20 :
      exit
    else :
      print(frase, contador)
      time.sleep(1)

Lo que provoca que a los 20 finalice 

2024-06-15 07_44_37-Arduino Lab for MicroPython.png

Podemos usar en vez de variables numéricas, variables tipo array para los bucles :

Catedu = ['Javier', 'Santiago', 'Silvia', 'Berta', 'Cristina', 'Nacho', 'Arturo', 'Chefo', 'Vladi', 'Ruben', 'Pablo', 'JuanFran']

def printCatedus():
    for persona in Catedu:
        print(persona)

printCatedus()

2024-06-15 07_51_00-Arduino Lab for MicroPython.png


Introducción

Arduino Alvik API

Para acceder a las funciones de Arduino Alvik API tenemos que ejecutar las instrucciones:

alvik = ArduinoAlvik()
alvik.begin()

Entonces ya podemos usar las siguientes:

FUNCION con sus Inputs Outputs
stop() para todas las funciones Alvik
is_on() true si esta encendido
false si esta apagado
is_target_reached() true si ha enviado M o R en el mensaje
get_ack() last_ack: el valor del último mensaje
stop() para todas las funciones Alvik
get_orientation() r: valor de balanceo p: valor de cabeceo y: valor de guiñada

get_accelerations()

 

ver uso en
https://libros.catedu.es/books/arduino-alvik/page/programas-de-ejemplo

ax
ay
az

get_gyros()

ver uso en
https://libros.catedu.es/books/arduino-alvik/page/programas-de-ejemplo

 

gx
by
gz
get_imu() las 6 anteriores
get_line_sensors()

left
center

right

brake() Frena el robot
get_battery_charge() battery_soc: el % de la batería
get_touch_any() touch_any es true si se ha apretado cualquier botón
get_touch_ok()
get_touch_cancel() 
get_touch_center()
get_touch_up()
get_touch_left()
get_touch_down()
get_touch_right()
touch_ok es true si se ha apretado ok

etc...
get_color_raw()
get_color_label()
color
get_version()
print_status()

versión del firmware
para actualizarlo ver https://docs.arduino.cc/tutorials/alvik/user-manual/#how-to-upload-firmware

 

set_behaviour(behaviour: int)
rotate(angle: float, unit: str = 'deg', blocking: bool = True)
move(distance: float, unit: str = 'cm', blocking: bool = True)
get_wheels_speed(unit: str = 'rpm') left_wheel_speed: the speed value
right_wheel_speed: the speed value
set_wheels_speed(left_speed: float, right_speed: float, unit: str = 'rpm')
set_wheels_position(left_angle: float, right_angle: float, unit: str = 'deg')
get_wheels_position(unit: str = 'deg') angular_velocity
drive(linear_velocity: float, angular_velocity: float, linear_unit: str = 'cm/s',angular_unit: str = 'deg/s')
get_drive_speed(linear_unit: str = 'cm/s', angular_unit: str = 'deg/s') linear_velocity: speed of the robot.
angular_velocity: speed of the wheels.
reset_pose(x: float, y: float, theta: float, distance_unit: str = 'cm', angle_unit: str = 'deg')
get_pose(distance_unit: str = 'cm', angle_unit: str = 'deg') x
y
theta
set_servo_positions(a_position: int, b_position: int)
set_builtin_led(value: bool)
set_illuminator(value: bool)
color_calibration(background: str = 'white')

rgb2hsv(r: float, g: float, b: float)

h: hue value
s: saturation value
v: brightness value

get_color(color_format: str = 'rgb')

r or h
g or s
b or v

hsv2label(h, s, v)

color label: like "BLACK" or "GREEN", if possible, otherwise return "UNDEFINED"

get_distance(unit: str = 'cm')

lee la distancia del sensor TOF:
ver ejemplo en https://libros.catedu.es/books/arduino-alvik/page/evita-obstaculos

left_tof: 45° to the left object distance
center_left_tof: 22° to the left object distance
center_tof: center object distance
center_right_tof: 22° to the right object distance
right_tof: 45° to the right object distance

get_distance_top(unit: str = 'cm')

top_tof: 45° to the top object distance

get_distance_bottom(unit: str = 'cm')

bottom_tof: 45° to the bottom object distance

on_touch_ok_pressed(callback: callable, args: tuple = ())

on_touch_cancel_pressed(callback: callable, args: tuple = ())

on_touch_center_pressed(callback: callable, args: tuple = ())

on_touch_up_pressed(callback: callable, args: tuple = ())

on_touch_left_pressed(callback: callable, args: tuple = ())

on_touch_down_pressed(callback: callable, args: tuple = ())

on_touch_right_pressed(callback: callable, args: tuple = ())




Unidades

¿Qué es eso de bloking?
Por ejemplo en rotate(angle: float, unit: str = 'deg', blocking: bool = True)

Si es true, todos los eventos no influyen, es decir el microprocesador esta centrado en esa instrucción
Si es falso, el microprocesador es libre de hacer otra cosa a la vez

Utiliza true si quieres precisión o no quieres que nada interaccione con la acción que estas ejecutando

Programas

Programas

Parpadeo leds

El programa
from arduino_alvik import ArduinoAlvik
from time import sleep
import sys

alvik = ArduinoAlvik()
alvik.begin()
sleep(5)

while True:
  alvik.left_led.set_color(1, 0, 0)
  alvik.right_led.set_color(1, 0, 0)
  sleep(1)
  alvik.left_led.set_color(0, 0, 0)
  alvik.right_led.set_color(0, 0, 0)
  sleep(1)

Origen: https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Resultado

Programas

Danza

Programa
from arduino_alvik import ArduinoAlvik
from time import sleep
import sys

alvik = ArduinoAlvik()
alvik.begin()
sleep(5)

while True:
  #Drive forward
  alvik.set_wheels_speed(10,10)
  sleep(2)
  #Turn left
  alvik.set_wheels_speed(0,20)
  sleep(2)
  #Turn right
  alvik.set_wheels_speed(20,0)
  sleep(2)
  #Drive backwards
  alvik.set_wheels_speed(-10,-10)
  sleep(2)

De https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/

Vídeo

Más caña

La instrucción  alvik.set_wheels_speed(0,20) significa que da 0 rpm a la rueda izquierda y 20rpm a la derecha, donde rpm significa revoluciones por minuto ¿y si multiplicamos todos los rpm por 10?

 

Programas

Control con la mano

Aquí trataremos de hacer que ALVIK responda a la posición de nuestra mano a través de el sensor ultrasonidos que tiene en frente suyo. Tendrá que intentar permanecer en una distancia intermedia con lo que tiene enfrente suyo.

 

image.png

 

from arduino_alvik import ArduinoAlvik
from time import sleep
import sys

alvik = ArduinoAlvik()
alvik.begin()
sleep(5)

#ESTABLECER VELOCIDAD

speed = 30

#IMPRIMIR VALORES Y ESTABLECER VARIABLES
while True:
    try:
        center = alvik.get_distance_top()
        print(center)
        sleep(0.01)

        #Si la mano esta cerca, Alvik se va hacia atras
        if center <= 12:
            alvik.set_wheels_speed(-speed, -speed)
        #Si la mano esta lejos, Alvik se acerca
        elif center <= 30 and center >= 18:
            alvik.set_wheels_speed(speed, speed)
        #Si la mano esta en una distancia de 12-18, Alvik se queda quieto
        else:
            alvik.set_wheels_speed(0, 0)

  #INTERRUPCIÓN DEL USUARIO
    except KeyboardInterrupt as e:
        print('over')
        alvik.stop()
        sys.exit()

 

Programas

Sigue líneas

Vamos a crear un programa SIGUE LÍNEAS. El objetivo es que el robot ALVIK sea capaz de seguir cualquier trazado de líneas utilizando sus sensores IR

image.png

Para poder conseguirlo simplemente tendremos que establecer distintas condiciones de que hacer dependiendo de que sensor del robot detecta el trazado negro.

En este programa también hemos hecho que el robot nos trasmita los valores de los distintos sensores y que el usuario pueda interrumpir el proceso (todo suponiendo que el robot está conectado al equipo).

from arduino_alvik import ArduinoAlvik
from time import sleep
import sys

alvik = ArduinoAlvik()
alvik.begin()
sleep(5)

#VELOCIDAD DEL ROBOT
base_speed = 30

#IMPRIMIR VALORES DE LOS SENSORES
while True:
    try:
        ir_left, ir_center, ir_right = alvik.get_line_sensors()
        print(ir_left, ir_center, ir_right)
        sleep(0.01)
        
        #Condiciones de giro, avance y parar
        if ir_center > 300:
            alvik.set_wheels_speed(base_speed, base_speed)
        elif ir_left > 300:
            alvik.set_wheels_speed(0, base_speed)
        elif ir_right > 300:
            alvik.set_wheels_speed(base_speed, 0)
        else:
            alvik.set_wheels_speed(0, 0)
          
  #INTERRUPCION DEL USUARIO
    except KeyboardInterrupt as e:
        print('over')
        alvik.stop()
        sys.exit()

Programas

Evita obstáculos

Programa

El núcleo del programa es la función api

get_distance(unit: str = 'cm')

Es sorprendente el sensor TOF como puede leer no sólo diréctamente sino a los lados :

El programa es extraido de https://docs.arduino.cc/tutorials/alvik/getting-started/ AuthorJose Garcia

from arduino_alvik import ArduinoAlvik
from time import sleep_ms
import sys

alvik = ArduinoAlvik()
alvik.begin()
sleep_ms(5000)  # waiting for the robot to setup
distance = 20
degrees = 45.00
speed = 50.00

while (True):

    distance_l, distance_cl, distance_c, distance_r, distance_cr  = alvik.get_distance()
    sleep_ms(50)
    print(distance_c)

    if distance_c < distance:
        alvik.rotate(degrees, 'deg')
    elif distance_cl < distance:
        alvik.rotate(degrees, 'deg')
    elif distance_cr < distance:
        alvik.rotate(degrees, 'deg')
    elif distance_l < distance:
        alvik.rotate(degrees, 'deg')
    elif distance_r < distance:
        alvik.rotate(degrees, 'deg')
    else:
        alvik.drive(speed, 0.0, linear_unit='cm/s')
Resultado

Programas

Programas de test

En el repositorio https://github.com/arduino/arduino-alvik-mpy/tree/main/examples podemos encontrar ejemplos para ver el uso de los diferentes sensores y actuadores, por ejemplo

Sensor name Part name Test program name
RGB Color detection APDS 9660 read_color_sensor.py
ToF 8x8 Array - up to 350 cm LSM6DSOX read_tof.py
IMU - 6 degree VL53L7CX read_imu.py
3x Line follower custom made line_follower.py
7x Touch sensor AT42QT2120 read_touch.py
Actuator name Part name Test program name
Geared motors w/ encoder GM12-N20VA-08255-150-EN wheels_positions.py
RGB LEDs RGB LEDs leds_settings.py
Detector de color

Modificación del read_color_sensor.py

from arduino_alvik import ArduinoAlvik
from time import sleep_ms
import sys

alvik = ArduinoAlvik()
alvik.begin()

while True:
    try:
        r, g, b = alvik.get_color()
        h, s, v = alvik.get_color('hsv')
        print(f'RED: {r}, Green: {g}, Blue: {b}, HUE: {h}, SAT: {s}, VAL: {v}')
        print(f'COLOR LABEL:')
        print ({alvik.get_color_label()})
        sleep_ms(1000)
    except KeyboardInterrupt as e:
        print('over')
        alvik.stop()
        sys.exit()

Detector TOF

Si ejecutamos read_tof.py

from arduino_alvik import ArduinoAlvik
from time import sleep_ms
import sys

alvik = ArduinoAlvik()
alvik.begin()

while True:
    try:
        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)
    except KeyboardInterrupt as e:
        print('over')
        alvik.stop()
        sys.exit()

Detecta hasta los obstáculos por arriba

Giro

Si ejecutamos read_imu.py

from arduino_alvik import ArduinoAlvik
from time import sleep_ms
import sys

alvik = ArduinoAlvik()
alvik.begin()

while True:
    try:
        ax, ay, az = alvik.get_accelerations()
        gx, gy, gz = alvik.get_gyros()
        print(f'ax: {ax}, ay: {ay}, az: {az}, gx: {gx}, gy: {gy}, gz: {gz}')
        sleep_ms(100)
    except KeyboardInterrupt as e:
        print('over')
        alvik.stop()
        sys.exit()

Vemos como el eje x cambia de -1  0  a 1 según la posición

Programas

Robótica para infantil

Se puede hacer un robot tipo Beebot, Colby, Escornabot.
Si no conocéis estos robots mirar el curso de Aularagon

bee-bot-2591033446.jpgescornabot-4126551417.jpg

Podemos cargar el siguiente programa, modificado de https://github.com/arduino/arduino-alvik-mpy/blob/main/examples/touch_move.py

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)

distancia = 15

movements = []


def blink():
    alvik.left_led.set_color(1, 0, 1)
    alvik.right_led.set_color(1, 0, 1)
    sleep_ms(200)
    alvik.left_led.set_color(1, 0, 0)
    alvik.right_led.set_color(1, 0, 0)


def add_movement():
    global movements

    if alvik.get_touch_up():
        movements.append('forward')
        blink()
        while alvik.get_touch_up():
            sleep_ms(100)
    if alvik.get_touch_down():
        movements.append('backward')
        blink()
        while alvik.get_touch_down():
            sleep_ms(100)
    if alvik.get_touch_left():
        movements.append('left')
        blink()
        while alvik.get_touch_left():
            sleep_ms(100)
    if alvik.get_touch_right():
        movements.append('right')
        blink()
        while alvik.get_touch_right():
            sleep_ms(100)
    if alvik.get_touch_cancel():
        movements = []
        for i in range(0, 3):
            val = i % 2
            alvik.left_led.set_color(val, 0, 0)
            alvik.right_led.set_color(val, 0, 0)
            sleep_ms(200)
        while alvik.get_touch_cancel():
            sleep_ms(100)


def run_movement(movement):
    if movement == 'forward':
        alvik.move(distancia, blocking=False)
    if movement == 'backward':
        alvik.move(-distancia, blocking=False)
    if movement == 'left':
        alvik.rotate(90, blocking=False)
    if movement == 'right':
        alvik.rotate(-90, blocking=False)
    while not alvik.get_touch_cancel() and not alvik.is_target_reached():
        alvik.left_led.set_color(1, 0, 0)
        alvik.right_led.set_color(1, 0, 0)
        sleep_ms(100)
        alvik.left_led.set_color(0, 0, 0)
        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)

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

        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()

El resultado es que perfectamente se puede usar como robótica en infantil
Los robots Beebot, Colby, Escornabot. utilizan la distancia de 15cm de desplazamiento, justo lo mismo que los palos depresores de lengua, luego fácilmente uno puede hacer un circuito :

Créditos

Autor:

Cualquier observación o detección de error en soporte.catedu.es

Los contenidos se distribuyen bajo licencia Creative Commons tipo BY-NC-SA excepto en los párrafos que se indique lo contrario.

image-1648462225402.gif

image-1648462299882.png

image-1648462361893.png