Arduino ALVIK
- Introducción
- Micropython
- Preparar ALVIK para MicroPython: Actualizar el firmware de Alvik
- Instalar Micropython
- Hola mundo
- Empezando MicroPython de Alvik
- Introducción al Python
- Arduino Alvik API
- MicroPython sin IoT
- GPIO del ESP32
- Parpadeo LED ESP32
- Parpadeo leds Alvik
- Danza
- Control con la mano
- Sigue líneas
- Evita obstáculos
- Programas de test
- Robótica para infantil
- Manejando servos
- Más ejemplos
- I2C
- MicroPython con IoT
- ¿Qué es Internet de las cosas IoT?
- Conectar a Wifi
- Crear bot en Telegram
- Encontrar tu ID en Telegram
- Mensajes a Telegram
- Pin pong Telegram
- Recepción mensajes Telegram
- Programando en bloques mBlock
- Preparar el ALVIK para mBlock: Actualizar el firmware de Alvik
- Instalando mBlock
- Instalando la extensión ALVIK en mBlock
- Dos formas de programar en mBlock
- Un ejemplo de programa en vivo
- Un ejemplo de programa en carga
- Otro ejemplo de programa en carga : Evita obstáculos
- Métodos para interactuar los objetos y el robot (dispositivo)
- Un ejemplo interactuando con un objeto
- Arduino IDE
- ¿Qué es Arduino IDE?
- Preparar Arduino IDE para Alvik: Instalar Placa ESP32 y libreria Arduino Avik
- Preparar ALVIK para Arduino IDE: Modo Bootloader
- Arduino IDE sin IoT: Un pequeña danza
- Arduino IDE sin IoT: Evita obstáculos
- Arduino IDE sin IoT: Coche a control remoto
- Internet de las cosas IoT
- Arduino IDE con IoT: Escaneo Wifi
- Arduino IDE con IoT: Arduino Cloud
- Arduino IDE con IoT: Coche teledirigido
- GPIO del ESP32
- Arduino IDE con IoT: ESP32 + Sensores externos + IoT
- Predictor meteorológico
- Créditos
Introducción
Qué es Arduino Alvik
SOFTWARE
Tienes dos opciones para programar Arduino Alvik :
- OPCIÓN A con el firmware https://alvikupdate.arduino.cc/
- LENGUAJE CÓDIGO MICROPYTHON
- LENGUAJE EN BLOQUES GRÁFICO mBlock que trabaja con Python
- OPCIÓN B reseteando bootloader
- LENGUAJE CÓDIGO ARDUINO IDE que trabaja con lenguaje C
Utiliza ArduinoIDE si ya trabajas en el aula con este lenguaje, sino, te aconsejamos Micropyhon o mBlock
👁️👁️Cambiar de una opción a otra implica resetear el Bootloader.
🫵 Es mejor que te decidas qué opción quieres, opción A o B 🫵
HARDWARE
Es un robot con las siguientes características :
- Placa microcontroladora Las placas Arduino tradicionales tenían microcontroladores como el ATMEL MEGA 328P etc..ver micros que no estaban conectados a Internet. EL ARDUINO ALVIK LLEVA EL ESP32 un micro más potente, y con conexión Wifi y Bluetooth mira esta página del curso ESP32 de Aularagon
- Precio unos 130€
- Especificaciones técnicas
- La batería es una 18650, es la mejor, con la protección de no ser accesible, pues tiene sus peligros
- Sensores
- 7 Botones de contacto AT42QT2120
- 3 Sensores sigue líneas
- Acelerómetro
- Giroscopio de 6 ejes LSM6DSOX
- Sensor de color RGB APDS 9660
- Sensor de distancia TOF 8x8 arrray hasta 350cm VL53L7CX
- Actuadores
- 2 Leds RGB
- 2 motores
AMPLIACIONES
Dispone de las siguientes conexiones
- Conexiones de ampliación
- 2 conectores para servos
- 2 Conexión I2C
- 2 conexiones Grove
En este curso lo utilizaremos para unir un servo
Además tiene uniones compatibles con piezas de construcción LEGO
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
PROGRAMAS PREDEFINIDOS
Al arrancar ALVIK con el firmware que veremos en Python y mBlock da la posibilidad de ejecutar 3 programas predefinidos :
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
- Programa rojo: Tocando los botones, se mueve 10 cm delante atrás, giro...
- Programa verde: Sigue la mano
- Programa azul: Seguidor de líneas
CURIOSIDADES
A diferencia del típico sensor a distancia SR-04 que funciona por ultrasonidos, el VL53L7CX es mucho más complejo, va por luz (no realiza imágenes, sino por difracción de la luz por lo tanto respeta la privacidad) y nos proporciona muchas más información, la API que veremos nos da 5 distancias en distintas direcciones.
Pensamiento computacional
¿Dónde se sitúa el Arduino Alvik dentro de la oferta de robótica? Como puedes ver en esta presentación, se sitúa dentro de los robots que se programan con código por lo tanto para un perfil de secundaria pero también en bloques con mBlock igual que el mBot, luego también tiene un perfil de primaria de tercer ciclo.
Guía orientativa
Tenemos un grupo Telegram Robótica Educativa en Aragón, si estás interesado en unirte, envía un mensaje por Telegram (obligatorio) a CATEDU 623197587 https://t.me/catedu_es y te añadimos en el grupo
Micropython
Preparar ALVIK para MicroPython: Actualizar el firmware de Alvik
Actualizar el firmware significa que nuestro Alvik le instalamos el interpretador de micropython y por lo tanto podremos:
- Programar en código con Python
- Programar en bloques con mBlock
Si ya tiene el firmware instalado en el Alvik puedes saltarte esta página
Con este firmware no podemos programar con Arduino IDE
Antes de nada enciende el Alvik con esta precaución :
Primero nos aseguramos que el Alvik este APAGADO antes de conectarlo con el PC
en caso contrario se puede perjudicar la batería
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Luego lo conectamos por cable
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Y ahora ya podemos encender nuestro Alvik
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Actualizamos el FIRMWARE
Esto lo hacemos una vez, entramos en https://alvikupdate.arduino.cc/ damos a conectar y luego updated (si no sabes qué puerto es, desconecta y conecta y te fijas cual aparece)
Puede tardar varios ciclos, paciencia
Asegúrate de tener el ALVIK encendido
Hasta que sale esta pantalla de éxito
ATENCIÓN ¿Y SI DA PROBLEMAS?
Por ejemplo se ha quedado enganchado, lo has desconectado antes de hora... entonces la solución pasa por utilizar un flasheador más potente
MicroPython Installer
Descargamos el programa y ejecutamos teniendo conectado el ESP32 del Alvik, (no hace falta encender el robot, pues sólo trabajamos con el ESP32) lo detecta y simplemente le damos a Instalar Micropython dentro del chip
Descargable en https://labs.arduino.cc/en/labs/micropython-installer
Si sigue puñetero y no detecta el Arduino Nano ESP32 tendrás que ponerlo en modo Bootoloader, haz los pasos 1, 2 y 3 de https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader y vuelve a intentarlo con el MicroPython Installer
Al acabar de instalar, sale este mensaje :
Aconsejamos apagar y desconectar totalmente y volver a conectar (acuérdate que no hay que conectar el ALVIK en el PC con el ALVIK encendido, lo conectas con el PC apagado y luego lo enciendes, tal y como dice arriba del todo)
Entramos en https://alvikupdate.arduino.cc/ damos a conectar y luego updated (si no sabes qué puerto es, desconecta y conecta y te fijas cual aparece)
AQUÍ VA A TARDAR VARIOS, VARIOS CICLOS, paciencia, paciencia
Asegúrate de tener el ALVIK encendido
Hasta que sale esta pantalla de éxito
Instalar Micropython
Conceptos previos:
- Los lenguajes de alto nivel, es decir el código, que es entendible por los humanos (C++, Java, Python...) son textos que se tienen que traducir al lenguaje entendible por el procesador MCU (Micro Controler Unit). Este lenguaje de bajo nivel que está escrito en binario es difícil de entender para los humanos
- El Compilador es un programa que Interpreta este texto de lenguaje de alto nivel, y lo convierte en lenguaje de bajo nivel
- El Arduino Alvik se puede programar con Arduino IDE como con Micropytno, los dos son de alto nivel
Tanto Micropython como Arduino IDE son lenguajes de tipo CODIGO por lo tanto sólo se aconseja EN SECUNDARIA
Cuando permita lenguaje tipo BLOQUES como Scratch, ya será adecuado para PRIMARIA
¿Dónde se compila Micropython?
Como puedes ver en este vídeo en 21:20 Python se compila dentro del microcontrolador es decir, dentro del ESP32. A diferencia con otros lenguajes, como el C++, el ordenador tiene el compilador, y se lo da ya en binario.
Fuente vídeo Exploring the Arduino Nano ESP32 | MicroPython & IoT
¿Y a mi qué más me da?
Pues sí que importa....
Si programas ESP32 con Arduino IDE o Arduino Cloud (que está basado en C++) te has cargado el compilador Python que has puesto en "Actualizar firmware" del ESP32 luego si quieres programar en Python, tienes que volver a "Actualizar firmware"
¿Y con esto ya puedo crear mis programas con Micropython?
No, con esto tienes el compilador interpretador dentro del chip, pero necesitas un editor en tu PC y que se comunique con el Micropython del chip
Arduino Lab for Micropython
Tal y como dice la página https://docs.arduino.cc/micropython/ hay dos editores para cargar MicroPython en el Arduino Alvik
- Arduino Lab for Micropython https://labs.arduino.cc/en/labs/micropython
- OpenMW https://openmv.io/pages/download
Nosotros en este curso elegimos Arduino Lab for Micropython por su sencillez y adaptación al Arduino Alvik
Tal y como dice aquí ES UN PROGRAMA PORTABLE, es decir, no hay que instalarlo, simplemente descomprimir y ejecutar
Ejecutamos el programa en el lugar donde lo hemos descomprimido (o donde quieras llevarte la carpeta) :
Primero nos aseguramos que el Alvik este APAGADO antes de conectarlo con el PC
en caso contrario se puede perjudicar la batería
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Luego lo conectamos por cable
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Y ahora ya podemos encender nuestro Alvik
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Al ejecutar el programa, vemos:
- Botón para conectar la placa
- Ejecutar o para el programa
- Gestor de fichero
- Donde escribimos el programa
- Ventana de estado
Licencia CC-BYSA Fuente https://docs.arduino.cc/micropython/environment/code-editor/
En el gestor de ficheros encontramos
- Los archivos que hay en la placa: Puedes ver y administrar scripts o datos guardados directamente en la placa.
- Los archivos que hay en tu equipo: lo que le permite seleccionar y administrar archivos para cargar o descargar.
- Descargar/Subir archivos: Utiliza esta opción para transferir archivos entre su equipo y la placa. Puedea cargar nuevos scripts o descargar registros de datos de su placa.
- Crear archivo/carpeta: Esta opción le permite crear nuevos archivos o carpetas directamente en la placa o en el directorio de su proyecto, lo que facilita la organización de su código y recursos.
Licencia CC-BYSA Fuente https://docs.arduino.cc/micropython/environment/code-editor/
Hola mundo
Vamos a comenzar con nuestro primer programa en Arduino Lab for MicroPython, el clásico Hola mundo 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
Runeamos y vamos contestando a sus preguntas
Empezando MicroPython de Alvik
Inspirado en el esquema del tutorial MicroPython Basics autora Francesca Sanfilippo & Karl Söderby
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
- una función con def una variable contador que en la función se declara global de esta manera se puede utilizar dentro de cualquier función del programa (en este caso el programa principal la funcion_contar().
- Vemos la típica operación de cuenta contador = contador + 1
- print visualiza dos cosas, la frase y el contador
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:
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
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()
Con esto ya podemos avanzar, pero si quieres
Introducción al Python
Esta es una muy breve introducción al Python como recordatorio de algunas instrucciones si ya has utilizado este lenguaje.
Si es la primera vez, te recomendamos que visites nuestro curso PYTHON PARA TODOS Python for everybody por Charles R. Severance licencia CC-BY-NCSA que empieza desde cero.
Lenguajes, intérpretes y compiladores
Python es un lenguaje de alto nivel destinado a ser relativamente sencillo para que los humanos lean y escriban y para que los ordenadores lean y procesen. Otros lenguajes de alto nivel incluyen Java, C ++, PHP, Ruby, Basic, Perl, JavaScript y muchos más. El hardware real dentro de la Unidad Central de Procesamiento (CPU) no comprende ninguno de estos lenguajes de alto nivel.
La CPU entiende un idioma que llamamos lenguaje de máquina. El lenguaje de máquina es muy simple y francamente muy tedioso de escribir porque está representado en ceros y unos:
El lenguaje de máquina parece bastante simple en la superficie, dado que solo hay ceros y unos, pero su sintaxis es aún más compleja y mucho más compleja que Python. Muy pocos programadores escriben lenguaje de máquina. En su lugar, creamos varios traductores para permitir que los programadores escriban en lenguajes de alto nivel como Python o JavaScript y estos traductores convierten los programas al lenguaje de máquina para su ejecución real por parte de la CPU.
Estos traductores de lenguaje de programación se dividen en dos categorías generales: (1) intérpretes y (2) compiladores.
Un intérprete lee el código fuente del programa como está escrito por el programador, analiza el código fuente e interpreta las instrucciones sobre la marcha. Python es un intérprete y cuando ejecutamos Python de forma interactiva, podemos escribir una línea de Python (una oración) y Python la procesa de inmediato y está lista para que escribamos otra línea de Python.
>>> x = 6
>>> print(x)
6
>>> y = x * 7
>>> print(y)
42
>>>
Está en la naturaleza de un intérprete poder tener una conversación interactiva como se muestra arriba. A un compilador debemos entregarle todo el programa en un archivo, y luego ejecuta un proceso para traducir el código fuente de alto nivel al lenguaje de máquina y luego el compilador coloca el lenguaje de máquina resultante en un archivo para su posterior ejecución.
Variables
Las variables son como cajas que puedes meter valores. Y los valores pueden ser de varios tipos :
- int si son enteros
- float si tienen decimales
- binarioDeben comenzar por 0b. Por ejemplo: 0b110, 0b11
- string son frases, son "cadenas" de caracteres entre "
- bool Solamente hay dos literales booleanos True o False
- lista Se pueden declarar variables que son conjuntos por ejemplo Colores = ["verde", "rojo", "naranja" ]
Para crear una variable puedes usar cualquier palabra, x, y, z o Nombre_alumno ... pero algunas palabras no puedes usar, ver
Para visualizar variables puedes usar la instrucción print poniendo entre paréntesis el valor o variable que quieres visualizar.
En la siguiente ventana puedes dar al botón play y ver el resultado
Modifica los valores como quieras, es un intérprete, juega y dale al play para ver el resultado
Como puedes ver se ha introducido un operador el + que realiza la suma del valor de x original (43) y se le incrementa una unidad resultando en la impresión un 44.
Cadenas
Cadenas son secuencias de caracteres, por ejemplo la palabra "banana"
fuente 'Python for Everybody' por Charles R. Severance
Se puede obtener su longitud con la función len, o obtener un carácter ...
Operadores
Este apartado de operadores es adaptado de Federico Coca Guia de Trabajo de Microbit CC-BY-SA
Los operadores aritméticos se utilizan para realizar operaciones matemáticas como sumas, restas, multiplicaciones, etc.
Operador | Descripción | Ejemplo |
---|---|---|
+ | Suma o concatenación en textos | 5+3=8 , "Hola" + "Mundo" = "Hola Mundo |
- | Diferencia | 6-3=3 |
* | Multiplicación | 3*3=9 |
/ | División | 6/2=3 |
// | Parte entera de un cociente | 10//3=3 |
% | Resto de un cociente | 10%3=1 |
** | Potenciación | 5**2=25 |
Los operadores de asignación se utilizan para asignar valores a variables.
Operador | Descripción | Ejemplo |
---|---|---|
= | Asignación | x=4 , a = a + 1 |
+= | Suma y asignación | x+=1 equivale a x = x + 1 |
-= | Diferencia y asignación | x-=1 equivale a x = x - 1 |
*= | Multiplicación y asignación | x*=3 equivale a x = x * 3 |
/= | División y asignación | x/=3 equivale a x = x / 3 |
%= | Asignación de restos | x%=3 equivale a x = x % 3 |
**= | Asignación de exponentes | x**=3 equivale a x = x ** 3 |
Los operadores de comparación comparan dos valores/variables y devuelven un resultado booleano: Verdadero o Falso True
o False
.
Operador | Descripción | Ejemplo |
---|---|---|
== | Igual a | 2==3 retorna False |
!= | Distinto de | 2!=3 retorna True |
< | Menor que | 2<3 retorna True |
> | Mayor que | 2>3 retorna False |
<= | Menor o igual que | 2<=3 retorna True |
>= | Mayor o igual que | 2>=3 retorna False |
Los operadores lógicos se utilizan para comprobar si una expresión es Verdadera o Falsa. Se utilizan en la toma de decisiones.
Operador | Descripción | Ejemplo |
---|---|---|
and | AND lógica | a and b #True si a y b son ciertos |
or | OR lógica | a or b #True si a o b son ciertos |
not | NOT lógica | not a #True si el operador a es falso |
in | pertenencia | Devuelve True si pertenece |
no int | no pertenencia | Devuelve True si no pertenece |
is | identidad | Devuelve True si son iguales |
is not | no identidad | Devuelve True si no son inguales |
Los operadores bit a bit o bitwise actúan sobre los operandos como si fueran cadenas de dígitos binarios. Operan bit a bit:
Operador | Descripción | Ejemplo |
---|---|---|
& | AND bit a bit | 5&6 # 101 & 110 = 110 = 4 |
| | OR bit a bit | 5 \| 6 # 101 \| 110 = 111 = 7 |
~ | NOT bit a bit | ~3 # ~011 = 100 = -4 |
^ | XOR bit a bit | 5^3 # 101^011 = 110 = 6 |
<< | Desplazamiento izquierda | 4<<1 # 100 << 1 = 1000 = 8 |
>> | Desplazamiento derecha | 4 >> 1 # 100 >> 1 = 010 = 2 |
Prueba, juega con este código:
Comentarios en Python
Una sola línea : Escribiendo el símbolo almohadilla (#) delante del comentario.
Multilínea: Escribiendo triple comillas dobles (“””) al principio y al final del comentario.
Entradas de teclado
Ya hemos visto salidas por pantalla con print, pero ahora con input puede leer variables del teclado, esto es mejor experimentarlo que leerlo :
Fíjate que hay que poner las líneas x = float (x) e y = float(y) para convertirlos a números decimales, en caso contrario las interpreta string y no puede multiplicar en Resultado, pero en el siguiente ejemplo no es necesario en la variable cel (celsius) pues se multiplica por números decimales 32.0 5.0 y 9.0
try y except son dos funciones que son un seguro para el programador por si el usuario en vez de teclear un número, mete un string o carácter
La sangría es importante en Python
La sangría se refiere a los espacios al comienzo de una línea de código. Mientras que en otros lenguajes de programación la sangría en el código es solo para facilitar la lectura, la sangría en Python es muy importante ya que se usa para indicar un bloque de código.
Condicionales
Las instrucciones if: else: son las que nos permiten realizar operaciones según las condiciones puestas. Ojo con la sangría
\n es un carácter especial que significa "Salto de página"
Bucles
- while ejecuta lo contenido en la sangría mientras sea verdadero la condición
- for ejecuta lo contenido en la sangría mientras y va recorriendo la variable dentro del rango creado
Para verlo mejor vamos a ver estos ejemplos
- EJEMPLO BUCLE WHILE
- mientras n sea positivo va ejecutando : imprime n y lo decrementa
- al decrementar llega un momento que deja de ser positivo y finaliza el bucle
- EJEMPLO BUCLE WHILE INFINITO
- Es muy típico en robótica, todo el rato hace el bucle (en robótica para que lea los sensores y realice cosas en los actuadores) pero este ejemplo no esta en un robot sino en tu pc y no queremos que se quede "colgado" luego al teclear "fin" acaba gracias a la instrucción break
- Fíjate que hay una instrucción continue para que pase a la siguiente iteración provocando que no imprime lo tecleado
- EJEMPLO BUCLE FOR FRIENDS
- Va recorriendo la variable friend dentro del cojunto lista friends
- como puedes ver la diferencia entre for y while es que for además recorre la variable
- EJEMPLO BUCLE FOR
- mientras n este en el rango de 0 a 5 se ejecuta
Venga pruébalo !!!
Funciones
No vamos a entrar en detalle, pero observa el siguiente código
- FUNCIONES PREDEFINIDAS Si observas, la primera línea llama a importar una librería externa, import math donde math es un fichero que tienen funciones predefinidas, vamos a utilizar una de ellas, la raiz cuadrada sqrt luego para llamar a esa función que esta definida dentro de math se hace con la instrucción math.sqrt
- FUNCIONES DEFINIDAS POR TI em este caso, se utiliza la palabra def para crear una función, que le vamos a pasar tres argumentos a, b y c y para finalizar la función usamos return para devolver el valor que queremos obtener
Para saber más de Python
CURSO PYTHON FOR EVERYBODY en español | ver |
Curso completo de Python 222pag pdf (*) | Descargar |
Curso completo de Python 422pag (*) | Descargar |
Curso completo de Python desde 0 (*) | Ver |
Curso de Python desde 0 (*) | Ver |
Manual de referencia Python (*) | Ver |
Programación en Python (*) | Ver |
Trabajando con ficheros en Python (*) | Ver |
Programación orientada a objeto en Python (*) | Ver |
un manual para aquellos usuarios con previos conocimientos de Python, como la programación modular y orientada a objetos. También algunos conocimientos de las librerías tkinter (Para crear interfaces gráficos y SQlite3 (para gestionar bases de datos). (*) |
Descargar |
(*) Agradecimientos a Pere Manel http://peremanelv.com
Arduino Alvik API
Estas instrucciones son específicas del ARDUINO ALVIK
Para acceder a las funciones de Arduino Alvik API tenemos que ejecutar las instrucciones:
alvik = ArduinoAlvik()
alvik.begin()
Entonces ya podemos usar las siguientes: (extraido de https://docs.arduino.cc/tutorials/alvik/api-overview/ )
Luego veremos en el apartado de programación del Arduino Alvik con código Arduino IDE que utilizaremos una biblioteca #include "Arduino_Alvik.h" que importa prácticamente las mismas funciones, ver https://libros.catedu.es/books/arduino-alvik/page/programas-arduino-ide-sin-iot
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 |
ax ay az |
get_gyros()
|
gx by gz |
get_imu() | las 6 anteriores |
get_line_sensors() |
left 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...
ver ejemplos en https://libros.catedu.es/books/arduino-alvik/page/robotica-para-infantil y en https://libros.catedu.es/books/arduino-alvik/page/mensajes-a-telegram |
get_color_raw() get_color_label() |
color |
get_version() print_status() |
versión del 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 = ()) |
He intentado hacer programas con estas instrucciones, pero una vez pulsado la tecla, sigue llamando a callback continuamente
No veo su utilidad teniendo get_touch |
Unidades
- m: centimeters
mm: millimeters
m: meters
inch: inch, 2.54 cm
in: inch, 2.54 cm - deg: degrees, example: 1.0 as reference for the other unit. 1 degree is 1/360 of a circle.
rad: radiant, example: 1 radiant is 180/pi deg.
rev: revolution, example: 1 rev is 360 deg.
revolution: same as rev
perc: percentage, example 1 perc is 3.6 deg.
%: same as perc - 'cm/s': centimeters per second
'mm/s': millimeters per second
'm/s': meters per second
'inch/s': inch per second
'in/s': inch per second - 'rpm': revolutions per minute, example: 1.0 as reference for the other unit.
'deg/s': degrees per second, example: 1.0 deg/s is 60.0 deg/min that is 1/6 rpm.
'rad/s': radiant per second, example: 1.0 rad/s is 60.0 rad/min that is 9.55 rpm.
'rev/s': revolution per second, example: 1.0 rev/s is 60.0 rev/min that is 60.0 rpm.
¿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
MicroPython sin IoT
GPIO del ESP32
Mapa de los pines en el Arduino Nano ESP32
Extraído de Youtube Exploring the Arduino Nano ESP32
Como podemos observar, nuestro objetivo pues es el GPIO0
¿Dónde está físicamente los GPIO ?
Pues como podemos ver en este esquema el GPIO0 está en el pin BOOT1
Fuente CC-BY-SA https://docs.arduino.cc/tutorials/alvik/user-manual/
-
SI USAMOS MICROPYTHON TENEMOS QUE USAR LAS VERDES
-
SI USAMOS CÓDIGO ARDUINO IDE TENEMOS QUE USAR LAS ROJAS
Como puedes observar, si cortocircuitas B1 = GPI0 = D15 con GND enciende el led RGB en color verdel esto pasa si Pones la placa en modo Bootloader.
Parpadeo LED ESP32
Objetivo
Vamos a hacer que parpadee el RGB integrado que tiene el ESP32 concretamente el color verde.
Programa
#extraido de https://youtu.be/R51tf66es9w?t=1540
from machine import Pin
import time
myLED = Pin(0,Pin.OUT)
while True:
myLED.value(0)
time.sleep(0.5)
myLED.value(1)
time.sleep(0.5)
Aclaraciones
- Al hacer from machine import Pin estamos importanto las definiciones input output de los pines del ESP32 nano arduino
- Ya hemos visto que lo que nos interesa el el 0 y lo ponemos como OUT
¿Y si queremos que parpadee el RGB en color ROJO qué cambiamos?
Easy peasy, cambiamos myLED = Pin (0, Pin.OUT) por myLED = Pin (46, Pin.OUT)
Que como puedes ver coincide también con un pin de poner en modo Bootloader: el BOOT0
Curiosidad: Por eso si se resetea Arduino Alvik (al encender, o al hacer dos clicks en el botón) se encienden y se apagan varias veces el led RGB en colores rojo y verde, pues se están activando los BOOTs
¿Y si queremos que parpadee el led color VERDE que hay al lado del USB (LED BUILTIN) ? ¿Qué cambiamos?
Easy peasy, cambiamos myLED = Pin (0, Pin.OUT) por myLED = Pin (48, Pin.OUT)
Resultado:
Parpadeo leds Alvik
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: CC-BY-SA https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Resultado
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 CC-BY-SA 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?
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.
ESTE PROGRAMA ESTA POR DEFECTO (marcado con el led verde) cuando instalas el firmware). Ver https://libros.catedu.es/books/arduino-alvik/page/que-es-arduino-alvik
Fuente https://docs.arduino.cc/tutorials/alvik/getting-started/ AuthorJose Garcia CC-BY-SA
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()
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
Fuente https://docs.arduino.cc/tutorials/alvik/getting-started/ AuthorJose Gracia CC-BY-SA
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()
No va muy preciso, el código es mejorable:
- Si la raya es fina, no avanza
- Si la raya no es negra no avanza
- La velocidad 30 es baja
- El margen límite 300 es demasiado generoso que hace que pueda quedarse quieto por detectar todo blanco (ver el final del vídeo)
Más preciso (agradecimientos a Mario Monteagudo Alda CP Ejea)
from arduino import *
from arduino_alvik import ArduinoAlvik
alvik = ArduinoAlvik()
def setup():
alvik.begin()
delay(1000)
def loop():
global base, iteracion
iz, ce, de = alvik.get_line_sensors()
error = ((1*iz+2*ce+3*de)/(iz+ce+de))-2
if ((ce > 400) and (de > 400)):
alvik.left_led.set_color(1, 1, 0)
alvik.right_led.set_color(1, 1, 0)
base = 0
ajuste = 30
iteracion = 25
elif ((ce > 400) and (iz > 400)):
alvik.left_led.set_color(1, 1, 0)
alvik.right_led.set_color(1, 1, 0)
base = 0
ajuste = -30
iteracion = 25
elif (abs(error) < 0.75) and (iteracion == 0):
alvik.left_led.set_color(0, 0, 1)
alvik.right_led.set_color(0, 0, 1)
base = 60
ajuste = 25 * error + 40 * error * abs(error) + 80 * error * error * error
elif (abs(error) < 0.75):
alvik.left_led.set_color(0, 1, 0)
alvik.right_led.set_color(0, 1, 0)
base = 40
ajuste = 20 * error + 40 * error * abs(error) + 80 * error * error * error
iteracion = iteracion -1
elif error > 0:
alvik.left_led.set_color(1, 0, 0)
alvik.right_led.set_color(1, 0, 0)
base = 0
ajuste = 60
iteracion = 25
else:
alvik.left_led.set_color(1, 0, 0)
alvik.right_led.set_color(1, 0, 0)
base = 0
ajuste = -60
iteracion = 25
veIz = base + ajuste
veDe = base - ajuste
alvik.set_wheels_speed(veIz,veDe)
delay(50)
def cleanup():
alvik.stop()
base = 40
iteracion = 0
start(setup, loop, cleanup)
Autor Mario Monteagudo Alda CP Ejea
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 :
- 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
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
El código es mejorable, pues que rote 45 grados tantas veces puede hacer que se quede "enganchado" en una esquina, ver el final del vídeo:
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
Robótica para infantil
Se puede hacer un robot tipo Beebot, Colby, Escornabot.
Si no conocéis estos robots mirar el curso de Aularagon
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 :
Manejando servos
Conexión
Se pueden conectar hasta dos servos, el A es el de arriba y el B es el de abajo
La api set_servo_positions
Nos permite controlar estos dos servos indicando el primer argumento el ángulo (0-180) del A y en el segundo el del B set_servo_positions(a_position: int, b_position: int)
Programa
Extraído de https://docs.arduino.cc/tutorials/alvik/user-manual/#add-servo-motors
from arduino_alvik import ArduinoAlvik
import time
alvik = ArduinoAlvik()
alvik.begin()
while True:
alvik.set_servo_positions(0,0)
time.sleep(2)
alvik.set_servo_positions(90,180)
time.sleep(2)
alvik.set_servo_positions(180,90)
time.sleep(2)
alvik.set_servo_positions(90,0)
time.sleep(2)
Resultado
Más ejemplos
Los puedes encontrar en https://courses.arduino.cc/explore-robotics-micropython/
I2C
El protocolo I2C se desarrolló originalmente en 1982 para receptores de TV, y su característica principal son dos líneas (aparte de la alimentación 3.3V-5V y masa):
- SDA que son datos bidireccionales
- SCL que es la señal de reloj
Un dispositivo hace de Master y proporciona la señal de reloj. (Puede haber extraordinariamente más de un master) y los otros dispositivos, (en plural, con los mismos cables, aquí esta la ventaja) hacen de Slave y cada uno tiene asociado una dirección.
Ejemplos de I2C con Arduino:
- Conexión con pantalla LCD https://libros.catedu.es/books/programa-arduino-mediante-codigo/page/lcd
- Comunicación entre dos Arduinos https://dronebotworkshop.com/i2c-arduino-arduino/
En Arduino Alvik, los pines SDA y SCL están conectados en los pines 11 y 12 y de ahí salen por los conectores QWIIC y Grove :
Podemos escanear los dispositivos I2C que estén conectados y averiguar la dirección que tienen asociada :
from machine import I2C
from machine import Pin
i2c = I2C(0, scl=Pin(12, Pin.OUT), sda=Pin(11, Pin.OUT))
print()
print('Scan i2c bus...')
print()
devices = i2c.scan()
if len(devices) == 0:
print("No i2c device !")
else:
print('i2c devices found:',len(devices))
print()
for device in devices:
print("Decimal address: ",device," | Hexa address: ",hex(device))
print()
Fuente : https://docs.arduino.cc/tutorials/alvik/user-manual/#grove-connectors
He conectado un OLED en el conector Grove
Y me ha salido que tenía dos dispositivos, el primero es interno del Alvik, que tiene dirección 43 y el segundo es el OLED conectado con la dirección 60 en decimal o 0x3c en hexadecimal que es la dirección por defecto en el OLED ssd1306:
Si ejecutamos el siguiente script, vemos que necesita importar la librería ssd1306 (se puede ver en su repositorio, que es compatible con el display ssd1306 128x64 I2C y con ESP32 de Arduino).. Esta librería tiene las funciones necesarias para visualizar lo que uno quiera en el OLED. Funciones de esta librería
from machine import I2C
from machine import Pin
import ssd1306
i2c = I2C(0, scl=Pin(12, Pin.OUT), sda=Pin(11, Pin.OUT))
# dirección por defecto 0x3c
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
while True:
oled.text('HOLA CATEDU !', 10, 10)
oled.show()
Y el resultado es :
MicroPython con IoT
¿Qué es Internet de las cosas IoT?
El Internet de las cosas (Internet of Thing IoT) describe objetos físicos —o grupos de estos— con sensores, capacidad de procesamiento, software y otras tecnologías que se conectan e intercambian datos con otros dispositivos y sistemas a través de internet u otras redes de comunicación. El Internet de las cosas se ha considerado un término erróneo porque los dispositivos no necesitan estar conectados a la Internet pública. Sólo necesitan estar conectadas a una red y ser direccionables individualmente
Fuente Wikipedia IoT Internet de las cosas CC-BY-SA
De Drawed by Wilgengebroed on FlickrTranslated by Prades97 CC BY-SA 3.0
Estamos hablando de dispositivos que se conectan a internet de forma desatendida, por vía hardware (o mejor dicho firmware) a diferencia de un ordenador, tablet o móvil, donde tienes que configurar por software el dispositivo y hay un diálogo entre usuario y dispositivo sobre el uso de Internet (el software solicita tal página web, tales datos etc por voluntad del usuario o por diálogo con el usuario) Aquí los dispositivos están ya configurados de los datos que se comunican. Es decir "conectar y olvidar".
Piensa en la diferencia entre un enchufe inteligente y un ordenador, el primero es lo que se considera dentro de IoT
Las formas "desatendidas" son un avance en la sociedad pero también puede generar problemas muy serios a nivel mundial, ver el caso Mirai
Las cosas claras. ¿asíncrono o síncrono?
Hay muchas herramientas IoT
- Blynk: lo que nos gusta de esta herramienta es que es casi "instantánea" o "síncrona". Esto es imprescindible con ciertos robots como el Rover Marciano con Arduino. Necesitamos que "gire" para evitar un obstáculo, no podemos esperar !!!. Veremos con BLYNK un protocolo que entre el dispositivo electrónico (nuestro robot) y nosotros (en ordenador, en una APP en el móvil) la comunicación es instantánea, gracias a un servidor que hará de intermedio, que puede ser local (BLYNK LEGACY) o en Internet (BLYNK IoT).
- Blynk legacy es la que se va a trabajar en
- Blynk IoT es la que se va a trabajar con
- MQTT El emisor envía datos, se almacenan en un servidor, y cuando puede, lo vuelca al cliente. Cliente y emisor pueden ser el dispositivo electrónico y nosotros o viceversa. Veremos que esto es lo que hace el protocolo MQTT y está tremendamente extendido por lo barato y fácil que es. Hace que los servidores no estén tan ocupados, por lo tanto hay varios proveedores que ofrecen este servicio gratuitamente. Hay robots como los que tienen la placa TDR STEAM IMAGINA que envía datos de temperatura, humedad, .. y pueden recibir datos pero no precisan de esta exigencia instantánea como un rover.
- Arduino cloud IoT
- Cyberpi y mBot2
Conectar a Wifi
Para ello necesitamos importar la librería network, crear un objeto network que se conecta a la wifi :
import network
import urequests
WIFI_NETWORK='NOMBREREDWIFI' ## tu red wifi
WIFI_PASSWORD='CONTRASENA' ## la contraseña de la red wifi
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_NETWORK, WIFI_PASSWORD)
print("\nconectando.....")
if wlan.isconnected():
print("Alvik se conectó a",WIFI_NETWORK)
else :
print ("Alvik NO se conectó a",WIFI_NETWORK)
Tiene que salir este mensaje:
>>>
raw REPL; CTRL-B to exit
>OK
conectando.....
Alvik se conectó a NOMBREREDWIFI
>
Crear bot en Telegram
Entramos en nuestro Telegram y chateamos con el creador de los bots: @BotFather y nos saldrá esta pantalla:
Si tecleamos /start nos sale las diferentes opciones
Para crear un nuevo bot, tecleamos /newbot y nos preguntará el nombre del bot
Por cierto, el nombre tiene que acabar con las letras bot,
NOS PROPORCIONARÁ EL TOKEN DEL ROBOT, QUE TOMAREMOS NOTA
Si tecleamos /mybots nos sale los diferentes bots creados y al pulsar en uno de ellos nos salen sus opciones
Encontrar tu ID en Telegram
Buscar tu ID : chat privado
En este caso para que mi Bot me envié mensajes a mi usuario de Telegram directamente busco mi ID.
Vamos a chatear con @myidbot
y le preguntamos por nuestro identificador con /getid
TOMAMOS NOTA DE NUESTRO IDENTIFICADOR ID
Buscar ID de un grupo
En este caso tendríamos que añadir a @myidbot al grupo y ejecutar el comando en el chat del grupo /getgroupid saldrá un identificador negativo
Una vez conseguido el ID podemos eliminar @myidbot del grupo
Mensajes a Telegram
Una vez que tengamos el TOKEN y el ID lo ponemos en las líneas
telegramBot="MI_TOKEN" ## el Token que sale de @BotFather
telegramChatId="MI_ID" ## El ID del usuario de Telegram destinatario lo da @myidbot
y entones si ejecutamos la URL
https://api.telegram.org/botMI_TOKEN/sendMessage?chat_id=MI_ID&text=MENSAJE_QUE_QUIERA_ENVIAR
Entonces aparece en mi Telegram desde mi bot el mensaje
Con la librería urequest nos permite con la instrucción urequiest.get(url) nos permite ejecutar la llamada url
El siguiente programa envía por Telegram el botón que estemos pulsando en el Arduino Alvik :
from arduino_alvik import ArduinoAlvik
from time import sleep
import random
import sys
import network
import urequests
import time
alvik = ArduinoAlvik()
alvik.begin()
def enviarmensaje(mensaje):
url="https://api.telegram.org/bot"+telegramBot+"/sendMessage?chat_id="+telegramChatId+"&text="+mensaje
respuesta = urequests.get(url)
#print (type(respuesta))
WIFI_NETWORK='' ## tu red wifi
WIFI_PASSWORD='' ## la contraseña de la red wifi
telegramBot="" ## el Token que sale de @BotFather
telegramChatId="" ## El ID del usuario de Telegram destinatario lo da @myidbot
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(WIFI_NETWORK, WIFI_PASSWORD)
if wlan.isconnected():
print("Alvik se conectó a",WIFI_NETWORK)
else :
print ("Alvik NO se conectó a",WIFI_NETWORK)
while True:
if alvik.get_touch_any():
alvik.left_led.set_color(1, 0, 0)
alvik.right_led.set_color(1, 0, 0)
else:
alvik.left_led.set_color(0, 1, 0)
alvik.right_led.set_color(0, 1, 0)
if alvik.get_touch_up() :
enviarmensaje("arriba")
if alvik.get_touch_down():
enviarmensaje("abajo")
if alvik.get_touch_left() :
enviarmensaje("izquierda")
if alvik.get_touch_right() :
enviarmensaje("derecha")
time.sleep(1)
Resultado
Para saber más...
- Si en vez de hacerlo con Micropython lo quieres hacer con ArduinoIDE te recomiendo esta página
- Un ejemplo de como el Alvik va a la plaza del parking y cuando lo consigue envía un mensaje a Telegram
Pin pong Telegram
Como paso previo a enviar y recibir mensajes, vamos a realizar los pasos de este vídeo
https://www.youtube.com/watch?v=eZkb9omr-sA
Paso 1: Librería uTelegram.py
Del repositorio de Jordi Prats
https://github.com/jordiprats/micropython-utelegram/blob/master/utelegram.py
import time
import gc
import ujson
import urequests
class ubot:
def __init__(self, token, offset=0):
self.url = 'https://api.telegram.org/bot' + token
self.commands = {}
self.default_handler = None
self.message_offset = offset
self.sleep_btw_updates = 3
messages = self.read_messages()
if messages:
if self.message_offset==0:
self.message_offset = messages[-1]['update_id']
else:
for message in messages:
if message['update_id'] >= self.message_offset:
self.message_offset = message['update_id']
break
def send(self, chat_id, text):
data = {'chat_id': chat_id, 'text': text}
try:
headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
response = urequests.post(self.url + '/sendMessage', json=data, headers=headers)
response.close()
return True
except:
return False
def read_messages(self):
result = []
self.query_updates = {
'offset': self.message_offset + 1,
'limit': 1,
'timeout': 30,
'allowed_updates': ['message']}
try:
update_messages = urequests.post(self.url + '/getUpdates', json=self.query_updates).json()
if 'result' in update_messages:
for item in update_messages['result']:
result.append(item)
return result
except (ValueError):
return None
except (OSError):
print("OSError: request timed out")
return None
def listen(self):
while True:
self.read_once()
time.sleep(self.sleep_btw_updates)
gc.collect()
def read_once(self):
messages = self.read_messages()
if messages:
if self.message_offset==0:
self.message_offset = messages[-1]['update_id']
self.message_handler(messages[-1])
else:
for message in messages:
if message['update_id'] >= self.message_offset:
self.message_offset = message['update_id']
self.message_handler(message)
break
def register(self, command, handler):
self.commands[command] = handler
def set_default_handler(self, handler):
self.default_handler = handler
def set_sleep_btw_updates(self, sleep_time):
self.sleep_btw_updates = sleep_time
def message_handler(self, message):
if 'text' in message['message']:
parts = message['message']['text'].split(' ')
if parts[0] in self.commands:
self.commands[parts[0]](message)
else:
if self.default_handler:
self.default_handler(message)
Y la cargamos dentro de nuestro ESP32, ejecutamos Arduino Lab for MicroPython, conectamos, vamos al gestor de archivos y lo llevamos dentro del ESP32 Alvik
Paso 2 Archivo config.py
El archivo config.py no es más que el archivo que contiene la wifi y el token, se puede descargar de https://github.com/jordiprats/micropython-utelegram/blob/master/demo/config.py-demo o también se puede copiar y pegar de aquí mismo
wifi_config = {
'ssid':'DEMO',
'password':'PASSW0RD'
}
utelegram_config = {
'token': 'TOKEN'
}
Ponemos los valores de nuestra wifi SSID, PASSWORD y TOKEN y borramos del nombre el -demo y lo dejamos como config.py
y como antes, lo pasamos al ESP32 Alvik
Se podría poner esa información en el código del programa principal main.py tal y como el programa de la página https://libros.catedu.es/books/arduino-alvik/page/mensajes-a-telegram
Paso 3 Programa principal main.py
El programa lo podemos descargar de https://github.com/jordiprats/micropython-utelegram/blob/master/demo/main.py
o de aquí mismo
tal cual, no hay que poner nuestro ssid, ni password ni token pues lo "lee" de config.py
from config import utelegram_config
from config import wifi_config
import utelegram
import network
import utime
debug = True
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.scan()
sta_if.connect(wifi_config['ssid'], wifi_config['password'])
if debug: print('WAITING FOR NETWORK - sleep 20')
utime.sleep(20)
def get_message(message):
bot.send(message['message']['chat']['id'], message['message']['text'].upper())
def reply_ping(message):
print(message)
bot.send(message['message']['chat']['id'], 'pong')
if sta_if.isconnected():
bot = utelegram.ubot(utelegram_config['token'])
bot.register('/ping', reply_ping)
bot.set_default_handler(get_message)
print('BOT LISTENING')
bot.listen()
else:
print('NOT CONNECTED - aborting')
🤔No sé por qué hay que esperar 20 segundos en utime.sleep(20) 🤷♂️sospecho que necesita tiempo para estar preparado para "escuchar"
Y lo llevamos al ESP32
Ejecución
Pulsamos el main.py del ESP32 (no hace falta encender Alvik pues todas las instrucciones son sólo del ESP32), ESPERAR 20 SEGUNDOS hasta que aparezca BOT LISTENING
Nos vamos a Telegram al usuario del bot que hemos creado, le tecleamos /ping y contesta el ESP32 pong
Recepción mensajes Telegram
Podemos ahora enviar un mensaje a ArduinoAlvik y que ejecute un programa por ejemplo el evita obstáculos:
- Envía un mensaje por Telegram que está preparado
- Si le enviamos /go el contesta voy
- Ejecuta la rutina de evita obstáculos
from arduino_alvik import ArduinoAlvik #### IMPORTAMOS LAS FUNCIONES DE ALVIK
from config import utelegram_config
from config import wifi_config
##### AÑADIMOS LIBRERÍAS PARA LOS OBSTÁCULOS
from time import sleep_ms
import sys
import utelegram
import network
import utime
################ añadimos urequest para enviar mensajes con url
import urequests
alvik = ArduinoAlvik() #### CREAMOS UN OBJETO ALVIK
alvik.begin() #### LO INICIALIZAMOS
################# VARIABLES PARA EVITAR OBSTÁCULOS
distance = 10
degrees = 45.00
speed = 50.00
############################################################
debug = True
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.scan()
sta_if.connect(wifi_config['ssid'], wifi_config['password'])
if debug: print('WAITING FOR NETWORK - sleep 20')
utime.sleep(20)
########################################################################################
def get_message(message):
bot.send(message['message']['chat']['id'], message['message']['text'].upper())
############################################################################################
def enviarmensaje(mensaje): ###FUNCION ENVIAR MENSAJE CON URL ojo cambiar PONAQUITUID
url="https://api.telegram.org/bot"+utelegram_config['token']+"/sendMessage?chat_id=PONAQUITUID&text="+mensaje
respuesta = urequests.get(url)
###########################################################################################
def reply_ping(message):
print(message)
bot.send(message['message']['chat']['id'], 'voy') ### CAMBIAMOS EL MENSAJE
evitamosobstaculos() ### y EVITAMOS OBSTÁCULOS
############################################################################################
def evitamosobstaculos(): ### FUNCIÓN EVITAR OBSTÁCULOS
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')
############################################################################################
if sta_if.isconnected():
bot = utelegram.ubot(utelegram_config['token'])
bot.register('/go', reply_ping) ### LA CONSIGNA SERÁ GO
bot.set_default_handler(get_message)
print('BOT LISTENING')
enviarmensaje("preparado")
bot.listen()
else:
print('NOT CONNECTED - aborting')
Programando en bloques mBlock
Preparar el ALVIK para mBlock: Actualizar el firmware de Alvik
Actualizar el firmware significa que nuestro Alvik le instalamos el interpretador de micropython y por lo tanto podremos:
- Programar en código con Python
- Programar en bloques con mBlock
Si ya tiene el firmware instalado en el Alvik puedes saltarte esta página
Con este firmware no podemos programar con Arduino IDE
Antes de nada enciende el Alvik con esta precaución :
Primero nos aseguramos que el Alvik este APAGADO antes de conectarlo con el PC
en caso contrario se puede perjudicar la batería
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Luego lo conectamos por cable
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Y ahora ya podemos encender nuestro Alvik
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
Actualizamos el FIRMWARE
Esto lo hacemos una vez, entramos en https://alvikupdate.arduino.cc/ damos a conectar y luego updated (si no sabes qué puerto es, desconecta y conecta y te fijas cual aparece)
Puede tardar varios ciclos, paciencia
Asegúrate de tener el ALVIK encendido
Hasta que sale esta pantalla de éxito
ATENCIÓN ¿Y SI DA PROBLEMAS?
Por ejemplo se ha quedado enganchado, lo has desconectado antes de hora... entonces la solución pasa por utilizar un flasheador más potente
MicroPython Installer
Descargamos el programa y ejecutamos teniendo conectado el ESP32 del Alvik, (no hace falta encender el robot, pues sólo trabajamos con el ESP32) lo detecta y simplemente le damos a Instalar Micropython dentro del chip
Descargable en https://labs.arduino.cc/en/labs/micropython-installer
Si sigue puñetero y no detecta el Arduino Nano ESP32 tendrás que ponerlo en modo Bootoloader, haz los pasos 1, 2 y 3 de https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader y vuelve a intentarlo con el MicroPython Installer
Al acabar de instalar, sale este mensaje :
Aconsejamos apagar y desconectar totalmente y volver a conectar (acuérdate que no hay que conectar el ALVIK en el PC con el ALVIK encendido, lo conectas con el PC apagado y luego lo enciendes, tal y como dice arriba del todo)
Entramos en https://alvikupdate.arduino.cc/ damos a conectar y luego updated (si no sabes qué puerto es, desconecta y conecta y te fijas cual aparece)
AQUÍ VA A TARDAR VARIOS, VARIOS CICLOS, paciencia, paciencia
Asegúrate de tener el ALVIK encendido
Hasta que sale esta pantalla de éxito
Instalando mBlock
mBlock es un programa especializado en el manejo de los robots de Makeblock (ver cursos de mBot en Aularagon), pero permiten muchas arquitecturas de placas pues los mismos robots de Makeblock estan basados en placas de hardware libre Arduino, ESP32...
Hay dos versiones, online y offline, las dos son buenas, no obstante
- Si tienes Windows o Mac preferimos la versión offline para no saturar la red en los centros, rapidez y comodidad.
- Si utilizas Linux o Chromebook tienes que usar la versión online obligatoriamente pues no hay versión instalable.
Tanto una opción como la otra, permite tener los proyectos en la nube de Makeblock, compartir, embeberlos, etc...
Versión online
Para la versión web primero hay que instalar mLink driver nos vamos a https://mblock.cc/pages/downloads y abajo nos encontramos mLink para descargar, descarga el mLink correspondiente a tu sistema operativo :
Licencia CC-BY -SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Lo instalamos, y entonces pedirá instalar los drivers que son pequeños programas que comunican el PC con el harware del robot
Licencia CC-BY -SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Si utilizas Chromebook lee la siguiente guía para conectar el robot
Una vez instalado ya podemos entrar en la web https://ide.mblock.cc/ para programar en bloques nuestro robot
Nota: La página https://ide.mblock.cc/ no suele estar bien situada en los buscadores si ponemos mBlock, la página que suele salir es esta https://www.mblock.cc/en/ y nos da dos opciones, trabajar con bloque, o con Python, elegimos bloques
Si has entrado sin querer en la URL https://ide.makeblock.com/ no permite el logueo en Europa
En resumen, la URL correcta es https://ide.mblock.cc/
En este editor tenemos que loguearnos podemos crear un nuevo usuario, utilizando una cuenta de Google/Apple o registrarnos con un correo electrónico
Versión offline Windows o Mac
Vamos a https://mblock.cc/pages/downloads y descargamos la versión correcta a nuestro sistema operativo.
Licencia CC-BY -SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
En windows hacemos doble click en el archivo ejecutable descargado
Licencia CC-BY -SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Lo instalamos, y entonces pedirá instalar los drivers que son pequeños programas que comunican el PC con el hardware del robot
Licencia CC-BY -SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Algunas veces la ventana de driver de la figura anterior esta escondida en el fondo, hay que minimizar ventanas para acceder a ella.
En MAC el archivo será un fichero mount con la extensión .dmg, por lo tanto hay que arrastar el icono a la carpeta de aplicaciones
Licencia CC-BY -SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Instalando la extensión ALVIK en mBlock
En mBlock instalar la extensión Alvik
- Pinchamos en el + de añadir dispositivo
- buscamos Alvik
- apretamos al + de descargarlo (al finalizar desaparece el + )
- dos clicks y se instala
Licencia CC-BY-SA https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Se nos instalan una colección de instrucciones para controlar el ALVIK completamente
Dos formas de programar en mBlock
DOS FORMAS DE PROGRAMAR EN MBLOCK :
OPCIÓN Programación en vivo
El programa reside en el ordenador, y en la placa hay instalado un Firmware para ir escuchando y ejecutando lo que manda el ordenador.
- VENTAJAS
- Te permite interactuar el robot y el ordenador, por ejemplo podemos hacer que cuando el detector de humedad detecte agua, que salga por pantalla un fondo acuático, o que pulsando una tecla del teclado se encienda un LED en la placa...
- DESVENTAJAS
- hay que cargar dentro del robot el Firmware exclusivo de mBlock para que Arduino haga caso a mBlock
- Hay que tener nuestro ordenador como intermediario, se come los recursos y puede que nuestro programa vaya lento
- Por supuesto necesita tener ordenador conectado al robot, o sea, trabaja como un esclavo del ordenador.
OPCIÓN Programación cargar a la placa
Todos los programas editores de Arduino (tanto los que programan con código como el Arduino IDE) como los editores de programas gráficos en bloque (mBlock, Snap4Arduino, Arduinoblocks, ...) permiten cargar el programa en la placa. Las ventajas y desventajas son las opuestas de trabajar en vivo.
EN VIVO ¿Qué es eso?
Existe una posibilidad de utilizar la placa "en vivo" frente a "cargar" el programa en la placa.
Es decir, interactuando con el ordenador. El programa está en el PC. En la placa hay un firmware que le dice que este a las órdenes del PC. De esta manera podemos por ejemplo:
- Enviar órdenes desde el ordenador a la placa.
Por ejemplo que al pulsar la tecla espacio que se encienda el led D13
- Enviar información desde la placa al ordenador
Por ejemplo que muestre por pantalla nos muestre la cantidad de luz, que registra el sensor LDR, etc...
Que nosotros sepamos, estos programas permiten la programación en vivo :
- mBlock placas: Arduino, Microbit, Raspberry Pi, ... robots de Makeblock: mBot, Cyberpi...
-EchidnaScratch CURSO DE ECHIDNA
VENTAJAS LA PROGRAMACIÓN EN VIVO PERMITE MUCHO JUEGO Y POSIBILIDADES A LA HORA DE ELABORAR PROYECTOS
INCONVENIENTES: Necesitas el ordenador encendido y conectado al robot.
Un ejemplo de programa en vivo
PROBANDO EN VIVO
- Entramos en mBlok, en dispositivos
- Seleccionamos Alvik
- En vivo
- Conectar
- Nos saldrá una ventana pop-up en Windows saldrá COMx donde x es un número. En otros sistemas operativos /dev/tty.[yourSerialPortName] o algo así. En teoría tiene que funcionar con el puerto elegido, sino, elegiremos otro, suele ser el más alto.
A funcionar así de sencillo !!!!!
la primera vez, tarda algo en responder, paciencia
RETO Ves probando así de rápido la multitud de instrucciones gráficas para saber cómo funcionan
Un ejemplo de programa en carga
Como ejemplo de programa en carga
- Creamos un sencillo programa con eventos de cuando botón ... es presionado ...
- Elegimos el botón Cargar
- Subir código
Ahora el robot es libre en movimientos no depende del ordenador, por lo tanto podemos desconectar el cable
Otro ejemplo de programa en carga : Evita obstáculos
Podemos hacer un evita obstáculos, en la página https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/ proponen este programa
Licencia CC-BY-SA fuente https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/
Pero no gira, luego proponemos este https://planet.mblock.cc/project/5547662
Métodos para interactuar los objetos y el robot (dispositivo)
Si queremos que nuestro robot se pueda comunicar con el objeto o objetos que tenga mBlock, antes con mBlock 3.0 la comunicación era inmediata, fíjate en este script de una alarma:
Mezcla en el mismo script:
- órdenes específicas de la placa arduino (set digital...)
- órdenes específicas del objeto que exista en mBlock (por defecto el oso panda) say .... switch costume to ....
- órdenes del fondo switch backdrop to ...
Con mBlock 5.0 YA NO SE PUEDE, pero tenemos unos trucos
MÉTODO UTILIZAR VARIABLES GLOBALES
Se pueden crear variables, en cualquier objeto, y las lee cualquier objeto,
Este método se utiliza con la opción EN VIVO
De esta manera si creamos una variable frase para todos los objetos:
Podemos usarla en el robot
y el programa del objeto que queramos, en este caso el oso panda lo puede visualizar
MÉTODO UTILIZAR MENSAJES
Cualquier objeto tiene a su disposición enviar mensajes a los otros
Este método se utiliza con la opción EN VIVO
MÉTODO EXTENSIÓN BROADCAST = TRANSMITIR MENSAJES
Este método se utiliza con la opción EN CARGA
Es parecido al anterior, hay que ir al + que hay abajo para instalar extensiones
Buscar la extensión "Broadcast" e instalarla
Se instala primero descargándola con el + aquí
Y luego añadir una vez descargada
Entonces aparecen unas nuevas instrucciones
y se instalan unas instrucciones extras parecidas a las anteriores pero más potentes
- En el mismo mensaje podemos transmitir valores asociados
- Funciona EN MODO CARGA
- Esto es muy útil pues hay instrucciones que sólo se pueden utilizar en modo CARGA, de esta manera podemos pasar valores de la placa electrónica a los objetos del ordenador (oso panda o lo que sea) simplemente teniendo conectado la placa con el ordenador.
El resto de objetos trabajan en modo vivo, es decir, si cambias un bloque, automáticamente se ven los efectos
A lo otros objetos TAMBIÉN hay que instalar la extensión BROADCAST
DESVENTAJA no se pueden transmitir mensajes de objetos a la placa. Sólo de la placa a los objetos
Un ejemplo interactuando con un objeto
Vamos a probar dos métodos anteriores, el de variable global y el envío de mensaje, por lo tanto vamos a trabajar EN VIVO
El Alvik va a enviar cuando pulse OK un mensaje COMENZAMOS a un objeto (un ovni) para que empiece a moverse y va grabando continuamente en dos variables globales ANGULOX y ANGULOY los ángulos del sensor de inclinación
En un objeto OVNI vamos a realizar un programa que se mueva según el ángulo. Como el ángulo va de 0 a 100 y el eje va de 0-250 luego lo multiplicaremos por dos para que se mueva con más margen.
El programa lo tienes aquí https://planet.mblock.cc/project/5548364
Y este es el resultado
Arduino IDE
¿Qué es Arduino IDE?
Necesitarás el entorno de desarrollo Arduino IDE (IDE, Integrated development environment) (aquí https://www.arduino.cc/en/Main/Software para descargártelo)
En Linux puede salir este mensaje "can't open device "/dev/ttyUSB0": Permission denied" donde 0 puede ser otro número, la solución aquí
Está constituido por un editor de texto para escribir el código, un área de mensajes, una barra de herramientas con botones para las funciones comunes, y una serie de menús.
Arduino utiliza para escribir el código fuente o programa de aplicación lo que denomina "sketch" (programa). Estos programas son escritos en el editor de texto. Existe la posibilidad de cortar/pegar y buscar/remplazar texto.
Preparar Arduino IDE para Alvik: Instalar Placa ESP32 y libreria Arduino Avik
Instalar placa Arduino ESP32 Boards by Arduino
Lo primero que tenemos que hacer es instalar la placa Arduino ESP32 tal y como dice esta captura
O este vídeo a partir de 9:30 (pongo el vídeo pues es interesante si quieres aprender más sobre Arduino ESP32)
Instalar Librería Arduino_Alvik.h
Las funciones que tiene la librería son prácticamente las vistas en las APIs, ver https://libros.catedu.es/books/arduino-alvik/page/arduino-alvik-api
Para ejecutarlo en el Arduino IDE tenemos que tener esta librería que es fácilmente instalable:
Tal y como dice https://docs.arduino.cc/tutorials/alvik/setting-alvik-arduino-ide/
- Arduino_Alvik: Esta es la librería principal que usaremos en nuestros programas y contiene comandos de alto nivel para controlar el "cerebro" del Alvik, que es la placa Nano ESP32.
- Arduino_AlvikCarrier: Esta biblioteca está diseñada para la placa STM del dispositivo y resulta útil en situaciones donde se requiere un control más preciso de los comandos. Permite desarrollos más complejos, especialmente cuando se requiere una mayor integración con el hardware. Fuera del contexto de este curso.
Preparar ALVIK para Arduino IDE: Modo Bootloader
¿Qué es eso del Boodloader? Es un pequeño programa que esta en el microcontrolador (Arduino, ESP32, etc...) que permite que arranque la placa y espere las instrucciones del programa del usuario, digamos que es como un "pequeño sistema operativo de arranque" por ejemplo en el Arduino, se ejecuta en un poco de tiempo cuando arranca la placa o se resetea, y espera el programa IDE por el puerto USB, si llega (él comprueba que es un IDE y no otra cosa) lo almacena en un sitio de la memoria Flash y lo ejecuta, sino, pues ejecuta el que ya esta cargado. El bootloader hace que parpadee el led 13 de un Arduino UNO y se reserva un trozo de memoria para el Bootloader (en el Arduino UNO ocupa sólo 0.5K de los 32K que tiene disponibles el micro para ello). En nuestro caso el ESP32 Nano Arduino igual pero cuando cargamos el micropython nos cargamos ese bootloader por otro que tiene el compilador microPython. Lo de "quemar" o "flashear" el bootlader nos lo podemos encontrar en los cursos de Aularagón en el Zigbee de domótica con Raspberry, o a la hora de quemar el Nano Arduino como Arduino UNO en el curso de mClon
Tal y como dice en https://docs.arduino.cc/tutorials/alvik/setting-alvik-arduino-ide/
- cortocircuitar B1 y GND
Yo lo hago con un destornillador y toco las dos puntas, con cuidado de no tocar nada más. - Mientras esta cortocircuitado PULSA EL BOTÓN RESET
- Soltar botón y cortocircuito pines B1 y GND y se queda el led de la placa ESP32 en color púrpura ver figura del paso 1, si no se queda púrpura, repetir el proceso paciencia
- Abrir el programa ARDUINO IDE PERO CERRAR OTROS
(como el Arduino Create Agent que se queda en segundo plano abajo a la derecha , el MicroPython Installer....) - Asegurarse que esta instalado la placa Arduino ESP32 correctamente al menos la versión 2.013
(ir a Tools-Boards-BoardManager) si hay una versión anterior, desinstalar el que hay (remove) e instalarlo de nuevo. - Ir a Tools-Port y seleccionar el puerto, habrá cambiado a uno nuevo, puede ser algo parecido a esto :
- Ir a Tools > Board - Arduino ESP32 Boards > Arduino Nano ESP32 (o esp32 > Arduino Nano ESP32 )
- Poner Tools-> Programmer- seleccionar ESPTOOL
- Sketch > Upload Using Programmer
- Cuando salga este mensaje pasar al paso 11
Leaving... Hard resetting via RTS pin...
- Apretar el botón RESET y ya puedes o ejecutar un programa en Arduino IDE o instalar MicroPython
Curiosidad:
¿Por qué al poner la placa en modo Bootloader o cada vez que enciendo Arduino Alvik se enciende y se apaga el led RGB de al lado con los colores Rojo y Verde?
Solución https://libros.catedu.es/books/arduino-alvik/page/gpio-del-esp32-lD7
P: ¿No hay otra forma que no sea meter el destornillador y cortocircuitar los pines B1 y GND?
R: Si, hemos elegido la anterior pues nos parece más rápida y sencilla pero en https://github.com/arduino-libraries/Arduino_Alvik?tab=readme-ov-file#how-to-update-firmware-of-arduino-alvik-carrier tienes otro método utilizado el programa STM32 Cube Programer
Arduino IDE sin IoT: Un pequeña danza
En la pagina https://www.arduinolibraries.info/libraries/arduino_alvik o desde https://github.com/arduino-libraries/Arduino_Alvik podemos descargarnos multitud de ejemplos de código escrito en Arduino IDE para manejar este robot
Una pequeña danza
Este sencillo programa hace mover el robot a una velocidad de 10 y va cambiando el giro de 45º a -45º cada segundo
#include "Arduino_Alvik.h"
Arduino_Alvik alvik;
void setup() {
alvik.begin();
}
void loop() {
alvik.drive(10, 45);
delay(10000);
alvik.drive(10, -45);
delay(10000);
}
y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?
No has preparado convenientemente el ALVIK haz https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader
Resultado
Arduino IDE sin IoT: Evita obstáculos
En la pagina https://www.arduinolibraries.info/libraries/arduino_alvik o desde https://github.com/arduino-libraries/Arduino_Alvik podemos descargarnos multitud de ejemplos de código escrito en Arduino IDE para manejar este robot
Evita obstáculos
Este sencillo programa hace mover el robot evitando obstáculos
#include "Arduino_Alvik.h"
Arduino_Alvik alvik;
void setup() {
alvik.begin();
delay(5000); // Waiting for the robot to setup
}
void loop() {
float distance = 12.0;
float degrees = 45.0;
float speed = 10.0;
float distance_l, distance_cl, distance_c, distance_r, distance_cr;
alvik.get_distance(distance_l, distance_cl, distance_c, distance_r, distance_cr);
delay(50);
Serial.println(distance_c);
if (distance_c < distance || distance_cl < distance || distance_cr < distance || distance_l < distance || distance_r < distance) {
alvik.rotate(degrees);
} else {
alvik.drive(speed, 0.0);
}
}
y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?
No has preparado convenientemente el ALVIK haz https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloaderResultado
Reto
Tienes muchos ejemplos en https://github.com/arduino-libraries/Arduino_Alvik/tree/main/examples
🫵🫵🫵🫵 ¿ A QUE ESPERAS? 🫵🫵🫵
Arduino IDE sin IoT: Coche a control remoto
Más adelante verás un coche teledirigido con el móvil y usando internet.
Pero en este caso vamos a usar DOS ARDUINOS ALVIKS uno como receptor y otro con envío de órdenes
La fuente de este programa lo puedes encontrar en https://github.com/arduino-libraries/Arduino_Alvik/blob/main/examples/remote_control/remote_control.ino
Se graban los dos programas en los dos alviks, y al apretar OK uno es el que envía la órdenes y el otro le apretamos CANCEL y es el receptor
Es muy curioso que la comunicación lo hace via Wifi pero sin usar ningún punto de acceso exterior, sino entre ellos comunicación pareada (peer)
/*
This file is part of the Arduino_Alvik library.
Copyright (c) 2024 Arduino SA
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// This example shows how to interface 2 Alvik robots via ESPnow.
// At startup, you can select if an Alvik is a trasmitter by pressing the "check button" or a receiver by pressing "cancel button". Use arrows to move the robot.
#include "Arduino_Alvik.h"
#include <esp_now.h>
#include <WiFi.h>
Arduino_Alvik alvik;
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t myData;
esp_now_peer_info_t peerInfo;
int alvik_mode = -1; // 0 is receiver, 1 is sender
bool led_blink = false;
void setup() {
Serial.begin(115200);
while((!Serial)&&(millis()>3000));
alvik.begin();
WiFi.mode(WIFI_STA);
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
while (alvik_mode == -1){
if (alvik.get_touch_cancel()){
alvik_mode = 0;
}
if (alvik.get_touch_ok()){
alvik_mode = 1;
}
}
if (alvik_mode == 0){
esp_now_register_recv_cb(OnDataRecv);
}
else{
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
}
void loop() {
if (alvik_mode==0){
alvik.left_led.set_color(led_blink, !led_blink, 0);
alvik.right_led.set_color(!led_blink, led_blink, 0);
delay(500);
}
else{
if (alvik.get_touch_any()){
if (alvik.get_touch_up()){
myData = 'F';
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}
if (alvik.get_touch_down()){
myData = 'B';
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}
if (alvik.get_touch_left()){
myData = 'L';
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}
if (alvik.get_touch_right()){
myData = 'R';
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}
if (alvik.get_touch_center()){
myData = 'S';
esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
}
}
alvik.left_led.set_color(0, 0, led_blink);
alvik.right_led.set_color(0, 0, led_blink);
delay(100);
}
led_blink = !led_blink;
}
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len){
Serial.print(incomingData[0]);
switch (incomingData[0]){
case 'F':
alvik.drive(7, 0);
break;
case 'B':
alvik.drive(-7, 0);
break;
case 'L':
alvik.drive(0, 45);
break;
case 'R':
alvik.drive(0, -45);
break;
case 'S':
alvik.brake();
break;
}
Serial.println();
}
El resultado es expectacular
Internet de las cosas IoT
El Internet de las cosas (Internet of Thing IoT) describe objetos físicos —o grupos de estos— con sensores, capacidad de procesamiento, software y otras tecnologías que se conectan e intercambian datos con otros dispositivos y sistemas a través de internet u otras redes de comunicación. El Internet de las cosas se ha considerado un término erróneo porque los dispositivos no necesitan estar conectados a la Internet pública. Sólo necesitan estar conectadas a una red y ser direccionables individualmente
Fuente Wikipedia IoT Internet de las cosas CC-BY-SA
De Drawed by Wilgengebroed on FlickrTranslated by Prades97 CC BY-SA 3.0
Estamos hablando de dispositivos que se conectan a internet de forma desatendida, por vía hardware (o mejor dicho firmware) a diferencia de un ordenador, tablet o móvil, donde tienes que configurar por software el dispositivo y hay un diálogo entre usuario y dispositivo sobre el uso de Internet (el software solicita tal página web, tales datos etc por voluntad del usuario o por diálogo con el usuario) Aquí los dispositivos están ya configurados de los datos que se comunican. Es decir "conectar y olvidar".
Piensa en la diferencia entre un enchufe inteligente y un ordenador, el primero es lo que se considera dentro de IoT
Las formas "desatendidas" son un avance en la sociedad pero también puede generar problemas muy serios a nivel mundial, ver el caso Mirai
Las cosas claras. ¿asíncrono o síncrono?
Hay muchas herramientas IoT
- Blynk: lo que nos gusta de esta herramienta es que es casi "instantánea" o "síncrona". Esto es imprescindible con ciertos robots como el Rover Marciano con Arduino. Necesitamos que "gire" para evitar un obstáculo, no podemos esperar !!!. Veremos con BLYNK un protocolo que entre el dispositivo electrónico (nuestro robot) y nosotros (en ordenador, en una APP en el móvil) la comunicación es instantánea, gracias a un servidor que hará de intermedio, que puede ser local (BLYNK LEGACY) o en Internet (BLYNK IoT).
- Blynk legacy es la que se va a trabajar en
- Blynk IoT es la que se va a trabajar con
- MQTT El emisor envía datos, se almacenan en un servidor, y cuando puede, lo vuelca al cliente. Cliente y emisor pueden ser el dispositivo electrónico y nosotros o viceversa. Veremos que esto es lo que hace el protocolo MQTT y está tremendamente extendido por lo barato y fácil que es. Hace que los servidores no estén tan ocupados, por lo tanto hay varios proveedores que ofrecen este servicio gratuitamente. Hay robots como los que tienen la placa TDR STEAM IMAGINA que envía datos de temperatura, humedad, .. y pueden recibir datos pero no precisan de esta exigencia instantánea como un rover.
- Arduino cloud IoT
- Cyberpi y mBot2
Arduino IDE con IoT: Escaneo Wifi
Desde https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiScan/WiFiScan.ino podemos encontrar este programa para escanear las redes wifi desde nuestro ESP32 Arduino
https://app.arduino.cc/sketches/54b6f875-2961-4ec5-8a48-608d9dde5feb?view-mode=preview
y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?
No has preparado convenientemente el ALVIK haz https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader
Instalando la librería Wifi.h
Te dará un error de compilación pues no tiene esta librería. Puedes descargar la versión última desde https://www.arduino.cc/reference/en/libraries/wifi/
Una vez descargada (un fichero ZIP no lo descomprimas) en el editor Arduino IDE se instala desde este menú
Seleccionamos el fichero Zip que has descargado y ya tenemos la librería instalada
Compilamos
Antes de compilar CONECTAMOS NUESTRO ESP32
Licencia CC-BY-NC-SA origen https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/
No hace falta encender el robot Arduino Alvik
Y seleccionamos la placa que ha reconocido
Y ya se puede compilar !!! no tiene que dar ningún fallo
Subirlo al ESP32
Pues si lo intentas subir
y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?
Lee https://libros.catedu.es/books/arduino-alvik/page/modo-bootloader
Resultado
Le damos a subir, y en la ventana de Output da como correcto
Y si nos vamos a la ventana del monitor serie
No nos sale nada !!! le das al botón de reset y ya sale :
¿Puedo ahora ejecutar un programa en MicroPyhon?
No, tal y como dice aquí https://libros.catedu.es/books/arduino-alvik/page/instalar-micropython tienes que instalar el interpretador/compilador de Micropython dentro del ESP32, sino Arduino Lab for Micropython no se podrá conectar porque no lo encontrará.
Arduino IDE con IoT: Arduino Cloud
Esta plataforma https://docs.arduino.cc/arduino-cloud/ nos permite conectar nuestras placas (Arduino v4, ESP32, et...) con un panel de control Dashboard y así controlarlos a distancia por Internet.
El mecanismo es sencillo, el ESP32 conectado por internet, pasa variables a un código (Sketch), a este conjunto se le llama Thing, y este se lo comunica a IoT CLOUD y la plataforma lo comunica a los paneles de control. Dashboard que se puede ver desde el PC o desde el móvil El proceso también funciona al revés.
Extraído de Youtube Exploring the Arduino Nano ESP32
- Creamos una cuenta en Arduino Cloud
- Instalamos Arduino Create Agent
- Build the Thing es decir preparamos nuestra placa ESP32 con el Sketch
- Creamos the device
- Creamos the thing
- Añadimos las variables
- Creamos el scketch y lo grabamos en el ESP32
- Construimos un Dashboard o panel de control
PASO 1 LOGUEARSE EN ARDUINO CLOUD
En Plan permite una cuenta gratuita sólo se pueden 2 things ver https://cloud.arduino.cc/plans
PASO 2 ADRUINO CREATE AGENT
Arduino Create Agent te lo puedes descargar desde https://cloud.arduino.cc/download-agent, se descarga, se ejecuta, hay que seguir los pasos, se queda en segundo plano en el PC y no tienes que preocuparte
PASO 3 Build the Thing: CREATE DEVICE
Primero añadimos un Device o placa en https://app.arduino.cc/devices
Elegimos placa Arduino
Si falla, ponemos la placa en modo Bootloader (ver qué es eso en https://libros.catedu.es/books/arduino-alvik/page/instalar-micropython ) y entonces detectará el puerto
Conectamos nuestro Arduino Alvik y saldrá un diálogo con un TOKEN on Secret key que lo guardaremos ante todo no hacerlo público
PASO 3 Build the Thing: CREATE THING
Una vez creada la placa, nos vamos a Thing, crear
Asociamos el Thing al Device, y le configuramos una red wifi (te predirá el Secret Key)
PASO 3 Build the Thing: CREATE THING-VARIABLES
Luego añadimos variables, por ejemplo RGBverde que va a encender y apagar la luz verde, va a ser tipo Bool y Read&Write
PASO 3 Build the Thing: CREATE THING-SKETCH
Dentro de Thinks nos vamos a SKETCH
y vemos que ha creado un código thingProperties.h que tiene que tener el SSID de la wifi, su contraseña y la palabra clave de nuestro ESP32, podemos ponerlo manualmente o nos fijamos y en Secret Tab estan ya puestos :
El otro script es el nombre que hemos creado en Thing y vemos que :
- LINEA 9 Esta declarada la variable que hemos añadido
- LINEA 16 Incluye la librería thingProperties.h
- LINEA 41 Añadimos en setup() la declaración que D13 SERÁ SALIDA pinMode(D13,OUTPUT);
- LINEA 60 AL 66 Añadimos en onRGBverdeChange una condicional, de tal manera que si la variable es cierta, que encienda el led y si es falsa que lo apague
¿Por qué es D13? ¿NO TENDRÍA QUE SER 48?
Eso ya lo hemos visto en https://libros.catedu.es/books/arduino-alvik/page/parpadeo-led-esp32
/*
Sketch generated by the Arduino IoT Cloud Thing "Untitled"
https://create.arduino.cc/cloud/things/34a0aae1-c7b9-42ab-92d4-0e37bd51031f
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
bool rGBverde;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
/// MI CODIGO
pinMode(D13,OUTPUT);
}
void loop() {
ArduinoCloud.update();
// Your code here
}
/*
Since RGBverde is READ_WRITE variable, onRGBverdeChange() is
executed every time a new value is received from IoT Cloud.
*/
void onRGBverdeChange() {
// Add your code here to act upon RGBverde change
if (rGBverde){
digitalWrite(D13,HIGH);
}else{
digitalWrite(D13,LOW);
}
}
/*
Since RGBrojo is READ_WRITE variable, onRGBrojoChange() is
executed every time a new value is received from IoT Cloud.
*/
void onRGBrojoChange() {
// Add your code here to act upon RGBrojo change
}
Lo subimos
Ojo, tienes que tener el Arduino Arduino Create Agent paso 2
PASO 4 Dashboard
Creamos un panel de control
Y le añadimos un Switch asociado a la variable RGBverde
Podemos ver el dashboard en un teléfono móvil instalando la APP Arduino IoT Cloud Remote
Al loguearse con tu cuenta, ya nos aparece el Dashboard
Resultado
Arduino IDE con IoT: Coche teledirigido
Aprovechamos el programa que enciende y apaga un led por Arduino Cloud
Variables
Le añadimos tres variables más :
- velocidad tipo entero Read&Write
- giro tipo entero Read&Write
- distancia tipo float Read
Sketch
En thingProperties.h añade automáticamente estas variables y funciones, no tienes que añadirlas :
void onGiroChange();
void onVelocidadChange();
void onRGBverdeChange();
float distancia;
int giro;
int velocidad;
bool rGBverde;
Pero en la función principal, nosotros vamos a poner el siguiente código :
- Línea 2 #include "Arduino_Alvik.h" para que incluya la libería de manejo del robot
- Línea 4 Creamos un objeto alvik Arduino_Alvik alvik;
- Línea 6 Creamos una variable tipo array de 5 elementos para almacenar las distancias que lee el sensor de distancia float distances[5];
- Línea 15 arrancamos el objeto alvik alvik.begin();
- Línea 41 que el alvik se mueva según la velocidad y el giro alvik.drive(velocidad,giro);
- Es la instrucción principal y qué sencilla 😍
- Línea 42 leemos el array de distancias alvik.get_distance(distances[0], distances[1], distances[2], distances[3], distances[4]);
- Línea 43 de todas las distancias, sólo nos importa la 2 distancia=distances[2];
Nota: la instrucción 41 se han colocado dentro de loop() pero también se podría haber colocado dentro de onGiroChange();
onVelocidadChange();
#include "thingProperties.h"
#include "Arduino_Alvik.h"
Arduino_Alvik alvik;
float distances[5];
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
alvik.begin();
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
/// MI CODIGO
pinMode(D13,OUTPUT);
}
void loop() {
ArduinoCloud.update();
// Your code here
alvik.drive(velocidad,giro);
alvik.get_distance(distances[0], distances[1], distances[2], distances[3], distances[4]);
distancia=distances[2];
}
/*
Since RGBverde is READ_WRITE variable, onRGBverdeChange() is
executed every time a new value is received from IoT Cloud.
*/
void onRGBverdeChange() {
// Add your code here to act upon RGBverde change
if (rGBverde){
digitalWrite(D13,HIGH);
}else{
digitalWrite(D13,LOW);
}
}
/*
Since RGBrojo is READ_WRITE variable, onRGBrojoChange() is
executed every time a new value is received from IoT Cloud.
*/
void onRGBrojoChange() {
// Add your code here to act upon RGBrojo change
}
/*
Since Velocidad is READ_WRITE variable, onVelocidadChange() is
executed every time a new value is received from IoT Cloud.
*/
void onVelocidadChange() {
// Add your code here to act upon Velocidad change
}
/*
Since Giro is READ_WRITE variable, onGiroChange() is
executed every time a new value is received from IoT Cloud.
*/
void onGiroChange() {
// Add your code here to act upon Giro change
}
Dashboard
Creamos un panel de control con:
- Un slider para velocidad de 0 a 50
- Un slider para el giro de -180 a +180
- Un gauge para distancia
Resultado
GPIO del ESP32
Mapa de los pines en el Arduino Nano ESP32
Extraído de Youtube Exploring the Arduino Nano ESP32
Como podemos observar, nuestro objetivo pues es el GPIO0
¿Dónde está físicamente los GPIO ?
Pues como podemos ver en este esquema el GPIO0 está en el pin BOOT1
Fuente CC-BY-SA https://docs.arduino.cc/tutorials/alvik/user-manual/
-
SI USAMOS MICROPYTHON TENEMOS QUE USAR LAS VERDES
-
SI USAMOS CÓDIGO ARDUINO IDE TENEMOS QUE USAR LAS ROJAS
Como puedes observar, si cortocircuitas B1 = GPI0 = D15 con GND enciende el led RGB en color verdel esto pasa si Pones la placa en modo Bootloader.
Arduino IDE con IoT: ESP32 + Sensores externos + IoT
OBJETIVO
Ahora vamos a utilizar el ESP32 SIN EL ARDUINO ALVIK podemos sacar la placa microcontroladora y ponerlo en una placa protoboard y experimentar con sensores y actuadores estándares en el mercado :
+
Para ver varias posibilidades, vamos a ver estos sensores y actuadores (recomendamos ver estas páginas actuadores y sensores)
- Un led de salida simple, para practicar salida digital en mi caso voy a elegir este gracioso semáforo
- Un sensor LDR pero para practicar los dos tipos de señal,
- con salida analógica
- con salida digital.
- Un sensor CO2 CCS811 con protocolo I2C
ESQUEMA DE CONEXIONES
- SEMAFORO
- LED ROJO al D1 del ESP32
- GND a GND
- MODULO SENSOR LDR
- SEÑAL DIGITAL al D0 del ESP32
- SEÑAL ANALÓGICA al A0 del ESP32
- VCC a 3V3
- GND A GND
- MODULO SENSOR CO2
- SCL al pin A5 del ESP32
- SDA al pin A4 del ESP32
- PIN WAKE a GND
- VCC a 3V3
- GND A GND
DEVICES
Nos vamos a Arduino Cloud, y en DEVICES añadimos el ESP32 y obtenemos el TOKEN o palabra secreta (si has hecho la práctica anterior, no es necesario pues ya tenemos el TOKEN o palabra secreta) como es similar al caso anterior, no lo desarrollamos. (Nos pedirá también el SSID y la contraseña de la red wifi)
VARIABLES
Añadimos las siguientes variables :
- CO2 tipo int y Read
- luz tipo int y Read
- luzdigital tipo bool y Read
- rojo tipo bool y Read&Write
EL SCKETCH -LIBRERIA CCS811
Primero añadiríamos la librería de keystudio https://fs.keyestudio.com/KS0457 pero no lo permite Arduino Cloud, viendo las instrucciones, vemos que son las mismas que en los ejemplos de esta librería la de DF que es la que instalamos :
esto provoca la incorporación de la línea 1 #include <DFRobot_CCS811.h>
EL SCKETCH -EL CÓDIGO
- Tenemos las variables definidas en las líneas 10-13 :
- int cO2;
- int luz;
- bool luzdigital;
- bool rojo;
- Definimos una variable de tipo el sensor CCS811 en la línea 23 DFRobot_CCS811 CCS811;
- En Setup en las líneas 48-21 arrancamos ese sensor:
- while(CCS811.begin() != 0){
Serial.println("failed to init chip, please check if the chip connection is fine");
delay(1000);
}
- while(CCS811.begin() != 0){
- Definimos los pines digitales 0 y 1 como entrada y salida respectivamente:
- pinMode(1,OUTPUT);
pinMode(0,INPUT);
- pinMode(1,OUTPUT);
- En las líneas 60-70 que lea el CCS811 y la parte de CO2 que lo meta en la variable CO2 (línea 63)
- if(CCS811.checkDataReady() == true){
Serial.print("CO2: ");
Serial.print(CCS811.getCO2PPM());
cO2=CCS811.getCO2PPM();
Serial.print("ppm, TVOC: ");
Serial.print(CCS811.getTVOCPPB());
Serial.println("ppb");
} else {
Serial.println("Data is not ready!");
}
- if(CCS811.checkDataReady() == true){
- En las línea 71 que luz sea la lectura del pin A0 luz = analogRead(A0);
- En las líneas 72-76 que según rojo se encienda o no el led
- if (rojo){
digitalWrite(1,HIGH);
}else{
digitalWrite(1,LOW);
}
- if (rojo){
- En la línea 77 que luzdigital sea la lectura de la salida digital del sensor LDR
- luzdigital=digitalRead(0);
#include <DFRobot_CCS811.h>
/*
Sketch generated by the Arduino IoT Cloud Thing "Untitled"
https://create.arduino.cc/cloud/things/17c10209-3874-430a-877c-c082ff7dd38d
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
int cO2;
int luz;
bool luzdigital;
bool rojo;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
//DFRobot_CCS811 CCS811(&Wire, /*IIC_ADDRESS=*/0x5A);
DFRobot_CCS811 CCS811;
void setup() {
// Initialize serial and wait for port to open:
Serial.begin(9600);
// This delay gives the chance to wait for a Serial Monitor without blocking if none is found
delay(1500);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud
ArduinoCloud.begin(ArduinoIoTPreferredConnection);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
while(CCS811.begin() != 0){
Serial.println("failed to init chip, please check if the chip connection is fine");
delay(1000);
}
pinMode(1,OUTPUT);
pinMode(0,INPUT);
}
void loop() {
ArduinoCloud.update();
// Your code here
if(CCS811.checkDataReady() == true){
Serial.print("CO2: ");
Serial.print(CCS811.getCO2PPM());
cO2=CCS811.getCO2PPM();
Serial.print("ppm, TVOC: ");
Serial.print(CCS811.getTVOCPPB());
Serial.println("ppb");
} else {
Serial.println("Data is not ready!");
}
luz = analogRead(A0);
if (rojo){
digitalWrite(1,HIGH);
}else{
digitalWrite(1,LOW);
}
luzdigital=digitalRead(0);
}
/*
Since Rojo is READ_WRITE variable, onRojoChange() is
executed every time a new value is received from IoT Cloud.
*/
void onRojoChange() {
// Add your code here to act upon Rojo change
}
DASHBOARD
- Un gauge ligado a CO2 desde 0 a 2000
- Un gauge ligado a Luz de 0 a 2.200
- Un Switch ligado a rojo
- Un led de oscuridad ligado a luzdigital
Alternativa : en vez de luz tendría que llamarse "oscuridad" que sea luz pero que vaya al revés
RESULTADO
ALTERNATIVA: Que el semáforo visualice los niveles peligrosos de CO2, por ejemplo el umbral del amarillo 600-1.000
¿Te atreves a poner un servomotor?
Predictor meteorológico
Predictor meteorológico
Autor Mario Monteagudo Asesor digital Centro de Profesorado de Ejea de los Caballeros
Usando IDE Arduino y el sensor Bosch BME280 se puede medir la presión atmosférica, temperatura y humedad y usando un código predictivo Algoritmo de Zambretti que usa las diferencias de presiones cada 3 horas, puede hacer pronóscticos. Para ello mide la presión cada 5 minutos y tienen en cuenta la altitud del lugar y la temperatura.
El ESP32 tendría que estar en el exterior y como hemos explicado, necesita 3 horas para hacer su primera predicción.
Este es el resultado
Y este es el código
#include "arduino_secrets.h"
//Predictor del tiempo mediante el algoritmo de Zambretti************************
//2024*Mario Monteagudo Alda*****mario.monteagudo@cpejea.es**********************
#include "arduino_secrets.h"
#include <SimpleBME280.h> //Biblioteca usada para el sensor
const float ALTURA = 497.0; //Altitud del lugar
SimpleBME280 bme280; //Declaración de la instancia del sensor
float presiones[37]; //Presiones corregidas cincominutales de las 3 últimas horas
int zambretti; //Número de Zambretti
float temperatura; //ºC
float humedad; //Humedad relativa en %
float presion; //Presión atmosférica en mbar
int contador = 0; //Contador de número de medidas de presión cincominutales tomadas
bool encendido = false; //Bandera para intermitencia del LED
/*
Arduino IoT Cloud Variables description
The following variables are automatically generated and updated when changes are made to the Thing
String boletin;
float fiabilidad;
float tendencia;
Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
which are called when their values are changed from the Dashboard.
These functions are generated with the Thing and added at the end of this sketch.
*/
#include "thingProperties.h"
void setup() {
pinMode(LED_BUILTIN,OUTPUT);
digitalWrite(LED_BUILTIN,HIGH);
// Inicialización de la comunicación serie y espera
Serial.begin(19200);
delay(2000);
// Defined in thingProperties.h
initProperties();
// Connect to Arduino IoT Cloud and wait
ArduinoCloud.begin(ArduinoIoTPreferredConnection, false);
delay(2000);
/*
The following function allows you to obtain more information
related to the state of network and IoT Cloud connection and errors
the higher number the more granular information you’ll get.
The default is 0 (only errors).
Maximum is 4
*/
setDebugMessageLevel(2);
ArduinoCloud.printDebugInfo();
bme280.begin(); //Inicialización del sensor y espera
delay(2000);
//Primera lectura del sensor
bme280.update();
presion = bme280.getP();
temperatura = bme280.getT();
//Corrección de la presión según la altitud y temperatura y paso de Pa a mbar
presion = (presion * pow(1 - (0.0065 * ALTURA) / (temperatura + (0.0065 * ALTURA) + 273.15),-5.257 ))/100.0;
for (int i=0; i<=36; i++) { presiones[i]=presion;}
fiabilidad = 0;
}
void loop() {
bme280.update();
presion = bme280.getP();
temperatura = bme280.getT();
humedad = bme280.getH();
presion = (presion * pow(1 - (0.0065 * ALTURA) / (temperatura + (0.0065 * ALTURA) + 273.15),-5.257 ))/100.0;
tendencia=presion-presiones[0];
for (int i=0; i<36; i++) { presiones[i]=presiones[i+1];}
presiones[36] = presion;
//Cálculo del número de Zambretti
if ((tendencia <= -1.6) & (presion > 985.0) & (presion < 1050.0)) {zambretti = round(127-0.12*presion);}
else if ((tendencia >= 1.6) & (presion > 947.0) & (presion < 1030.0)) {zambretti = round(185-0.16*presion);}
else if ((abs(tendencia) < 1.6) & (presion > 960.0) & (presion < 1033.0)) {zambretti = round(144-0.13*presion);}
else {zambretti = 0;}
//Boletín con el pronóstico
boletin = "Temperatura: " + String(temperatura,1) + " ºC" + "\n" +
"Humedad relativa: " + String(humedad,1) + " %" + "\n" +
"Presión: " + String(presion,0) + " mbar" + "\n" +
"Tendencia: " + String(tendencia,2) + " mbar" + "\n" +
pronostico(zambretti);
Serial.println(boletin + "\n");
//Espera de cinco minutos para la actualización
unsigned long tiempo = millis();
while ((millis()-tiempo) < 5*60*1000 )
{
ArduinoCloud.update();
delay(1000);
encendido = !encendido;
digitalWrite(LED_BUILTIN,encendido);
}
contador = min(36, contador + 1);
//Después de tres horas de medidas, la fiabilidad es del 100%
fiabilidad = map(contador, 0, 36, 0, 100);
}
//Cadena de texto con el pronóstico meteorológico***********************
String pronostico(int z)
{
switch (z)
{
case 1:
return "Tiempo estable"; break;
case 2:
return "Buen tiempo"; break;
case 3:
return "Buen tiempo con ligera inestabilidad"; break;
case 4:
return "Buen tiempo evolucionando a chubascos"; break;
case 5:
return "Chubascos evolucionando a tiempo inestable"; break;
case 6:
return "Inestable evolucionando a lluvioso"; break;
case 7:
return "Intervalos de lluvia con empeoramiento"; break;
case 8:
return "Intervalos de lluvia evolucionando a gran inestabilidad"; break;
case 9:
return "Muy inestable con lluvia"; break;
case 10 :
return "Tiempo estable"; break;
case 11:
return "Buen tiempo"; break;
case 12:
return "Buen tiempo con posibles chubascos"; break;
case 13:
return "Buen tiempo con probables chubascos"; break;
case 14:
return "Chubascos con intervalos despejados"; break;
case 15:
return "Variable con algo de lluvia"; break;
case 16:
return "Inestable con intervalos de lluvia"; break;
case 17:
return "Lluvia a intervalos frecuentes"; break;
case 18:
return "Muy inestable con lluvia"; break;
case 19:
return "Tormentoso con lluvia abundante"; break;
case 20 :
return "Tiempo estable"; break;
case 21:
return "Buen tiempo"; break;
case 22:
return "Evolucionando a buen tiempo"; break;
case 23:
return "Buen tiempo evolucionando a mejor"; break;
case 24:
return "Buen tiempo con posibles chubascos a primeras horas"; break;
case 25:
return "Chubascos a primeras horas evolucionando a mejor"; break;
case 26:
return "Variable evolucionando a mejor"; break;
case 27:
return "Inestable a primeras horas evolucionando a estable"; break;
case 28:
return "Inestable con probable mejoría"; break;
case 29:
return "Inestable con breves intervalos de buen tiempo"; break;
case 30:
return "Muy inestable con intervalos de buen tiempo"; break;
case 31:
return "Tormentoso con probable mejoría"; break;
case 32:
return "Tormentoso con mucha lluvia"; break;
default:
return "Tiempo indeterminado";
}
}
Créditos
Autor:
- CATEDU Julio 2024 por Javier Quintana Peiró
- CATEDU Marzo 2025 Capitulo por bloques por Javier Quintana Peiró
- Predictor meteorológico
Autor Mario Monteagudo Asesor digital Centro de Profesorado de Ejea de los Caballeros
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.