Potřeboval jsem nahradit velmi drahé čidlo teploty a relativní vlhkosti Sensirion něčím levnějším, úspornějším a připojitelným na sběrnici I2C. Čidlo mělo být současně dostupné u běžně používaných distributorů el. součástek (Farnell, SOS, Mouser, …). Po dlouhém hledání jsem objevil senzor HDC1000 od TI, který splňoval všechny potřebné parametry. Jediná jeho nevýhoda je pouzdro BGA, ale má jen 8 vývodů, což by nemuselo být na překážku. Navrhli jsme tedy a vyrobili plošný spoj. určený na testování a nechal jsem osadit vzorek. Protože ale ještě zařízení, do kterého je čidlo určeno není hotové, použil jsem k oživení Arduino a jako sekundární výsledek jsem napsal knihovnu pro ovládání.
Arduino a senzor byly propojeny na klasické bastlířské destičce, senzor byl připojený na vývody I2C sběrnice, jak je patrné na obrázku.
Pro otestování jsem do Arduina nahrál známý I2C scanner, abych ověřil, že je čip dostupný na celé paletě hodinových kmitočtů a také abych ověřil funkci adresového přepínače. Výsledek, jak je vidět na dalším obrázku, je dle očekávání.
Čip reaguje na všech testovaných kmitočtech a po přepnutí přepínače mění svoji adresu.
Dalším krokem bylo vytvoření knihovny pro obsluhu a testovacího příkladu (zdrojové kódy celého projektu pro Arduino CodeBlocks jsou na konci článku). Knihovna je napsaná velmi spartánsky – obsahuje minimum potřebných funkcí a požaduje pouze dvě funkce, poskytnuté hlavním programem.
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 |
/* HDC1000.cpp Author: Pavel Brychta */ #include "hdc1000.h" #include #include #define HDC_REG_TEMPERATURE (0x00) #define HDC_REG_HUMIDITY (0x01) #define HDC_REG_CONFIGURATION (0x02) #define HDC_REG_SERIALID1 (0xfb) #define HDC_REG_SERIALID2 (0xfc) #define HDC_REG_SERIALID3 (0xfd) #define HDC_REG_MANUFACTURERID (0xfe) #define HDC_REG_DEVICEID (0xff) void HDC1000_readBytes(uint8_t i2caddress, uint8_t *values, uint8_t length); void HDC1000_writeBytes(uint8_t i2caddress, uint8_t *values, uint8_t length); HDC1000::HDC1000(uint8_t i2caddress) { _device = i2caddress; } void HDC1000::start(void) { uint8_t phase1[] = {HDC_REG_CONFIGURATION, 0x10, 0x00}; // temperature & humidity, both with 14 bit resolution // uint8_t phase1[] = {HDC_REG_CONFIGURATION, 0x30, 0x00}; // temperature & humidity, both with 14 bit resolution, HEATER ON HDC1000_writeBytes(_device, phase1, sizeof(phase1)); } void HDC1000::measure(void) { uint8_t phase1[] = {0x00}; // start measurement HDC1000_writeBytes(_device, phase1, sizeof(phase1)); } void HDC1000::readRawValues(uint16_t *rawTemp, uint16_t *rawHum) { uint8_t data[4]; HDC1000_readBytes(_device, data, 4); // read raw data *rawTemp = ((uint16_t)data[0] << 8) + data[1]; *rawHum = ((uint16_t)data[2] << 8) + data[3]; } float HDC1000::convertTemp(uint16_t rawTemp) { float result; result = (rawTemp / 65536.0) * 165.0 - 40.0; return result; } float HDC1000::convertHum(uint16_t rawHum) { float result; result = (rawHum / 65536.0) * 100.0; return result; } uint16_t HDC1000::getManufacturerID(void) { uint8_t phase1[] = {HDC_REG_MANUFACTURERID}; uint8_t data[2]; uint16_t result; HDC1000_writeBytes(_device, phase1, sizeof(phase1)); // set pointer HDC1000_readBytes(_device, data, 2); // read value result = (data[0] << 8) + data[1]; return result; } |
Výsledný test prokázal, že čip pracuje, teplotu měří správně, pouze hodnota RH je špatně – moje podezření je, že kolega při pájení čipu použil příliš mnoho tavidla, které poškodilo kondenzátor pro měření vlhkosti. Uvidíme, jak dopadne testování série, osazené jinou technologií…
A na závěr jak jsem už uvedl – ke stažení je kompletní projekt pro Arduino CodeBlocks IDE. Vlastní samostatná knihovna je pak v adresáři libraries…
pekne popsane !!!