Construyendo un dispositivo inteligente con nodemcu y un display OLED

Últimamente se están poniendo de moda los dispositivos «inteligentes» que, básicamente, consiste en cacharros que están conectados de una manera o de otra a internet o a nuestra red doméstica y que aceptan comandos desde la red para controlar sus distintas funciones.

La verdad es que han bajado mucho de precio y el poder controlarlas desde los distintos asistentes de voz le dan un extra adicional. He trasteado un poco con Alexa y con Google Home, pero todavía estoy en el proceso de encontrarle el sitio correcto. En cualqueir caso, como soy un alma inquieta he preferido ver cuanto me costaba crear mi propio «dispositivo inteligente» con los materiales que tenía a mano… Esto es lo que he usado:

  • Pantalla OLED de 1,3″ con el chip SSH1106 de 128×64. En concreto esta.
  • Una placa Weimos D1 mini (compatible), que se basa en el chip ESP8266. En concreto esta.
  • Un relé preparado para 5V. En mi caso este.

El chip ESP8266 es una maravilla que integra wifi junto con un microcontrolador que puede ser programado desde el IDE del Arduino (entre otras formas) y el empaquetado en forma de placa nocemcu hace que sea muy sencillo hacer proyectos con este, siendo más barato y más potente que un arduino habitual. De hecho los componentes de este proyecto comprados en aliexpress (quitando cables y gastos de envío) no suman más de 6 Euros… Irresistible para montar un prototipo.

Al lío… Es esquema de conexiones es este:

En realidad el pulsador no hace falta, lo he incluido para poder comunicar al dispositivo manualmente el cambio de estado (es un rollo tener que hacerlo todo en remoto) y no es necesario para la primera versión.

Para poder programar la placa desde el IDE del Arduino vamos a tener que ir a la sección de Archivo->Preferencias y añadir la url http://arduino.esp8266.com/stable/package_esp8266com_index.json en el campo Gestor de URLs Adicionales de Tarjetas, quedando como en la imagen:

Luego nos vamos a Herramientas->Placas->Gestión de tarjetas y buscamos ESP8266 e instalamos la versión de ESP8266 Community.

Con esto ya nos aparecerá el tipo de tarjeta Wemos o NodeMCU en la lista de tarjetas que podemos conectar con el IDE.

Lo siguiente es encontrar una librería que nos permita interactuar por I2C con nuestra pantalla (y que sea lo más flexible posible para usos futuros). Esto es lo que me llevó más tiempo, básicamente porque los ejemplos que proporcionan están preparados para otro chip y la nomenclatura de los pines es diferente… Al final la mejor es esta:

https://github.com/ThingPulse/esp8266-oled-ssd1306

Yo he usado como base el ejemplo que viene al instalar la placa y se llama WIFIServer (creo que lo han cambiado por una versión nueva, os dejo el código completo al final de todas formas). El funcionamiento es de tal manera que al arrancar se conecta a la red wifi que tengamos configurada y queda esperando conexiones, cuando recibe una petición https://server_ip/gpio/0 ponemos a cero el GPIO2 y si recibimos una https://server_ip/gpio/1 lo ponemos a 1… Como esa salida la tenemos conectada al relé, pues ya podemos encender o apagar lo que queramos desde la web.

Para sacar la información por la pantalla, básicamente, utilizo la función drawString que me imprime en las coordenadas dadas de la pantalla una cadena (y en la fuente que hayamos seleccionado antes)… Podéis verlo en funcionamiento en este video:

Os pongo el código antes de integrar lo del botón… Básicamente lo que falta por poner es que cuando detectemos una pulsación del botón (D3 pase a cero) cambiemos el estado del pin conectado al relé (así tenemos control manual, cosa que echo de menos en las bombillas inteligentes, por ejemplo).


#include <ESP8266WiFi.h>
#include "SH1106Wire.h"

const char* ssid = "tussid";
const char* password = "tupassword";

SH1106Wire display(0x3c, 4, 5);

WiFiServer server(80);

void setup() {
 
  Serial.begin(115200);
  delay(10);

  pinMode(2, OUTPUT);
  digitalWrite(2, 0);
  
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  display.init();
  display.flipScreenVertically();
  display.setFont(ArialMT_Plain_10);

  display.clear();
  display.setTextAlignment(TEXT_ALIGN_LEFT);
  display.drawString(0,0,"Connecting...");
  display.display();
      
  WiFi.begin(ssid, password);
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  
  display.clear();
  display.drawString(0,0,String(ssid));
  display.drawString(0,10, "IP: "+WiFi.localIP().toString());
  display.display();
    
  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.println(WiFi.localIP());
}

void loop() {
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
  
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
  
  int val;
  if (req.indexOf("/gpio/0") != -1)
    val = 0;
  else if (req.indexOf("/gpio/1") != -1)
    val = 1;
  else {
    Serial.println("invalid request");
    client.stop();
    return;
  }

  digitalWrite(2, val);
  display.setColor(BLACK);
  display.fillRect(0, 26, 100, 10);
  display.setColor(WHITE);
  display.drawString(0,26,"GPIO: "+String(val));
  display.display();
  
  client.flush();

  String s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\nGPIO is now ";
  s += (val)?"high":"low";
  s += "</html>\n";

  client.print(s);
  delay(1);
  Serial.println("Client disonnected");
}

Si habéis leido el código veréis que hay algunas cosas que se hacen de más, por ejemplo, pintamos un rectángulo en negro para borrar la línea antes de pintarla de nuevo con el valor del GPIO. Eso es debido a que esta librería está pensada para borrar la pantalla cada vez que la actualicemos y, por eso, no limpia el hueco en el que va a escribir (igual podemos hacer un fork que lo solucione, ya veremos) y sin esa limpieza las letras se escriben unas encima de otras.

Una nota final… El servidor no envía cabeceras CORS, por lo que si vais a utilizarlo desde javascript en cualquier otro servidor os saltará un error en la consola (y en mac ni siquiera hará la llamada real), en linux y windows funcionará aunque no recibiréis la respuesta.

Sigo modificando el código y demás a ver qué termino consiguiendo… Hasta es posible que le diseñe un PCB… Ya os iré contando.

Año nuevo, consola vieja

Bueno, en realidad no es una «consola» son muuuchas consolas en una. Ya os conté anteriormente como había construido mi mini máquina aracade.Esta vez, viendo que se habían vuelto a poner de moda las versiones «mini» de las consolas retro (que, por cierto, estoy intentando coleccionar) decidí construirme la mía… No sería mucho más barato, pero si que tendría el control de todo lo que metería en la misma. Este es el resultado:

Estuve tentado de imprimir también la carcasa en 3D con mi impresora.. Pero sabía que el resultado iba a ser peor y quería algo que fuese, como mínimo, familiar. La consola es capaz de ejecutar juegos de NES, SNES, Megadrive, Master system, PSX, Neo Geo, Game Boy, GBA, Game Gear y Arcades… Además, he incluido que se puedan ejecutar programas del CPC 464 y de C64 y VIC-20… Vamos, todo lo que puede dar de si una Raspberry Pi 3.

Así que aquí os dejo la lista de «ingredientes» para que los vayáis preparando:

También se puede hacer con una SD de 8Gb, pero entonces podrás meter menos juegos. El resto de lo necesario supongo que ya lo tenéis (cable HDMI,cargador y cable de móvil microusb)

Cuando las tengáis continuamos… No quiero que nos precipitemos… Así tenemos proyecto para el año nuevo.

Por cierto… ¡Feliz 2018!

Construir una pantalla para AMSTRAD en cartón

Bueno, no completamente en cartón, es cierto, los componentes electrónicos no pueden, de momento hacerse con cartón… No obstante, el resto si.

2016-04-23

El caso es que, merced a mi nostalgia ochentera me compré un viejo CPC 128 para recordar los tiempos en que yo tenía una CPC464 (que, por desgracia, alguien en casa de mis padres decidió que merecía el triste destino de los desechos). Una ved adquirido uno de segunda mano venía el segundo problema, ¿cómo poder verlo? Si lo recordáis los AMSTRAD venían con una pantalla que tenía la fuente de alimentación incorporada.

Mirando a mi alrededor vi que tenía un montón de cosas que ya no usaba, sin embargo, la mayoría era de la era PC, posterior a la de los CPC, pero, ¡quien dijo miedo! me propuse utilizar todo lo posible de lo que tenía alrededor y no comprar nada nuevo… Si, eso se suele llamar reciclar… Excepto la parte electrónica imprescindible.

Lo primero que «reciclé» es una pantalla de un portatil que ya tenía más de 10 años de antiguedad pero que era muy bueno en su época. ¿El problema? Que solo se trataba de un panel LCS y, como tal, necesitaba un controlador para poder decodificar las señales de entrada a algo visible… Buscando, buscando encontré en ebay un controlador adecuado que es este:

(HDMI+DVI+VGA) LCD screen Controller Board Kit for 15″ 1400X1050 ITSX95C que luce muy parecido a esta foto:

s-l1600

Hay que ser muy cuidadoso de que el modelo de panel que teneis coincide exactamente con el del controlador o no pasará nada de nada… De hecho, el primero que pedí tuvieron que cambiármelo por otro.El montaje quedaba de esta manera, más o menos:

IMG_20150420_163557

Con este artefacto ya disponía de entradas DVI, VGA y HDMI para mi panel, y tras comprobar que funcionaba adecuadamente el siguiente paso era.. Convertir la salida del CPC en VGA… Otra cosa que no es sencilla, porque la salida de video es un RGB ciertamente especial… Pero no hay problema que no tenga solución en china, en este caso venía con esta forma:

516709548_502

Y se puede encontrar en aliexpress con este sugerente nombre:

Arcade game RGB/CGA/EGA/YUV to VGA HD video converter board 1 VGA output

El caso es que esta placa dispone de una entrada RGBS (es la que usé yo) y una salida VGA (entre otras muchas cosas que hacen esta placa muy interesante). Solo me faltaba montar los cables con la entrada RGB hacia estos pines y ya tendría la conversión RGBS->VGA->Panel.

Solo nos quedaba el problema de la alimentación… El CPC necesitaba dos entradas, una de 5V y otra de 12V, las dos placas que hemos visto necesitaban (curiosamente) 5V esta última y 12V el controlador del panel… Así pues solo necesitábamos alguna fuente de alimentación que nos diese suficiente «chicha» para alimentar estas tres cosas… Y, ¡cómo no! estaba rodeado de esqueletos de PCs con sus viejas fuentes de alimentación ATX que, curiosamente, dan salidas de 12V y de 5V en cantidad abundante.

Un poquito de paciencia y soldador y ya tenía montados todos los cables, desde la fuente a las placas y al CPC y desde el CPC a la placa de conversión… Probamos y…. ¡Funciona! Eso si, el maremagnum de cables y la colocación del panel sobre la mesa no era lo que más prometía… Esta vez, no obstante, no quería hacer nada demasiado definitivo, por lo que, simplemente, encontré suficiente cajas de cartón como para montar esto:

2016-04-23-2
2016-04-23

Y con esto y un bizcocho… Listos para jugar a todo color…

2016-04-23-3

Si te interesó esto, igual te interesa alguno de estos:

Impresión 3D: la adherencia

Una vez que conseguí que mi impresora 3D estuviese calibrada (el cabezal se movía paralelo a la cama en el eje X) y que empezó a escupir filamento a una temperatura adecuada, llegamos al siguiente problema… ¿Porqué no se me pega el plástico a la cama?

IMG_20150828_085400Es muy frustrante encontrarse con que el cabezal empieza a moverse de un lado a otro, escupiendo plástico y que, en lugar de quedarse en la cama enfriándose, se levante y se vaya a acompañar al cabezal en su viaje sin sentido… Y es ahí donde empecé a darme cuenta que cada cosita que quisiese hacer con esta impresora sería una prueba más en el examen del «impresor 3D». Y ahora tocaba estudiarse el tema de la adherencia de la primera capa.

Evidentemente, cuando no te sabes la lección pasa esto:

Como resultado de mis indagaciones he conseguido averiguar varias cosas:

1.- Cada material distinto se pega a cosas distintas a temperaturas distintas. Mi impresora venía con una cama de aluminio a la que pegar una cinta, esto para PLA funciona, para ABS no he probado todavía.

2.- La cama se debe calentar para que el plástico se pegue mejor. En PLA no es necesario en teoría, pero en la práctica he conseguido muchos mejores resultados calentando la cama a 55º que dejándola fría.

3.- Puedes poner encima de la cama lo que quieras, pero asegúrate de tener algo que haga que el material se pegue. Muchas personas ponen un cristal o un espejo sobre la cama para tener una primera capa perfecta, pero ahí si quieres que se te pegue necesitas ponerle algo más (generalmente laca o pegamento)

4.- Todo lo que se pega se tiene que despegar, y cuanto más pegado está más difícil de despegar se hace. Tenéis que tenerlo en cuenta a la hora de retirar la pieza… Yo he tenido que despegar la cinta incluso para poder sacar lo que había impreso… No quiero saber lo que tienen que hacer los que imprimen con ABS y acetona…

5.- Antes de echarle la culpa a la adherencia de la cama vuelve a revisar la calibración, puede que tengas el cabezal demasiado alto o demasiado bajo y por eso no fluye correctamente el filamento.

6.- Prueba, prueba, prueba… Es lo que tuve que hacer, dado que la cinta que venía con la máquina no me convenció me decidí a probar todas las opciones posibles: me compré un cristal para recortarlo a mano (FAIL), compré cinta kapton, cinta de pintor del chino… Y lo que mejor me funcionó fue la cinta azul… En principio es una cinta de pintor normal y corriente (pero azul) que generalmente no se encuentra en ningún sitio, pero tuve la suerte de verla en el Bricor y ¡Bingo! es lo que estoy usando hasta el momento.

Y, al final, conseguirás que la primera capa se pegue (más o menos)… Así fue mi primera vez:

Y lo que veis en la foto superior tardó muchos días en salir de la impresora… Pero al final «me acompañó la fuerza»… ;-)

Más 3D: Calibración, esa palabra

Como ya os comenté en la entrada anterior: Entrando al mundo 3D a lo barato, ahora que dispongo del hardware necesario para imprimir en 3D lo lógico es que quiera imprimir algo. Es lo normal.

No obstante la tecnología actual, al menos la barata, no está preparada para usuarios normales, necesita de experimentados, atrevidos e incansables frikis que estén dispuestos a dejarse horas y horas hasta que esto empiece a funcionar. Una vez montada la impresora y comprobado que todos los cables estaban bien (probando a mover a izquierda y derecha, arriba y abajo, delante y detrás, etc.) lo que me pide el cuerpo es intentar imprimir algo.

Pero, ¡quietos ahí! no es tan sencillo como meter el filamento en el extrusor (¿se me nota ya el uso de la jerga 3d??) e instalar el programa en el ordenador (El Repetier-Host, por cierto, un trabajo excelente), primero hay que calibrarla.

¿Y qué significa calibrar una impresora 3D? Pues básicamente has de conseguir que el eje Z esté paralelo a la cama (debería estarlo con el suelo también, pero ya no puedes contar con que el suelo esté a nivel y la mesa ya ni lo esperamos) y que el cabezal de extrusión (el hotend en este caso) esté a la distancia adecuada de la cama en el momento de empezar a imprimir, porque una primera capa bien hecha es fundamental para que el resto de la pieza se construya adecuadamente.

Lo básico de como calibrar una prusa se puede ver en este video presentado por esta simpática moza:

Aunque no es mi misma impresora, lo básico si que coincide… Aunque no veas lo complicado que es conseguir que el cabezal esté a 0,2 mm de la cama en todos los puntos a la vez.

Después de intentar calibrar varias veces con el truquito de la hoja de papel, moviendo los tornillitos de la cama, moviendo el tornillo de ajuste Z e intentando intuir lo que era la distancia correcta me decido a imprimir de una vez…

El resultado: el esperado. La primera capa no se pega a la cama porque está demasiado cerca, demasiado lejos, porque el extrusor no está a la temperatura, porque el filamento no está bien metido… En fins! Una tarde muy entretenida, aunque finalmente conseguí algún sólido (que parecía más bien las columnas salomónicas del altar de la basílica de San Pedro) no fue hasta unas horas más tarde en las que conseguí algo que, por fin, se podía decir estaba correctamente impreso… Y fue esto (si, un poco friki si que soy):
IMG_20150818_194650Hasta aquí parece fácil y que hemos llegado a un final feliz, ¿no? Pues no… Os seguiré contando.