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