msgbartop
El Día del Tentáculo ha llegado
msgbarbottom

12 dic 15 Attiny85: módulo RF a 433 MHz, modo de bajo consumo, y cómo despertarlo con interrupciones

Hace ya bastante tiempo escribí algo acerca de un sistema de riego controlado por WhatsApp que estuve desarrollando. Se basaba en el uso de una Raspberry Pi que actuaba como cerebro del sistema de riego y de comunicaciones, permitiendo el control de todo el sistema mediante mensajería por WhatsApp. La Raspberry, a su vez, se comunicaba con los los relojes de riego mediante módulos de radiofrecuencia a 433 MHz, un sistema de comunicación barato y razonablemente efectivo. En el otro lado, como se comentó en su momento, la válvula de riego se controlaba con un chip Attiny85, programado mediante Arduino.

Como se vio en su momento, el sistema funcionaba razonablemente bien. Sin embargo, varios problemas me llevaron a un callejón sin salida. El principal de ellos, y del que hablaremos hoy, era el consumo del receptor Attiny85. Sobre el papel es un sistema de muy bajo consumo, óptimo para este tipo de funciones. Sin embargo, el sistema de control de la válvula de riego no dejaba demasiado espacio para una batería, así que la alimentación disponible era, como poco, reducida. Pronto se demostró el que el Attiny con el sistema de radiofrecuenca devoraba la batería. Ésta apenas duraba unas 48-72 horas. Y esto, en un sistema que se supone que ha de ser autónomo y con un bajo mantenimiento, era sencillamente inaceptable, sobre todo si lo comparamos con relojes de riego de jardón convencionales, que con un par de pilas AA o una pila cuadrada de 9v pueden funcionar de manera ininterrupida durante meses.

Probé varias soluciones, desde el uso inicial de una batería recargable de 9v hasta el uso de un panel solar con una batería de móvil incorporada. Éste último caso consiguió producir mejoras, llegando el sistema a funcionar durante una semana de manera ininterrumpida. Pero en cualquier caso, no era una gran mejora. Tocaba afrontar el problema de base: un exceso de consumo.

Batería cuadrada de 9v y panel solar con regulador

Batería cuadrada de 9v y panel solar con regulador

En efecto, el problema estaba provocado por un exceso de consumo. Tal y como estaba diseñado, el sistema estaba permanentemente a la escucha de señales por RF, en un bucle sin fin, dado que la señal de encender o apagar la válvula de riego podía darse en cualquier momento. Esta aproximación era, como poco, inadecuada desde el punto de vista del consumo.

Para mejorar esto, probé varias alternativas: desde emitir sólo en determinadas ventanas de tiempo, hasta desconectar la alimentación al módulo de radiofrencuencia y activarlo sólo durante varios segundos cada minuto. Opciones bastante malas, la verdad, ya que se basaban en la precisión de un reloj interno que, como es conocido, no es un prodigio de la precisión.

Otra posibilidad hubiera podido ser un método en el que el Attiny consultara a la Raspberry si había algún comando por ejecutar. Pero por desgracia, los módulos RF de 433 MHz son unidireccionales, por lo que hubiera sido preciso incorporar un emisor al Attiny y un receptor a la Raspberry, complicando de manera innecesaria todo el sistema. Finalmente, la solución vino de mano de dos elementos presentes en el Attiny. El modo sleep y el uso de interrupciones.

El Attiny85 dispone de varios modos de bajo consumo (sleep mode) que sirven para reducir el consumo del chip cuando está a la espera de algún evento. En el caso del Attiny85, puede reducir el consumo hasta en un 90%. Pero no se trataba sólo de dormir al chip, sino de ser capaz de despertarlo cuando se recibiera una recepción de datos en el módulo de RF. Y para ello, nos encontramos con las interrupciones.

Las interrupciones son eventos que provocan un cambio en el estado de reposo o ejecución de un programa -en este caso, un programa cargado en el Attiny85-. Hay interrupciones tanto hardware como software, siendo las hardware las provocadas por un evento externo al programa en sí. Dentro de las interrupciones hardware, en el caso de Arduino, podemos distinguir las interrupciones Externas, y las provocadas por un Cambio en el Pin. El nombre es un poco confuso, pues ambas son externas al chip en sí, pero mientras las Externas están limitadas a un número concreto de patillas en el chip, las de Cambio en Pin pueden ocurrir en cualquiera de las patillas. En el caso concreto del Attiny85, las Externas sólo se producen en el Pin2 (INT0, patilla 7), mientras que las de Cambio en Chip se pueden producir en cualquier otra patilla.

De hecho, es factible despertar al Attiny85 del modo de bajo consumo mediante el uso de interrupciones. En el caso concreto del artículo enlazado, se usa el Pin3 (patilla 7) -luego se usa el modo de Cambio de Pin- para despertar al chip del modo de bajo consumo, como he podido comprobar personalmente (el ejemplo se basa en el uso de un botón conectado a 5v). Sin embargo, a la hora de probarlo con el módulo de RF a 433 MHz el sistema no funcionaba. No era capaz de realizar cambios en el sistema.

A modo de recordatorio, el sistema de control de la válvula consiste básicamente en un relé que activa o desactiva la válvula en función del tiempo que se desea mantener activo el riego. Este relé está controlado por una de las patillas del Attiny, protegida mediante un optoacoplador.

Tras varias pruebas, pude averiguar que el problema estaba causado por una particularidad en el receptor del módulo RF. Sólo he sido capaz de hacerlo comunicar con el chip Attiny a través del del pin de Interrupción Externa (Pin2, INT0), por lo que el ejemplo referenciado anteriormente no resultaba válido. En mi caso, ha sido necesario hacer uso de la patilla INT0:

#include
#include
#include

RCSwitch mySwitch = RCSwitch();
const int rele = 4;
const int dataPin = 0; //INT0, PCINT2
void setup() {
pinMode(dataPin, INPUT);
digitalWrite(dataPin, HIGH);
pinMode(rele, INPUT);
mySwitch.enableReceive(dataPin);

// Flash quick sequence so we know setup has started
for (int k = 0; k < 10; k = k + 1) {
if (k % 2 == 0) {
pinMode(rele, OUTPUT);
}
else {
pinMode(rele, INPUT);
}
delay(250);
} // for
}

void sleep() {

GIMSK |= _BV(PCIE); // Enable Pin Change Interrupts
PCMSK |= _BV(PCINT2); // Use PB3 as interrupt pin
ADCSRA &= ~_BV(ADEN); // ADC off
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // replaces above statement

sleep_enable(); // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
sei(); // Enable interrupts
sleep_cpu(); // sleep

cli(); // Disable interrupts
PCMSK &= ~_BV(PCINT2); // Turn off PB2 as interrupt pin
sleep_disable(); // Clear SE bit
ADCSRA |= _BV(ADEN); // ADC on

sei(); // Enable interrupts
} // sleep

ISR(PCINT0_vect) {
// This is called when the interrupt occurs, but I don't need to do anything in it
}

void loop() {

if (mySwitch.available()) {

sleep();
int value = mySwitch.getReceivedValue();

if (value == 0) {
// Serial.print("Unknown encoding");
} else {

pinMode(rele,OUTPUT);
delay(10000);
pinMode(rele,INPUT);
}
mySwitch.resetAvailable();
}
}

(Explicación rápida del ejemplo: Se declaran INT0 como receptor de RF, y el Pin4 como control del relé. Se realiza un ciclo de encendido y apagado del relé al inicio para mostrar que el programa ha iniciado, se declara la interrupción del modo de bajo consumo con INT0, y se pasa al bucle principal. Se espera a una interrupción, se comprueba que la señal RF recibida es correcta, y se enciende el relé durante 10 segundos)

Resultado: ¡éxito! No sólo el sistema funciona, sino que he podido comprobar una gran mejora en el consumo del sistema. Durante la fase activa del programa, en la que el relé está activo y se ha recibido la señal de radiofrecuencia, todo el sistema consume unos 9 mA. Cuando está en modo de bajo consumo, a la espera de recibir la señal, baja a niveles inferiores a 1 mA.

VN:F [1.9.20_1166]
Rating: 9.0/10 (2 votes cast)

Etiquetas: , , , ,

22 mar 14 Riego de jardín con WhatsApp y radiofrecuencia

Llevo unas cuantas semanas sin escribir, y es que entre el trabajo y diversas ocupaciones no he podido ponerme a darle a la tecla. Sin embargo, no he estado ocioso todo este tiempo. Y este vídeo es la prueba de ello:

Como se puede ver (aunque un poco oscuro), se trata de un reloj de riego de jardín controlado por WhatsApp. Los mensajes son enviado por WhatsApp y recibidos por una Raspberry Pi, que activa el reloj de riego mediante radiofrecuencia.

El reloj, por otro lado, está controlado por un chip Attiny85, programado con Arduino. El conjunto está alimentado por una batería de 9v. Con un regulador se baja el voltaje a 5v, que proporciona alimentación tanto al sistema attiny como al propio motor de riego. El esquema básico de funcionamiento es el mismo que el de este diagrama…

Diagrama de control RF del sistema de riego con Raspberry y Arduino

…pero reemplazando el arduino por el attiny.

Otro día, con más tiempo, doy más detalles del funcionamiento.

VN:F [1.9.20_1166]
Rating: 0.0/10 (0 votes cast)

Etiquetas: , , , , , ,

26 ene 14 Sistema de control de riego controlado por WhatsApp

Este fin de semana he seguido avanzando con el tema de la domótica. Tras conseguir intercomunicar un arduino y la raspberry por radiofrecuencia, he conseguido progresar bastante. Como puede verse en el siguiente vídeo:

Se trata de un reloj de riego barato comprado en el Leroy Merlín. Le he reemplazado la lógico, y dejado tan sólo el servomotor que controla el paso del agua. Para ello he necesitado lo siguiente:

  • Mejorar el alcance por de los módulos RF: Esa ha sido la parte sencilla. Tan sólo ha sido necesario soldar sendas antenas de 17 cm. a los módulos de emisión y recepción. ¿Por qué 17 cm.? Porque corresponden (aproximadamente) con 1/4 de la longitud de onda a la que emiten los módulos, lo que permite maximizar la eficiencia de los módulos. He podido comprobar que la señal es perfectamente recibida en toda la casa, a lo largo de las tres plantas. No está mal, para unos módulos de 2€.
  • Modificar el código de mensajería Raspberry/WhatsApp: Además de incorporar un comando para comunicarse con los relés controlados a través de RF, ha sido preciso tener en cuenta que el reloj de riego tiene un servomotor en vez de una electroválvula. La diferencia es que la electroválvula abre paso al agua cuando se la alimenta con voltaje, por lo que simplemente activando el relé se abre. El servomotor, por el contrario, se activa para hacer girar 90º una llave de paso, y tiene que volver a activarse para volver a hacer girar 90º la llave de paso para cerrar el paso de agua. Por lo tanto, tiene una implementación lógica diferente, que ha sido preciso modelar.
  • Modificar el reloj de riego: He eliminado la circuitería del reloj, dejando tan sólo el servomotor. Éste se compone de un motor convencional, alimentado por dos pilas AA de 1.5v, y un interruptor, que permite saber cuándo está completamente abierta o cerrada la llave de paso. Para poder controlar ambos sistemas con arduino, se requieren dos puertos de E/S: uno para activar el relé, y otro para detectar el estado del interruptor.

El sistema quedaría de la siguiente manera:

Diagrama de control RF del sistema de riego con Raspberry y Arduino

Hay una serie de posibles mejoras en las que empezar a trabajar:

  • Mejorar la codificación del sistema de RF: Actualmente sólo es capaz de controlar un único dispositivo. Hay que incorporar una implementación de un sistema de comunicación que permita dar instrucciones a múltiples módulos. También sería conveniente mejorar la seguridad de los mensajes intercambiados. Hasta el momento, el módulo arduino ejecuta cualquier mensaje que reciba, sin verificar fuente, por lo que un atacante malicioso podría activar/desactivar el sistema de riego de manera arbitraria. Lo ideal sería incorporar un sistema de codificación basado en identidad, junto con un cifrado basado en clave pública/privada, pero igual esto último es matar moscas a cañonazos… :mrgreen:
  • Incorporar un sistema de programación de eventos: Hasta ahora es posible dar instrucciones al sistema, pero no programar eventos. Hasta el momento uso una aproximación, consistente en crear en /etc/crontab disparadores que activen el sistema, pero no es especialmente práctico. Mi intención es incorporar un calendario online (Google Calendar, por ejemplo) para poder programar eventos de una manera sencilla
  • Miniaturizar el hardware: Actualmente está todo en una placa de prototipado, y hago uso de la placa con 4 relés. Mi intención es pasar de un arduino a un attiny85, y hacer uso de un único relé. Las piezas están ya encargadas; en cuanto lleguen, habrá que tirar de soldador. :D
  • Desarrollar una aplicación web para monitorizar el sistema: Aquí no hay mucho más que decir. :)
VN:F [1.9.20_1166]
Rating: 9.5/10 (2 votes cast)

Etiquetas: , , , ,

24 ene 14 Código de control de Raspberry Pi por WhatsApp

Llevo desde hace algunos meses trabajando en un sistema de control de domótica controlado por WhatsApp en Raspberry: , , . La parte central del sistema es la librería yowsup, que permite comunicarse por línea de comandos con WhatsApp desde linux. He modificado el código del mismo, para poder capturar los mensajes enviados desde el teléfono, e interactuar con los GPIO de la Raspberry. Este es el código que hasta el momento he desarrollado:

Código fuente de control de Raspberry por WhatsApp

Varios comentarios al mismo:

  • El código es feo de narices, lo sé. Hacía mucho tiempo que no tiraba una sola línea de código, y nunca he sido un especialista en python, lenguaje que he tenido que aprender sobre la marcha. Así que no esperes nada especialmente elegante.
  • La manera menos problemática para ejecutar el sistema es la siguiente:screen -dmS whatsapp sudo python /home/pi/yowsup/src/yowsup-cli -c /home/pi/yowsup/src/config.example -E 346xxxxxxxx -a -k, siendo 6xxxxxxxx el teléfono desde el que queremos comunicarnos. El parámetro “-E” es una de las modificaciones que he efectuado. Permite lanzar el yowsup ejecutando el modo de control de las electroválvulas (Electro.py), que es básicamente donde he metido las zarpas.
  • Aunque se puede lanzar sin hacer uso de screen, aconsejo encarecidamente hacer uso del mismo, ya que nos permitirá recuperar la sesión desde terminales distintos a aquel desde donde hemos lanzado el programa, lo que siempre es una ventaja.
  • Es imperativo lanzar mi modificación de yowsup con sudo (o como root), ya que se trastea con la GPIO.
  • Una buena manera de automatizar el inicio de yowsup cuando se encienda la raspberry es añadiendo el comando anterior a /etc/rc.local
  • Aparte del sistema de control de los relés, también contiene el sistema de control de movimiento con el sensor PIR

Espero que os resulte de utilidad. :mrgreen:

VN:F [1.9.20_1166]
Rating: 10.0/10 (2 votes cast)

Etiquetas: , ,

23 ene 14 Control de relé por RF con Raspberry Pi y Arduino Nano

Hoy hemos tenido algunos avances interesantes. He sido capaz de controlar desde la Raspberry Pi un relé conectado al Arduino Nano:

Para ello, he hecho uso unos módulos RF que trabajan a 433 MHz, controlados mediante la librería RCswitch, además de hacer uso de algunas instrucciones obtenidas de NinjaBlocks: Adding 433 to your Raspberry Pi

Siguientes pasos: integrar el uso de la librería en el sistema de control de la Raspberry con WhatsApp, y transferir la operativa desde el Arduino Nano a un chip Attiny85.

VN:F [1.9.20_1166]
Rating: 0.0/10 (0 votes cast)

Etiquetas: , , , ,