# Arduino ALVIK

# Introducción

# Qué es Arduino Alvik

[![3-411-796-2950742771.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/3-411-796-2950742771.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/3-411-796-2950742771.png)

##### <span style="text-decoration: underline;"><span style="color: rgb(22, 145, 121); text-decoration: underline;">**SOFTWARE** </span></span>

<span style="color: rgb(0, 0, 0);">Tienes dos opciones para programar Arduino Alvik :</span>

- <span style="color: rgb(0, 0, 0);">**OPCIÓN A** con el firmware https://alvikupdate.arduino.cc/ </span>
    - <span style="color: rgb(0, 0, 0);">LENGUAJE CÓDIGO **MICROPYTHON**</span>
    - <span style="color: rgb(0, 0, 0);">LENGUAJE EN BLOQUES GRÁFICO **mBlock** que trabaja con Python </span>
- <span style="color: rgb(0, 0, 0);">**OPCIÓN B** reseteando bootloader</span>
    - <span style="color: rgb(0, 0, 0);">LENGUAJE CÓDIGO **ARDUINO IDE** que trabaja con lenguaje C</span>

<p class="callout info"><span style="color: rgb(0, 0, 0);">Utiliza **ArduinoIDE** si ya trabajas en el aula con este lenguaje, sino, te aconsejamos Micropyhon o mBlock</span></p>

<span style="color: rgb(0, 0, 0);">👁️👁️Cambiar de una opción a otra implica resetear el Bootloader.</span>

<p class="callout danger"><span style="color: rgb(0, 0, 0);">**🫵 Es mejor que te decidas qué opción quieres, opción A o B 🫵**</span></p>

<span style="color: rgb(0, 0, 0);">**<span style="color: rgb(22, 145, 121);"><span style="color: rgb(0, 0, 0);">[![2024-07-11 20_01_25-Microsoft PowerPoint - [Presentación1].png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-20-01-25-microsoft-powerpoint-presentacion1.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-20-01-25-microsoft-powerpoint-presentacion1.png)</span></span>**</span>

##### <span style="text-decoration: underline;"><span style="color: rgb(22, 145, 121); text-decoration: underline;">**HARDWARE** </span></span>

Es un robot con las siguientes características :

- **Placa** **microcontroladora** Las placas Arduino tradicionales tenían microcontroladores como el ATMEL MEGA 328P etc..[ver](https://libros.catedu.es/books/programa-arduino-mediante-codigo/page/conozcamoslo) 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](https://libros.catedu.es/books/esp32-en-el-aula/page/que-es-esp32)
- Precio unos 130€
- [Especificaciones técnicas](https://docs.arduino.cc/resources/datasheets/AKX00066-datasheet.pdf)
- **La batería es una 18650**, es la mejor, con la protección de no ser accesible,[ pues tiene sus peligros](https://libros.catedu.es/books/rover-marciano-alphabot-rasbperry-y-python/page/121-ojo-con-las-baterias-18650)
- **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

[![prj-00-robot-illustration.webp](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/prj-00-robot-illustration.webp)](https://libros.catedu.es/uploads/images/gallery/2024-06/prj-00-robot-illustration.webp)

[![prj-00-components.webp](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/prj-00-components.webp)](https://libros.catedu.es/uploads/images/gallery/2024-06/prj-00-components.webp)

##### <span style="text-decoration: underline;"><span style="color: rgb(22, 145, 121); text-decoration: underline;">**AMPLIACIONES** </span></span>

<span style="color: rgb(0, 0, 0);">Dispone de las siguientes conexiones</span>

- **Conexiones de ampliación**
    - 2 conectores para servos
    - 2 Conexión I2C
    - 2 conexiones Grove

[![datasheet_connectors.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/datasheet-connectors.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/datasheet-connectors.png)

En este curso lo utilizaremos para unir un servo

Además tiene uniones compatibles con piezas de construcción LEGO

[![423403-5-1000x1000.jpg](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/423403-5-1000x1000.jpg)](https://libros.catedu.es/uploads/images/gallery/2025-03/423403-5-1000x1000.jpg)

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

##### <span style="text-decoration: underline;"><span style="color: rgb(22, 145, 121); text-decoration: underline;">**PROGRAMAS PREDEFINIDOS** </span></span>

<span style="color: rgb(0, 0, 0);">Al arrancar ALVIK con el firmware que veremos en Python y mBlock da la posibilidad de ejecutar 3 programas predefinidos :</span>

[![select-examples.gif](https://libros.catedu.es/uploads/images/gallery/2024-06/select-examples.gif)](https://libros.catedu.es/uploads/images/gallery/2024-06/select-examples.gif)

Licencia CC-BY-NC-SA origen [https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/](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

##### <span style="text-decoration: underline;"><span style="color: rgb(22, 145, 121); text-decoration: underline;">**CURIOSIDADES** </span></span>

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.

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/_qOaqZwT73s" width="560"></iframe>

# 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.

{{@4518}}

# Software

La programación con Arduino Alvik puede ser de dos opciones

- con bloques utilizando mBlock
- con código (Python o Arduino IDE)

{{@13859}}

# Micropython

# Preparar ALVIK para MicroPython: Actualizar el firmware de Alvik

{{@13342}}

# Instalar Micropython

<p class="callout info"><span style="color: rgb(22, 145, 121);">**Conceptos previos:**</span>  
- 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</p>

<p class="callout success">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</p>

##### <span style="color: rgb(22, 145, 121);">**¿Dónde se compila Micropython?**</span>

Como puedes ver [en este vídeo en 21:20 ](https://youtu.be/R51tf66es9w?t=1286)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.  
[![2024-07-04 18_44_27-(1) Exploring the Arduino Nano ESP32 _ MicroPython & IoT Cloud - YouTube.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-18-44-27-1-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-18-44-27-1-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)  
<span style="color: rgb(0, 0, 0);">[Fuente vídeo Exploring the Arduino Nano ESP32 | MicroPython &amp; IoT](https://youtu.be/R51tf66es9w?t=1512)</span>

##### <span style="color: rgb(22, 145, 121);">**¿Y a mi qué más me da?**</span>

Pues sí que importa....

<p class="callout danger">Si programas ESP32 con Arduino IDE o Arduino Cloud o con Steamakersblock (que está basado en C++) **te has cargado el compilador Python que has puesto en** ["Actualizar firmware"](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-micropython-actualizar-el-firmware-de-alvik) del ESP32 luego si quieres programar en Python, tienes que volver a  ["Actualizar firmware"](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-micropython-actualizar-el-firmware-de-alvik)   
O sea, si pasas de \[ArduiIDE\] o \[Arduino Cloud\] o \[Steamakersblok\] a Micropytho **tienes que volver a instalar el compilador Micropython**</p>

##### <span style="color: rgb(22, 145, 121);">**¿Y con esto ya puedo crear mis programas con Micropython?**</span>

<span style="color: rgb(0, 0, 0);">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</span>

##### <span style="color: rgb(22, 145, 121);">**Arduino Lab for Micropython**</span>

Tal y como dice la página [https://docs.arduino.cc/micropython/](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](https://labs.arduino.cc/en/labs/micropython)
- **OpenMW** [https://openmv.io/pages/download](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

[![2024-07-04 09_56_30-Arduino Labs.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-09-56-30-arduino-labs.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-09-56-30-arduino-labs.png)

<p class="callout info">Ejecutamos el programa en el lugar donde lo hemos descomprimido (o donde quieras llevarte la carpeta) :</p>

[![2024-07-04 10_00_12-Arduino.Lab.for.MicroPython-win_x64.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-10-00-12-arduino-lab-for-micropython-win-x64.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-10-00-12-arduino-lab-for-micropython-win-x64.png)

<p class="callout warning">{{@13342#bkmrk-%7B%7B%4012238%23bkmrk-%257b%257}}</p>

Al ejecutar el programa, vemos:

1. Botón para conectar la placa
2. Ejecutar o para el programa
3. Gestor de fichero
4. Donde escribimos el programa
5. Ventana de estado

[![IDEOverview.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/ideoverview.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/ideoverview.png)  
*Licencia CC-BYSA Fuente [https://docs.arduino.cc/micropython/environment/code-editor/](https://docs.arduino.cc/micropython/environment/code-editor/)*

En el gestor de ficheros encontramos

1. **Los archivos que hay en la placa**: Puedes ver y administrar scripts o datos guardados directamente en la placa.
2. **Los archivos que hay en tu equipo**: lo que le permite seleccionar y administrar archivos para cargar o descargar.
3. D**escargar/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.
4. **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.

[![IDEFileManager.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/idefilemanager.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/idefilemanager.png)*Licencia CC-BYSA Fuente [https://docs.arduino.cc/micropython/environment/code-editor/](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:

```python
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/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)

Pulsamos a conectar, nos pregunta por el puerto

[![2024-06-14 23_20_41-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/2024-06-14-23-20-41-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/2024-06-14-23-20-41-arduino-lab-for-micropython.png)

Runeamos y vamos contestando a sus preguntas

[![2024-06-14 23_22_58-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/2024-06-14-23-22-58-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/2024-06-14-23-22-58-arduino-lab-for-micropython.png)

<p class="callout warning">**ATENCIÓN** si quieres que se ejecute en el Alvik SIN necesidad de darle al "play" del programa, entonces lo tienes que grabar como main.py en el Alvik entonces se ejecuta automáticamente</p>

# Empezando MicroPython de Alvik

<p class="callout success"><span style="color: rgb(0, 0, 0);">Inspirado en el esquema del [tutorial MicroPython Basics ](https://docs.arduino.cc/micropython/basics/micropython-basics/)autora Francesca Sanfilippo &amp; Karl Söderby</span></p>

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

```python
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:

```python
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

```python
import time

frase = "Hola mundo "
contador = 0

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

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

El resultado:

[![2024-06-15 07_32_00-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/2024-06-15-07-32-00-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/2024-06-15-07-32-00-arduino-lab-for-micropython.png)

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

```python
import time

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

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

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

Lo que provoca que a los 20 finalice

[![2024-06-15 07_44_37-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/2024-06-15-07-44-37-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/2024-06-15-07-44-37-arduino-lab-for-micropython.png)

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

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

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

printCatedus()
```

[![2024-06-15 07_51_00-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/2024-06-15-07-51-00-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/2024-06-15-07-51-00-arduino-lab-for-micropython.png)

Con esto ya podemos avanzar, pero si quieres[   ](https://drive.google.com/file/d/1pUxzeBBbpskfIHHtlH68zrOPEIFKR_vE/view?usp=sharing)

# Introducción al Python

{{@12327}}

# Arduino Alvik API

<p class="callout warning">Estas instrucciones son específicas del ARDUINO ALVIK </p>

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

```python
alvik = ArduinoAlvik()
alvik.begin()
```

Entonces ya podemos usar las siguientes: (extraido de [https://docs.arduino.cc/tutorials/alvik/api-overview/](https://docs.arduino.cc/tutorials/alvik/api-overview/) )

<p class="callout success">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](https://libros.catedu.es/books/arduino-alvik/page/arduino-ide-sin-iot-un-pequena-danza) </p>

<table border="1" id="bkmrk-funcion-salida-stop%28" style="border-collapse: collapse; width: 100%; height: 313.598px;"><colgroup><col style="width: 53.8625%;"></col><col style="width: 46.2434%;"></col></colgroup><tbody><tr><td>**FUNCION con sus Inputs**</td><td>**Outputs**</td></tr><tr><td style="height: 29.6806px;">stop()</td><td style="height: 29.6806px;">para todas las funciones Alvik</td></tr><tr style="height: 46.4722px;"><td style="height: 46.4722px;">is\_on()</td><td style="height: 46.4722px;">true si esta encendido  
false si esta apagado</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">is\_target\_reached()</td><td style="height: 29.6806px;">true si ha enviado M o R en el mensaje</td></tr><tr><td>get\_ack()</td><td>last\_ack: el valor del último mensaje</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">stop()</td><td style="height: 29.6806px;">para todas las funciones Alvik</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">get\_orientation()</td><td style="height: 29.6806px;">r: valor de balanceo p: valor de cabeceo y: valor de guiñada</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">get\_accelerations()

ver uso en   
[https://libros.catedu.es/books/arduino-alvik/page/programas-de-ejemplo](https://libros.catedu.es/books/arduino-alvik/page/programas-de-test)

</td><td style="height: 29.6806px;">ax  
ay  
az</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">get\_gyros()  
  
ver uso en   
[https://libros.catedu.es/books/arduino-alvik/page/programas-de-ejemplo](https://libros.catedu.es/books/arduino-alvik/page/programas-de-test)

</td><td style="height: 29.6806px;">gx  
by  
gz</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">get\_imu()</td><td style="height: 29.6806px;">las 6 anteriores</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">get\_line\_sensors()</td><td style="height: 29.6806px;">left  
center

right

</td></tr><tr style="height: 29.6806px;"><td style="height: 29.6806px;">brake()</td><td style="height: 29.6806px;">Frena el robot</td></tr><tr><td>get\_battery\_charge()</td><td>battery\_soc: el % de la batería</td></tr><tr><td>get\_touch\_any()</td><td>touch\_any es true si se ha apretado cualquier botón</td></tr><tr><td>get\_touch\_ok()   
get\_touch\_cancel()   
get\_touch\_center()  
get\_touch\_up()  
get\_touch\_left()  
get\_touch\_down()  
get\_touch\_right()  
</td><td>touch\_ok es true si se ha apretado ok etc...

ver ejemplos en

[https://libros.catedu.es/books/arduino-alvik/page/robotica-para-infantil](https://libros.catedu.es/books/arduino-alvik/page/robotica-para-infantil)

y en

[https://libros.catedu.es/books/arduino-alvik/page/mensajes-a-telegram](https://libros.catedu.es/books/arduino-alvik/page/mensajes-a-telegram)

</td></tr><tr><td>get\_color\_raw()  
get\_color\_label()  
</td><td>color</td></tr><tr><td>get\_version()  
print\_status()  
</td><td>versión del firmware  
para actualizarlo ver [https://docs.arduino.cc/tutorials/alvik/user-manual/#how-to-upload-firmware](https://docs.arduino.cc/tutorials/alvik/user-manual/#how-to-upload-firmware)

</td></tr><tr><td>set\_behaviour(behaviour: int)</td><td>  
</td></tr><tr><td>rotate(angle: float, unit: str = 'deg', blocking: bool = True)</td><td>  
</td></tr><tr><td>move(distance: float, unit: str = 'cm', blocking: bool = True)</td><td>  
</td></tr><tr><td>get\_wheels\_speed(unit: str = 'rpm')</td><td>left\_wheel\_speed: the speed value  
right\_wheel\_speed: the speed value</td></tr><tr><td>set\_wheels\_speed(left\_speed: float, right\_speed: float, unit: str = 'rpm')</td><td>  
</td></tr><tr><td>set\_wheels\_position(left\_angle: float, right\_angle: float, unit: str = 'deg')</td><td>  
</td></tr><tr><td>get\_wheels\_position(unit: str = 'deg')</td><td>angular\_velocity</td></tr><tr><td>drive(linear\_velocity: float, angular\_velocity: float, linear\_unit: str = 'cm/s',angular\_unit: str = 'deg/s')</td><td>  
</td></tr><tr><td>get\_drive\_speed(linear\_unit: str = 'cm/s', angular\_unit: str = 'deg/s')</td><td>linear\_velocity: speed of the robot.  
angular\_velocity: speed of the wheels.</td></tr><tr><td>reset\_pose(x: float, y: float, theta: float, distance\_unit: str = 'cm', angle\_unit: str = 'deg')</td><td>  
</td></tr><tr><td>get\_pose(distance\_unit: str = 'cm', angle\_unit: str = 'deg')</td><td>x  
y  
theta</td></tr><tr><td>set\_servo\_positions(a\_position: int, b\_position: int)</td><td>  
</td></tr><tr><td>set\_builtin\_led(value: bool)</td><td>  
</td></tr><tr><td>set\_illuminator(value: bool)</td><td>  
</td></tr><tr><td>color\_calibration(background: str = 'white')</td><td>  
</td></tr><tr><td>rgb2hsv(r: float, g: float, b: float)

</td><td>h: hue value  
s: saturation value  
v: brightness value</td></tr><tr><td>get\_color(color\_format: str = 'rgb')

</td><td>r or h  
g or s  
b or v</td></tr><tr><td>hsv2label(h, s, v)

</td><td>color label: like "BLACK" or "GREEN", if possible, otherwise return "UNDEFINED"  
</td></tr><tr><td>get\_distance(unit: str = 'cm')

</td><td>lee la distancia del sensor TOF:  
ver ejemplo en [https://libros.catedu.es/books/arduino-alvik/page/evita-obstaculos](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  
</td></tr><tr><td>get\_distance\_top(unit: str = 'cm')

</td><td>top\_tof: 45° to the top object distance  
</td></tr><tr><td>get\_distance\_bottom(unit: str = 'cm')

</td><td>bottom\_tof: 45° to the bottom object distance  
</td></tr><tr><td>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 = ())

</td><td>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

</td></tr></tbody></table>

##### <span style="color: rgb(22, 145, 121);">**Unidades**</span>

- 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.

<p class="callout info">¿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</p>

# MicroPython sin IoT

# GPIO del ESP32

##### <span style="color: rgb(22, 145, 121);">**Mapa de los pines en el Arduino Nano ESP32** </span>

[![2024-07-07 20_10_30-Exploring the Arduino Nano ESP32 _ MicroPython & IoT Cloud - YouTube.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-20-10-30-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-20-10-30-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)  
Extraído de[ Youtube Exploring the Arduino Nano ESP32](https://www.youtube.com/watch?v=R51tf66es9w&t=1286s)

Como podemos observar, nuestro objetivo pues es el GPIO0

##### <span style="color: rgb(22, 145, 121);">**¿Dónde está físicamente los GPIO ?**</span>

Pues como podemos ver en este esquema el GPIO0 está en el pin BOOT1

[![2024-07-07 20_14_06-Alvik User Manual _ Arduino Documentation.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-20-14-06-alvik-user-manual-arduino-documentation.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-20-14-06-alvik-user-manual-arduino-documentation.png)  
Fuente CC-BY-SA [https://docs.arduino.cc/tutorials/alvik/user-manual/](https://docs.arduino.cc/tutorials/alvik/user-manual/)

- <p class="callout warning">SI USAMOS MICROPYTHON TENEMOS QUE USAR LAS VERDES</p>
- <p class="callout warning">SI USAMOS CÓDIGO ARDUINO IDE TENEMOS QUE USAR LAS ROJAS</p>

<p class="callout info">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.](https://libros.catedu.es/books/arduino-alvik/page/instalar-micropython)</p>

# Parpadeo LED ESP32

##### <span style="color: rgb(22, 145, 121);">**Objetivo**</span>

Vamos a hacer que parpadee el RGB integrado que tiene el ESP32 concretamente el color verde.

##### <span style="color: rgb(22, 145, 121);">**Programa**</span>

```
#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)
```

##### <span style="color: rgb(22, 145, 121);">**Aclaraciones**</span>

- 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

<details id="bkmrk-%C2%BFy-si-queremos-que-p"><summary>¿Y si queremos que parpadee el RGB en color ROJO qué cambiamos?</summary>

Easy peasy, cambiamos **myLED = Pin (0, Pin.OUT)** por **myLED = Pin (46, Pin.OUT)**

</details>Que como puedes ver coincide también con un pin de poner en modo Bootloader: el BOOT0

<p class="callout info">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</p>

<details id="bkmrk-%C2%BFy-si-queremos-que-p-1"><summary>¿Y si queremos que parpadee el led color VERDE que hay al lado del USB (LED BUILTIN) ? ¿Qué cambiamos?</summary>

Easy peasy, cambiamos **myLED = Pin (0, Pin.OUT)** por **myLED = Pin (48, Pin.OUT)**

</details>##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>:

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/XlbX6xPrqNE" title="July 4, 2024" width="478"></iframe>

# Parpadeo leds Alvik

##### <span style="color: rgb(22, 145, 121);">**El programa**</span>

```python
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/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)

##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="602" src="https://www.youtube.com/embed/d_cLdqU8Koo" title="June 14, 2024" width="338"></iframe>

# Danza

##### <span style="color: rgb(22, 145, 121);">**Programa**</span>

```python
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/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)

##### <span style="color: rgb(22, 145, 121);">**Vídeo**</span>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="602" src="https://www.youtube.com/embed/3uW_2uUMuTc" title="June 15, 2024" width="338"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Más caña**</span>

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?

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="602" src="https://www.youtube.com/embed/rAAwrOV7CRo" title="June 15, 2024" width="338"></iframe>

# 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.

<p class="callout info">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](https://libros.catedu.es/books/arduino-alvik/page/que-es-arduino-alvik)</p>

[![image.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/Rr2image.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/Rr2image.png)Fuente [https://docs.arduino.cc/tutorials/alvik/getting-started/](https://docs.arduino.cc/tutorials/alvik/getting-started/) Author<svg fill="none" height="4" viewbox="0 0 3 4" width="3" xmlns="http://www.w3.org/2000/svg"><circle cx="1.5" cy="2" fill="#95A5A6" r="1.5"></circle></svg>Jose 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

[![image.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/5hzimage.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/5hzimage.png)Fuente [https://docs.arduino.cc/tutorials/alvik/getting-started/](https://docs.arduino.cc/tutorials/alvik/getting-started/) Author<svg fill="none" height="4" viewbox="0 0 3 4" width="3" xmlns="http://www.w3.org/2000/svg"><circle cx="1.5" cy="2" fill="#95A5A6" r="1.5"></circle></svg>Jose 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).

```python
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)

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/6Nz4B13j3Vg" title="July 12, 2024" width="478"></iframe>

Más preciso (agradecimientos a Mario Monteagudo Alda CP Ejea)

```python
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

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/jJ_ulJH5SLM" width="560"></iframe>

# Evita obstáculos

##### <span style="color: rgb(22, 145, 121);">**Programa**</span>

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/](https://docs.arduino.cc/tutorials/alvik/getting-started/) Author<svg fill="none" height="4" viewbox="0 0 3 4" width="3" xmlns="http://www.w3.org/2000/svg"><circle cx="1.5" cy="2" fill="#95A5A6" r="1.5"></circle></svg>Jose Garcia

```python
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')

```

##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<span style="color: rgb(0, 0, 0);">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:</span>  
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/CWx501rFpyA" title="July 12, 2024" width="478"></iframe>

# Programas de test

En el repositorio [https://github.com/arduino/arduino-alvik-mpy/tree/main/examples](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

<table id="bkmrk-sensor-name-part-nam"><thead><tr><th>**Sensor name**</th><th>**Part name**</th><th>**Test program name**</th></tr></thead><tbody><tr><td>RGB Color detection</td><td>APDS 9660</td><td>read\_color\_sensor.py</td></tr><tr><td>ToF 8x8 Array - up to 350 cm</td><td>LSM6DSOX</td><td>read\_tof.py</td></tr><tr><td>IMU - 6 degree</td><td>VL53L7CX</td><td>read\_imu.py</td></tr><tr><td>3x Line follower</td><td>custom made</td><td>line\_follower.py</td></tr><tr><td>7x Touch sensor</td><td>AT42QT2120</td><td>read\_touch.py</td></tr><tr><th>**Actuator name**</th><th>**Part name**</th><th>**Test program name**</th></tr><tr><td>Geared motors w/ encoder</td><td>GM12-N20VA-08255-150-EN</td><td>wheels\_positions.py</td></tr><tr><td>RGB LEDs</td><td>RGB LEDs</td><td>leds\_settings.py</td></tr></tbody></table>

##### <span style="color: rgb(22, 145, 121);">**Detector de color**</span>

Modificación del read\_color\_sensor.py

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

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/j0tgpjJKK40" width="560"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Detector TOF**</span>

Si ejecutamos read\_tof.py

```python
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

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/XHXCfblL4ks" width="560"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Giro**</span>

Si ejecutamos read\_imu.py

```python
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

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/E083Xe_IMFY" width="560"></iframe>

# Robótica para infantil

Se puede hacer un robot tipo Beebot, Colby, Escornabot.   
Si no conocéis estos robots mirar [el curso de Aularagon](https://moodle.catedu.es/course/view.php?id=55)

[![bee-bot-2591033446.jpg](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/bee-bot-2591033446.jpg)](https://libros.catedu.es/uploads/images/gallery/2024-06/bee-bot-2591033446.jpg)[![escornabot-4126551417.jpg](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/escornabot-4126551417.jpg)](https://libros.catedu.es/uploads/images/gallery/2024-06/escornabot-4126551417.jpg)

Podemos cargar el siguiente programa, modificado de [https://github.com/arduino/arduino-alvik-mpy/blob/main/examples/touch\_move.py](https://github.com/arduino/arduino-alvik-mpy/blob/main/examples/touch_move.py)

```python
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 :

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="567" src="https://www.youtube.com/embed/h8wAwcPxYL0" title="June 15, 2024" width="319"></iframe>

# Manejando servos

##### <span style="color: rgb(22, 145, 121);">**Conexión**</span>

Se pueden conectar hasta dos servos, el A es el de arriba y el B es el de abajo

[![2024-07-11 13_06_45-Qué es Arduino Alvik _ Librería CATEDU.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-13-06-45-que-es-arduino-alvik-libreria-catedu.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-13-06-45-que-es-arduino-alvik-libreria-catedu.png)

##### <span style="color: rgb(22, 145, 121);">**La api set\_servo\_positions** </span>

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

##### **<span style="color: rgb(22, 145, 121);">Programa</span>**

Extraído de [https://docs.arduino.cc/tutorials/alvik/user-manual/#add-servo-motors](https://docs.arduino.cc/tutorials/alvik/user-manual/#add-servo-motors)

```python
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)
```

##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/hIoayWNgGao" title="July 11, 2024" width="478"></iframe>

# Más ejemplos

Los puedes encontrar en [https://courses.arduino.cc/explore-robotics-micropython/](https://courses.arduino.cc/explore-robotics-micropython/)

[![2025-03-28 14_18_30-Lessons _ Explore Robotics in MicroPyton.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-28-14-18-30-lessons-explore-robotics-in-micropyton.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-28-14-18-30-lessons-explore-robotics-in-micropyton.png)  
  
[![2025-03-28 14_19_02-Lessons _ Explore Robotics in MicroPyton.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-28-14-19-02-lessons-explore-robotics-in-micropyton.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-28-14-19-02-lessons-explore-robotics-in-micropyton.png)

[![2025-03-28 14_19_56-Lessons _ Explore Robotics in MicroPyton.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-28-14-19-56-lessons-explore-robotics-in-micropyton.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-28-14-19-56-lessons-explore-robotics-in-micropyton.png)

# 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.

<p class="callout info">Ejemplos de I2C con Arduino:  
- Conexión con pantalla LCD [https://libros.catedu.es/books/programa-arduino-mediante-codigo/page/lcd](https://libros.catedu.es/books/programa-arduino-mediante-codigo/page/lcd)  
- Comunicación entre dos Arduinos [https://dronebotworkshop.com/i2c-arduino-arduino/](https://dronebotworkshop.com/i2c-arduino-arduino/)</p>

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 :  
[![datasheet_connectors.png](https://libros.catedu.es/uploads/images/gallery/2024-06/scaled-1680-/datasheet-connectors.png)](https://libros.catedu.es/uploads/images/gallery/2024-06/datasheet-connectors.png)

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/u9lBFCULtME?si=lXLv4Sq-YBCfOVuW&start=1654" title="YouTube video player" width="560"></iframe>

Podemos escanear los dispositivos I2C que están conectados y averiguar la dirección que tienen asociada :

```python
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](https://docs.arduino.cc/tutorials/alvik/user-manual/#grove-connectors)

He conectado un OLED en el conector Grove

[![2025-05-07 13_24_53-WhatsApp.png](https://libros.catedu.es/uploads/images/gallery/2025-05/scaled-1680-/2025-05-07-13-24-53-whatsapp.png)](https://libros.catedu.es/uploads/images/gallery/2025-05/2025-05-07-13-24-53-whatsapp.png)

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:

[![2025-05-07 13_29_41-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2025-05/scaled-1680-/2025-05-07-13-29-41-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2025-05/2025-05-07-13-29-41-arduino-lab-for-micropython.png)

Si ejecutamos el siguiente script, vemos que necesita importar la **librería ssd1306** (se puede ver en su [repositorio](https://github.com/lexus2k/ssd1306), 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](https://docs.micropython.org/en/latest/esp8266/tutorial/ssd1306.html)

```python
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 :

[![2025-05-07 13_35_08-WhatsApp.png](https://libros.catedu.es/uploads/images/gallery/2025-05/scaled-1680-/2025-05-07-13-35-08-whatsapp.png)](https://libros.catedu.es/uploads/images/gallery/2025-05/2025-05-07-13-35-08-whatsapp.png)

<p class="callout info">Si quieres por ejemplo esto :  
[![hello_world.jpg](https://libros.catedu.es/uploads/images/gallery/2025-05/scaled-1680-/hello-world.jpg)](https://libros.catedu.es/uploads/images/gallery/2025-05/hello-world.jpg)  
mira este [código](https://github.com/TimHanewich/MicroPython-SSD1306)</p>

# MicroPython con IoT

# ¿Qué es Internet de las cosas IoT?

{{@5133}}

# 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:

&gt;&gt;&gt;   
raw REPL; CTRL-B to exit  
&gt;OK  
conectando.....  
Alvik se conectó a NOMBREREDWIFI  
&gt;

# Crear bot en Telegram

{{@10223}}

# Encontrar tu ID en Telegram

{{@10224}}

# 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&amp;text=MENSAJE\_QUE\_QUIERA\_ENVIAR](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)
  
```

##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/8jN3Ns8uW7g" width="560"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Para saber más...**</span>

- Si en vez de hacerlo con Micropython lo quieres hacer con ArduinoIDE [te recomiendo esta página](https://blog.330ohms.com/2021/03/09/crea-tu-propio-bot-de-telegram-con-esp32/)
- [Un ejemplo ](https://github.com/ronibandini/Alvik/blob/main/obstacles/obstacles.py)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](https://www.youtube.com/watch?v=eZkb9omr-sA)

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/eZkb9omr-sA" width="560"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Paso 1: Librería uTelegram.py** </span>

Del repositorio de Jordi Prats  
[https://github.com/jordiprats/micropython-utelegram/blob/master/utelegram.py](https://github.com/jordiprats/micropython-utelegram/blob/master/utelegram.py)

[![2024-07-06 22_09_11-micropython-utelegram_utelegram.py at master · jordiprats_micropython-utelegram.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-22-09-11-micropython-utelegram-utelegram-py-at-master-jordiprats-micropython-utelegram.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-22-09-11-micropython-utelegram-utelegram-py-at-master-jordiprats-micropython-utelegram.png)

```python
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

[![2024-07-06 22_12_32-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-22-12-32-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-22-12-32-arduino-lab-for-micropython.png)

##### <span style="color: rgb(22, 145, 121);">**Paso 2 Archivo config.py**</span>

<span style="color: rgb(0, 0, 0);">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](https://github.com/jordiprats/micropython-utelegram/blob/master/demo/config.py-demo) o también se puede copiar y pegar de aquí mismo</span>

```
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

[![2024-07-06 23_01_23-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-23-01-23-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-23-01-23-arduino-lab-for-micropython.png)

y como antes, lo pasamos al ESP32 Alvik

[![2024-07-06 23_05_34-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-23-05-34-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-23-05-34-arduino-lab-for-micropython.png)

<p class="callout success">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](https://libros.catedu.es/books/arduino-alvik/page/mensajes-a-telegram) </p>

##### <span style="color: rgb(22, 145, 121);">**Paso 3 Programa principal main.py**</span>

El programa lo podemos descargar de [https://github.com/jordiprats/micropython-utelegram/blob/master/demo/main.py](https://github.com/jordiprats/micropython-utelegram/blob/master/demo/main.py)

o de aquí mismo

<p class="callout info">tal cual, no hay que poner nuestro ssid, ni password ni token pues lo "lee" de config.py</p>

```

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')
```

<p class="callout success">🤔No sé por qué hay que esperar 20 segundos en utime.sleep(20) 🤷‍♂️sospecho que necesita tiempo para estar preparado para "escuchar"</p>

Y lo llevamos al ESP32

[![2024-07-06 23_12_08-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-23-12-08-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-23-12-08-arduino-lab-for-micropython.png)

##### <span style="color: rgb(22, 145, 121);">**Ejecución**</span>

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

[![2024-07-06 23_14_35-Arduino Lab for MicroPython.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-23-14-35-arduino-lab-for-micropython.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-23-14-35-arduino-lab-for-micropython.png)

Nos vamos a Telegram al usuario del bot que hemos creado, le tecleamos **/ping** y contesta el ESP32 **pong**

[![2024-07-06 23_17_14-JavierArduino — Mozilla Firefox.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-06-23-17-14-javierarduino-mozilla-firefox.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-06-23-17-14-javierarduino-mozilla-firefox.png)

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/eZkb9omr-sA" width="560"></iframe>

# 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')
```

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/jwe__PTmp7g" width="560"></iframe>

# Programando en bloques mBlock

# Preparar el ALVIK para mBlock: Actualizar el firmware de Alvik

<p class="callout success"><span style="color: rgb(0, 0, 0);">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**</span></p>

<p class="callout warning"><span style="color: rgb(0, 0, 0);">Si ya tiene el firmware instalado en el Alvik **puedes saltarte esta página**</span></p>

<p class="callout warning"><span style="color: rgb(0, 0, 0);">Con este firmware **no** podemos programar con Arduino IDE</span></p>

##### <span style="color: rgb(22, 145, 121);">**Antes de nada enciende el Alvik con esta precaución :**</span>

<p class="callout warning">Primero **<span style="background-color: rgb(241, 196, 15);">nos aseguramos que el Alvik este <span style="color: rgb(0, 0, 0);">APAGADO </span>antes de conectarlo con el PC</span>   
<span style="color: rgb(224, 62, 45);">en caso contrario se puede perjudicar la batería</span>**[![robot-off.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/robot-off.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/robot-off.png)  
Licencia CC-BY-NC-SA origen [https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)  
  
Luego lo **conectamos** por cable[![connecting-final.gif](https://libros.catedu.es/uploads/images/gallery/2024-06/connecting-final.gif)](https://libros.catedu.es/uploads/images/gallery/2024-06/connecting-final.gif)  
Licencia CC-BY-NC-SA origen [https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)  
  
Y ahora ya podemos **encender** nuestro Alvik  
[![alvik-on.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/alvik-on.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/alvik-on.png)  
Licencia CC-BY-NC-SA origen [https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)</p>

##### <span style="color: rgb(22, 145, 121);">**Actualizamos el FIRMWARE**</span>

Esto lo hacemos una vez, entramos en [https://alvikupdate.arduino.cc/](https://alvikupdate.arduino.cc/) damos a **conectar** y luego **updated** *(si no sabes qué puerto es, desconecta y conecta y te fijas cual aparece)*

<p class="callout info">Puede tardar varios ciclos, **paciencia**</p>

**[![2025-03-28 10_18_52-Arduino® Alvik Updater 🤖.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-28-10-18-52-arduino-alvik-updater.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-28-10-18-52-arduino-alvik-updater.png)**

<p class="callout warning">Asegúrate de tener el ALVIK **encendido**</p>

Hasta que sale esta pantalla de éxito

[![2025-03-26 11_59_36-Arduino® Alvik Updater 🤖.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-11-59-36-arduino-alvik-updater.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-11-59-36-arduino-alvik-updater.png)

## <span style="color: rgb(22, 145, 121);">**ATENCIÓN ¿Y SI DA PROBLEMAS?**</span>

Por ejemplo se ha quedado enganchado, lo has desconectado antes de hora... entonces la solución pasa por utilizar un flasheador más potente

##### <span style="color: rgb(22, 145, 121);">**MicroPython Installer**</span>

[Descargamos el programa ](https://labs.arduino.cc/en/labs/micropython-installer)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](https://labs.arduino.cc/en/labs/micropython-installer)

[![2024-07-04 19_17_33-MicroPython Installer.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-19-17-33-micropython-installer.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-19-17-33-micropython-installer.png)

<p class="callout warning">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 ](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader) y vuelve a intentarlo con el MicroPython Installer</p>

Al acabar de instalar, sale este mensaje :

[![2025-03-28 10_15_55-MicroPython Installer.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-28-10-15-55-micropython-installer.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-28-10-15-55-micropython-installer.png)

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/](https://alvikupdate.arduino.cc/) damos a **conectar** y luego **updated** *(si no sabes qué puerto es, desconecta y conecta y te fijas cual aparece)*

<p class="callout info">AQUÍ VA A TARDAR VARIOS, VARIOS CICLOS, **paciencia, paciencia**</p>

**[![2025-03-28 10_18_52-Arduino® Alvik Updater 🤖.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-28-10-18-52-arduino-alvik-updater.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-28-10-18-52-arduino-alvik-updater.png)**

<p class="callout warning">Asegúrate de tener el ALVIK **encendido**</p>

Hasta que sale esta pantalla de éxito

[![2025-03-26 11_59_36-Arduino® Alvik Updater 🤖.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-11-59-36-arduino-alvik-updater.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-11-59-36-arduino-alvik-updater.png)

# Instalando mBlock

{{@13340}}

# Instalando la extensión ALVIK en mBlock

##### <span style="color: rgb(22, 145, 121);">**En mBlock instalar la extensión Alvik**</span>

1. <span style="color: rgb(0, 0, 0);">Pinchamos en el + de **añadir** dispositivo</span>
2. <span style="color: rgb(0, 0, 0);">**buscamos** Alvik </span>
3. <span style="color: rgb(0, 0, 0);">apretamos al + de **descargarlo** (al finalizar desaparece el + )</span>
4. <span style="color: rgb(0, 0, 0);">dos clicks y se **instala**</span>

<span style="color: rgb(0, 0, 0);">[![2025-03-25 23_34_33-mBlock v5.4.3.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-25-23-34-33-mblock-v5-4-3.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-25-23-34-33-mblock-v5-4-3.png)  
*Licencia CC-BY-SA [https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/](https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/)*  
</span>

<span style="color: rgb(0, 0, 0);">![COM-port.png](https://docs.arduino.cc/4d06db3ba809aa6d418afa2d31f7b51b/add-device.gif)</span>

<span style="color: rgb(0, 0, 0);">Se nos instalan una colección de instrucciones para controlar el ALVIK completamente </span>

##### [![2025-03-26 10_39_58-mBlock v5.4.3.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-10-39-58-mblock-v5-4-3.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-10-39-58-mblock-v5-4-3.png)

# Dos formas de programar en mBlock

{{@2986}}

# Un ejemplo de programa en vivo

##### <span style="text-decoration: underline;"><span style="color: rgb(22, 145, 121); text-decoration: underline;">**PROBANDO EN VIVO** </span></span>

1. Entramos en mBlok, en dispositivos
2. Seleccionamos Alvik
3. En vivo
4. Conectar
5. 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.

[![2025-03-26 11_03_38-Configuración.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-11-03-38-configuracion.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-11-03-38-configuracion.png)

A funcionar así de sencillo !!!!!

<p class="callout warning">la primera vez, tarda algo en responder, paciencia</p>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/pPkUVh7UqyI" title="26 de marzo de 2025" width="478"></iframe>

<p class="callout success">**RETO** Ves probando así de rápido la multitud de instrucciones gráficas para saber cómo funcionan</p>

# Un ejemplo de programa en carga

Como ejemplo de programa en carga

1. Creamos un sencillo programa con eventos de **cuando botón ... es presionado ...**
2. Elegimos el botón **Cargar**
3. **Subir** código

[![2025-03-26 12_38_48-mBlock v5.4.3.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-12-38-48-mblock-v5-4-3.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-12-38-48-mblock-v5-4-3.png)

Ahora el robot **es libre en movimientos** no depende del ordenador, por lo tanto podemos desconectar el cable

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/J-rgIfJ8ewk" width="560"></iframe>

# 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/](https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/)* proponen este programa

<video controls="controls" height="394" style="width: 790px; height: 394px;" width="790"> <source src="https://docs.arduino.cc/12c3deb73b1dee522a0b0532e8afcf92/tof-video.mp4" type="video/mp4"></source></video>  
*Licencia CC-BY-SA fuente [https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/](https://docs.arduino.cc/tutorials/alvik/getting-started-mblock/)*

Pero no gira, luego proponemos este [https://planet.mblock.cc/project/5547662](https://planet.mblock.cc/project/5547662)

[![2025-03-26 13_13_53-mBlock v5.4.3.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-13-13-53-mblock-v5-4-3.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-13-13-53-mblock-v5-4-3.png)

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/gOKHZ6CqQ28" title="EVITA OBSTACULOS mblock alvik" width="478"></iframe>

# Métodos para interactuar los objetos y el robot (dispositivo)

{{@13349}}

# 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<span style="background-color: rgb(251, 238, 184);"> **vamos a trabajar EN VIVO**</span>

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

[![2025-03-26 14_10_40-mBlock v5.4.3.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-14-10-40-mblock-v5-4-3.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-14-10-40-mblock-v5-4-3.png)

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.

[![2025-03-26 14_12_05-mBlock v5.4.3.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-26-14-12-05-mblock-v5-4-3.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-26-14-12-05-mblock-v5-4-3.png)

El programa lo tienes aquí [https://planet.mblock.cc/project/5548364](https://planet.mblock.cc/project/5548364)

Y este es el resultado

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/k3RkCdRqhAs" width="560"></iframe>

# Arduino IDE

# ¿Qué es Arduino IDE?

{{@2938#bkmrk-necesitar%C3%A1s-el-entor}}

{{@2938#bkmrk-en-linux-puede-salir}}

{{@2938#bkmrk-est%C3%A1-constituido-por}}

{{@2938#bkmrk-arduino-utiliza-para}}

{{@2938#bkmrk-}}

# Preparar Arduino IDE para Alvik: Instalar Placa ESP32 y libreria Arduino Avik

##### <span style="color: rgb(22, 145, 121);">**Instalar placa Arduino ESP32 Boards by Arduino**</span>

Lo primero que tenemos que hacer es instalar la placa Arduino ESP32 tal y como dice esta captura

[![2024-07-04 11_15_28-sketch_jun3a _ Arduino IDE 2.3.2.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-15-28-sketch-jun3a-arduino-ide-2-3-2.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-15-28-sketch-jun3a-arduino-ide-2-3-2.png)

O [este vídeo a partir de 9:30 ](https://youtu.be/R51tf66es9w?t=571)(pongo el vídeo pues es interesante si quieres aprender más sobre Arduino ESP32)

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="315" src="https://www.youtube.com/embed/R51tf66es9w?si=DAfiKpm7tBEcu7HV&start=570" title="YouTube video player" width="560"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Instalar Librería Arduino\_Alvik.h**</span>

<p class="callout success"><span style="color: rgb(0, 0, 0);">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](https://libros.catedu.es/books/arduino-alvik/page/arduino-alvik-api) </span></p>

Para ejecutarlo en el Arduino IDE tenemos que tener esta librería que es fácilmente instalable:

[![2024-07-11 21_10_55-Configuración.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-21-10-55-configuracion.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-21-10-55-configuracion.png)

Tal y como dice [https://docs.arduino.cc/tutorials/alvik/setting-alvik-arduino-ide/](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

<p class="callout info"><span style="color: rgb(0, 0, 0);">**¿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](https://libros.catedu.es/books/raspberry-pi/page/43-domotica), o a la hora de q[uemar el Nano Arduino como Arduino UNO en el curso de mClon](https://libros.catedu.es/books/mclon-con-nanoarduino/page/11-placa-electronica-nanoarduino)</span></p>

<span style="color: rgb(0, 0, 0);">Tal y como dice en [https://docs.arduino.cc/tutorials/alvik/setting-alvik-arduino-ide/](https://docs.arduino.cc/tutorials/alvik/setting-alvik-arduino-ide/)</span>

1. <span style="color: rgb(0, 0, 0);">**cortocircuitar B1 y GND  
    [![2024-07-11 20_11_20-Exploring the Arduino Nano ESP32 _ MicroPython & IoT Cloud - YouTube.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-20-11-20-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-20-11-20-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)** Yo lo hago con un destornillador y toco las dos puntas, con cuidado de no tocar nada más.</span>
2. <span style="color: rgb(0, 0, 0);">**Mientras** esta cortocircuitado **PULSA EL BOTÓN RESET  
    [![2025-03-27 18_35_58-oculto _ Librería CATEDU.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-27-18-35-58-oculto-libreria-catedu.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-27-18-35-58-oculto-libreria-catedu.png)** </span>
3. <span style="color: rgb(0, 0, 0);">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**</span>
4. <span style="color: rgb(0, 0, 0);">Abrir el programa </span>**ARDUINO IDE PERO CERRAR OTROS** <span style="color: rgb(0, 0, 0);">(como el Arduino Create Agent que se queda en segundo plano abajo a la derecha , el MicroPython Installer....)  
    [![image.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/aeeimage.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/aeeimage.png)  
    </span>
5. <span style="color: rgb(0, 0, 0);">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.  
    [![2024-07-11 20_23_19-Configuración.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-20-23-19-configuracion.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-20-23-19-configuracion.png)  
    </span>
6. <span style="color: rgb(0, 0, 0);">Ir a **Tools-Port** y seleccionar el puerto, habrá cambiado a uno nuevo, puede ser algo parecido a esto :  
    [![2025-03-27 13_55_44-sketch_mar27a _ Arduino IDE 2.3.4.png](https://libros.catedu.es/uploads/images/gallery/2025-03/scaled-1680-/2025-03-27-13-55-44-sketch-mar27a-arduino-ide-2-3-4.png)](https://libros.catedu.es/uploads/images/gallery/2025-03/2025-03-27-13-55-44-sketch-mar27a-arduino-ide-2-3-4.png)  
    </span>
7. <span style="color: rgb(0, 0, 0);">Ir a **Tools &gt; Board - Arduino ESP32 Boards &gt; Arduino Nano ESP32** (o esp32 &gt; Arduino Nano ESP32 )</span>
8. <span style="color: rgb(0, 0, 0);">Poner Tools-&gt; Programmer- seleccionar **ESPTOOL  
    [![2024-07-11 20_22_12-.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-20-22-12.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-20-22-12.png)**  
    </span>
9. <span style="color: rgb(0, 0, 0);">Sketch &gt; **Upload Using Programmer   
    [![2024-07-11 20_27_00-.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-20-27-00.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-20-27-00.png)** </span>
10. <span style="color: rgb(0, 0, 0);">Cuando salga este mensaje pasar al paso 11  
      
    </span>```
    Leaving...
    Hard resetting via RTS pin...
    ```
11. <span style="color: rgb(0, 0, 0);">Apretar el botón **RESET** y ya puedes o ejecutar un programa en Arduino IDE o instalar MicroPython</span>

<p class="callout success"><span style="color: rgb(0, 0, 0);">**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](https://libros.catedu.es/books/arduino-alvik/page/gpio-del-esp32-lD7)</span></p>

<p class="callout info"><span style="color: rgb(0, 0, 0);">**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](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</span></p>

# Arduino IDE sin IoT: Un pequeña danza

En la pagina [https://www.arduinolibraries.info/libraries/arduino\_alvik](https://www.arduinolibraries.info/libraries/arduino_alvik) o desde [https://github.com/arduino-libraries/Arduino\_Alvik](https://github.com/arduino-libraries/Arduino_Alvik) podemos descargarnos multitud de ejemplos de código escrito en Arduino IDE para manejar este robot

##### <span style="color: rgb(22, 145, 121);">**Una pequeña danza**</span>

 Este sencillo programa hace mover el robot a una velocidad de 10 y va cambiando el giro de 45º a -45º cada segundo

```c++
#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);
}
```

<details id="bkmrk-y-da-este-error-no-d"><summary>y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?</summary>

No has preparado convenientemente el ALVIK haz [https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader)

</details>##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="634" src="https://www.youtube.com/embed/1zG26a3Lf1g" title="July 11, 2024" width="356"></iframe>

# Arduino IDE sin IoT: Evita obstáculos

En la pagina [https://www.arduinolibraries.info/libraries/arduino\_alvik](https://www.arduinolibraries.info/libraries/arduino_alvik) o desde [https://github.com/arduino-libraries/Arduino\_Alvik](https://github.com/arduino-libraries/Arduino_Alvik) podemos descargarnos multitud de ejemplos de código escrito en Arduino IDE para manejar este robot

##### <span style="color: rgb(22, 145, 121);">**Evita obstáculos**</span>

 Este sencillo programa hace mover el robot evitando obstáculos

```c++
#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);
  }
}
```

<details id="bkmrk-y-da-este-error-no-d"><summary>y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?</summary>

No has preparado convenientemente el ALVIK haz [https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader) </details>##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="599" src="https://www.youtube.com/embed/QerJTBuIqSs" title="Evita obstáculos con Arduino IDE y ALVIK" width="337"></iframe>

##### <span style="color: rgb(22, 145, 121);">**Reto**</span>

<p class="callout success">Tienes muchos ejemplos en [https://github.com/arduino-libraries/Arduino\_Alvik/tree/main/examples](https://github.com/arduino-libraries/Arduino_Alvik/tree/main/examples)  
🫵🫵🫵🫵 ¿ A QUE ESPERAS? 🫵🫵🫵</p>

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

```c++
/*
    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

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="815" src="https://www.youtube.com/embed/yzlXUp9fais" title="ARDUINO IDE CONTROL REMOTO ALVIK" width="458"></iframe>

# Internet de las cosas IoT

{{@5133}}

# Arduino IDE con IoT: Escaneo Wifi

Desde [https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiScan/WiFiScan.ino](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](https://app.arduino.cc/sketches/54b6f875-2961-4ec5-8a48-608d9dde5feb?view-mode=preview)

<iframe frameborder="0" src="https://app.arduino.cc/sketches/54b6f875-2961-4ec5-8a48-608d9dde5feb?view-mode=embed" style="height: 510px; width: 100%; margin: 10px 0;"></iframe>

<details id="bkmrk-y-da-este-error-no-d"><summary>y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?</summary>

No has preparado convenientemente el ALVIK haz [https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader)

</details>##### <span style="color: rgb(22, 145, 121);">**Instalando la librería Wifi.h**</span>

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/](https://www.arduino.cc/reference/en/libraries/wifi/)

[![2024-07-04 11_41_25-WiFi - Arduino Reference.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-41-25-wifi-arduino-reference.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-41-25-wifi-arduino-reference.png)

Una vez descargada (un fichero ZIP<span style="text-decoration: underline;"> no lo descomprimas</span>) en el editor Arduino IDE se instala desde este menú

[![2024-07-04 11_43_04-.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-43-04.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-43-04.png)

Seleccionamos el fichero Zip que has descargado y ya tenemos la librería instalada

##### **<span style="color: rgb(22, 145, 121);">Compilamos</span>**

Antes de compilar CONECTAMOS NUESTRO ESP32

[![connecting-final.gif](https://libros.catedu.es/uploads/images/gallery/2024-06/connecting-final.gif)](https://libros.catedu.es/uploads/images/gallery/2024-06/connecting-final.gif)  
Licencia CC-BY-NC-SA origen [https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/](https://courses.arduino.cc/explore-robotics-micropython/lessons/getting-started/)

<p class="callout info">No hace falta encender el robot Arduino Alvik</p>

Y seleccionamos la placa que ha reconocido

[![2024-07-04 11_46_46-sketch_jul4a _ Arduino IDE 2.3.2.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-46-46-sketch-jul4a-arduino-ide-2-3-2.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-46-46-sketch-jul4a-arduino-ide-2-3-2.png)

Y ya se puede compilar !!! no tiene que dar ningún fallo

[![2024-07-04 11_47_46-sketch_jul4a _ Arduino IDE 2.3.2.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-47-46-sketch-jul4a-arduino-ide-2-3-2.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-47-46-sketch-jul4a-arduino-ide-2-3-2.png)

##### <span style="color: rgb(22, 145, 121);">**Subirlo al ESP32**</span>

Pues si lo intentas subir

[![2024-07-04 11_51_03-sketch_jul4a _ Arduino IDE 2.3.2.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-51-03-sketch-jul4a-arduino-ide-2-3-2.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-51-03-sketch-jul4a-arduino-ide-2-3-2.png)

<details id="bkmrk-y-da-este-error-no-d-1"><summary>y da este error NO DEU dfu-util: No DFU capable USB device available Failed uploading: uploading error: exist status 74 ¿Por qué?</summary>

Lee [https://libros.catedu.es/books/arduino-alvik/page/modo-bootloader](https://libros.catedu.es/books/arduino-alvik/page/preparar-alvik-para-arduino-ide-modo-bootloader)

</details>##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

Le damos a subir, y en la ventana de Output da como correcto

[![2024-07-04 11_53_15-sketch_jul4a _ Arduino IDE 2.3.2.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-53-15-sketch-jul4a-arduino-ide-2-3-2.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-53-15-sketch-jul4a-arduino-ide-2-3-2.png)

Y si nos vamos a la ventana del monitor serie

[![2024-07-04 11_54_32-.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-54-32.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-54-32.png)

No nos sale nada !!! le das al botón de reset y ya sale :

[![2024-07-04 11_55_29-sketch_jul4a _ Arduino IDE 2.3.2.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-04-11-55-29-sketch-jul4a-arduino-ide-2-3-2.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-04-11-55-29-sketch-jul4a-arduino-ide-2-3-2.png)

<details id="bkmrk-%C2%BFpuedo-ahora-ejecuta"><summary>¿Puedo ahora ejecutar un programa en MicroPyhon?</summary>

No, tal y como dice aquí [https://libros.catedu.es/books/arduino-alvik/page/instalar-micropython](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á.

</details>

# Arduino IDE con IoT: Arduino Cloud

Esta plataforma [https://docs.arduino.cc/arduino-cloud/](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.

[![2024-07-07 21_26_04-Exploring the Arduino Nano ESP32 _ MicroPython & IoT Cloud - YouTube.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-21-26-04-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-21-26-04-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)Extraído de[ Youtube Exploring the Arduino Nano ESP32](https://www.youtube.com/watch?v=R51tf66es9w&t=1286s)

1. Creamos una cuenta en **Arduino Cloud**
2. Instalamos **Arduino Create Agent**
3. **Build the Thing** es decir preparamos nuestra placa ESP32 con el Sketch 
    1. Creamos the device
    2. Creamos the thing
    3. Añadimos las variables
    4. Creamos el scketch y lo grabamos en el ESP32
4. Construimos un **Dashboard** o panel de control

##### <span style="color: rgb(22, 145, 121);">**PASO 1 LOGUEARSE EN ARDUINO CLOUD**</span>

**En Plan** permite una cuenta gratuita sólo se pueden 2 **things** ver [https://cloud.arduino.cc/plans](https://cloud.arduino.cc/plans)

##### <span style="color: rgb(22, 145, 121);">**PASO 2 ADRUINO CREATE AGENT**</span>

**Arduino Create Agent** te lo puedes descargar desde [https://cloud.arduino.cc/download-agent](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

[![2024-07-07 21_55_42-Editing Page Arduino Cloud _ Librería CATEDU.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-21-55-42-editing-page-arduino-cloud-libreria-catedu.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-21-55-42-editing-page-arduino-cloud-libreria-catedu.png)

##### <span style="color: rgb(22, 145, 121);">**PASO 3 Build the Thing: CREATE DEVICE**</span>

Primero añadimos un Device o placa en [https://app.arduino.cc/devices](https://app.arduino.cc/devices)

[![2024-07-07 21_50_29-Devices _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-21-50-29-devices-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-21-50-29-devices-arduino-cloud.png)

Elegimos placa Arduino

[![2024-07-07 21_52_49-Setup Device _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-21-52-49-setup-device-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-21-52-49-setup-device-arduino-cloud.png)

Si falla, ponemos la placa en modo Bootloader (ver qué es eso en [https://libros.catedu.es/books/arduino-alvik/page/instalar-micropython](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**

**[![2024-07-07 22_43_26-Exploring the Arduino Nano ESP32 _ MicroPython & IoT Cloud - YouTube.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-22-43-26-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-22-43-26-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)**

##### <span style="color: rgb(22, 145, 121);">**PASO 3 Build the Thing: CREATE THING**</span>

<span style="color: rgb(0, 0, 0);">Una vez creada la placa, nos vamos a Thing, crear</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-07 22_45_52-Things _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-22-45-52-things-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-22-45-52-things-arduino-cloud.png)</span>

<span style="color: rgb(0, 0, 0);">Asociamos el Thing al Device, y le configuramos una red wifi (te predirá el Secret Key)</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-10 14_17_16-Untitled Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-10-14-17-16-untitled-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-10-14-17-16-untitled-thing-arduino-cloud.png)</span>

##### <span style="color: rgb(22, 145, 121);">**PASO 3 Build the Thing: CREATE THING-VARIABLES**</span>

<span style="color: rgb(0, 0, 0);">Luego añadimos variables, por ejemplo RGBverde que va a encender y apagar la luz verde, va a ser tipo Bool y Read&amp;Write</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-11 12_15_52-micosa-alvik Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/pPS2024-07-11-12-15-52-micosa-alvik-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/pPS2024-07-11-12-15-52-micosa-alvik-thing-arduino-cloud.png)</span>

##### <span style="color: rgb(22, 145, 121);">**PASO 3 Build the Thing: CREATE THING-SKETCH**</span>

<span style="color: rgb(0, 0, 0);">Dentro de Thinks nos vamos a SKETCH</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-11 12_17_56-micosa-alvik Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-12-17-56-micosa-alvik-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-12-17-56-micosa-alvik-thing-arduino-cloud.png)</span>

<span style="color: rgb(0, 0, 0);">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 :</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-16 10_28_00-DETECTOR CO2 Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-16-10-28-00-detector-co2-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-16-10-28-00-detector-co2-thing-arduino-cloud.png)</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-11 12_19_15-micosa-alvik Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-12-19-15-micosa-alvik-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-12-19-15-micosa-alvik-thing-arduino-cloud.png)</span>

<span style="color: rgb(0, 0, 0);">El otro script es el nombre que hemos creado en Thing y vemos que :</span>

- <span style="color: rgb(0, 0, 0);">LINEA 9 Esta declarada la variable que hemos añadido</span>
- <span style="color: rgb(0, 0, 0);">LINEA 16 Incluye la librería  ***thingProperties.h*** </span>
- <span style="color: rgb(0, 0, 0);">*LINEA 41* Añadimos en setup() la declaración que D13 SERÁ SALIDA **pinMode(D13,OUTPUT);**</span>
- <span style="color: rgb(0, 0, 0);">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</span>

<details id="bkmrk-%C2%BFpor-qu%C3%A9-es-d13%3F-%C2%BFno"><summary>¿Por qué es D13? ¿NO TENDRÍA QUE SER 48?</summary>

Eso ya lo hemos visto en [https://libros.catedu.es/books/arduino-alvik/page/parpadeo-led-esp32](https://libros.catedu.es/books/arduino-alvik/page/parpadeo-led-esp32)

[![2024-07-07 20_14_06-Alvik User Manual _ Arduino Documentation.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-20-14-06-alvik-user-manual-arduino-documentation.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-20-14-06-alvik-user-manual-arduino-documentation.png)  
Fuente [https://docs.arduino.cc/tutorials/alvik/user-manual/](https://docs.arduino.cc/tutorials/alvik/user-manual/)

{{@12239#bkmrk-si-usamos-micropytho}}

</details>```c++
/* 
  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

[![2024-07-11 12_32_16-micosa-alvik Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-12-32-16-micosa-alvik-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-12-32-16-micosa-alvik-thing-arduino-cloud.png)

Ojo, tienes que tener el Arduino **Arduino Create Agent paso 2**

##### <span style="color: rgb(22, 145, 121);">**PASO 4 Dashboard**</span>

<span style="color: rgb(0, 0, 0);">Creamos un panel de control</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-11 12_38_29-Dashboards _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-12-38-29-dashboards-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-12-38-29-dashboards-arduino-cloud.png)</span>

<span style="color: rgb(0, 0, 0);">Y le añadimos un Switch asociado a la variable RGBverde</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-11 12_39_36-ENCENDER-LEDS-ARDUINO-ALVIK Dashboard _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-12-39-36-encender-leds-arduino-alvik-dashboard-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-12-39-36-encender-leds-arduino-alvik-dashboard-arduino-cloud.png)</span>

<span style="color: rgb(0, 0, 0);">Podemos ver el dashboard en un teléfono móvil instalando la [APP Arduino IoT Cloud Remote](https://play.google.com/store/search?q=arduino+cloud+iot&c=apps)</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-11 12_43_31-arduino cloud iot - Aplicaciones de Android en Google Play.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-12-43-31-arduino-cloud-iot-aplicaciones-de-android-en-google-play.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-12-43-31-arduino-cloud-iot-aplicaciones-de-android-en-google-play.png)</span>

<span style="color: rgb(0, 0, 0);">Al loguearse con tu cuenta, ya nos aparece el Dashboard</span>

##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<span style="color: rgb(0, 0, 0);"><iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/YDVMybJtWUU" width="560"></iframe>

</span>

# Arduino IDE con IoT: Coche teledirigido

Aprovechamos[ el programa que enciende y apaga un led por Arduino Cloud](https://libros.catedu.es/books/arduino-alvik/page/arduino-ide-con-iot-arduino-cloud)

##### <span style="color: rgb(22, 145, 121);">**Variables**</span>

Le añadimos tres variables más :

1. **velocidad** tipo entero Read&amp;Write
2. **giro** tipo entero Read&amp;Write
3. **distancia** tipo float Read

[![2024-07-11 23_56_28-micosa-alvik Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-11-23-56-28-micosa-alvik-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-11-23-56-28-micosa-alvik-thing-arduino-cloud.png)

##### <span style="color: rgb(22, 145, 121);">**Sketch**</span>

En thingProperties.h añade **automáticamente** estas variables y funciones, **no tienes que añadirlas** :

```c++
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\];**

<p class="callout info">Nota: la instrucción 41 se han colocado dentro de loop() pero también se podría haber colocado dentro de onGiroChange();  
onVelocidadChange();</p>

```c++
#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
}
```

##### <span style="color: rgb(22, 145, 121);">**Dashboard**</span>

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

[![2024-07-12 00_10_53-ENCENDER-LEDS-ARDUINO-ALVIK Dashboard _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-12-00-10-53-encender-leds-arduino-alvik-dashboard-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-12-00-10-53-encender-leds-arduino-alvik-dashboard-arduino-cloud.png)

##### <span style="color: rgb(22, 145, 121);">**Resultado**</span>

<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" frameborder="0" height="849" src="https://www.youtube.com/embed/5cWl3y3A3z8" title="Video de WhatsApp 2024 07 11 a las 22 33 50 9b9d9c60" width="478"></iframe>

# GPIO del ESP32

{{@13356}}

# Arduino IDE con IoT: ESP32 + Sensores externos + IoT

##### <span style="color: rgb(22, 145, 121);">**OBJETIVO**</span>

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 :

![2024-07-15 13_08_38-esp32 nano arduino at DuckDuckGo.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-13-08-38-esp32-nano-arduino-at-duckduckgo.png) + ![2024-07-15 13_09_30-placa protoboard at DuckDuckGo.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-13-09-30-placa-protoboard-at-duckduckgo.png)

Para ver varias posibilidades, vamos a ver estos sensores y actuadores (recomendamos ver estas páginas [actuadores ](https://libros.catedu.es/books/programa-arduino-mediante-codigo/page/actuadores-y-otras-salidas-GLB)y [sensores](https://libros.catedu.es/books/programa-arduino-mediante-codigo/page/sensores))

- Un led de salida simple, para practicar salida digital en mi caso voy a elegir este gracioso [semáforo](https://www.tiendatec.es/maker-zone/modulos/647-modulo-semaforo-led-tres-colores-para-arduino-8406471540007.html)
- Un [sensor LDR ](https://solectroshop.com/es/sensores-de-luz-y-de-color/1299-sensor-digital-de-intensidad-de-luz-con-foto-resistencia-ldr-con-controlador-lm393.html)pero para practicar los dos tipos de señal, 
    - con salida analógica
    - con salida digital.
- Un [sensor CO2 CCS811 ](https://wiki.keyestudio.com/KS0457_keyestudio_CCS811_Carbon_Dioxide_Air_Quality_Sensor)con protocolo I2C

+[![2024-07-15 13_11_03-semaforo arduino at DuckDuckGo.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-13-11-03-semaforo-arduino-at-duckduckgo.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-15-13-11-03-semaforo-arduino-at-duckduckgo.png)+![sensorluzarduino.jpg](https://libros.catedu.es/uploads/images/gallery/2022-10/scaled-1680-/sensorluzarduino.jpg)+![CCS811-KEYSTUDUUDIO.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/ccs811-keystuduudio.png)

##### <span style="color: rgb(22, 145, 121);">**ESQUEMA DE CONEXIONES**</span>

- <span style="color: rgb(0, 0, 0);">**SEMAFORO** </span>
    - <span style="color: rgb(0, 0, 0);">LED ROJO al D1 del ESP32</span>
    - <span style="color: rgb(0, 0, 0);">GND a GND</span>
- **<span style="color: rgb(0, 0, 0);">MODULO SENSOR LDR</span>**
    - <span style="color: rgb(0, 0, 0);">SEÑAL DIGITAL al D0 del ESP32</span>
    - <span style="color: rgb(0, 0, 0);">SEÑAL ANALÓGICA al A0 del ESP32</span>
    - <span style="color: rgb(0, 0, 0);">VCC a 3V3</span>
    - <span style="color: rgb(0, 0, 0);">GND A GND</span>
- **<span style="color: rgb(0, 0, 0);">MODULO SENSOR CO2</span>**
    - <span style="color: rgb(0, 0, 0);">SCL al pin A5 del ESP32</span>
    - <span style="color: rgb(0, 0, 0);">SDA al pin A4 del ESP32</span>
    - <span style="color: rgb(0, 0, 0);">PIN WAKE a GND</span>
    - <span style="color: rgb(0, 0, 0);">VCC a 3V3</span>
    - <span style="color: rgb(0, 0, 0);">GND A GND</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-07 20_14_06-Alvik User Manual _ Arduino Documentation.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-07-20-14-06-alvik-user-manual-arduino-documentation.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-07-20-14-06-alvik-user-manual-arduino-documentation.png)</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-15 14_47_48-New ESP32 Project - Wokwi Simulator.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-14-47-48-new-esp32-project-wokwi-simulator.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-15-14-47-48-new-esp32-project-wokwi-simulator.png)</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-15 14_08_38-(1) Exploring the Arduino Nano ESP32 _ MicroPython & IoT Cloud - YouTube.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-14-08-38-1-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-15-14-08-38-1-exploring-the-arduino-nano-esp32-micropython-iot-cloud-youtube.png)</span>

##### <span style="color: rgb(22, 145, 121);">**DEVICES** </span>

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)

##### <span style="color: rgb(22, 145, 121);">**VARIABLES**</span>

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&amp;Write**

##### **<span style="color: rgb(22, 145, 121);">EL SCKETCH -LIBRERIA CCS811</span>**

Primero añadiríamos la librería de keystudio [https://fs.keyestudio.com/KS0457](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 :

[![2024-07-15 13_41_58-DETECTOR CO2 Thing _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-13-41-58-detector-co2-thing-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-15-13-41-58-detector-co2-thing-arduino-cloud.png)

esto provoca la incorporación de la línea 1 **\#include &lt;DFRobot\_CCS811.h&gt;**

##### **<span style="color: rgb(22, 145, 121);">EL SCKETCH -EL CÓDIGO</span>**

- <span style="color: rgb(0, 0, 0);">Tenemos las variables definidas en las líneas 10-13 : </span>
    - **<span style="color: rgb(0, 0, 0);">i</span><span style="color: rgb(0, 0, 0);">nt cO2;</span>**
    - **<span style="color: rgb(0, 0, 0);"> int luz;</span>**
    - **<span style="color: rgb(0, 0, 0);"> bool luzdigital;</span>**
    - **<span style="color: rgb(0, 0, 0);"> bool rojo;</span>**
- <span style="color: rgb(0, 0, 0);">Definimos una variable de tipo el sensor CCS811 en la línea 23 **DFRobot\_CCS811 CCS811;**  
    </span>
- <span style="color: rgb(0, 0, 0);">En Setup en las líneas 48-21 arrancamos ese sensor: </span>
    - <span style="color: rgb(0, 0, 0);"> **while(CCS811.begin() != 0){**  
         **Serial.println("failed to init chip, please check if the chip connection is fine");**  
         **delay(1000);**  
         **}**</span>
- <span style="color: rgb(0, 0, 0);">Definimos los pines digitales 0 y 1 como entrada y salida respectivamente: </span>
    - **<span style="color: rgb(0, 0, 0);">pinMode(1,OUTPUT);  
         pinMode(0,INPUT);</span>**
- 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!");**  
         **}**
- 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);**  
         **}**
- En la línea 77 que luzdigital sea la lectura de la salida digital del sensor LDR 
    - **luzdigital=digitalRead(0);**

```c++
#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
}
```

##### <span style="color: rgb(22, 145, 121);">**DASHBOARD**</span>

- <span style="color: rgb(0, 0, 0);">Un gauge ligado a **CO2** desde 0 a 2000</span>
- <span style="color: rgb(0, 0, 0);">Un gauge ligado a **Luz** de 0 a 2.200</span>
- <span style="color: rgb(0, 0, 0);">Un Switch ligado a **rojo**</span>
- <span style="color: rgb(0, 0, 0);">Un led de oscuridad ligado a **luzdigital**</span>

<span style="color: rgb(0, 0, 0);">[![2024-07-15 14_16_36-CO2 Dashboard _ Arduino Cloud.png](https://libros.catedu.es/uploads/images/gallery/2024-07/scaled-1680-/2024-07-15-14-16-36-co2-dashboard-arduino-cloud.png)](https://libros.catedu.es/uploads/images/gallery/2024-07/2024-07-15-14-16-36-co2-dashboard-arduino-cloud.png)</span>

<p class="callout info"><span style="color: rgb(0, 0, 0);">**Alternativa** : en vez de luz tendría que llamarse "oscuridad" que sea luz pero que vaya al revés</span></p>

##### <span style="color: rgb(22, 145, 121);">**RESULTADO**</span>

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/WS02iGCux4U" width="560"></iframe>

<p class="callout info">**ALTERNATIVA:** Que el semáforo visualice los niveles peligrosos de CO2, por ejemplo el umbral del amarillo 600-1.000  
</p>

<p class="callout success">**¿Te atreves a poner un servomotor?**</p>

# Predictor meteorológico

### <span style="color: rgb(22, 145, 121);">**Predictor meteorológico**</span>

<p class="callout info">Autor Mario Monteagudo Asesor digital Centro de Profesorado de Ejea de los Caballeros</p>

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

<iframe allowfullscreen="allowfullscreen" height="314" src="https://www.youtube.com/embed/psGhrktsdQI?t=1s" width="560"></iframe>

Y este es el código

```c++
#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";
  }
}
```

# Muro

[https://padlet.com/CATEDU/alvik](https://padlet.com/CATEDU/alvik)

<iframe allow="camera;microphone;geolocation;display-capture;clipboard-write" frameborder="0" src="https://padlet.com/embed/lvl56wg6cej8kr4u" style="width: 100%; height: 608px; display: block; padding: 0; margin: 0;"></iframe>

<div class="padlet-embed" id="bkmrk--1" style="border: 1px solid rgba(0,0,0,0.1); border-radius: 2px; box-sizing: border-box; overflow: hidden; position: relative; width: 100%; background: #F4F4F4;"><div style="display: flex; align-items: center; justify-content: end; margin: 0; height: 28px;">[<div style="display: flex; align-items: center;">![Hecho con Padlet](https://padlet.net/embeds/made_with_padlet_2022.png)</div>](https://padlet.com?ref=embed)</div></div>

# 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](https://catedu.es/soporte-catedu/)

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

[![image-1648462225402.gif](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462225402.gif)](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462225402.gif)

[![image-1648462299882.png](https://libros.catedu.es/uploads/images/gallery/2022-03/scaled-1680-/image-1648462299882.png)](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462299882.png)

[![image-1648462361893.png](https://libros.catedu.es/uploads/images/gallery/2022-03/scaled-1680-/image-1648462361893.png)](https://libros.catedu.es/uploads/images/gallery/2022-03/image-1648462361893.png)