Projekt: Snímač teploty DS18B20
Zo stránky SensorWiki
Zadanie
- Zobrazte teplotu z dvoch snímačov teploty pripojených na zbernicu 1-Wire.
- Vypracovali
- Bc. Ján Baláž
- Bc. Jozef Kupčiha
- Študijný odbor: Aplikovaná mechatronika
- Ročník: 2. Ing.
Vypracovanie
1-Wire Zbernica
Ako už z názvu vyplýva ide o jednovodičové sériove rozhranie s možnosťou polo duplexnej obojsmernej komunikácie. Zbernica sa skladá v podstate z dvoch vodičov a to dátového a zemiaceho. Dátový vodič slúži zároveň na napájanie zariadeni pripojených na tuto zbernicu.
Oblasti použitia napr:
- identifikačné systémy
- senzory (teploty, vlhkosti a podobne )
- digitálne potenciometre a iné
Vlastnosti:
- dĺžka vodiča až 100m
- na jednu linku je možné pripojiť do 150 zariadení s unikátnym sériovým číslom zabezpečenie pomocou 8-bitového CRC kódu
- obojsmerná poloduplexná prevádzka
- identifikácia zariadenia na základe 8-bajtového sériového čísla a 1- bajtovej informácie o type zariadenia
- realizácia prepojenia je pomocou krútenej dvoj linky – twisted pair
Zapojenie:
Zariadenia sú trvalo pripojené na napájacie napätie „PullUp“ rezistor obr.1
Komunikacia
Komunikácia je inicializovaná mikropočítačom zmenou úrovne napätia na zbernici na 0 V. Komunikácia je založená na takzvaných „časových slotoch“, čiže od závislosti doby trvania poklesu úrovne napätia je slave zariadením identifikovaný typ operácie (zápis log.1 alebo log.0, čítanie log.1 alebo log.0, reset a identifikácia zariadenia).
Inicializácia
- - Na začiatku uPC (master) ztiahne zbernicu k zemi (cez pull up rezistor) na minimálne 480us, potom ju uvoľní.
- - Na uvoľnenie zbernice a vrátenie do kľudového stavu je potrebných 60us. Po tejto dobe je možné prečítať stav zbernice.
- - Ak je na zbernici pripojené nejaké zariadenie, odpovedá ztiahnutím zbernice na dobu 60 až 240 us. Ak sa na zbernici nenacháda žiadne zariadenie, zbernica ostáva po celú dobu v kľudovom stave.
- - Celková dĺžka trvania inicializačného procesu je minimálne 2x480us, teda až po dobe 960us môže prísť ďalší signál od mástra.
Vysielanie
- Log 1
- - stiahnutie zbernice po dobu mnimálne 1us.
- - uvoľnenie zbernice.
- - dĺžka slotu pre zápis je v rozsahu 60 až 120us.
- Log 0
- - stiahnutie zbernice po dobu mnimálne 60us.
- - uvoľnenie zbernice.
- - dĺžka slotu pre zápis je v rozsahu 60 až 120us.
Čítanie
- - čítanie je inicializované mástrom. Ten najprv stiahne zbernicu po dobu minimálne 1us, následne ju uvoľní.
- - následuje čítanie zbernice mástrom. To je inicializované po minimálne 15us od začiatku slotu (ten je určený počiatkom stiahnutia zbernice mastrom).
- - ak slave chce vyslať log 1, ponechá zbernicu uvoľnenú až do konca slotu (master prečíta log 1 - uvoľnená zbernica).
- - ak slave chce vyslať log 0, ztiahne zbernicu (master prečíta log 0 - ztiahnutá zbernica).
- - celková dĺžka slotu čítania je 60 až 120us.
V našom prípade sme pracovali so snímačmi teploty s označením DS18B20. Preto sú na obrázkoch vyššie použité pre lepšie pochopenie komunikácie na zbernici informácie z datasheetu snímača DS18B20
Priebeh komunikacie na zbernici 1Wire
Každé zariadenie obsahuje výrobcom nastavenú 64-bitovú informáciu v internej ROM pamäti. Prvých horných 8 bitov slúži na zabezpečenie CRC kódom, potom nasleduje 48-bitové sériové číslo zariadenia a dolných 8 bitov tvorí kód identifikujúci typ zariadenia. Táto 64-bitová informácia je unikátna pre každé vyrobené zariadenie s možnosťou tak jednoznačnej identifikácie aj viacerých zariadení rovnakého typu pripojených na jednu linku.
Komunikácia má tri stupne:
- Inicializácia
Vykonáva sa pri resete PRESENCE pulsom od slave zariadenia
- ROM príkaz
V prípade, že je na jednej zbernici viac zariadení tak použíjme tieto príkazy pre prácu s jednotlivými zariadeniam. Príkazy: a) Search ROM [F0h] - Vyhladavanie adries zariadení pripojených na zbernicu b) Read ROM [33h] – tento príkaz môže byť použitý iba pri jednom zariadení na zbernici – umožňuje prečítať 64 bitový ROM kód c) Match ROM [55h] – tento príkaz spolu so 64 bit ROM kódom umožňuje vybrať to zariadenie s ktorým chceme pracovať. Odpovedá iba SLAVE, ktorého ROM kód sa zhoduje s odoslaným ROM kódom d) Skip ROM [CCh] – bez adresácie – komunikuje sa s zariadením bez adresácie – iba jedno zariadenie na zbernici e) Alarm search [ECh] – podobný príkazu Search ROM s tým že odpovedá iba SLAVE s nastaveným alarm bitom
- Funkčný príkaz
Tieto príkazy umožňujú čítať, zapisovať do pamäte, merať teplotu a zisťovať (stav) napájanie. Napr: a) CONVERT [44h] – zmeria sa teplota a zapíše do pamäte. b) READ SCRATCHPAD [BEh] - Čítanie pamäte (data o teplote). Čítajú sa postupne bajty od LSB. c) A iné
Senzor teploty DS18B20
Popis
- napájanie je 3,0V – 5,5V
- rozsah meranej teploty od –55°C do +125°C (-67°F do +257°F)
- presnosť 0,5°C v rozmedzí –10°C do +85°C
- rozlíšenie senzora je voliteľné v rozsahu 9 až 12 bit
- meranie teploty s rozlíšením 12 bit trvá 750ms
Všetky informácie su uvedené v DataSheete obvodu Ktorý si môžte stiahnuť tu
Vyhotovenie senzora
Senzor sa vyrába v troch púzdrach: TO-92, SO-8 a uSOP-8.
Pamäť senzora
Pamäť senzora – nazvaná SCRATCHPAD obsahuje 8 bajtov.
Bajt 0 a 1 obsahujú 16 bitové číslo s údajom o teplote. Ďalšie Bajty sú vysvetlené v obrázku nižšie
Bajt číslo 4
Nastavenia konfiguračných bitov v Bajte čislo 4
Obsah Bajtu 0 a 1
Vysvetlenie obsahu bajtu 0 a 1
Príklady získania teploty
Zapojenie a Program
Funkcia zariadenia
Zariadenie ma za úlohu odmerať teplotu na viacerých snímačoch (v tomto prípade dvoch). Následne tieto hodnoty zobraziť na displeji.
Snímače sú pripojené k zberici 1-wire. Identifikácia jednotlivých snímačov je základe ich jedinečného sériového čísla.
Snímače využívajú v zapojení tri vodiče. Dátový vodič, vodič pre napájanie
snímača a spoločný neutrálny vodič.
Schéma celého zapojenia v simulaćnom programe ISIS Proteus
Program
Program je písaný v jazyku C, v AVR Studio 4, určenom pre prácu so zariadeniami firmy Atmel.
Použitý je 8-bitový mikrokontrolér s označením ATmega16.
Pre komunikáciu so snímačmi teploty je použitý pin 0 portu A.
Pre komunikáciu s LCD displejom sú využívané piny 0 až 5 portu C.
Využívané piny
Port A
pin 0: 1-wire komunikacia
Port C
pin 0: treti datovy bit
pin 1: druhy datovy bit
pin 2: prvy datovy bit
pin 3: nulty datovy bit
pin 4: enable pin
pin 5: RS pin
(poznámka: čísla pinov nekorešpondujú s číslami vývodov mikrokontroléra, tie sú uvedené v datasheete)
Štruktúra programu
Program je pre lepšiu prehľadnosť napísaný vo viacerých súboroch.
Skladá sa z týchto časti:
- main.c ktorý obsahuje hlavný program
- lcd.c ktorý obsahuje funkcie pre obsluhu a komunkáciu s LCD displejom
- 1wire.c ktorý obsahuje funkcie potrebné pre správnu komunikáciu na zbernici
(z pohľadu mástra)
- hlavičkové subory k 1wire zbernici a LCD displeju (1wire.h a lcd.h)
V následujúcej časti nižšie sú popísané vybrané (najdôležitejšie) časti programu.
1wire.c
Inicializácia na zbernici
Principiálne znázornenie možného riešenia na vývojovom diagrame
(pzn. nekorešponduje úplne s kódom nižšie)
Funkcia pre 1-wire reset:
/*-----------------------------------------------------------------------------
* Generovanie 1-wire reseru. Vráti 0 ak bol zaznamenaý presence impulz, ináč vráti 1
*/
uint8_t
OWTouchReset(void) {
_delay_us(1);
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(480); // oneskorenie pre resetovaci impulz
THERM_INPUT_MODE(); // nastavenie 1wire pinu ako vstup - uvoľnenie zbernice
_delay_us(70);
return(THERM_PIN & _BV(THERM_DQ) ? 1 : 0); //podmienene vyhodnotenie
}
Čítanie bajtu a bitu
Principiálne znázornenie možného riešenia na vývojovom diagrame
(pzn. nekorešponduje úplne s kódom nižšie)
Funkcia pre čítanie bajtu:
/*-----------------------------------------------------------------------------
* Čítanie bajtu z 1-wire zbernice
*/
uint8_t
OWReadByte(void) {
int i, result = 0; // result - prijatý bajt
for (i = 0; i < 8; i++) { //cyklus pre načítavanie po bitoch
result >>= 1; // rotácia doprava lebo načítava sa od LSB (poslený bit sa zapise na HSB)
/*testovanie vráteného bitu z funkcie pre čítanie bitu na zbernici*/
if (OWReadBit()) // volanie funkcie na čítanie bitu zo zbernice (či vráti log 1)
result |= 0x80; // použitie masky (1000 0000) - zapis log 1
}
return(result); // vráti prečítaný bajt
}
Funkcia pre čítanie bitu:
/*-----------------------------------------------------------------------------
* Čítanie jedného bitu na 1-wire zbernici a jeho vrátenie
*/
uint8_t
OWReadBit(void) {
OWdelay();
// začiatok slotu čítania bitu
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(6); // oneskorenie pre uvoľnenie zbernice
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup
_delay_us(9); // oneskorenie pre čítanie zo zbernice
return(THERM_PIN & _BV(THERM_DQ) ? 1 : 0); // vráti stav na zbernici (log 0 alebo 1)
/*ak zbernica ostala stiahnutá (drží slave) stav log 0, ináč log 1*/
}
Vysielanie bajtu a bitu
Principiálne znázornenie možného riešenia na vývojovom diagrame
(pzn. nekorešponduje úplne s kódom nižšie)
Funkcia pre zápis bajtu:
/*-----------------------------------------------------------------------------
* Zápis bajtu na 1-wire zbernicu
*/
void
OWWriteByte(uint8_t data) { // data - obsahuje vysielaný bajt
uint8_t i;
/* vyslanie bitu s najnižšou váhou (LSB)*/
for (i = 0; i < 8; i++) { // cyklus pre rotáciu posielaného bitu na najnižsiu úroveň
OWWriteBit(data & 0x01); // maska pre určenie či sa posiela log 0 alebo 1
data >>= 1; // rotácia (vysielaného bajtu) o jeden bit doprava
}
}
Funkcia pre zápis bitu:
/*-----------------------------------------------------------------------------
* Zápis jedneho bitu na 1-wire zbernicu
*/
void
OWWriteBit(uint8_t bit) {
OWdelay();
if (bit) { // testovanie, aký bit sa posiela (0 alebo 1)
// ak sa posiela log 1
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(6); // oneskorenie pre log 1
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup
_delay_us(64);
} else {
// ak sa posiela log 0
THERM_LOW(); // ztiahnutie zbernice
THERM_OUTPUT_MODE(); // nastavenie 1wire pinu ako výstup
_delay_us(60); // oneskorenie pre log 0
THERM_INPUT_MODE(); // uvoľnenie zbernice - nastavenie 1wire pinu ako vstup
_delay_us(10);
}
}
main.c
Hlavný program. Načítava adresy snímačov na zbernici, Meria telotu a vypisuje na displej.
Funkcie potrebné k obsluhe displeja sú v súbre lcd.c. Je možné ho stiahnuť nižšie spolu s ostatnými súbormi v jednom archíve.
#define F_CPU 8000000L
#include <util/delay.h>
#include <avr/io.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd.h"
#include "1wire.h"
uint8_t ROM1[2][8],pocet_cidel=0;
int8_t cidla;
int16_t teplota1,teplota2;
char text[16];
char cele[16];
char desatine[16];
int p=0;
int main(void)
{
lcd_init(LCD_DISP_ON); // inicializácia dipleja
_delay_ms(100);
/* hľadanie snímačov na zbernici*/
cidla = OWFirst(ROM1[0],1,0); // hľadanie prvneho snimaca
if(cidla) // ak bol najdeny
pocet_cidel++; // počet snímačov + 1
cidla = OWNext(ROM1[pocet_cidel],1,0); // hľanie ďalších snímačov
if(cidla) // ak bol najdeny
pocet_cidel++; // počet snímačov + 1
do
{
cidla = OWNext(ROM1[pocet_cidel],1,0); // hľanie ďalších snímačov
if(cidla) // ak bol najdeny
pocet_cidel++; // počet snímačov + 1
}while(cidla); // dokiaľ boli nájdené dalšie snímače
_delay_ms(10);
while(1)
{
/* Vypis na disp Senzor 1 a senzor 2 */
lcd_clrscr(); // zmazanie displeja
lcd_gotoxy(0,0); // pozícia kurzora
lcd_puts("Senzor:1");
lcd_gotoxy(0,1); // pozícia kurzora
lcd_puts("Senzor:2");
_delay_ms(2000);
for (p = 0; p < 10; p++) // Cyklus pre načítanie a zobrazenie (10krat)
{
teplota1=DS18B20_read_temp(ROM1[0]); // načítanie teploty1 zo senzora 0
_delay_ms(100);
teplota2=DS18B20_read_temp(ROM1[1]); // načítanie teploty2 zo senzora 1
_delay_ms(100);
//----Vypis zo Senzora 1----
itoa(teplota1/10,cele,10); // Prevedie Cele cisla na znaky
itoa(teplota1%10,desatine,10); // Prevedie Desatine cisla na znaky
lcd_clrscr();
lcd_gotoxy(0,0);
lcd_puts(cele); // vypis na disp v tvare XX.X°C
lcd_puts(".");
lcd_puts(desatine);
lcd_putc(0b10110010);
lcd_puts("C");
//----Vypis zo Senzora 2----
itoa(teplota2/10,cele,10); // Prevedie Cele cisla na znaky
itoa(teplota2%10,desatine,10); // Prevedie Desatine cisla na znaky
lcd_gotoxy(0,1); // vypis na disp v tvare XX.X°C
lcd_puts(cele);
lcd_puts(".");
lcd_puts(desatine);
lcd_putc(0b10110010);
lcd_puts("C");
_delay_ms(500);
}
}
}
Súbory na stiahnutie
main.c
lcd.c
1wire.c
lcd.h
1wire.h
Realizácia
Najprv sme overovali spravnosť zapojenia a funkčnosť programu cez simulačný software ISIS Proteus 7. V tomto simulačnom prostredí sme využili možnosti pozorovania zbernice pomocou osciloskopu čo nám veľmi uľahčilo hľadanie chyby pri pri nesprávnej (nefunkčnej) komunikácii. Výsledkom simulácie je zobrazenie teplôt z dvoch senzorov DS18B20, ako je vidieť na obrázku nižšie.
Po úspešnom doladení programu za pomoci simulácie sme zrealizovali aj skutočné zapojenie, kde používame:
- Procesor ATmega16
- Dva teplotné snímače DS18B20
- Displej 16x1 znakov