Kapacitní čidlo vlhkosti nám může posloužit k měření vlhkosti půdy a lze pomocí něho a Pica například vytvořit automatický zavlažovací systém pro květiny. Čidlo převádí kapacitu na napětí v rozsahu 0 až 3V. Základem jeho zapojení je použit populární obvod TCL555I (NE555). Stačí nám ho zapojit k analogově digitálnímu převodníku ADC Pica a můžeme měřit vlhkost. Existují i odporová čidla vlhkosti, která však jsou téměř nepoužitelná, protože silně trpí rozpadem elektrod díky elektrolýze, která probíhá ve vlhkém prostředí vždy.

Problémem však je nekvalita výroby řady výrobců (a neserióznost řady prodejců), kdy např. napěťová reference chybí a je nahrazena odporem (potom čidlo měří v závislosti na napájecím napětí, tedy nesmysly) a špatné zapojení rezistoru R1. Detailně je o tom pojednáno ve videu Capacitive Soil Moisture Sensors don’t work correctly + Fix for v2.0 v1.2 Arduino ESP32 Raspberry Pi. Je třeba dobře vybírat. Mě se snad podařilo koupit čidlo dobré.

Černý drát je zem, červený drát je napájecí napětí 3.3V až 5V a žlutý drát je měřené napětí v rozsahu 0 až 3V.

Předběžné výsledky


Poznámka: Suché čidlo měří 1V, ponořené 0.5V, budeme ho muset ještě detailně proměřit, protože to nějak neodpovídá specifikaci a možná jde o další zmetek.
Základ programu je převzat z předchozího měření teploty, takže program měří i teplotu pomocí čidla UMW DS8B20 a vlhkost a zobrazuje ji na displeji OLED SH1106.
#include <stdio.h>
const int ROMSize = 8;
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"
#include "modules/pico-onewire/api/one_wire.h"
#include "ss_oled.hpp"
// RPI Pico I2c
#define SDA_PIN 4
#define SCL_PIN 5
#define PICO_I2C i2c0
#define I2C_SPEED 100 * 1000
int main()
{
static uint8_t ucBuffer[1024];
char buf[128];
uint8_t uc[8];
int i, j, rc;
char szTemp[32];
uint16_t araw; // z adc
const float conversion_factor = 3.3f / (1<<12);
float napeti;
// displej pripojen na Pin 4 SDA a Pin 5 SCL
picoSSOLED myOled(OLED_128x64, 0x3c, 0, 0, PICO_I2C, SDA_PIN, SCL_PIN, I2C_SPEED);
rc = myOled.init() ;
myOled.set_back_buffer(ucBuffer);
stdio_init_all();
One_wire one_wire(15); // cislo teploty cteme na GP15 - Pin 20 on Pi Pico
one_wire.init();
rom_address_t address{};
// inicializace ADC
adc_init();
adc_select_input(0); // merime na pinu 31 (ADC0)
while (true) {
one_wire.single_device_read_rom(address);
printf("Device Address: %02x%02x%02x%02x%02x%02x%02x%02x\n", address.rom[0], address.rom[1], address.rom[2], address.rom[3], address.rom[4], address.rom[5], address.rom[6], address.rom[7]);
sprintf(buf,"%02x%02x%02x%02x%02x%02x%02x%02x",address.rom[0], address.rom[1], address.rom[2], address.rom[3], address.rom[4], address.rom[5], address.rom[6], address.rom[7]);
one_wire.convert_temperature(address, true, false);
myOled.fill(0,1);
myOled.set_contrast(127);
myOled.write_string(0,0,0,buf, FONT_8x8, 0, 1);
printf("Temperature: %3.1foC\n", one_wire.temperature(address));
sprintf(buf,"%3.1f C",one_wire.temperature(address));
myOled.write_string(0,0,3,buf, FONT_12x16, 0, 1);
// cteni ADC
araw = adc_read();
napeti = araw*conversion_factor;
printf("araw = %d: napeti %f\n", araw,napeti ); // na debug
sprintf(buf,"%5.3f V",napeti); // na displej
myOled.write_string(0,0,5,buf, FONT_12x16, 0, 1);
sleep_ms(1000);
}
return 0;
}
cmake_minimum_required(VERSION 3.13)
# initialize the SDK based on PICO_SDK_PATH
# note: this must happen before project()
include(pico_sdk_import.cmake)
project(vlhkost1)
# set(CMAKE_C_STANDARD 11)
# initialize the Raspberry Pi Pico SDK
pico_sdk_init()
# rest of your project
add_executable(vlhkost1
ds18b20_test.cpp
)
add_subdirectory(modules/pico-onewire)
add_subdirectory(modules/pico-ss-oled)
target_link_libraries(vlhkost1
pico_stdlib
pico_one_wire
pico_ss_oled
hardware_adc
)
pico_enable_stdio_usb(vlhkost1 1)
pico_enable_stdio_uart(vlhkost1 0)
# create map/bin/hex/uf2 file in addition to ELF.
pico_add_extra_outputs(vlhkost1)
Zabalený projekt verze 0.1: teplota_vlhkost-0.1.tar.gz
Měření
Čidlo se ukazuje jako zmetek, neodpovídá specifikaci. Při napájecím napětí 5.0V 3 Voltový stabilizátor stabilizuje referenční napětí na hodnotě 3.33V a při napájecím napětí 3.3V stabilizuje na referenční napětí na hodnotě 3.23V. Značení součástek neodpovídá schématu. Jeho výstupní měřené napětí je od 0.5V (plně ve vodě) do 1.0V (na suchu), specifikace říká 0 V až 3V.

Drobná úprava kódu
Referenční napětí Pica jsem změril pomocí UTI-T UT61E+ (přesnost měření napětí na daném rozsahu +/- 0.05% +5dig) a podle skutečné hodnoty jsem upravil konverzní faktor. Protože měření napětí pomocí ADC na Picu hodně skáče, změřím 10 hodnot rychle za sebou a budu zobrazovat jejich průměr. Přesnost měření je teď 1% z naměřené hodnoty.
const float conversion_factor = 3.22f / (1<<12);
araw = adc_read();
for( uint8_t i=0; i<9; i++ ) {
araw += adc_read();
sleep_ms(5);
}
napeti = araw*conversion_factor*0.1;
Zabalený projekt verze 0.2: teplota_vlhkost-0.2.tar.gz
Závěr
Pro jednoduché hlídání zalitých květin se čidlo dá snad použít. V každém případě je nutné každý kus aspoň přibližně ocejchovat a až potom používat. Za cenu 38 Kč to docela jde. Lepší čidla budou o hodně dražší.