Sensores con módulos RF433


La radiofrecuencia de 433MHz es una banda de frecuencia utilizada comúnmente en dispositivos inalámbricos, como controles remotos, sistemas de seguridad, sistemas de monitoreo, domótica y, por supuesto, Arduino.

Módulos FS1000A y MX-RM-5V

En el mundo Arduino los más conocidos son el módulos emisor FS1000A y módulo el receptor MX-RM-5V son muy populares dado su bajo coste y fácil implementación.

Estos módulos trabajan a una frecuencia de 433MHz que pertenece a una banda libre así que no hay problemas para usarlo y no tener problemas con la ley.

¿Por qué hacer este montaje?

Bien, uno de los problemas que tiene una maqueta es su cableado. Suele volverse engorroso y difícil de manejar, tomas de corriente, transformadores, linea DCC, decoración, etc. En mi caso particular, mi maqueta es modular y, en toda su extensión, unos 7 metros. Para tener menos cableado me plantee esta solución, crear una red de sensores comunicados por radio frecuencia. Ya había usado estos módulos en proyectos anteriores, así que me puse manos a la obra y bueno tenemos este articulo donde intentaremos explicar como podemos aplicar esta solución.

La solución es utilizar 2 Arduinos. El primero es un emisor el cual envía la trama de datos del tipo Qx o qx. El otro Arduino, receptor, recoge este mensaje y lo reenvía a la central DCC por comunicación serial.

¿Por que no usarlo con la central DCCpp LMD?

Pues he intentado hacer la comunicación mediante Serial y no obtuve buenos resultados. Así que opte por usar la librería VirtualWire. El problema es que esta librería utiliza interrupciones para la entrada de datos, por defecto la interrupción 1, y esto no es compatible con la central DCC LMD. Así

Para este montaje usaremos un módulo MX-RM-5V (receptor) y un Arduino UNO y el módulo FS1000A (emisor) junto con un Arduino NANO.

Emisor FS1000A

Módulo FS1000A

El módulo FS1000A cuenta con tres pines Data, GND y VCC y las siguientes características:

  • Modelo: FS1000A
  • Voltaje de operación: 3.3-12 V
  • Consumo: max. 45 mA
  • Frecuencia: 433 MHz
  • Modulación: ASK / OOK
  • Potencia: 10 mW
  • Interfaz: TTL
  • Dimensiones sin conector: 19 x 20 mm

Conexiones módulo FS1000A

La función principal para la recepción de datos se llama “SendBloque” y recibe dos variables, sensor y estado. Previamente, el programa que estemos haciendo, tiene que mandar esta información.

Otro punto importante es la compatibilidad con la librería DCC_Decoder ya que este usa la interrupción 0 y la librería VirtualWire usa la interrupción 1


Función para el envío del estado del sensor:

#include <VirtualWire.h>      // Librería para RF433

// Pin Tx RF433  vw_tx_pin = 7 (definido por librería VirtualWire)

// Estado de los sensores
bool bloque[8] = { false, false, false, false, false, false, false, false };
bool BloqueStatus[8] = { false, false, false, false, false, false, false, false };


void setup(){
  // Pines de entrada
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);

  // Otras configuraciones...

  // Setup RF433 FS1000A (Siempre al final del setup!!)
  vw_set_ptt_inverted(true);  // Requerido para FS1000A y DR3100 RF433
  vw_setup(2000);             // Bits por seg
}

void loop(){

  // Lectura de todos los sensores
  bloque[0] = digitalRead(3);
  bloque[1] = digitalRead(4);
  bloque[2] = digitalRead(5);
  bloque[3] = digitalRead(6);
  bloque[4] = digitalRead(8);
  bloque[5] = digitalRead(9);
  bloque[6] = digitalRead(10);
  bloque[7] = digitalRead(11);

  // Se puede poner un delay de 100 o 150 ms
  delay(100);

  // Lee todos los bloques 
  for (int i = 0; i <= 7; i++) {
    if (bloque[i] && BloqueStatus[i]) {
      BloqueStatus[i] = false;
      SendBloque(i, BloqueStatus[i]);
    }
    if (!bloque[i] && !BloqueStatus[i]) {
      BloqueStatus[i] = true;
      SendBloque(i, BloqueStatus[i]);
    }
  }
}

// Función para el envío de la trama Qsensor o qsensor
void SendBloque(uint8_t sensor, bool estado) {

  uint8_t buf[VW_MAX_MESSAGE_LEN]; // Cadena para enviar
  String str = "";

  // Construimos la trama
  if (estado) str = "<Q" + String(sensor) + ">"; 
  else str = "<q" + String(sensor) + ">";
  
  str.toCharArray(buf, sizeof(buf)); // convertimos el String en un array

  vw_send((uint8_t *)buf, strlen(buf)); // Enviamos el array
  vw_wait_tx(); // Esperamos hasta que el mensaje se envíe
}


El circuito más sencillo que podemos montar sería el siguiente:

Fritzing conexión emisor rf433


Cada pulsador representa un sensor y podemos darle el valor que queramos de tal manera que enviara Qx o qx.


Por otra parte tenemos la recepción de los datos. Para esto tenemos que montar un Arduino y tiene que hacer de enlace entre la central y la radiofrecuencia. Esto hay tiene que ser así por los problemas de interrupciones descrito más arriba.

Módulo MX-RM-5V

  • Modelo: MX-05V
  • Voltaje de operación: 5V
  • Consumo en reposo: max. 4 mA
  • Frecuencia: 433.92MHz
  • Sensibilidad de recepción: -105db
  • Dimensiones sin conector: 30 * 14 * 7 mm


Conexiones módulo MX-RM-5V

En este caso la función de recepción es prácticamente la misma que se puede encontrar en el programa origina de DCC++. Es muy fácil de implementar con unos cambios mínimos como los que se describen más abajo.

La diferencia radica en que cambiamos el Serial.read() por vw_get_message(). También hay que tener en cuenta que la configuración tiene que estar al final del setup() y podemos cambiar el pin de recepción en este caso hemos usado el pin A4 y los bits por segundo, igual que en el transmisor tiene que ser de 2000.


#include <VirtualWire.h>

// Pin Rx recepción de datos
const int receive_pin = A4; 

// Carácter para la recepción RF433 (char)
uint8_t b;  

uint8_t sensores[8] = { true, true, true, true, 
                        true, true, true, true
					   };

void setup(){
  Serial.begin(115200);  // Velocidad serial
  delay(200);

  // Otro código

  // Configuración RF433 MX-RM-5V ¡¡¡Siempre al final del setup()!!!
  vw_set_rx_pin(receive_pin);
  vw_set_ptt_inverted(true);  // Requerido para RF433 MX-RM-5V o RD3100
  vw_setup(2000);             // Bits por segundo
  vw_rx_start();              // Start the receiver PLL running
}

void loop(){
  Recibe433();
}


// Recibe datos RF433
void  Recibe433() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)){ // Non-blocking
	int i;
	for (i = 0; i < buflen; i++){
	Serial.print((char)buf[i]);
	b = (char)buf[i];
    if (b == '<') {                   // start of new command
      commandString[0] = 0;
    } else if (b == '>') {              // end of new command
        Serial.println(commandString); // Imprime el comando
 		// decodata(commandString);	// Función para usar los datos
    } else if (strlen(commandString) <  MAX_COMMAND_LENGTH)  // if commandString still has space, append character just read from serial line
        sprintf(commandString, "%s%c", commandString, b); // otherwise, character is ignored (but continue to look for '<' or '>')
    }
  }
}
Módulo MX-RM-5V conectado a Arduino Uno


Y con esto tenemos la recepción de los datos. Desde este Arduino podemos mandar la información a la central o usarla en ese mismo Arduino con, por ejemplo, una pantalla. Próximamente pondremos alguna cosa más sobre pantallas… pero podemos conectar cualquier dispositivo de salida como leds o pantallas.

La antena que podemos utilizar tanto en emisor como en el transmisor puede ser de unos 17,31cm de hilo de cobre. Si quieres más información sobre como llegar a estos datos, puedes consultar las fuentes.

Este es un buen sistema si tienes una maquetas modular para ahorrar en cableado. También comentar que solo lo hemos probado con uno de los módulos y aún hace falta hacer más pruebas con varios módulos en simultaneo.

Fuentes:

Programarfacil.com