Když jsem ve svém okolí mluvil o ARDUINU, dostal se ke mně zajímavý úkol. Sestrojit zařízení, které by každou hodinu změřilo teplotu vody a uložilo ji do paměti. Po několika dnech by se ze zařízení teploty přečetly a ty dále vyhodnocovaly. Měření mělo probíhat napěťově nezávislé a také s poměrem cena výkon. Než hledat nějaké specifické zařízení, které by fungovalo podobně, bylo jednoduší si takový zařízení vyrobit a to právě za použití ARDUINA.
Připojil jsem tedy digitální teplotní obvod DS18B20 a pomocí ARDUINA a jeho vestavěné paměti, jsem teploty začal ukládat. ARDUINO NANO V3, které jsem si koupil, má k dispozici 1 Kb EEPROM paměti. Což je vlastně 1024 B to znamená, že můžete uložit hodnotu od 0 do 255 a to na 1024 pozic. Pro účely tohoto zařízení jsem se rozhodl použít první 2 byty na ukládaní kroku programu a další volnou paměť poté na ukládaní teploty.
Vzhledem k tomu, že hodnota teploty má desetinou čárku, což by byl další znak, teplotu jsem vynásobil deseti. Tím jsem se ale dostal při 30 stupních na hodnotu 300, což bych uložit nemohl vzhledem k paměti, do které jde uložit nejvyšší hodnota 255. Proto jsem hodnotu před uložením ještě vydělil dvěma. Tím docílím možnosti ukládat data od 2 do 51 stupňů, což je při měření teploty vody dostačující.
Další problém, který jsem v tomto případě řešil, byl jak uložené hodnoty dostat poté do počítače. Na to existuje v celku jednoduchá metoda a to že mi si necháme vypsat údaje pomocí virtuálního sérového portu, kterým se Arduino hlásí k počítači při připojeném usb kabelu. Zvlaštností však je, že pokaždé, když inicializujete spojení se s virtuálním sériovým portem Arduino restartuje program a začne úplně od začátku. Nedá se tedy zjisti v jakém je zrovna kroku, jelikož se vlastně vy restartuje. Toho jsem nakonec využil a naprogramoval jsem Arduino, tak aby mi poslal, výstup vždy 10 vteřinu po startu programu.
Pro samotný program jsem použil funkci pro čtení z čidla a dvě vlastní funkce, které ukládají a poté čtou údaje. Také jsem si zde pohrál s počítáním času a to tak že mám proměnné vteřin , minut , hodin ,dni a pomocí programu jim přidávám hodnoty. Celý zdrojový kód vypadá takto.
#include <EEPROM.h>
#include <OneWire.h>
int DS18S20_Pin = 2; //DS18S20 Signal pin on digital 2
unsigned long time;
// int spanek = 1000 * 6;
//Temperature chip i/o
OneWire ds(DS18S20_Pin); // on digital pin 2
int vterin =0;
int minut =0;
int hodin =0;
int dni = 0;
int pocitcyk ;
int pocitadlo ;
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
float temperature = getTemp();
int teplota = temperature * 10; // odstranime desetinou carku 23,5 = 235
int teplota2 = teplota /2; // vydelime 2 pro omezeni 255 tedy max 25,5
int final= teplota2*2;
vterin ++; // přičtem další vteřinu
if (vterin == 60){ // pokud je vteřin 60
vterin = 0; // vynulujem vteřiny
minut ++; // přičtem minutu
}
if (minut == 60){ // pokud je minut 60
minut = 0; // vynulujem minuty
hodin ++; // přičtem hodinu
uloz_teplotu(teplota2); // uložime teploty do paměti
}
if (hodin == 24){ // pokud je hodin 24
hodin = 0; // vynulujem hodiny
dni ++; // prictem den
}
if (minut ==0 and vterin == 2){
// po zapnutí programu a každou hodinu
vypis(); // vypis programu při připojení vyrtualního seriového portu a restartu programu
}
// wait a second so as not to send massive amounts of data
delay(1000);
}
float uloz_teplotu(int teplota2)
{
// EEPROM.write(1,0);
/* Zjistim jak je na tom pocitadlo ciklu a podle toho zjistim
adresu pro ulozeni nove hodnoty */
pocitcyk = EEPROM.read(0);
if (pocitcyk==255){
EEPROM.write(0,0);
pocitcyk=0;
if (EEPROM.read(1)==3){
// 4x = 1020 to je max !
EEPROM.write(1,0);
// počítadlo vynulujeme a začneme přepisovat starší data
}else{
// protože v eprom je spousta mista uložíme nové počítadlo.
EEPROM.write(1,EEPROM.read(1)+1);
}
}else{
pocitcyk ++;
EEPROM.write(0,pocitcyk);
}
pocitadlo = pocitcyk + (EEPROM.read(1)*255);
pocitadlo = pocitadlo + 2; // přeskočíme první 2 byty ty mam pro uložení počítadel
EEPROM.write(pocitadlo,teplota2);
//prints time since program started
}
float vypis(){
Serial.println(" *********************** ");
Serial.println(" * Ijacek.007 * ");
Serial.println(" * 24.6.2012 * ");
Serial.println(" * blog.ijacek007.cz * ");
Serial.println(" *********************** ");
Serial.print(" pocitadlo ");
Serial.print(EEPROM.read(0));
Serial.print(" cteni z eprom ");
Serial.print(EEPROM.read(1));
Serial.print(" skutecny pocet ");
Serial.print( EEPROM.read(0) + (EEPROM.read(1)*255) );
Serial.println(" ");
for (int i = 2; i < 1022; i++) {
int datai = EEPROM.read(i);
if (datai != 255){
Serial.print(" pozice ");
Serial.print(i-2);
Serial.print(" teplota ");
Serial.print(datai *2 );
Serial.println(" stupnu ");
}
}
}
float getTemp(){
//returns the temperature from one DS18S20 in DEG Celsius
byte data[12];
byte addr[8];
if ( !ds.search(addr)) {
//no more sensors on chain, reset search
ds.reset_search();
return -1000;
}
if ( OneWire::crc8( addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return -1000;
}
if ( addr[0] != 0x10 && addr[0] != 0x28) {
Serial.print("Device is not recognized");
return -1000;
}
ds.reset();
ds.select(addr);
ds.write(0x44,1); // start conversion, with parasite power on at the end
byte present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for (int i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
}
ds.reset_search();
byte MSB = data[1];
byte LSB = data[0];
float tempRead = ((MSB << 8) | LSB); //using two's compliment
float TemperatureSum = tempRead / 16;
return TemperatureSum;
}
Po naprogramování ARDUINA jsem hledal obal do kterého bych mohl modul schovat. Připojit baterie a dokončit tak výrobek aby mohl plnit svou funkci. Jako napájení jsem zvolil 5 AA baterii zapojených do série které tvoří 7,5 V zdroj. Pro možnost potopit čidlo pod vodu jsem jej zatavil pomocí tavného lepidla.
Jako obal jsem zvolil nefunkční bezdrátový domovní zvonek. Ten měl však šachtici pouze na 3 AA baterie a tak jsem další 2 připájel dovnitř do „přístroje“.
Při zavřeném krytu vypadá celé zařízení vcelku profesionálně. Díky průhlednému plastu jde zároveň vidět i dioda ARDUINA power.
Vzhledem k veliké vlhkosti přímo nad vodní hladinou jsem raději celou elektroniku umístil ještě do sáčku abych vlhkost co nejvíce omezil. Pomocí elektrikářských stahovacích pásek už pak stačilo zařízení upevnit aby zůstalo na svém místě.
Za týden se na místo instalace vrátím abych stáhl první naměřené hodnoty. Životnost paměti EEPROM ARDUINO uvádí na 100.000 zápisů / přepisu. Pokud by tento teploměr fungoval celý rok jen s výměnou baterii a jednou za měsíc by se odečetly data a vynulovala paměti mohl by spolehlivě ukládat data teploměr zhruba 10 let.
Odkazy
Pokud Vás zajíma možnost měření teploty na pc pod windows či linux nemusíte to řešit Arduinem. Stačí totiž jen obvod DS18S20 a připojit jej k seriovému portu. Zde je velice pěkná stránka s návodem jak to celé zprovoznit. DS18B20 jako teploměr k pc
Vložit komentář
* - vyžadované údaje. RSS kanál s komentáři