PFG – Sensor de humedad FC-28
Introducción
El sensor de humedad utilizado es el FC-28. Se basa, al igual que el sensor de lluvia, es un divisor de voltaje ajustable mediante un potenciómetro. Según el fabricante:
- This is a summary of the moisture sensor can be used to detect soil moisture, when soil water deficiency, the module outputs a high level, whereas output low level. Using this sensor to water the flowers make an automatic device, without people to manage your garden plants.
- Sensitivity can be adjusted (figure blue digital potentiometer adjust)
- Soil humidity module on the environment humidity the most sensitive, generally used to detect soil humidity
- Module in soil moisture can not reach the setting threshold, DO mouth output high level, when soil moisture more than setting threshold value, module D0 output low level
- Has fixed bolt hole, convenient installation
- Comparator using LM393 chip, work stability
- Two small plate interface specifications (3 wires)
- VCC external 3.3~5 V
- GND external GND
- DO small plate digital output interface (0 and 1)
- Digital output D0 can be directly connected with the single chip microcomputer, through the single chip microcomputer to detect high and low level, thus to detect soil humidity
Se va a utilizar la salida analógica del sensor, la cual se ha comprobado mediante experimentos que oscila entre 0 (máxima humedad) y 4080 (nada de humedad). Es necesario por tanto realizar un ajuste experimental del valor para obtener la humedad relativa como un valor entre 0 y 100, siendo 100 la máxima humedad relativa que es capaz de captar el sensor.
Este ajuste se hará calculando una recta tal que en el eje de abcisas esté la salida en V del sensor y en el eje de ordenadas el valor de humedad relativa en % que le corresponda. Conocidos dos puntos (0 mV, 100% HR) y (4080 mV, 0% HR) obtenemos:
Conexión
El sensor dispone de 4 pines, de izquierda a derecha:
- Pin 1: salida analógica. Es la que utilizaremos, conectada a una entrada analógica de nuestra placa.
- Pin 2: salida digital. No se usa.
- Pin 3: alimentación, se escoge que sea a 3.3V.
- Pin 4: GND.
Se decide instalar todos los sensores en la placa Texas Instrument Stellaris Launchpad para comprobar su rendimiento.
A partir del diagrama de la placa TI obtenemos los pines de conexionado:
- Sensor de temperatura: A11
- Sensor de lluvia: A9
- Sensor de humedad: A8
Nota: los sensores no se corresponden con los instalados pero sirven para ver el conexionado. La placa TI Stellaris utilizada es otra versión, pero comparten los pines que se ven en la imagen.
Prueba del sensor
#define HUMIDITY_SENSOR A8 void setup() { Serial.begin(9600); } void loop() { int humidity; humidity = 100-0.0245*analogRead(HUMIDITY_SENSOR); Serial.println(humidity); delay(500); }
El sensor funciona correctamente. Realizando pruebas con una maceta obtenemos valores de 0 – 2% HR cuando la tierra está totalmente seca y valores en torno al 70% HR al regarla. Se observa también como el valor va disminuyendo como a poco al ir secándose la tierra.
Comunicación I2C del valor
Se modifican los programas escritos para el sensor de lluvia.
Texas Instrument
Como necesitamos conocer el número de bytes que se van a enviar y la humedad oscila entre 0 y 100%, se completan con ceros a la izquierda antes de ser enviado, quedando los valores entre 000 y 100 y enviándose siempre 3 bytes.
#include <Wire.h> #include <math.h> #define SLAVE_ADDRESS 0x08 #define TAG_TEMP "TEMP" #define TAG_RAIN "RAIN" #define TAG_HUM "HUMIDITY" #define TEMPERATURE_SENSOR A11 #define RAIN_SENSOR A9 #define HUMIDITY_SENSOR A8 String var; char c; double temperature; int int_temperature; int rain; int humidity; String value; char char_array[] = ""; // configuracion inicial void setup() { // configuracion de los pines digitales pinMode(RAIN_SENSOR, INPUT); // inicializamos comunicacion serial //Serial.begin(9600); // inicializamos i2c como esclavo Wire.begin(SLAVE_ADDRESS); // llamadas para la comunicacion Wire.onReceive(receiveData); Wire.onRequest(sendData); } // bucle principal void loop() {} // llamada para recibir datos void receiveData(int byteCount) { var = ""; while (Wire.available() > 0) { c = Wire.read(); var.concat(c); } //Serial.print("Received: "); //Serial.println(var); if (var == TAG_TEMP) { //Serial.println("TEMP request received"); temperature = Thermister(analogRead(TEMPERATURE_SENSOR)) *100; int_temperature = (int) temperature; value = (String) int_temperature; } else if (var == TAG_RAIN) { rain = digitalRead(RAIN_SENSOR); if (rain == 1) rain = 0; else if (rain == 0) rain = 1; value = (String) rain; } else if (var == TAG_HUM) { humidity = 100-0.0245*analogRead(HUMIDITY_SENSOR); value = (String) humidity; if (humidity < 10) value = String("00" + value); else if (humidity <100) value = String("0" + value); } // Convert String to char* unsigned int value_length = value.length()+1; ((String)value).toCharArray(char_array, value_length); } // llamada para enviar datos void sendData() { Wire.write(char_array); //Serial.print("sent: "); //Serial.println(char_array); } // A partir de la salida del termistor calculamos la temperatura double Thermister(int RawADC) { double res; double Vo; Vo = (RawADC)*(3.3/4095.0); res = log(10000*(3.3/Vo-1)); res = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * res * res ))* res ); //res = 1 / (0.001126068758413 + ( 0.000234572594529 + (0.000000086312248 * res * res ))* res ); res = res - 273.15;// Convert Kelvin to Celcius return res; }
Raspberry Pi
Se añade la lectura del sensor de humedad, la inclusión de este valor en el array de valores y la escritura en el fichero LOG.
#include <stdio.h> #include <stdlib.h> #include "functions.h" #define ARDUINO 0x04 #define TI 0x08 #define TAG_REFRESH_RATE "REFRESH_RATE" #define TAG_TIMESTAMP "TIMESTAMP" #define TAG_TEMP "TEMP" #define TAG_RAIN "RAIN" #define TAG_HUM "HUMIDITY" int main() { char * buf; int refresh_rate; char * timestamp; uint nBytesTAG_TEMP = sizeof(TAG_TEMP)-1; // no enviamos el caracter '\0' uint nBytesTAG_RAIN = sizeof(TAG_RAIN)-1; uint nBytesTAG_HUM = sizeof(TAG_HUM)-1; uint nBytesTEMP = 4; uint nBytesRAIN = 1; uint nBytesHUM = 3; float temperature; uint rain; uint humidity; char temperature_char[] = {0}; char rain_char[] = {0}; char humidity_char[] = {0}; buf = readVar(TAG_REFRESH_RATE); refresh_rate = atoi((char *) &buf); printf("%s: %d\n", TAG_REFRESH_RATE, refresh_rate); for(;;) { // Leemos los valores se los sensores temperature = readSensor(TI, TAG_TEMP, nBytesTAG_TEMP, nBytesTEMP) / 100.00; usleep(50000); rain = readSensor(TI, TAG_RAIN, nBytesTAG_RAIN, nBytesRAIN); usleep(50000); humidity = readSensor(TI, TAG_HUM, nBytesTAG_HUM, nBytesHUM); //weatherRequest(); timestamp = getTime(); // Convertimos los valores a char* sprintf(temperature_char, "%.2f", temperature); sprintf(rain_char, "%d", rain); sprintf(humidity_char, "%d", humidity); // Creamos los char** que cotienen variables y vectores char * variables_array[] = {TAG_TIMESTAMP, TAG_TEMP, TAG_RAIN, TAG_HUM, NULL}; char * values_array[] = {timestamp, temperature_char, rain_char, humidity_char, NULL}; printf("%s: %s\n", TAG_TEMP, temperature_char); printf("%s: %s\n", TAG_RAIN, rain_char); printf("%s: %s\n", TAG_HUM, humidity_char); printf("%s\n", timestamp); // Guardamos en el log los valores writeVar(variables_array, values_array); usleep(refresh_rate * 1000000); } return 0; }
Prueba
Observamos que la humedad se obtiene correctamente.
También comprobamos que la escritura en el fichero LOG es correcta.
Estimado EODOS:
tengo un problema con la medición del sensor. Hoy me ha llegado mi FC-28. Lo he conectado correctamente a placa Arduino UNO y he cargado el código pertinente. El problema es que me da valores incoherentes. En estado normal (al aire, sin tocar el sensor) da constantemente valores de 10 y si lo sumerjo en un vaso de agua me da un valor máximo de 24. ¿Tienes alguna idea? He probado a calibrarlo girando el potenciometro pero no varía nada. La cosa es que he comprado tres sensores idénticos y en los tres me pasa igual.
Te agradecería una respuesta, cualquier ayuda será bien recibida.
Gracias de antemano,
Un saludo!
El potenciometro lo que hace es cambiar el umbral en el que conmuta la salida digital del sensor, no la analógica.
Posiblemente tu sensor lo hayas adquirido en una tienda distinta a la mía y vendrá calibrado de otra manera. Los valores que uso en el programa los obtuve experimentalmente de la misma forma que tú, cogiendo el valor en seco y cogiendo el valor de máxima humedad y haciendo una recta con esos dos valores para obtener cualquier valor intermedio.
Cómo saber que el valor obtenido de acuerdo a la humedad es de la forma de una ecuación lineal y no un valor en una escala de forma exponencial o logarítmica?
Saludos
A falta de documentación oficial, todos los ejemplos que se pueden encontrar que usen ese sensor aplican una escala lineal.
Por ejemplo:
http://arduinotronics.blogspot.com/2014/01/when-do-i-water-my-plants-soil.html
Estimado Eodos,
Eh adquirido ese sensor de humedad (FC-28) quisiera saber como podría calibrarlo? y también quisiera saber su precisión. Si fueras tan amable de ayudarme.
Hola Rick. Desconozco esos datos. Toda la información que uso la he sacado de la referencia que adjunto al final de la entrada. Un saludo.
y1 es el menor valor que toma el sensor, y0 es el 100 para sacar el porcentaje
X1 es igual a el mayor valor que toma el sensor
Y por ultimo la division que hiciste X0 es igual a 0.
De donde sacaste ese 0?
x0, x1 son los valores mínimo y máximo que toma el sensor. y0, y1 son los valores de humedad relativa que me interesan. En concreto, x0, que es el valor de 0mV devuelto por el sensor, corresponde a 100% de humedad, y 4080mV el valor que he obtenido con 0% HR.
el sensor tambien se puede usar con una raspberry pi b+???
Sí. El sensor puede ser conectado a cualquier sistema con puertos IO.