Mis experiencias previas cuando pido una PCB a fabrica siempre suelen ser parecidas, por algún motivo incomprensible confío demasiado en mi y, como norma general, acabo pidiendo placas que no funcionan porque me he olvidado algo.
En esta ocasión tenía todo el circuito montado en una placa de prototipos y solo me faltaba poner el relé reed en el GPIO2, pensaba, el GPIO2 es un pin «normal» que tiene una resistencia de pullup, simplemente lo tengo que conectar, detectar en el programa y hacer lo que tenga que hacer. Por algún motivo he decidido hacerlo físicamente y me he encontrado lo siguiente:
- El GPIO2 no es tan «normal» como pensaba, tiene que estar a nivel alto en el arranque del ESP, al colocar mi interruptor de láminas que ponía el puerto a GND el ESP directamente no arrancaba.
- No había pensado en una cosa «tonta», detectamos que el interruptor de láminas está activado o no en el programa, pero el micro está habitualmente en deep sleep, con lo que teóricamente tendríamos que acercar el imán para activarlo y esperar a que despierte. No es muy intuitivo pensar que tienes que aguantar un imán cerca de una cosa durante 10 minutos para que algo funcione.
Sí, pero ¿como lo solucionamos?
Lo primero es muy sencillo, ya que parece que el GPIO2 no se lleva bien con ser un puerto de input si existe la posibilidad de que esté a nivel bajo en el arranque vamos aintercambiar el GPIO2 y el GPIO3. En el GPIO2 ponemos el led que es output y en el GPIO3 ponemos el relé reed que es input. Os recuerdo que el GPIO3 es el RX, pero eso no parece crear problemas, exceptuando la primera vez que vamos a cargar un programa y no nos acordamos que lo tenemos a nivel alto. Sobre este tema hay que hacer una reflexión importante, si esto va a acabar siendo una PCB tendremos que poner como mínimo un jumper para poder abrirlo en el momento en el que la tengamos que programar, no vamos a ir cortando pistas.
Lo segundo ya es un poco más complicado, os explico el proceso mental:
- Primera opción: «claro, conecto el pin al reset!!!». No funciona, si yo acerco el imán pongo el reset a nivel bajo, pero el micro solo arranca cuando el reset vuelve a nivel alto, por lo que el «invento» no arranca.
- Segunda opción: «pues en lugar de dejar el imán permanentemente lo acerco y cuando lo separo se inicia la web, para asegurarme de que no se consumen las baterías la web solo funciona un momento». Tampoco funciona porque hay que tener el imán sacado para que inicie y entonces el micro no es capaz de saber si es un reinicio normal o se ha pedido con el imán.
- Tercera opción: la misma que la segunda, pero buscando algún registro del ESP que me diferencie si el reinicio viene de un deep sleep o de pulsar el botón de reset. No he encontrado la manera, básicamente porque creo que no la hay, recordemos que el ESP vuelve a la vida después de que el GPIO16 ponga el RST a nivel bajo. Técnicamente es lo mismo que pulsar el botón de reset, por lo que me parece lógico que no haya forma de diferenciar.
- Cuarta opción: voy a hacer pruebas con el CH_PD, en teoría, poníéndolo a nivel bajo hago un reset y debería de ser un reset diferente al de poner a nivel bajo la línea de RST, por lo que eso me permitiría hacer algo parecido a la segunda opción. No funciona muy bien y no me gusta demasiado.
- Quinta opción: llego a la conclusión que lo que necesito es un detector de flancos negativos, es decir algo que cuando el relé ponga el pin a nivel bajo envíe un pulso negativo al reset, de esta forma la respuesta será inmediata (aún me quedan algunos retos).
El detector de flancos negativos
Supongo que es una cuestión de idioma, pero no encuentro mucha información en Internet, aunque no me gusta demasiado resolverlo con puertas lógicas (que estarán consumiendo en modo deep sleep) busco y encuentro unos pocos artículos. Como norma general explican como hacer un detector de flancos usando puertas diferentes, pero no quiero añadir más integrados con más consumo. Encuentro uno que lo hace con puertas iguales (un solo chip con más de una puerta es una buena solución). Entro sin mirar y es un artículo mio de 2011 que publiqué en su día en http://www.zigbe.net y que trasladé a este blog. la reflexíón es que me debo de estar haciendo mayor porque busco en Internet solución a problemas que ya sabía solucionar hace 7 años. En todo caso después de leerme el artículo veo que la conclusión es que como la velocidad de las puertas es muy alta el pulso es muy corto y resulta insuficiente (en su día resultaba insuficiente para despertar un Xbee y asumo que el problema será más o menos el mismo para un ESP8266).
Volviendo a las soluciones intuitivas, si un condensador descargado se comporta (más o menos) como un cortocircuito hasta que se carga voy a unir el GPIO3 y el RST con un condensador. Como hay resietencias de pullup a ambos lados por el condensador no circula nada. Cuando pongo a masa el GPIO3 con el interruptor de láminas el condensador se tiene que cargar, por lo que acaba llegando un impulso al pin de RST, y todo eso sin consumir nada cuando está en sleep.
Ahora, cuando acercas el imán el ESP arranca en ese momento, leyendo el GPIO3 sabemos que tiene el imán cerca. Aún así, como veréis más adelante nos queda algún lío que resolver.