← Índice Valentina Tech
Laboratorio 8 · Curso de Programación · CircuitPython

Emociones con luz: programación como lenguaje expresivo

Objetivos

En este laboratorio aprenderás a:


Material necesario


Introducción

En el laboratorio anterior aprendiste los diccionarios (clave → valor) y los usaste para guardar el color de cada emoción.

En este laboratorio no vamos a re-aprender los diccionarios: vamos a usarlos como herramienta para algo nuevo.

La gran idea de hoy es esta:

👉 que la placa tenga estados internos y que cada estado tenga su propio comportamiento

No se trata solo de que cambie de color, sino de que la placa actúe distinto según cómo se “siente”.


😊 ¿Qué es una emoción en programación?

En programación no hablamos de emociones como humanos, sino como:

Por ejemplo:


💡 Curiosidad:
Muchos robots no “sienten emociones”, pero simulan estados para comunicarse mejor con humanos.


📦 Recordatorio rápido: el diccionario (del Lab 7)

Ya conoces los diccionarios. Solo para refrescar, guardan información en pares clave → valor:

Hoy el diccionario nos servirá para guardar el color de cada emoción. Pero el color es solo el principio…


🔁 ¿Qué es una máquina de estados?

Una máquina de estados es un sistema que:


🧠 Analogía sencilla

Piensa en un semáforo:

Tu placa va a funcionar igual: una emoción a la vez, y cada emoción con su propio comportamiento.


🌈 Conociendo los estados emocionales

Usaremos 3 emociones:

Cada una tendrá un color y comportamiento.


Nuestro sexto programa

Vamos a crear una máquina de estados donde:

👉 cada emoción tiene un color y una forma de comportarse


Código completo

import time
from adafruit_circuitplayground import cp

emociones = {
    "feliz": (0, 255, 0),
    "triste": (0, 0, 255),
    "enojado": (255, 0, 0)
}

cp.pixels.brightness = 0.2

estado = "feliz"

while True:

    # 1) El usuario elige la emoción con los botones
    if cp.button_a:
        estado = "feliz"
    elif cp.button_b:
        estado = "enojado"

    # 2) Buscamos el color de la emoción actual (diccionario del Lab 7)
    color = emociones[estado]

    # 3) Cada emoción se COMPORTA distinto
    if estado == "feliz":
        for i in range(10):
            cp.pixels[i] = color
        time.sleep(0.5)
        for i in range(10):
            cp.pixels[i] = (0, 0, 0)
        time.sleep(0.5)

    elif estado == "enojado":
        for i in range(10):
            cp.pixels[i] = color
        time.sleep(0.1)
        for i in range(10):
            cp.pixels[i] = (0, 0, 0)
        time.sleep(0.1)

    else:  # triste
        for i in range(10):
            cp.pixels[i] = color
        time.sleep(0.2)

Explicación del código


1. Diccionario de emociones

emociones = {
    "feliz": (0, 255, 0),
    "triste": (0, 0, 255),
    "enojado": (255, 0, 0)
}

Como en el Lab 7, cada emoción tiene un color asociado.


2. Elegir la emoción con los botones

if cp.button_a:
    estado = "feliz"
elif cp.button_b:
    estado = "enojado"

Los botones cambian el estado de la máquina.


3. Buscar el color del estado actual

color = emociones[estado]

Usamos el diccionario para saber de qué color va esta emoción.


4. Cada estado se comporta distinto

if estado == "feliz":
    # parpadeo suave (pausas de 0.5 s)
    ...

elif estado == "enojado":
    # parpadeo rápido (pausas de 0.1 s)
    ...

else:  # triste
    # luz fija y tenue
    ...

Aquí está la idea clave del laboratorio:

👉 el mismo programa hace cosas diferentes según el estado.

Eso es una máquina de estados en acción.


🧠 Curiosidad:
Este mismo concepto se usa en videojuegos para controlar personajes con “estados” como calma, alerta o ataque.


Cómo funciona físicamente

  1. El programa mantiene un “estado interno”
  2. Ese estado define el comportamiento visual
  3. El usuario cambia el estado con botones
  4. La placa responde mostrando colores

👉 Esto se llama máquina de estados


Retos del laboratorio


🟢 Reto 1: Más emociones

Agrega nuevas emociones:

💡 Objetivo: ampliar el diccionario.


🟡 Reto 2: Emociones con sonido

Haz que:

💡 Objetivo: combinar sensores con estados.


🔴 Reto 3: La placa se aburre

Haz que, si no presionas ningún botón durante un rato, la placa cambie sola al estado “triste”.

💡 Pista: usa un contador que suba en cada vuelta del bucle y se reinicie a 0 cuando presionas un botón. Cuando el contador sea muy grande → estado = "triste".

💡 Objetivo: que la máquina de estados cambie por sí misma, no solo por botones.


🔴 Reto avanzado: Clave secreta

Usa una máquina de estados para detectar una secuencia de botones, por ejemplo
A → A → B, y “desbloquear”.

💡 Pista: detecta el toque nuevo (espera a que sueltes el botón antes de leer el
siguiente), o si no paso avanzará muchas veces de golpe.

💡 Objetivo: aplicar la máquina de estados para recordar una secuencia.
Es la versión avanzada de la “combinación secreta” del Laboratorio 2 con frutas.

Código completo:

import time
from adafruit_circuitplayground import cp

VERDE = (0, 255, 0)
ROJO = (255, 0, 0)
APAGADO = (0, 0, 0)

clave = ["A", "A", "B"]   # la secuencia secreta
paso = 0                  # por dónde vas (el estado)

cp.pixels.brightness = 0.2
cp.pixels.fill(APAGADO)

while True:

    tecla = ""

    # detectar un toque NUEVO: esperar a que se suelte el botón
    if cp.button_a:
        tecla = "A"
        while cp.button_a:
            pass
    elif cp.button_b:
        tecla = "B"
        while cp.button_b:
            pass

    if tecla != "":

        if tecla == clave[paso]:
            paso = paso + 1        # botón correcto: avanza
        else:
            paso = 0               # botón incorrecto: reinicia
            cp.pixels.fill(ROJO)
            time.sleep(0.5)
            cp.pixels.fill(APAGADO)

        if paso == len(clave):
            cp.pixels.fill(VERDE)  # ¡desbloqueado!
            time.sleep(2)
            cp.pixels.fill(APAGADO)
            paso = 0

Explicación del código:

1. La clave y el estado

clave = ["A", "A", "B"]   # la secuencia secreta
paso = 0                  # por dónde vas (el estado)

clave es una lista (como en el Lab 6) con los botones que hay que pulsar en orden.

paso es el estado de la máquina: recuerda cuántos botones correctos llevas
seguidos. Empieza en 0.


2. Leer un botón (y esperar a soltarlo)

tecla = ""

if cp.button_a:
    tecla = "A"
    while cp.button_a:
        pass
elif cp.button_b:
    tecla = "B"
    while cp.button_b:
        pass

tecla guarda el botón que se pulsó. Empieza vacía ("").

Si pulsas A, guardamos "A"; si pulsas B, guardamos "B".

La parte importante es while cp.button_a: pass, que significa:
👉 “mientras el botón siga presionado, no hagas nada”.

Así el programa espera a que sueltes el botón. Sin esto, como el bucle se repite
muchísimas veces por segundo, un solo apretón contaría como muchos toques y la clave
avanzaría sola.


3. ¿Fue el botón correcto?

if tecla != "":

    if tecla == clave[paso]:
        paso = paso + 1        # correcto: avanza
    else:
        paso = 0               # incorrecto: reinicia
        cp.pixels.fill(ROJO)
        time.sleep(0.5)
        cp.pixels.fill(APAGADO)

Primero comprobamos tecla != "": solo seguimos si de verdad pulsaste algo.

clave[paso] es el botón que toca en este momento de la secuencia:

Este es el corazón de la máquina de estados: el mismo botón hace cosas distintas
según el valor de paso.


4. ¿Completaste la secuencia?

if paso == len(clave):
    cp.pixels.fill(VERDE)  # ¡desbloqueado!
    time.sleep(2)
    cp.pixels.fill(APAGADO)
    paso = 0

len(clave) es cuántos botones tiene la clave (aquí son 3).

Cuando paso llega a ese número, significa que acertaste todos en orden:
la placa se pone verde 2 segundos y luego vuelve a empezar (paso = 0).


Resumen del laboratorio

En este laboratorio aprendiste:

Ahora tu placa ya no solo responde:

👉 ahora tiene estados internos que definen cómo se comporta

Valentina Tech · Circuit Playground Express · CircuitPython