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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#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.
Referencias
[1] Sensor comprado.
[2] Imagen del sensor.