Saltar al contenido principal

Simulador GPIO

El simulador GPIO hace de placa para los programas que ejecutas en Windows. Cada pin del programa se conecta a una tarjeta: un LED que se enciende, un pulsador que pulsas con el ratón, un potenciómetro que giras, una tira de LEDs WS2812… Así pruebas un programa que usa el módulo GPIO o el módulo LED sin tener la placa delante.

Se abre con Build › Debug › GPIO Sim, en la cinta. Es un panel del IDE como los demás: lo puedes acoplar o dejar flotando (La interfaz).

  • Solo ve los programas que corren en Windows, con Windows x64 en Build › Target. En una placa, el programa mueve sus pines de verdad y el simulador no se entera.
  • No hace falta abrirlo antes de Run. Se conecta solo en cuanto el programa usa GPIO o LED, y desde entonces se pone al día cada 30 ms.
El simulador GPIO con cuatro pines en la tabla y las tarjetas de una matriz WS2812 de 8 × 8, un potenciómetro y un generador de señal

Un recorrido​

La tira de LEDs del ejemplo LedStrip, en una matriz de 8 × 8.

  1. Crea el proyecto. Pulsa Home › Project › New y, en Example Projects, haz doble clic en LedStrip (Proyectos). Su programa principal, Code/Matrix8x8Plasma.aru, crea una tira de 64 LEDs en el GP17 y le pinta un plasma de colores.
  2. Abre el simulador con Build › Debug › GPIO Sim. La tabla ya trae dos pines: el GP17, conectado a WS2812 Strip, y el GP19, a Signal generator, que este programa no usa. Los guarda el ejemplo en Config/jaru_sim.json.
  3. Elige la forma. En la tarjeta WS2812 Strip · GP17, despliega Layout y elige 8 x 8.
  4. Ejecuta. Pulsa Run. La tarjeta enseña el plasma, y debajo, 64 LEDs | 8x8 | Bright: 255.
  5. Prueba el cableado. Cambia Wiring a Serpentine H: una fila de cada dos va al revés y el dibujo se rompe en esas filas, porque el programa cuenta los LEDs fila a fila. Es lo que verías en una matriz cableada en zigzag.

Para usar tus propios pines, añádelos con Add GPIO Pin y conéctalos a un dispositivo en la columna Connected to.

La tabla de pines​

La tabla de la izquierda tiene los pines que vas a usar. No se llena sola con los del programa: cada pin lo añades tú.

  • Add GPIO Pin pide el número del pin, de 0 a 48. Un pin nuevo es una entrada digital sin nada conectado: INPUT, DIGITAL, NONE, LOW y -- Free --. No deja repetir un pin.
  • Delete GPIO Pin quita la fila elegida y su tarjeta, sin preguntar.
ColumnaQué enseña
GPIOEl pin: GP2, GP17…
DirectionINPUT o OUTPUT. Lo pone el programa, con GPIO.pinmode o con GPIO.awrite; hasta entonces, el pin es una entrada.
TypeDIGITAL; ADC_IN, con un Potentiometer, un Temperature o un Signal generator; PWM Ch.0 (con su canal) si el programa usa GPIO.awrite; DAC_OUT, una salida analógica sin canal.
PullNONE, PULLUP o PULLDOWN, según GPIO.pinmode.
StatusEn un pin digital, HIGH (punto verde) o LOW (punto gris). En uno analógico, el valor y una barra.
Connected toEl dispositivo conectado al pin, o -- Free --.

Con el ratón:

  • Clic en Connected to: sale la lista de dispositivos. Elige uno y pulsa Intro, o haz clic fuera: su tarjeta sale a la derecha. Esc lo deja como estaba, y -- Free -- quita la tarjeta. Cada pin lleva un dispositivo como mucho.
  • Clic en Status, en una entrada digital, con el programa en marcha: el pin pasa de LOW a HIGH o al revés. Es un interruptor rápido, sin tarjeta.
  • Clic en Status, en un pin analógico: sale una casilla con el valor, de 0 a 4095. Escribe otro y pulsa Intro (Esc no lo cambia). Si el programa está en marcha, lo lee con GPIO.aread.

Con un PWM de 10 Hz o menos, Status hace parpadear el pin al ritmo del PWM, como lo verías en un LED.

Mueve los mandos con el programa en marcha

Cada vez que empieza un programa, la VM pone todos los pines a cero. Lo que hayas puesto antes en las tarjetas (un potenciómetro girado, un interruptor encendido) no le llega al programa hasta que lo vuelvas a tocar.

Las tarjetas​

A la derecha sale una tarjeta por cada pin con dispositivo, en el orden en que los conectas. El título dice el dispositivo y el pin, como Potentiometer · GP2.

DispositivoQué esEl programa lo usa con
Red LED, Green LED, Blue LEDUn LED que se enciende con el pin.GPIO.write, GPIO.awrite
PushbuttonUn pulsador: el pin cambia mientras lo tienes pulsado.GPIO.read, GPIO.onInterrupt
SwitchUn interruptor: cada clic lo enciende o lo apaga.GPIO.read, GPIO.onInterrupt
PotentiometerUn mando que giras: de 0 a 4095.GPIO.aread
TemperatureUn sensor de temperatura: de 0 a 4095.GPIO.aread
PhototransistorUn sensor de luz: de 0 a 4095.GPIO.aread
OscilloscopeDibuja la señal PWM del pin.GPIO.awrite
Signal generatorDa tensiones al azar o las de un fichero CSV.GPIO.aread
WS2812 StripUna tira o una matriz de LEDs de colores.LED.new y show()

LED​

Un LED redondo que sigue al pin, y al lado, su estado:

  • Con GPIO.awrite (PWM), brilla según el ciclo de trabajo. La tarjeta da el ciclo, como Duty: 128 / 255 (50%), y debajo el canal, la frecuencia y la resolución, como PWM Ch.0 | 5000Hz | 8bit.
  • Con GPIO.write, se enciende con HIGH: ON (HIGH) u OFF (LOW).

Pushbutton y Switch​

Un botón redondo que pulsas con el ratón:

  • Pushbutton cambia el pin mientras lo tienes pulsado y lo devuelve al soltarlo.
  • Switch cambia el pin con cada clic y lo deja así.

Lo que lee el programa depende del modo del pin, como en una placa:

  • con GPIO.PULLUP, el botón pulsado da 0 (LOW) y suelto, 1;
  • con GPIO.INPUT o GPIO.PULLDOWN, pulsado da 1 y suelto, 0.

La tarjeta dice las dos cosas: PRESSED (LOW), Released (HIGH)… Las interrupciones de GPIO.onInterrupt saltan con los cambios del botón, como en la placa.

Potentiometer, Temperature y Phototransistor​

Los tres dan al pin un valor de 0 a 4095, el que lee GPIO.aread:

  • Potentiometer: gira el mando arrastrando a su alrededor, o haz clic en un punto del círculo para llevarlo ahí. El 0 está arriba, y el valor crece en el sentido de las agujas del reloj. También puedes hacer clic en la barra de abajo: el valor salta a ese punto.
  • Temperature: no tiene mando; haz clic en la barra. La tarjeta enseña el valor en grados, de 0 °C (0) a 100 °C (4095), y debajo, el número (Raw: 2048).
  • Phototransistor: arrastra hacia arriba para darle más luz y hacia abajo para menos. Con Shift, el valor se mueve más despacio.

En el potenciómetro y el fototransistor, la rueda del ratón mueve el valor de 1 % en 1 % (unos 41), y con Shift, de 0,1 % en 0,1 %. En los tres, también puedes escribir el valor en la columna Status de la tabla.

Oscilloscope​

Dibuja la señal de una salida PWM (GPIO.awrite): la onda cuadrada, con su frecuencia y su ciclo de trabajo. Arriba dice el canal, la frecuencia, la resolución y el ciclo, y a la derecha, el ciclo en números (Duty: 128 / 255).

Los botones - y +, dentro de la pantalla, enseñan menos o más ciclos de la onda: de 1 a 20, y 3 de serie. Sin PWM en el pin, dice No signal.

Signal generator​

Da al pin una tensión que cambia sola, para probar un programa que lee un sensor. Sus controles:

  • Random o CSV: tensiones al azar o las de un fichero.
  • ▶ Play lo pone en marcha y ■ Stop lo para. Funciona aunque el programa no esté en marcha: la gráfica de abajo enseña lo que va dando.
  • Loop: al acabar el CSV, vuelve a empezar. Encendida de serie.
  • La casilla de ms: cada cuántos milisegundos da un valor nuevo, de 10 a 5000. De serie, 50.
  • Min y Max: la tensión que da 0 y la que da 4095, de 0 a 3,3 V. De serie, 0 y 3,3.
  • CSV... carga un fichero y pasa el generador a CSV.

Abajo, la tarjeta dice la tensión y el valor que lee el programa: 1,99V | ADC: 2465.

Con Random, cada valor nuevo es una tensión al azar entre Min y Max: el programa lee un número al azar entre 0 y 4095.

Con CSV, el generador recorre el fichero a su ritmo: cada línea es un punto, con el tiempo en milisegundos desde el principio y la tensión en voltios, separados por una coma. Entre un punto y el siguiente, une los dos con una recta. Las líneas en blanco, las que empiezan por # y una cabecera de texto se saltan. Esta sube a 3 V en medio segundo y vuelve a bajar:

# tiempo_ms,voltios
0,0
500,3
1000,0

Si la tensión lleva decimales, escríbelos como los escribe tu Windows: con coma (250,1,5) si Min y Max salen como 0,0 y 3,3, y con punto (250,1.5) si salen como 0.0 y 3.3. Al llegar al último punto, vuelve a empezar si Loop está encendida; si no, se para y deja el último valor.

WS2812 Strip​

Enseña la tira de LEDs que crea el programa con LED.new en ese pin. Se pinta cada vez que el programa llama a show().

  • Layout elige la forma: Strip (una tira, en filas que llenan la tarjeta) o una matriz de 8 x 8, 16 x 16, 32 x 8, 8 x 32 o 4 x 4 (ancho por alto). El cambio se ve en el siguiente show() del programa.
  • Wiring dice cómo va cableada la matriz, y solo cuenta en una matriz. El LED 0 está arriba a la izquierda:
    • Sequential: fila a fila, todas de izquierda a derecha.
    • Serpentine H: fila a fila, en zigzag: la primera de izquierda a derecha, la segunda de derecha a izquierda, y así.
    • Serpentine V: columna a columna, en zigzag: la primera hacia abajo, la segunda hacia arriba, y así.

Los LEDs que no caben en la matriz no se ven. Abajo, la tarjeta dice cuántos LEDs tiene la tira, la forma y el brillo de setBrightness: 64 LEDs | 8x8 | Bright: 255. Si no hay ninguna tira en ese pin, No active strip.

Lo que guarda​

El simulador guarda sus pines en Config/jaru_sim.json, dentro del proyecto: cada pin, con el dispositivo que lleva. Es el del ejemplo LedStrip:

{
"pins" : [
{
"gpio" : 17,
"connectedTo" : "WS2812 Strip"
},
{
"gpio" : 19,
"connectedTo" : "Signal generator"
}
]
}
  • Lo guarda al cerrar el simulador, al cerrar el proyecto o abrir otro, y al cerrar el IDE. Sin proyecto abierto, no guarda nada.
  • Lo lee al abrir el simulador, y al abrir un proyecto con el simulador abierto.
  • No guarda nada más: Layout, Wiring, los ajustes del generador y la posición de los mandos vuelven a los de serie cada vez.

Con el código​

En Windows, el módulo GPIO no toca ningún hardware: lee y escribe en una memoria que comparte con el simulador. El programa no sabe si el simulador está abierto. Sin él, nadie mueve las entradas: un pin de entrada lee 0 (1 con GPIO.PULLUP), y GPIO.aread, 0.

Este programa espera un Pushbutton en el GP4, un Potentiometer en el GP2 y un Red LED en el GP5. Mientras pulsas el botón, el LED brilla según el potenciómetro:

use GPIO

GPIO.pinmode(4, GPIO.PULLUP) // GP4: Pushbutton

while (true)
var valor = GPIO.aread(2) // GP2: Potentiometer, de 0 a 4095
if (GPIO.read(4) == 0) then // con PULLUP, pulsado es 0
GPIO.awrite(5, valor / 16) // GP5: Red LED, brillo de 0 a 255
else
GPIO.awrite(5, 0)
end
pause(50)
end

El módulo LED maneja tiras WS2812. LED.new(pin, n) crea una tira de n LEDs en el pin, de 1 a 1024. Los colores se ponen con setPixel(i, r, g, b), fill(r, g, b), setHSV y fillHSV; el brillo, con setBrightness (de 0 a 255), y clear() los pone todos a negro. Nada de eso llega a la tira hasta que llamas a show(). Este enciende un LED rojo que recorre una tira de 64 en el GP17:

use LED

var tira = LED.new(17, 64)
tira.setBrightness(128)

var paso = 0
while (true)
tira.clear()
tira.setPixel(paso % 64, 255, 0, 0)
tira.show() // la tarjeta se pinta aquí
paso = paso + 1
pause(50)
end
  • En Windows caben 8 tiras y 2.048 LEDs entre todas. Más allá, LED.new da error.
  • La tarjeta enseña los colores tal cual los pone el programa. setOrder, que en una placa dice en qué orden espera la tira los colores, aquí no cambia nada.

Todo el módulo GPIO está en GPIO.

Problemas conocidos​

  • Las pistas de los botones dicen otra cosa. Al pasar el ratón por Add GPIO Pin y Delete GPIO Pin, la pista dice «New Source Code».
  • El Phototransistor sale como digital en la tabla. La tabla da su pin como DIGITAL y con HIGH/LOW. El valor que lee el programa es el de la tarjeta.
  • Un CSV con decimales depende de Windows. Un fichero escrito con punto decimal no carga en un Windows con coma decimal, ni al revés: las líneas que no entiende se saltan sin avisar.
  • El botón del generador se queda en Stop. Cuando un CSV acaba sin Loop, el generador se para, pero el botón sigue diciendo ■ Stop. Un clic lo vuelve a poner en marcha.

Todos los problemas conocidos de JARU, juntos, están en Problemas conocidos.