Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
Mitja Mastnak
MIKROKRMILNIŠKO MERJENJE TEMPERATURE IN PRENOS MERILNIH PODATKOV S PROTOKOLOM SNMP
Diplomsko delo
Maribor, september 2010
I
Diplomsko delo visokošolskega strokovnega študijskega programa
MIKROKRMILNIŠKO MERJENJE TEMPERATURE IN PRENOS MERILNIH
PODATKOV S PROTOKOLOM SNMP
Študent: Mitja Mastnak
Študijski program: VS ŠP Elektrotehnika
Smer: Elektronika
Mentor: doc. dr. Boštjan Vlaovič
Lektor(ica): Mateja Čuk
Maribor, september 2010
II
III
ZAHVALA
Na prvem mestu se zahvaljujem mentorju doc. dr.
Boštjanu Vlaoviču, ki me je z veseljem sprejel pod
svoje mentorstvo, mi s svojim širokim teoretičnim
znanjem ter z dolgoletnimi praktičnimi izkušnjami
pomagal ter vodil skozi celotno opravljanje
diplomskega dela.
Hvala tudi tehniškemu sodelavcu Andreju Romihu,
ki je bil, tekom nastanka diplomske naloge, vselej
pripravljen pomagati pri tehničnih stvareh.
Posebna zahvala velja staršem, ki so mi v vseh teh
letih študija stali ob strani ter me finančno in
moralno podpirali.
Nenazadnje se zahvaljujem tudi Maši Filipič, svoji
punci, za njeno podporo, potrpežljivost in za vsa
odrekanja v času nastanka diplomske naloge.
IV
MIKROKRMILNIŠKO MERJENJE TEMPERATURE IN PRENOS
MERILNIH PODATKOV S PROTOKOLOM SNMP
Ključne besede: protokol SNMP, mikrokrmilnik, PIC18F67J60, Ethernet, temperaturni
senzor DS18S20, temperaturni senzor DS18B20, protokol 1-wire,
merjenje temperature, EEPROM, MRTG, NMS
UDK: 621.398:681.584.63(043.2)
Povzetek
Diplomsko delo opisuje zasnovo in realizacijo prototipnega sistema za merjenje
temperature in njegovo povezavo v omrežje Ethernet. Jedro sistema je Microchipov
mikrokrmilnik PIC 18F67J60, na katerem teče aplikacija za merjenje temperature s
senzorji DS18x20 ter aplikacija za prenos podatkov na osebni računalnik z uporabo
protokola SNMP. Glavni namen enote je merjenje temperature, avtomatsko zaznavanje
priključenih senzorjev ter prenos izmerjenih podatkov s pomočjo protokola SNMP na
osebni računalnik, na katerem se podatki shranjujejo in prikazujejo v grafični obliki.
Cilj diplomske naloge je bil realizirati čim bolj univerzalen in cenovno ugoden sistem za
merjenje temperature ter enostavno nadziranje in shranjevanje izmerjenih podatkov s
pomočjo osebnega računalnika.
V
MICROCONTROLLER-BASED TEMPERATURE MEASUREMENT
WITH SNMP PROTOCOL SUPPORT
Key words: SNMP potocol, microcontroller, PIC18F67J60, Ethernet, temperature sensor
DS18S20, temperature sensor DS18B20, 1-wire protocol, temperature
measurement, EEPROM, MRTG, NMS
UDK: 621.398:681.584.63(043.2)
Abstract
This diploma work describes the design and realization of prototype system for measuring
temperature and its connection to Ethernet network. The core of system is Microchip’s PIC
18F67J60 microcontroller on which runs application for measuring temperature with
DS18x20 sensors and application for data transfer to the PC using the Ethernet protocol.
The main purpose of the unit is temperature measurement, automatic detection of
connected sensors and transfer the measured data using SNMP to PC where data are
stored and displayed in graphical form.
The aim of the diploma work was to realize the most universal an affordable system for
temperature measuring and simple supervising and storing of measured data through
personal computer.
VI
Kazalo
1 UVOD ............................................................................................................................................................ 1
1.1 PREGLED OBSTOJEČIH REŠITEV ................................................................................................................ 3
2 ZASNOVA IZVEDBE SISTEMA ............................................................................................................... 6
2.1 PROTOKOL SNMP.................................................................................................................................... 6
3 IZVEDBA .................................................................................................................................................... 12
3.1 SPECIFIKACIJA ZAHTEV .......................................................................................................................... 12
3.2 IZBIRA KOMPONENT ............................................................................................................................... 12
3.2.1 Primerjava in izbira mikrokrmilnika............................................................................................. 12
3.2.2 Izbira temperaturnih senzorjev...................................................................................................... 13
3.2.3 Izbira vmesnikov............................................................................................................................ 14
3.3 MIKROKRMILNIK PIC 18F67J60 ...................................................................................................... 16
3.3.1 Opis družine 18FxxJxx .................................................................................................................. 16
3.3.2 Vgrajeni vmesnik Ethernet ............................................................................................................ 17
3.4 1-WIRE ................................................................................................................................................. 23
3.4.1 Opis delovanja............................................................................................................................... 23
3.4.2 Algoritem protokola ...................................................................................................................... 24
3.5 ETHERNET .......................................................................................................................................... 28
3.5.1 Zgodovina...................................................................................................................................... 28
3.5.2 Topologija LAN-omrežja ............................................................................................................... 29
3.5.3 Prenos in zgradba podatkov.......................................................................................................... 29
3.6 PROGRAMSKA REŠITEV SISTEMA (SW-IZVEDBA) ................................................................................... 31
3.6.1 Opis delovanja merilne enote........................................................................................................ 33
3.6.2 MRTG (Multi Router Traffic Grapher) ......................................................................................... 33
3.6.3 Razdelitev zunanjega EEPROM-pomnilnika................................................................................. 34
3.6.4 Inicializacija programa................................................................................................................. 34
3.6.5 Izdelava menija ............................................................................................................................. 36
3.6.6 Iskanje senzorjev na vodilu ........................................................................................................... 36
3.6.7 Meritev temperature ...................................................................................................................... 40
3.6.8 Pošiljanje podatkov na PC ............................................................................................................ 42
3.6.9 Zajemanje podatkov na PC ........................................................................................................... 45
3.7 IZVEDBA STROJNEGA DELA .................................................................................................................... 47
4 SKLEP ......................................................................................................................................................... 56
4.1 MOŽNOSTI UPORABE .............................................................................................................................. 56
VII
4.2 IDEJE ZA NADGRADNJO .......................................................................................................................... 57
5 LITERATURA............................................................................................................................................ 58
6 PRILOGE.................................................................................................................................................... 60
VIII
Slike
Slika 1.1: Blok shema zasnovanega sistema..........................................................................2
Slika 2.1: Blok shema izvedenega sistema ............................................................................7
Slika 2.2: Model SNMP.........................................................................................................8
Slika 2.3: Primer informacijske baze ...................................................................................11
Slika 3.1: Blok shema vmesnika za Ethernet (PIC18F67J60 datasheet) .............................18
Slika 3.2: Povezava mikrokrmilnika PIC in RJ-45 Ethernet priključka ..............................19
Slika 3.3: Notranja povezava SFR-registrov in Ethernet vmesnika ....................................20
Slika 3.4: Organizacija Ethernet pomnilnika .......................................................................21
Slika 3.5: Delovanje Ethernet pomnilnika ...........................................................................22
Slika 3.6: Pošiljanje logične 0 in logične 1..........................................................................24
Slika 3.7: Unikatna 64-bitna koda senzorja (ID-naslov) .....................................................24
Slika 3.8: Diagram ROM-ukazov (DS18B20 datasheet).....................................................26
Slika 3.9: Diagram ukazov za senzor (DS18B20 datasheet) ...............................................27
Slika 3.10: Zgradba Ethernet paketa....................................................................................30
Slika 3.11: Poenostavljen model OSI ..................................................................................31
Slika 3.12: Razvojno okolje mikroC PRO for PIC..............................................................32
Slika 3.13: Primer prikazovanja podatkov v grafikonu .......................................................34
Slika 3.14: Razdelitev naslovnih lokacij zunanjega EEPROM-pomnilnika 24C64............35
Slika 3.15: Inicializacija programa ......................................................................................35
Slika 3.16: Deklaracija zunanjih in prototipnih funkcij.......................................................36
Slika 3.17: Deklaracija tabel ................................................................................................36
Slika 3.18: Funkcija Primerjaj_ROM ..................................................................................37
Slika 3.19: Nastavitev resolucije senzorjev DS18B20 ........................................................38
Slika 3.20: Funkcija Vnesi_ime...........................................................................................39
Slika 3.21: Krožni sistem pomikanja po tabeli ....................................................................39
Slika 3.22: Del funkcije Vnos_imena, ki shrani ime senzorja v pomnilnik ........................40
Slika 3.23: Meritev in pretvorba temperature ......................................................................41
Slika 3.24: Sprejemanje zahtev............................................................................................43
Slika 3.25: Odgovor na SNMP-zahtevo ..............................................................................44
Slika 3.26: Primer tvorjene spletne strani ............................................................................46
IX
Slika 3.27: Konfiguracijska datoteka enega senzorja ..........................................................47
Slika 3.28: Shema napajalnika.............................................................................................48
Slika 3.29: Tiskano vezje napajalnika .................................................................................48
Slika 3.30: Razpored elementov na tiskanem vezju ............................................................49
Slika 3.31: Shema reset vezja ..............................................................................................49
Slika 3.32: Tiskano vezje reset vezja...................................................................................49
Slika 3.33: Razpored elementov (reset vezje)......................................................................49
Slika 3.34: LV18FJ MCU Card ...........................................................................................50
Slika 3.35: Shema ICSP-vezja .............................................................................................51
Slika 3.36: Shema LCD-zaslona..........................................................................................51
Slika 3.37: Vezava RJ45 vtičnice ........................................................................................52
Slika 3.38: Shema tipkovnice ..............................................................................................52
Slika 3.39: Tiskano vezje tipkovnice...................................................................................53
Slika 3.40: Razpored elementov (tipkovnica)......................................................................53
Slika 3.41: Shema vezja za Ethernet komunikacijo.............................................................54
Slika 3.42: Tiskano vezje vezja za Ethernet komunikacijo .................................................54
Slika 3.43: Razpored elementov (vezje za Ethernet komunikacijo) ....................................54
Slika 3.44: Shema EEPROM-vezja .....................................................................................55
Slika 3.45: Tiskano vezje EEPROM-vezja..........................................................................55
Slika 3.46: Razpored elementov (EEPROM-vezje).............................................................55
Tabele
Tabela 3.1: Značilnosti družine PIC 18FxxJxx ...................................................................15
X
UPORABLJENE KRATICE
ANSI − Ameriški nacionalni inštitut za standardizacijo (American
National Standards Institute)
CMOS − Komplementaren kovinsko-oksidni polprevodnik
(Complementary Metal-Oxide Semiconductor)
COFF − Skupen format objektnih datotek (Common Object File
Format)
CRC − Ciklično preverjanje redundance (Cyclic Redundancy
Check)
CSMA/CD − Večkraten dostop s poslušanjem prenosnega medija in
z zaznavanjem trkov
DHCP − Protokol za dinamično konfiguracijo gostitelja (Dynamic
Host Configuration Protocol)
EEPROM − Električno zbrisljiv in programirljiv bralni pomnilnik
(Electrically Erasable Programmable Read-Only Memory)
E-MAIL − Elektronska pošta (Electronic MAIL)
EUSART − Izboljšan univerzalni asinhroni sprejemnik/oddajnik
(Enhanced Universal Synchronous Asynchronous
Receiver/Transmitter)
FLASH – Bliskovni pomnilnik (FLASH memory)
GSM − Globalni sistem za mobilne komunikacije (Global System
for Mobile communication)
I2C − Vodilo I2C (Inter-Integrated Circuit)
ICSP − Serijsko programiranje v vezju (In-Circuit Serial
Programming)
IEEE − Inštitut inženirjev elektrotehnike in elektronike (Institute of
Electrical and Electronics Engineers)
IP − Internetni protokol (Internet Protocol)
LCD − Zaslon na tekoče kristale (Liquid Crystal Display)
LED − Svetleča dioda (Light-Emitting Diode)
LSB − Najmanj utežen bit (Least Significant Bit)
XI
MAC − Krmiljenje dostopa do medija (Media Access Control)
MIB − Baza upraviteljskih informacij (Management Information
Base)
MRTG − Večusmerjevalniški risalnik mrežnega prometa (Multi
Router Traffic Grapher)
MSB − Najbolj utežen bit (Most Significant Bit)
NMS – Sistem za nadzor in upravljanje omrežja (Network
Managemen System)
OID – Označevalnik objekta (Object Identifier)
OSI − Medsebojno povezovanje odprtih sistemov (Open Systems
Interconnection model)
PDU – Podatkovna enota protokola (Protocol Data Unit)
PHY Fizični oddajno/sprejemni vmesnik (Physical Layer
Transceiver)
PIC − Programirljivi krmilnik vmesnika (Programmable Interface
Controller)
PLL − Fazno sklenjena zanka (Phase-Locked Loop)
PWM − Pulzno-širinska modulacija (Pulse-Width Modulation)
RAM − Pomnilnik z naključnim dostopom (Random Access
Memory)
SDRAM – Sinhroni dinamični pomnilnik z naključnim dostopom
(Synchronous Dynamic Random Access Memory)
SFR − Registri za poseben namen (Special Function Registers)
SMS − Storitev kratkih sporočil (Short Message Service)
SNMP − Protokol za preprosto upravljanje omrežja
(Simple Network Management Protocol)
SPI − Serijski periferni vmesnik (Serial Pheripherial Interface)
TCP − Protokol za krmiljenje prenosa (Transmission Control
Protocol)
TQFP − Tanko 4-kotno ploščato ohišje (Thin Quad Flat Pack)
UDP − Protokol za uporabniške podatke (User Datagram Protocol)
UTP − Neoklopljen vpredeni par (Unshielded Twisted Pair)
1
1 UVOD
Ker je danes veliko merilnih sistemov avtomatiziranih, njihov nadzor in upravljanje pa
velikokrat poteka preko oddaljene nadzorne naprave, s katero uporabnik spremlja stanje
naprave, se nam je porajala ideja za izdelavo nekakšnega univerzalnega merilnega sistema,
ki bo sposoben meriti različne veličine: temperaturo, vlažnost, pritisk itd., hkrati pa bo
čimbolj neodvisen od okolja delovanja (fleksibilen), podatke pa bo mogoče nadzirati ter
upravljati na daljavo.
Našo idejo smo razdelili na sistem, ki bi bil sestavljen iz treh enot. Prva enota bi se
uporabljala za merjenje fizikalnih veličin. Sestavljena bi bila iz merilnega modula,
merilnih senzorjev in zaslona LCD (Liquid Crystal Display – zaslon na tekoče kristale),
tipkovnice in pomnilniške kartice (slika 1.1). Zadnje tri komponente bi se lahko priključile
le po potrebi, saj bi enota delovala tudi brez njih, torej povsem samostojno (na sliki 1.1
označeno v črtkanem barvnem okvirju). Merilni modul bi podpiral tudi več protokolov,
preko katerih bi potekala komunikacija med merilnim modulom in senzorji (1-wire, I2C –
Inter-Integrated Circuit/protokol za serijsko komunikacijo …). Pomnilniška kartica bi se
uporabljala za shranjevanje izmerjenih podatkov, LCD-zaslon pa za prikaz le-teh. S
pomočjo tipkovnice bi za priključene senzorje lahko vnesli imena, v nasprotnem primeru
pa bi imena enota določila samodejno (npr. senzor1, senzor2, senzor3 itd.) ali pa bi jih
določili preko SNMP (Simple Network Management Protocol – protokol za preprosto
upravljanje omrežja) s strani nadzornega ali glavnega modula. Izmerjene vrednosti bi se
shranjevale na pomnilniško kartico, do njih pa bi lahko dostopali tudi preko Etherneta z
uporabo protokola SNMP. Druga enota bi podatke zbirala, jih preverjala in po potrebi
uporabnika obveščala o stanju merilnega modula preko SMS-sporočil (Short Message
Service – storitev kratkih sporočil) in e-pošte. Na sliki 1.1 so opcijski deli sistema označeni
s črtkanim barvnim okvirjem. Drugo enoto bi sestavljali GSM-modul (Global System for
Mobile communication – globalni sistem za mobilne komunikacije) za oddajanje podatkov
oziroma pošiljanje SMS-sporočil preko GSM-omrežja, brezžični modul (antena) za
pošiljanje elektronskih sporočil in nadzorni modul, ki bi skrbel za pravilno delovanje
sistema in upravljal ter nadzoroval prvo enoto (slika 1.1). Na eni strani bi nadzorni modul
komuniciral z merilnim modulom, na drugi pa s tretjo enoto oziroma z glavnim modulom
(PC – Personal Computer/osebni računalnik – strežnik). Tudi ta
2
MERILNI MODUL
SENZOR 1
SENZOR 2
SENZOR 3
SENZOR N
1-W
IRE
I2C,...
POMNILNIŠKA
KARTICA
NADZORNI MODUL
ETHERNET
GLAVNI MODUL
(PC-STREŽNIK)
SMTP
SMS
GSM
LCD ZASLON
TIPKOVNICA
SNMP
SNMP
SNMP
S
lika
1.1
: B
lok
shem
a za
snov
aneg
a si
stem
a
3
komunikacija bi uporabljala protokol SNMP. Nadzorni modul bi uporabili pri neodvisni
različici merilnega sistema, v primeru povezave v informacijski sistem podjetja pa bi
njegovo vlogo v celoti ali delno prevzel glavni modul. Možnosti konfiguracije sistema bi
bile naslednje:
• Uporaba merilnega modula kot samostojno enoto.
• Uporaba merilnega in nadzornega modula, če ni informacijskega sistema.
• Uporaba merilnega in glavnega modula, če je informacijski sistem.
• Uporaba kombinacije druge in tretje možnosti, če informacijski sistem ne
podpira SMS-ov.
Naloga glavnega modula bi bila zajem podatkov in informacij, ki bi jih sprejela iz druge
enote, jih obdelala ter prikazala na spletnem strežniku v grafični obliki. S tretjo enoto bi
bilo možno nadzirati in upravljati celoten sistem, saj bi lahko upravljali in nadzirali drugo
enoto, slednja pa bi na podlagi prejetih zahtev upravljala prvo.
Diplomska naloga v uvodu predstavi zasnovano rešitev merilnega sistema in obstoječe
rešitve, ki so dobavljive na trgu in njihove značilnosti. V nadaljevanju je na kratko opisan
protokol SNMP, v tretjem poglavju pa natančneje opisujemo izvedbo merilnega sistema.
Tu podamo razloge za izbiro komponent ter vmesnikov in določimo specifikacije zahtev
merilnega sistema, ki so osnova za izvedbo sistema. Izvedba na kratko opiše tudi
uporabljen mikrokrmilnik ter njegove značilnosti, protokola 1-wire in Ethernet ter vgrajeni
vmesnik Ethernet. Sledi programska rešitev sistema, v kateri predstavimo potek aplikacije
in njeno delovanje ter programsko izvedbo izdelanega merilnega sistema s poudarkom na
lastnih programskih rešitvah. Na koncu drugega dela sledi izvedba strojnega dela
izdelanega sistema, kjer predstavimo posamezne sklope merilnega sistema.
V zaključnem delu diplomske naloge povzamemo opravljeno delo in možnosti uporabe
merilnega sistema ter podamo predloge za izboljšave in morebitne nadgradnje.
1.1 Pregled obstoječih rešitev
Kljub temu, da je na tržišču mnogo tovrstnih produktov, se pri implementaciji konkretnih
rešitev nemalokrat pojavijo težave. Tovrstne naprave ali niso dovolj prilagodljive ali pa so
4
izjemno drage. Že čisto osnovni sistemi za merjenje temperature lahko dosežejo zelo
visoke cene, če pa ima še kakšno dodatno možnost, kot je komunikacija s PC preko
Etherneta, pa si marsikdo tega ne more privoščiti, sploh, če je potreba po večji količini
tovrstnih modulov. Sledi kratek pregled nekaterih obstoječih rešitev in njihovih lastnosti.
• MessPC Ethernet box [1]:
o možnost priključitve štirih senzorjev temperature ali vlage ali do 12
senzorjev z dodatnim panelom,
o lasten IP-naslov (Internet Protocol – internetni protokol),
o nastavitev prikazovanja izmerjenih rezultatov preko spletnega
brskalnika,
o zajem podatkov preko SNMP s programom MRTG (Multi Router
Traffic Grapher – večusmerjevalniški risalnik mrežnega prometa),
o možnost posodabljanja programske kode s strani uporabnika,
o pošiljanje SNMP-pasti z binarnimi vhodnimi signali,
o obveščanje o preseženih vrednostih preko e-pošte, SNMP-pasti in
SMS-sporočil,
o možnost uporabe senzorjev temperature, vlažnosti ali kombinacije
obeh, senzorjev dima ter senzorjev gibanja,
o cena: 225 evrov in
o cena dodatnega panela: 175 evrov.
• SensorProbe8 [2]:
o možnost priklopa do 8 senzorjev temperature ali vlažnosti ter vseh
inteligentnih senzorjev iz ACKP-družine,
o implementiran spletni strežnik, TCP/IP-sklad (Transmission Control
Protocol/Internet Protocol – protokol za krmiljenje
prenosa/internetni protokol), polni SNMP, SMS in E-MAIL,
o nastavitev alarmiranja o dogodkih preko spletnega vmesnika,
o obveščanje o dogodkih preko e-pošte (dva elektronska naslova),
SMS-sporočil ali SNMP-pasti,
o podpira vse glavne komunikacijske protokole,
5
o prikazovanje podatkov v obliki grafa,
o območje delovanja temperaturnih senzorjev od –35 °C do +55 °C,
senzorjev vlažnosti pa od 20 % do 80 %,
o omogoča zajemanje podatkov z uporabo protokola SNMP,
o nastavitev analognih vhodov za vseh 8 vrat (0–5 VDC),
o vsebuje SNMP MIB-strukturo (Management Information Base –
baza upraviteljskih informacij) in
o cena: 645 dolarjev.
• HWg-STE: Ethernet thermometer [3]:
o vgrajen spletni strežnik za nastavitev naprave,
o obveščanje o previsokih ali prenizkih vrednostih preko e-pošte,
o izdelan grafični vmesnik za prikazovanje temperature (za Windows
okolje),
o možnost izvažanja podatkov v programsko orodje Microsoft Excel,
o kompatibilen s protokolom SNMP,
o podpira omrežni protokol DHCP (Dynamic Host Configuration
Protocol – protokol za dinamično konfiguracijo gostitelja),
o vodoodporen,
o območje merjenja temperature od –10 °C do +80 °C,
o resolucija merjenja 0,1 °C in
o možnost priklopa dveh senzorjev.
6
2 Zasnova izvedbe sistema
Zaradi obsežnosti projekta smo se odločili, da se v okviru diplomske naloge posvetimo
samo prvi in tretji enoti, drugo enoto pa pustimo za morebitne nadgradnje sistema. Poleg
tega smo se pri prvi enoti omejili le na merjenje temperature.
Naš izdelani merilni sistem je torej sestavljen iz dveh enot. Prvo enoto sestavljajo
temperaturni senzorji, merilni modul, LCD-zaslon in tipkovnica (slika 2.1). Naloga te
enote je samo merjenje temperature. Za komunikacijo med temperaturnimi senzorji in
merilnim modulom je uporabljen 1-wire protokol. Tipkovnico potrebujemo za vnašanje
imen senzorjev ter za navigacijo po meniju, kateri se prikazuje na LCD-zaslonu. Merilni
modul je nato povezan preko Etherneta z uporabo protokola SNMP z drugo enoto, ki smo
jo poimenovali nadzorni modul oziroma PC-strežnik. Glavna naloga te enote je zajemanje
podatkov, ki jih pridobiva iz merilnega modula in prikazovanje le-teh na spletu v grafični
obliki, kjer se vodi statistika izmerjenih podatkov.
2.1 Protokol SNMP
Protokol SNMP se uporablja za nadzor in upravljanje naprav, povezanih v računalniško
omrežje. Njegova naloga je zbiranje in organiziranje informacij o mrežnih napravah, kar
skrbniku mrežnega sistema omogoča lažje spremljanje delovanja sistema, lažje odkrivanje
in reševanje napak itd. V tipičnem sistemu je večje število nadzorovanih naprav.
Programska oprema, imenovana agent, teče na teh sistemih in sporoča podatke preko
protokola SNMP nadzorovanim napravam. Agenti SNMP pošiljajo nadzorne podatke
nadzornim napravam v obliki spremenljivk (npr. spomin, temperatura procesorja,
sistemsko ime …). Nadzorni sistem lahko zahteva informacije z uporabo ukazov GET,
GETNEXT ali GETBULK protokola SNMP, lahko pa agent sam pošlje podatke (brez
zahteve nadzornega sistema) z uporabo ukazov TRAP ali INFORM protokola SNMP.
Nadzorni sistemi lahko tudi upravljajo nadzorovane naprave oziroma izvajajo spremembe
omrežne infrastrukture z ukazom SET. Spremenljivke v okviru protokola SNMP so
organizirane hierarhično oziroma v drevesno strukturo (slika 2.3). Organiziranost
spremenljivk skupaj z meta podatki (npr. tip in opis) opisuje informacijska baza za
upravljanje podatkov (MIB). To je baza, ki opisuje strukturo nadzorovanih informacij.
7
MERILNI MODUL
SENZOR 1
SENZOR 2
SENZOR 3
SENZOR N
1-W
IRE
NADZORNI MODUL
(PC-STREŽNIK)
ETHERNET
LCD ZASLO
NTIPKOVNICA
SNMP
SNMP
S
lika
2.1
: B
lok
shem
a iz
ved
eneg
a si
stem
a
8
Nadzorovane naprave uporabljajo hierarhične imenske prostore (namespace), ki vsebujejo
označevalnike objekta (OID – Object Identifier/označevalnik objekta). Vsak OID določa
spremenljivko, katero lahko beremo ali nastavljamo preko protokola SNMP. Označevalnik
objekta unikatno definira nadzorovan objekt v hierarhiji MIB (slika 2.3). Baze MIB
uporabljajo zapis imenovan ASN.1 (Abstract Syntax Notation one – abstraktna sintaksa
zapisa ena).
Omrežje nadzorovano s protokolom SNMP je sestavljeno iz treh ključnih komponent (slika
2.2):
• nadzorovane naprave,
• agenta in
• NMS (Network Management System – sistem za nadzor in upravljanje
omrežja).
SNMP
Agent
Upraviteljska baza
Agent
Upraviteljska baza
Agent
Upraviteljska baza
Agent
Upraviteljska baza
NMS
Nadzorovane naprave
Sistem za nadzor
in upravljanje
Slika 2.2: Model SNMP
9
Nadzorovana naprava je dejansko omrežna naprava, ki vsebuje agenta SNMP in se nahaja
v nadzorovanem omrežju. Nadzorne naprave zbirajo in hranijo nadzorovane informacije in
jih delijo s sistemom NMS. Nadzorovana naprava je lahko vsaka naprava, ki podpira
protokol SNMP (npr. tiskalniki, usmerjevalniki, telefoni IP, računalniki …). NMS je
aplikacija, ki omogoča komunikacijo med skrbnikom omrežja in nadzorovano napravo.
Sistemi NMS zagotovijo potreben procesorski čas in pomnilniški prostor za nadzor
omrežja. V vsakem nadzorovanem omrežju je lahko eden ali več sistemov NMS.
Agent je aplikacija oziroma programski modul, ki se nahaja v nadzorovani napravi in ima
dostop do shranjenih informacij, ki si jih izmenjuje z NMS.
Nadzorovane naprave se nadzirajo in upravljajo s pomočjo štirih osnovnih SNMP-ukazov:
• read – ukaz, ki ga uporablja NMS za nadziranje naprav,
• write – ukaz, ki ga uporablja NMS za upravljanje naprav,
• trap – ukaz, ki ga uporabljajo nadzorovane naprave za obveščanje NMS o
posebnih dogodkih in
• transverzalni operatorji – ukazi, ki jih uporablja NMS za odkrivanje
podprtih spremenljivk in zbiranje informacij.
Poznamo tri glavne različice protokola SNMP:
• SNMPv1
Šibka lastnost te različice je varnost. Avtentikacija NMS je izvedena v
obliki "community string – skupnost", kot geslo, ki ni prikrito.
• SNMPv2
Zaradi raznoraznih nestrinjanj z varnostjo se ta različica ne uporablja
množično. Ta različica prinaša določene izboljšave in popravke na
področju performans, medtem ko različica SNMPv2c prinaša izboljšave
tudi pri varnosti in komunikaciji.
• SNMPv3
Protokol SNMP se je reorganiziral s tretjo različico, ki je leta 2004 postala
tudi standardna verzija za protokol SNMP. Ta verzija ima zelo izboljšano
varnost komunikacije (zagotavlja, da nihče ne more prestreči paketa na poti
ter šifriranje paketov), hkrati pa tudi boljšo možnost oddaljenega
konfiguriranja.
10
V praksi večina agentov podpira več različic protokola SNMP. Naša aplikacija podpira
samo prvo različico, torej SNMPv1.
Protokol SNMP deluje v aplikacijski plasti modela OSI (Open Systems Interconnection
model – medsebojno povezovanje odprtih sistemov). V različici SNMPv1 NMS in agent
komunicirata preko pet podatkovnih enot protokola (PDU – Protocol Data
Unit/podatkovna enota protokola):
• GET zahteva – se uporablja za pridobitev dela nadzorovanih informacij,
• GETNEXT zahteva – se uporablja iterativno za zaporedno pridobivanje
nadzorovanih informacij,
• GET odgovor – uporabi agent kot odgovor na GET ali SET zahtevo,
• SET zahteva – za inicializacijo in spreminjanje vrednosti,
• TRAP – se uporabi za sporočanje alarmov ali drugih asinhronih dogodkov
na nadzorovanih napravah. V različici SNMPv1 so asinhroni dogodki
imenovani "trap – past", v vseh poznejših različicah pa "inform –
obvestilo".
Verziji SNMPv2 sta bili dodani naslednji enoti PDU:
• GETBULK zahteva – hitrejša metoda za pridobitev več nadzorovanih
podatkov in
• INFORM – podobna operaciji TRAP, vendar zahteva odgovor.
Agent pošilja podatke iz MIB-a, ki vsebuje podatke o lokalni konfiguraciji. Podatki v
MIB-u so shranjeni v drevesni strukturi (slika 2.3), pri čemer ima vsak podatek svoj naslov
določen z OID. Vsaka spremenljivka predstavlja neko lastnost nadzorovane naprave.
Obstajata dva tipa nadzorovanih objektov v bazi MIB:
• skalarni objekti, ki definirajo eno instanco objekta in
• tabelarni objekti, ki definirajo več sorodnih instanc objekta združenih v
tabelo MIB.
Primer skalarnega objekta je atInput, ki vsebuje eno instanco objekta (celoštevilsko
vrednost), kot primer tabelarnega objekta pa lahko navedemo AppleTalk (slika 2.3). Ko
11
NMS, ki želi izvedeti status naprave; t. j. vrednost nekaterih spremenljivk; pošlje agentu
zahtevo GET z ustreznim OID, ki opisuje zahtevano informacijo. Agent prejme zahtevo,
prebere OID, ga poišče v bazi MIB in kot odgovor pošlje NMS-ju vrednost zahtevane
spremenljivke. V kolikor se OID v bazi MIB ne najde, agent pošlje odgovor v obliki
napake.
ccitt (0) iso (1) iso-ccitt (2)
standard (0) registration-authority (1)
member-body (2)
identified-organization (3)
dod (6)
internet (1)
directory (1) mgmt (2) experimental (3) private (4) security (5) snmp v2 (6)
mib-2 (1) mib-2 (1)
cisco (9)
temporaryvariables (3)
DECnet (1) XNS (2) Apple Talk (3) Novell (4) VINES (5) Chassis (6)
atInput (1)
atLocal (2)
atBcastin (3)
atForward (4)
Slika 2.3: Primer informacijske baze
12
3 IZVEDBA
3.1 Specifikacija zahtev
Merilni sistem naj zadosti naslednjim zahtevam:
• sprotno prikazovanje izmerjenih podatkov v obliki grafa,
• določanje imen senzorjev preko tipkovnice,
• omogoča dodajanje temperaturnih senzorjev, brez da bi bilo potrebno
popravljati programsko kodo,
• možnost pošiljanja podatkov preko Etherneta,
• naprava naj bo čim bolj fleksibilna, v smislu prenosljivosti naprave (da se
bo naprava lahko uporabljala v raznovrstnih pogojih) in
• naprava naj bo čim cenejša in čim manjša, z minimalnim številom dodatnih
elementov.
3.2 Izbira komponent
3.2.1 Primerjava in izbira mikrokrmilnika
ZAHTEVE MIKROKRMILNIKA:
• velikost (čip naj bo čim manjši),
• vgrajeni Ethernet vmesnik,
• čim manj dodatnih (zunanjih) elementov za delovanje našega sistema in
• čim nižja cena.
Zaradi preteklih izkušenj in predznanja smo se odločili za mikrokrmilnik proizvajalca
Microchip. Proizvajalec ponuja široko paleto PIC-mikrokrmilnikov (Programmable
Interface Controller – programirljivi krmilnik vmesnika), s katerimi se je mogoče povezati
z Ethernetom. Ena izmed možnosti je uporaba PIC-a in dodatnega Ethernet vmesnika. Ker
je eden izmed naših ciljev nižja cena, smo to možnost izključili. Mikrokrmilnike smo
omejili na tiste, ki imajo Ethernet vmesnik vgrajen že v sam čip (tabela 3.1). S tem se je
seznam PIC-ev zmanjšal na devet kandidatov iz družine 18F97J60. Z velikostjo ni bilo
13
težav, saj so vsi mikrokrmilniki iz te družine v malem ohišju tipa TQFP (Thin Quad Flat
Pack – tanka štirikotna ploščata ohišja). Seznam smo dodatno skrčili glede na število V/I
priključkov. Med temi devetimi PIC-i na seznamu so PIC-i s 70, 55 in 39 V/I priključki.
Omejili smo se na PIC-e z 39 V/I priključki, kar za izvedbo našega sistema povsem
zadostuje. S tem smo skrčili seznam na tri mikrokrmilnike. Med temi tremi PIC-i smo
primerjali ceno in dobavljivost. Z dobavljivostjo ni veliko težav, saj je mogoče PIC-e
naročiti v tujini. Tudi rok dobave je razmeroma kratek, poštnina pa največkrat ne preseže
cene 5-ih evrov. V Sloveniji teh PIC-ev sicer ni na trgu, zato smo se odločili za nakup pri
angleškem podjetju Farnell. Na podlagi dobavljivosti smo tako izbrali PIC-mikrokrmilnike
serije 18F, in sicer PIC 18F67J60, njegova cena pa znaša 5,36 evrov1.
Izbrani mikrokrmilnik ima 64 priključkov, vsebuje 128k zlogov programskega pomnilnika
FLASH (FLASH memory – bliskovni pomnilnik), 3808 zlogov podatkovnega pomnilnika
SDRAM (Synchronous Dynamic Random Access Memory – sinhroni dinamični pomnilnik
z naključnim dostopom), 8192 zlogov oddajno sprejemnega Ethernet medpomnilnika, 10-
bitni A/D (Analog/Digital – analogno/digitalni) pretvornik, dva MSSP-modula (Master
Synchronous Serial Port – glavna sinhrona serijska vrata) s podporo za SPI (Serial
Pheripherial Interface – serijski periferni vmesnik) in I2C komunikacijo, en modul
EUSART (Enhanced Universal Synchronous Asynchronous Receiver/Transmitter –
izboljšan univerzalni asinhroni sprejemnik/oddajnik), dva 8-/16-bitna časovnika in dva
primerjalnika (tabela 3.1).
3.2.2 Izbira temperaturnih senzorjev
Na trgu obstaja veliko temperaturnih senzorjev, ki pa se med seboj zelo razlikujejo.
Nekateri so analogni, drugi digitalni. Če bi se odločili za analogne, bi morali za njih
uporabiti A/D pretvornik, saj mikrokrmilnik operira samo z digitalnimi informacijami. To
pa bi s seboj prineslo omejitev dodajanja senzorjev, ker ima mikrokrmilnik samo enajst
analognih vhodov. Torej bi nanj lahko priključili največ enajst senzorjev. To bi se sicer
dalo rešiti tako, da bi uporabili posebej čip za A/D pretvornik, čemur pa smo se izognili,
saj je bil naš interes sestaviti sistem s čim manj dodatnimi elementi. Prav tako so njihove
1 Cena velja za čas nastanka diplomske naloge.
14
razdalje zelo omejene. Torej izbira analognih senzorjev za naš sistem ni najboljša rešitev.
Smotrno je izbrati digitalnega, ki ne potrebuje A/D pretvornika, saj se podatek digitalizira
že v samem senzorju. Med digitalnimi so trenutno zelo popularni temperaturni senzorji
DS18x20, proizvajalca Dallas Semiconductor. Ti senzorji ne dosežejo visokih cen,
dobavljivi so v skoraj vsaki trgovini z elektroniko, so majhni, za svoje delovanje ne
potrebujejo veliko dodatnih elementov, so zelo natančni, najpomembneje pa je to, da se
lahko priključujejo vzporedno na eno vodilo in za naše potrebe delujejo na zelo velikih
razdaljah. Na podlagi tega smo se odločili za senzorje DS18x20.
3.2.3 Izbira vmesnikov
Izbrani senzorji uporabljajo vodilo 1-wire. Ta protokol je zelo preprost, komunikacija pa
poteka samo preko ene žice, od tod tudi njegovo ime.
Za povezavo merilne enote v omrežje smo izbrali Ethernet, ki spada v prvi najnižji sloj
poenostavljenega modeli OSI, kot je prikazano v razdelku 3.5.3 na sliki 3.11. To je tudi
ena izmed naših glavnih zahtev sistema. Model je sestavljen iz štirih slojev, zato je
potrebno določiti protokol za vsak sloj posebej. Za prvi sloj smo torej izbrali Ethernet
protokol. Naslednji sloj je internetni sloj. Tukaj imamo na razpolago več možnosti (IP,
ICMP, ARP, IGMP, IGMP-AC …); izbira pa je odvisna od tega, kako je sistem zasnovan.
Mi smo se poslužili protokola IP, ki je odgovoren za naslavljanje in usmerjanje podatkov
med napravo in računalnikom. Na transportnem sloju sta najbolj razširjena protokola TCP
in UDP (User Datagram Protocol – protokol za uporabniške podatke). Glede na naše
potrebe smo izbrali protokol UDP, saj je hitrost prenosa večja, ker tukaj ni potrebe po
povezavi med odjemalcem in strežnikom, tako kot pri protokolu TCP, ampak strežnik
vseskozi pošilja podatke, ne glede na to ali jih je odjemalec prejel ali ne. V našem sistemu
se podatki pošiljajo tako pogosto, da tudi, če se vmes kakšen podatek izgubi, le-to ne
vpliva na delovanje sistema. Za nadzor podatkov in krmiljenje merilne enote v aplikacijski
plasti pa smo izbrali protokol SNMP, saj je to standardiziran protokol za nadzor nad
omrežnimi napravami.
15
Tab
ela
3.1:
Zn
ačil
nos
ti d
ruži
ne
PIC
18F
xxJx
x MS
SP
Čip
i dru
žin
e
18F
xxJ6
0
FL
AS
H
pro
gram
ski
pom
nil
nik
(zlo
gi)
SD
RA
M
pod
atko
vni
pom
nil
nik
(zlo
gi)
Eth
ern
et
RX
/TX
bu
ffer
(zlo
gi)
V/I
10
bit
A/D
(št
.
kan
alov
)
CCP/ECCP
S
PI
I2 C
EUSART
Število primerjalnikov
Čas
ovn
iki
8/16
-bit
P
SP
Zunanje pomnilniško
vodilo
PIC
18F
66J6
0 64
K
3808
81
92
39
11
2/3
1 D
a D
a 1
2 2/
3 N
e N
e
PIC
18F
66J6
5 96
K
3808
81
92
39
11
2/3
1 D
a D
a 1
2 2/
3 N
e N
e
PIC
18F
67J6
0 12
8K
3808
81
92
39
11
2/3
1 D
a D
a 1
2 2/
3 N
e N
e
PIC
18F
86J6
0 64
K
3808
81
92
55
15
2/3
1 D
a D
a 2
2 2/
3 N
e N
e
PIC
18F
86J6
6 96
K
3808
81
92
55
15
2/3
1 D
a D
a 2
2 2/
3 N
e N
e
PIC
18F
87J6
0 12
8K
3808
81
92
55
15
2/3
1 D
a D
a 2
2 2/
3 N
e N
e
PIC
18F
96J6
0 64
K
3808
81
92
70
16
2/3
2 D
a D
a 2
2 2/
3 D
a D
a
PIC
18F
96J6
5 96
K
3808
81
92
70
16
2/3
2 D
a D
a 2
2 2/
3 D
a D
a
PIC
18F
97J6
0 12
8K
3808
81
92
70
16
2/3
2 D
a D
a 2
2 2/
3 D
a D
a
16
Povzetek izbranih protokolov:
• temperaturni senzorji: 1-Wire
• omrežje:
o aplikacijska plast: SNMP
o transportna plast: UDP
o internetna plast: IP
o povezovalna plast, omrežje: Ethernet
3.3 MIKROKRMILNIK PIC 18F67J60
3.3.1 Opis družine 18FxxJxx
Značilnost mikrokrmilnikov PIC, družine 18F97J60, je vgrajen Ethernet vmesnik. Vsi
krmilniki iz te družine imajo popolno podporo protokola IEEE (Institute of Electrical and
Electronics Engineers – inštitut inženirjev elektrotehnike in elektronike) 802.3 10Base-T.
V tej družini je devet mikrokrmilnikov, ki se med seboj razlikujejo v količini pomnilnika
EEPROM (Electrically Erasable Programmable Read-Only Memory – električno zbrisljiv
in programirljiv bralni pomnilnik), pomnilnika FLASH, pomnilnika RAM (Random
Access Memory – pomnilnik z naključnim dostopom) in število V/I priključkov.
Nekaj karakteristik mikrokrmilnika:
• fleksibilna struktura oscilatorja:
o nastavljiva frekvenca z enim 25 MHz zunanjim izvorom (od 2,778
do 41,667 MHz),
o interni 31 kHz oscilator,
o sekundarni oscilator (32 kHz) z uporabo časovnika 1 (Timer1),
o varnostni urin modul omogoča varno ustavitev mikrokrmilnika, če
se ura ustavi in
o dve hitrosti delovanja oscilatorja.
• periferija:
o zmožnost izvora/ponora toka do 25 mA na vratih B in C,
o pet časovnikov,
o štirje zunanji priključki za prekinitve,
17
o dva navadna in trije izboljšani primerjalniki,
o eden, dva ali štirje PWM-moduli (Pulse-Width Modulation –
pulzno-širinska modulacija),
o do dva EUSART-modula,
o 10-bitni A/D pretvornik,
o paralelna "slave" vrata in
o do dva sinhrona serijska modula s podporo SPI in I2C.
• posebne lastnosti:
o 5,5-voltni tolerantni vhodi (samo za digitalne pine),
o nizka poraba, zelo hitra CMOS-tehnologija (Complementary Metal-
Oxide Semiconductor – komplementaren kovinsko-oksidni
polprevodnik),
o energijsko upravljanje (zagon, brezdelje in način mirovanja),
o možnost nastavitve prioritet prekinitev,
o razširjen pazikuža (Watchdog) časovnik (do 134 s),
o 3,3-voltno napajanje za programiranje v vezju (ICSP – In-Circuit
Serial Programming/serijsko programiranje v vezju) in
o napetostno območje delovanja od 2,35 V do 3,6 V (od 3,1 V do 3,6
V za Ethernet modul).
• ohišja:
Vsi mikrokrmilniki iz družine 18F97J60 TQFP-ohišju.
3.3.2 Vgrajeni vmesnik Ethernet
V tem poglavju je na kratko opisan vmesnik Ethernet, več informacij pa je na voljo v
navodilih za PIC-mikrokrmilnike iz družine 18F97J60 [7].
Opis vmesnika za Ethernet
Mikrokrmilnik PIC 18F67J60 vsebuje integriran vmesnik za Ethernet (slika 3.1), ki
vsebuje polno implementirana vmesnika MAC (Media Access Control – krmiljenje
dostopa do medija) in PHY (Physical Layer Transceiver – fizični oddajno/sprejemni
18
vmesnik). Za delovanje je potrebno dodati samo dva transformatorja in nekaj pasivnih
elektronskih komponent. Ethernet vmesnik je v skladu s standardom IEEE 802.3 in podpira
vse specifikacije standarda 10Base-T za priključitev na omrežje preko kabla UTP
(Unshielded Twisted Pair – noklopljen vpredeni par). Ethernet vmesnik je sestavljen iz
naslednjih komponent:
• sprejemno/oddajni vmesnik PHY, ki kodira in dekodira analogne podatke,
• MAC-modula za implementacijo IEEE 802.3 logike in vmesnika,
• 8 kB pomnilnika RAM za sprejemanje in oddajanje paketov,
• logike za kontroliranje dostopa do pomnilnika RAM in
• vmesnika do kontrolnih registrov za nadzorovanje Ethernet vmesnika.
8-kB Ethernet
RAM
pomnilnika
Arbiter
kanal 2
kanal 1
kanal 3
Naslovi
ethernet
pomnilnika
Ethernet
podatki
kanal 1
Kazalci
ethernet
pomnilnika
Mikrokrmilniški SFR registri
EDATA Nadzor
etherneta
MIRD/MIWR
MIREGADR
Podatki PHY registra
Naslovi PHY registra
Krmiljenje LED A/LED B
Mikrokrmilniško podatkovno vodilo
RBIAS
TPIN+
TPIN-
TPOUT+
TPOUT-
MAC
PHY
RX
RXBM
RXF (Filter)
DMA in
IP vsota
TX
TXBM
Nadzor pretoka MIIM
vmesnik
TX
RXMII
vmesnik
Gost. vmesnik
kanal 2
Slika 3.1: Blok shema vmesnika za Ethernet (PIC18F67J60 datasheet)
19
Povezava mikrokrmilnika v omrežje
Za delo z Ethernetom ima mikrokrmilnik namenjene štiri V/I priključke:
• TPIN +: pozitivni vhod sprejemnika,
• TPIN –: negativni vhod sprejemnika,
• TPOUT +: pozitivni izhod oddajnika in
• TPOUT –: negativni izhod oddajnika.
Ethernet vmesnik ima ločeno napajanje za fizični oddajnik in sprejemnik ter oddajnikov
notranji PLL (Phase-Locked Loop – fazno sklenjena zanka). Na voljo sta tudi dva izhoda
za LED-diodi (Light-Emitting Diode – svetleča dioda), ki sta lahko nastavljeni na več
načinov. Označujeta lahko status naprave, status sprejemanja oziroma oddajanja itd.
Vmesnik je optimiziran za urino frekvenco 25 MHz. To lahko zagotovimo s povezavo
oscilatorja na priključka OSC1 in OSC2. Dodatno potrebujemo nekaj zunanjih komponent:
upore, kondenzatorje in ločilna transformatorja (slika 3.2).
Slika 3.2: Povezava mikrokrmilnika PIC in RJ-45 Ethernet priključka
20
Dostop do Ethernet vmesnika
Za svoje delovanje uporablja Ethernet vmesnik tri pomnilniške prostore:
• pomnilnik RAM, namenjen oddajanju in sprejemanju podatkov,
• 8-bitne SFR-registre (Special Function Registers – registri za poseben
namen), ki so namenjeni kontroli modula in prenosom podatkov med
Ethernet pomnilnikom in glavnim pomnilnikom in
• posebne 16-bitne registre za nadzor modula PHY.
Ethernet pomnilnik in PHY nadzorni registri se nahajajo znotraj Ethernet vmesnika (slika
3.3), do njih pa ima uporabnik izključen dostop. Prenos podatkov se izvrši z uporabo
Ethernet pomnilnika in njegovih kazalcev, ki se nahajajo v prostoru za posebne registre in
so namenjeni za izračunavanje naslovov pomnilnika (slika 3.3).
Prikazana je povezava SFR-registrov in Ethernet modula.
Mikrokrmilniški SFR registri
Naslov pomnilnika
Ethernet vmesnik
Ethernet pomnilnik
Podatki PHY registera (V/I)
Naslov PHY registra
Ethernet podatki
PHY registri
EDATA
ERDPT(H:L)EWRPT (H:L)ETXST (H:L)ETXND (H:L)ERXST (H:L)ERXND (H:L)
ERXRDPT (H:L)ERXWRPT (H:L)
MIRD (H:L)MIWR (H:L)
MIREGADR
0000h
1FFFh
00h
1Fh
Slika 3.3: Notranja povezava SFR-registrov in Ethernet vmesnika
21
Namenski pomnilnik
Eden najpomembnejših delov Ethernet vmesnika je namenski pomnilnik (slika 3.4), ki je
razdeljen na sprejemni in oddajni del. Njuno velikost določi uporabnik s pomočjo posebnih
registrov.
Do pomnilnika lahko nato dostopamo preko registra EEDATA (Ethernet data – Ethernet
podatki) in s pomočjo posebnih Ethernet registrov:
• ETXSTH, ETXSTL – vsebujeta začetni naslov oddajnega pomnilnika,
• EWRPTH, EWRPTL – predstavljata kazalec na lokacijo pisanja v
oddajnem delu pomnilnika,
• ETXNDH, ETXNDL – vsebujeta končni naslov oddajnega pomnilnika,
• ERXSTH, ERXSTL – vsebujeta začetni naslov sprejemnega pomnilnika,
• ERDPTH, ERDPTL – predstavljata kazalec na lokacijo branja v
sprejemnem delu pomnilnika in
• ERXNDH, ERXNDL – vsebujeta končni naslov sprejemnega pomnilnika.
0000h
Zapisovanje podatkov v medpomnilnik
(Podatek AAh se zapi EDATA)še v
Oddajni
medpomnilnik
Sprejemni
medpomnilnik
(Kro FIFO)žni
55h
1FFFhKonec sprejemnega medpomnilnika
(ERXNDH : ERXNDL)
Kazalec na bralni medpomnilnik
(ERDPTH : ERDPTL)
Začetek sprejemnega medpomnilnika
(ERXSTH : ERXSTL)
Konec oddajnega medpomnilnika
(ETXNDH : ETXNDL)
Začetek oddajnega medpomnilnika
(ETXSTH : ETXSTL)
AAhKazalec na pisalni medpomnilnik
(EWRPTH : EWRPTL)
Branje podatkov iz medpomnilnika
(Podatek 55h se prebere iz EDATA)
Slika 3.4: Organizacija Ethernet pomnilnika
22
Sprejemni del pomnilnika je narejen po sistemu FIFO (First In First Out – prvi noter, prvi
ven), katerega nadzira strojna oprema. S tem je omogočeno hitro zapisovanje podatkov,
pridobljenih preko Etherneta. Sprejeti podatek je shranjen v Ethernet pomnilniku, dokler
ga z aplikacijo ne preberemo. Ko se podatek prebere, se pomnilniški prostor, na katerem je
bil shranjen podatek, smatra kot prost. Podatki se v pomnilnik zapisujejo eden za drugim,
dokler pomnilnik ne pride do konca (kazalec kaže na ERXND), nato pa se v kazalec
pisanja avtomatsko naloži začetni naslov pomnilnika in podatki se zopet pričnejo
zapisovati od začetnega naslova dalje. Na sliki 3.5 je prikazano delovanje Ethernet
pomnilnika.
ERXRDPT
ERDPT:
Prebrani podati
iz aplikacije
PB
ERXST ERXND
Paket 1
Paket 2
Paket 3
Paket 4
(zadnji prejeti
paket)
Smer branja in zapisovanja podatkov
(naslovi se pove )čujejo od spodaj navzgor
ERXWRPT:
Prikazuje konec
zadnjega prejetega
paketa
PB PB
Neuporabljen
medpomnilnik
(lahko vsebuje
stare podatke)
PB: Meja paketa je določena z
naslednjim paketom oz. kazalcem,
ki rezervira prostor pred vsakim
prejetim paketom.
Notranji pisalni kazalec
kaže na zadnjo lokacijo
pakata v medpomnilniku
Slika 3.5: Delovanje Ethernet pomnilnika
23
3.4 1-WIRE
1-wire protokol je razvilo podjetje Dallas Semiconductor za komunikacijo z nekaterimi
svojimi komponentami (A/D pretvorniki, pomnilniki, temperaturnimi senzorji, digitalnimi
potenciometri, identifikacijskimi čipi itd.). Omrežje sestavljajo gospodar, običajno je to
mikrokrmilnik in ena ali več perifernih komponent (sužnji). Povezani so na skupno vodilo,
po katerem se prenašajo vsi potrebni kontrolni signali in podatki. Posamezne komponente
se lahko napajajo neposredno iz vodila (parasite power – parazitno napajanje) ali pa imajo
lastno 5-voltno napajanje.
3.4.1 Opis delovanja
1-wire je proces komunikacije med dvema neenakovrednima enotama, in sicer
gospodarjem ter sužnjem. Tovrstno komunikacijo imenujemo dvosmerna komunikacija.
Oddajnik vedno odda najprej najmanj utežen bit (LSB – Least Significant Bit) in nato še
vse ostale bite po vrstnem redu do najbolj uteženega bita (MSB – Most Significant Bit).
Gospodar sinhronizira celoten prenos podatkov med postajami tako, da daje signal na urino
linijo, katero vse postaje uporabljajo za časovno usklajevanje operacij oddajanja in
sprejemanja v omrežju. Različne izvedbe omogočajo različne urine in bitne hitrosti (16,
100 in 200 kHz).V primeru, da želimo senzorju poslati logično 1, mora gospodar svoje
vodilo postaviti na nizek nivo, in sicer za največ 15 µs, za logično 0 pa za najmanj 60 µs
(slika 3.6). Nato gospodar vodilo sprosti, dvižni upor pa poskrbi, da se vodilo dvigne na
visok logični nivo. Senzor vzorči 1-wire vodilo po tem, ko gospodar prične z zapisovanjem
logične 0 oziroma 1, in sicer od 15 µs do 60 µs. Če je vodilo med vzorčenjem na visokem
logičnem nivoju, je gospodar senzorju poslal logično 1, v nasprotnem primeru pa logično
0. Časovne reže so podrobneje predstavljene v navodilih za 1-wire temperaturne senzorje
[4]. Pred komunikacijo mora gospodar omrežje (povezavo) resetirati tako, da vodilo zadrži
na nizkem nivoju najmanj 480 µs in nato preveri, če je podrejena naprava odgovorila z
impulzom prisotnosti. Z odgovorom naprava potrdi pripravljenost na komunikacijo z
gospodarjem. V nasprotnem primeru je potrebno na ta impulz počakati, saj podrejena
naprava še ni pripravljena na komunikacijo. Kako dolgo preverjamo prisotnost tega
impulza je odvisno od programske izvedbe.
24
ČASOVNA REŽA ZA ZAPIS “1” ČASOVNA REŽA ZA ZAPIS “0”ZAČETEK
REŽE
ZAČETEK
REŽE
1-WIRE
VODILO
Dvi uporžni
Gospodar postavi navzdol DS18B20 postavi navzdolLEGENDA 1-WIRE VODILA
MIN MAXTYP
Vzorčenje vodila Vzorčenje vodilaMAXTYPMIN
60µ µss < Tx “0” < 120> 1µs
1µs < “0” <TREC
15µs 15µs 30µs 15µs 15µs 30µs
VPU
GND
8
Slika 3.6: Pošiljanje logične 0 in logične 1
Ko gospodar zazna impulz prisotnosti, pokliče napravo, s katero želi komunicirati, tako, da
na vodilo pošlje njen edinstven 64-bitni naslov (ID-naslov) (slika 3.7). Od tega trenutka
dalje lahko gospodar komunicira samo z naslovljeno napravo, vse ostale ne kontaktira. Ko
gospodar ponovno resetira omrežje, so vse naprave v stanju pripravljenosti na gospodarjev
klic.
8-BIT CRC 48-BIT SERIJSKA ŠTEVILKA 8-BIT KODA DRUŽINE
MSB LSB MSB LSB MSB LSB
Slika 3.7: Unikatna 64-bitna koda senzorja (ID-naslov)
3.4.2 Algoritem protokola
Sam algoritem je zelo preprost. Delno je opisan že v razdelku 3.4.1. Celoten algoritem oz.
njegov potek je prikazan na diagramih, in sicer na sliki 3.8 in sliki 3.9.
Če transakcijsko sekvenco pogledamo na široko, kot neko zaokroženo celoto, je ta
razdeljena na tri korake, in sicer:
• korak 1: inicializacija,
• korak 2: ROM-ukaz in
25
• korak 3: ukaz za senzor.
Transakcijska sekvenca se prične z inicializacijo (slika 3.8). Inicializacija je sestavljena iz
reset impulza, ki ga gospodar generira tako, da svoj izhod spusti na logično 0 in impulza
prisotnosti, ki ga kot odgovor na reset pošlje podrejena naprava. Impulz prisotnosti nam
pove, da je senzor na vodilu in je pripravljen na komunikacijo. Dolžine teh impulzov so
podane v [4].
Za tem, ko gospodar detektira impulz prisotnosti, lahko pošlje ROM-ukaz (slika 3.8). Teh
ukazov je več, in sicer:
• "Beri ROM" (Read ROM): s tem ukazom sprožimo branje unikatne 64-
bitne kode senzorja. Ta ukaz uporabimo, če imamo na vodilu samo en
senzor.
• "Ujemanje ROM" (Match ROM): ukaz, s katerim naslavljamo senzorje.
• "Poišči ROM" (Search ROM): ta ukaz ima podobno vlogo kot "beri ROM",
le da tega uporabljamo v primeru, ko imamo na vodilu več senzorjev.
• "Poišči alarm" (Alarm Search): slednji ukaz poišče tiste senzorje, pri
katerih se je sprožil alarm pri zadnji pretvorbi temperature.
• "Preskoči ROM" (Skip ROM): ta ukaz se uporablja le v primeru, ko je na
vodilu en senzor in ga ni treba naslavljati.
Vse pa je odvisno od tega, kaj želimo narediti v naslednjem koraku. Podroben opis funkcij
teh ukazov je opisan v navodilih za temperaturni senzor DS18B20 oziroma DS18S20 [4].
V naši aplikaciji je uporabljen samo en ROM-ukaz, in sicer Match ROM. Tovrstnega
ukaza se poslužujemo pri naslavljanju senzorjev, ko želimo senzorjem, ki so priključeni na
vodilo ukazati, s katerim od njih želimo komunicirati.
Ko se izvede ROM-ukaz, je na vrsti ukaz za senzor (slika 3.9). Mi uporabljamo ukaze
"Pretvori temperaturo", "Beri pomnilnik" in "Piši v pomnilnik".
• "Pretvori temperaturo" (Convert temperature): ukaz, ki pove senzorju, naj
začne z meritvijo temperature.
• "Beri pomnilnik" (Read scratchpad): ukaz, ki pove, da želimo brati iz
beležke2.
2 Beležka je pomnilnik SRAM (Static Random Access Memory – statični bralno-pisalni pomnilnik), ki si ga
lahko predstavljamo kot nekakšen seznam oziroma beležko.
26
ZAPOREDJE INICIALIZACIJE
MASTER TX RESET PULSE
DS18x20 TX PRESENCE PULSE
MASTER TX ROM COMMAND
MASTER TX
BIT 0
DS18x20 TX FAMILIY CODE
1 BYTE
DS18x20 TX SERIAL NUMBER
6 BYTES
DS18x20 TX CRC BYTE
MASTER TX
BIT 1
MASTER TX
BIT 63
EChALARM SEARCH
COMMAND
F0hSEARCH ROM COMMAND
55hMATCH ROM COMMAND
33hREAD ROM COMMAND
CCh SKIP ROM COMMAND
BIT 0MATCH?
BIT 0MATCH?
DEVICE(S) WITH ALARM FLAG SET?
BIT 1MATCH?
BIT 63MATCH?
BIT 63MATCH?
BIT 1MATCH?
DS18x20 TX BIT 63
DS18x20 TX /BIT 63
MASTER TX BIT 63
DS18x20 TX BIT 1
DS18x20 TX /BIT 1
MASTER TX BIT 1
DS18x20 TX BIT 0
DS18x20 TX /BIT 0
MASTER TX BIT 0
DS18x20 TX BIT 0
DS18x20 TX /BIT 0
MASTER TX BIT 0
N N N N
Y
MASTER TX FUNCTION COMMAND(DIAGRAM 2)
Y
Y
Y
Y
Y
Y
Y
N N
NN
N N
Y
N
Y
N
Y
Y
Slika 3.8: Diagram ROM-ukazov (DS18B20 datasheet)
27
MASTER TX FUNCTION COMMAND
44hCONVERT
TEMPERATURE?
48hCOPY
SCRATCHPAD?
PARASITE POWER ?
DS18x20 BEGINS CONVERSION
MASTER ENABLES STRONG
PULLUP ON DQ
DEVICE CONVERTING TEMPERATURE
?
MASTER RX »0s«
MASTER RX »1s«
DS 18x20 CONVERTS
TEMPERATURE
MASTER DISABLES STRONG PULLUP
PARASITE POWER ?
MASTER ENABLES STRONG
PULLUP ON DQCOPY IN PROGRESS
?
4EhWRITE
SCRATCHPAD?
BEhREAD
SCRATCHPAD?
MASTER TX TH BYTE TO
SCRATCHPAD
MASTER TX TL BYTE TO
SCRATCHPAD
MASTER TX CONFIG. BYTE
TO SCRATCHPAD
MASTER RX DATA BYTE
FROM SCRATCHPAD
MASTER TX RESET ?
HAVE 8 BYTES BEEN READ ?
MASTER RX SCRATCHPAD CRC BYTE
B8hRECALL E2
?
MASTER BEGINS DATA RECALL FROM E2 PROM
DEVICE BUSY
RECALLING DATA ?
B4hREAD POWER
SUPPLY?
PARASITE POWERED ?
RETURN TO INITIALIZATION SEQUENCE (DIAGRAM 1) FOR NEXT TRANSACTION
MASTER RX »0s«
MASTER RX »1s«
DATA COPIED FROM
SCRATCHPAD TO EEPROM
MASTER DISABLES DTRONG PULLUP
MASTER RX »0s«
MASTER RX »1s«
MASTER RX »0s«
MASTER RX »1s«
Y
N
Y
N Y
Y
N
N Y
Y N
N
NNNN
Y Y Y Y
N Y
N
Y N
Y
N
Y
Slika 3.9: Diagram ukazov za senzor (DS18B20 datasheet)
28
• "Piši v pomnilnik" (Write scratchpad): ukaz, ki pove, da želimo pisati v
beležko.
Preostali ukazi, ki so podrobneje opisani v navodilih senzorja [4], so:
• "Kopiraj pomnilnik" (Copy scratchpad): ukaz kopira vsebino pomnilnika v
EEPROM.
• "Beri napajanje" (Read Power Supply): z ukazom gospodar ugotovi, ali se
kateri od senzorjev napaja neposredno iz vodila (Parasite power – parazitno
napajanje).
• "Povrni pomnilnik" (Recall E2): ta ukaz povrne nastavljene vrednosti, ki so
shranjene v EEPROM-u, iz EEPROM-a v pomnilnik (scratchpad).
Na koncu sledi reset impulz, ki označuje konec komunikacije oziroma začetek nove
sekvence.
3.5 ETHERNET
Ethernet je omrežje, ki ga uvrščamo v skupino omrežij po standardu IEEE 802.3, protokola
sloja podatkovne povezave LAN (Local Area Network – lokalno omrežje), s pomočjo
katerega se prenašajo podatki v obliki paketov. Podatek, ki ga želimo poslati se razdeli na
manjše dele (pakete), ti pa se nato posamezno pošiljajo do ciljne naprave, kjer se zopet
sestavijo v celoto. Za prenos se uporablja protokol CSMA/CD (Carrier Sense Multiple
Access with Collision Detection – večkraten dostop s poslušanjem prenosnega medija in z
zaznavanjem trkov), pri katerem vsaka naprava posluša in začenja pošiljati podatke šele,
ko je vodilo prosto.
Omogoča informacijsko povezavo najrazličnejših naprav na enotnem omrežju in resnično
integracijo proizvodnega in poslovno-informacijskega nivoja industrije.
3.5.1 Zgodovina
Začetki Etherneta segajo v leto 1973, standard pa je bil sprejet leta 1980. Prvotna ideja
Etherneta je bila povezati več računalnikov s pomočjo deljenega koaksialnega kabla, ki se
uporablja za prenašanje informacij.
29
Naslednji velik korak je predstavljala zamenjava prenosnega medija s kablom UTP. Kabel
UTP je zgrajen iz štirih paric (parica sta dve med seboj vpredeni žici). Prvi standard z
novim prenosnim medijem je bil 10Base-T. S tem standardom se je spremenila tudi
topologija omrežja. Pred tem so bile vse naprave na enem kablu, pri čemer je do vsake
vodil svoj kabel UTP. Po štirih paricah se podatki lahko hkrati prenašajo in oddajajo, zato
se tukaj pojavita pojma, polni dvosmerni prenos (full-duplex) in polovični prenos (half-
duplex). Za omenjenim standardom se je pojavil standard 10BaseFX, kar je bil velik korak
za Ethernet razvoj. Ta standard je uvedel za prenosni medij optično vlakno, kar je drastično
zmanjšalo motnje in povečalo doseg. Za tem so se zvišale še hitrosti, 100 Mb/s (100Base-
T, 100BaseFX). Sprememba je prišla z uvedbo gigabitnega Etherneta. Ta Ethernet, za
razliko od prejšnjih standardov (100Base-T in FX), uporablja za prenos podatkov namesto
dveh paric vse štiri. Tako je hitrost narasla tudi na 10 Gb/s in več [5].
3.5.2 Topologija LAN-omrežja
Topologija je zasnovana tako, da se naprave lahko povezujejo v lokalna omrežja. Glede na
način, kako se naprave povezujejo v omrežje, določimo topologijo omrežja. Ločimo med
naslednjimi topologijami:
• topologija vodila,
• topologija zvezde in
• topologija obroča.
3.5.3 Prenos in zgradba podatkov
V omrežjih Ethernet mehanizem naslavljanja uporablja naslov za omrežno kartico, s
katerim se lahko identificira napravo oziroma omrežni vmesnik, ki je v tej napravi. Ta
naslov se imenuje fizični naslov ali MAC-naslov. Vsaka samostojna naprava priklopljena
na Ethernet omrežje ima svoj unikaten MAC-naslov. Ko je MAC-naslov dodeljen določeni
napravi v omrežju, je ta naprava enkratno prepoznavna (oziroma določljiva) med vsemi
drugimi napravami v omrežjih širom po svetu, kar zagotavlja, da bo poslani paket
podatkov prišel do svojega cilja (do naslovnika) znotraj nekega omrežja.
30
Zgradba Ethernet paketa je definirana s standardom IEEE 802.3ac [5]. Vsak paket pa je
sestavljen iz štirih delov (slika 3.10):
• glave MAC, ki vsebuje naslov sprejemnika in pošiljatelja ter Ethernet tip,
• protokola, po katerem se prenašajo podatki,
• podatkov, ki jih želimo poslati in
• CRC-vsote (Cyclic Redundancy Check – ciklično preverjanje redundance),
za preverjanje pravilnosti podatkov in glave.
MAC glava
(14 zlogov)
Ciljni MAC naslov 80 00 20 7A 3F 3E
Izvorni MAC naslov80 00 20 20 3A AE 80 00
PolnitevIP, ARP, itd.
Vsota CRC 00 20 20 3A
Ethernetni okvir tip II
(64 do 1518 zlogov)
Podatki
(46 - 1500 zlogov)
Slika 3.10: Zgradba Ethernet paketa
Kako se podatki prenašajo določa poenostavljen model OSI (slika 3.11), ki je sestavljen iz
štirih slojev:
• povezovalna plast:
Skrbi za določanje enote sporočil, načina ugotavljanja napak, odpravo
napak, kontrolo pretoka in omrežno topologijo.
• internetna plast:
Rešuje problem pošiljanja paketov skozi eno ali več omrežij. Zahteva
pošiljanje podatkov od izvornega do ciljnega omrežja. Ta proces se imenuje
usmerjanje. Opravlja dve osnovi funkciji: naslavljanje gostitelja in
identifikacija ter usmerjanje paketa.
• transportna plast:
Ta plast definira način prenosa podatkov (TCP, UDP …), dolga sporočila
pri oddajanju razbije na manjše dele in jih sestavi pri sprejemanju. Odkriva
in odpravlja napake.
31
Slika 3.11: Poenostavljen model OSI
• aplikacijska plast:
Je vmesnik med uporabnikom in komunikacijskim omrežjem (OSI-
modelom). Tu so definirani protokoli (npr. SNMP, HTTP …).
3.6 Programska rešitev sistema (SW-izvedba)
Za razvoj smo izbrali programski jezik ANSI C (American National Standards Institute –
ameriški nacionalni inštitut za standardizacijo). Uporabili smo razvojno orodje mikroC
PRO for PIC (slika 3.12). Orodje vključuje knjižnice, ki smo jih s pridom uporabili, kar
nam je znatno olajšalo delo pri pisanju programske kode.
MikroC PRO for PIC je zelo močno orodje za razvijanje aplikacij za PIC-mikrokrmilnike,
ki ga je razvilo srbsko podjetje MikroElektronika [8]. Njegov namen je zagotoviti
programerju čim lažjo rešitev za razvoj aplikacij za vgrajene sisteme. Vsebuje tudi
prevajalnik, ki je popolnoma kompatibilen z ANSI C-standardom in ima zelo napredni IDE
(Integrated Development Environment – integrirano razvojno okolje), kar uporabniku
omogoča hitro, enostavno in zelo učinkovito programiranje. Podprt je tudi z veliko primeri,
da se začetniki lahko seznanijo tako z okoljem kot samim programiranjem. Programsko
orodje ponujajo na njihovi spletni strani [8]. Prav tako je na voljo v omejeni (demo) verziji,
ki je polno-funkcionalna do generirane programske kode (hex) velikosti 2 kB.
Nekaj značilnosti mikroC PRO for PIC razvojnega orodja:
• pisanje izvorne kode jezika C z uporabo vgrajenega urejevalnika kode
(Code editor),
32
• uporaba vključenih knjižnic drastično pospeši razvoj,
• uporaba integriranega mikroICD razhroščevalnika za spremljanje izvajanja
programa na strojnem nivoju,
• generiranje COFF-datoteke (Common Object File Format – skupen format
objektnih datotek) za programsko in strojno razhroščevanje v programskem
orodju MPLAB IDE proizvajalca Microchip,
• pregled toka programa z uporabo integriranega programskega simulatorja
in
• podroben pregled RAM- in ROM-statistike, statistike programske kode,
drevesne strukture podprogramov itd.
Slika 3.12: Razvojno okolje mikroC PRO for PIC
33
3.6.1 Opis delovanja merilne enote
Poglavitni cilj merilne enote je merjenje temperature in posredovanje izmerjenih vrednosti.
Enota je sestavljena iz mikrokrmilnika PIC, LCD-zaslona, Dallas-ovih temperaturnih
senzorjev, tipkovnice in priključka za Ethernet.
Ob vklopu enote se nam na zaslonu LCD pojavi meni z dvema izbirama. Prva je zagon
aplikacije, druga pa nastavitev enote, kjer lahko izbiramo jezik in med seboj zamenjujemo
senzorje. Če želimo na mikrokrmilnik dodati senzor(je), ga preprosto priključimo na
vodilo, izklopimo in ponovno vklopimo napravo oziroma jo resetiramo. Naprava sama
zazna, da je na vodilu priključen nov senzor in zanj zahteva vnos imena. Za vnašanje imen
uporabimo tipkovnico, ki jo uporabljamo tudi za navigacijo po meniju. Ko končamo z
dodajanem senzorjev, sledi zagon aplikacije, ki prične z meritvijo temperature. Glede na
prejeto zahtevo priključeni senzorji merijo temperaturo, izmerjeni podatki pa se na zahtevo
pošiljajo preko Etherneta na PC, kjer jih zajamemo s pomočjo programa MRTG in jih
prikazujemo na spletni strani v obliki grafa.
3.6.2 MRTG (Multi Router Traffic Grapher)
MRTG je brezplačno orodje, ki ga je razvil Tobias Oetiker, švicarski razvijalec
programske opreme [17]. Orodje je bilo sprva razvito z namenom spremljanja prometa na
usmerjevalnikih, danes pa ga lahko uporabimo tudi za ustvarjanje in zbiranje drugih tipov
statistik oziroma grafikonov. Z njegovo uporabo lahko spremljamo pretok podatkov vseh
vrst omrežnih naprav kot tudi vse ostalo, od vremenskih podatkov do nadzorovanja
prodajnih avtomatov. Pri meritvah uporablja MRTG dve vrednosti (Imput – vhod, Output –
izhod), podatke pa pridobiva preko agenta SNMP – pogoj je, da naprava podpira uporabo
protokola SNMP. MRTG tipično zajema podatke vsakih pet minut. Ti se prikažejo v obliki
spletne strani z več grafikoni, ki jih prikaže za različne časovne intervale (slika 3.13). Če
so nastavljene vrednosti presežene, omogoča MRTG tudi pošiljanje ustreznih sporočil.
34
Slika 3.13: Primer prikazovanja podatkov v grafikonu
3.6.3 Razdelitev zunanjega EEPROM-pomnilnika
Zunanji pomnilnik EEPROM 24C64 je razdeljen na 3 dele (slika 3.14). Prvi del, ki se
nahaja od naslova 0000h do 0FF7h, vsebuje unikatne 64-bitne ID-naslove senzorjev. Vsak
senzor zasede 8 lokacij pomnilnika. Prvi senzor se shrani na naslov 0000h–0007h, drugi na
0008h–000Fh itd. Tukaj smo naleteli na omejitev, saj je število priključenih senzorjev
pogojeno z velikostjo pomnilnika. Velikost celotnega EEPROM-pomnilnika je 8 kB, ker
pa je velikost prvega dela, kjer se shranjujejo ID-naslovi 4088 zlogov, bi omogočal naš
sistem priklop do 511 senzorjev. Ampak, ker smo omejeni tudi s programskim
pomnilnikom mikrokontrolerja, se dejansko lahko prključi le 100 senzorjev. Drugi del je
namenjen shranjevanju imen senzorjev in se začne na naslovu 0FF8h ter konča na naslovu
1FEFh. Prvi in drugi del sta enako velika, saj ima vsak senzor tudi svoje pridruženo ime.
Razdalja med posameznim ID-jem in njegovim imenom znaša toliko, kot je dolžina prvega
dela. Če se ID-senzor nahaja na prvi lokaciji (00000h–00007h), se njegovo ime nahaja za
vrednost 0FF8h višje, torej na naslovih od 0FF8h do 0FFFh. Zadnji, tretji del pomnilnika
EEPROM od naslova 1FF0h do 1FFFh, pa je namenjen različnim informacijam. Zaenkrat
je uporabljena samo prva lokacija (1FF0h), in sicer hrani informacijo o izbiri jezika,
preostali del pomnilnika pa je na voljo za morebitne nadgradnje.
3.6.4 Inicializacija programa
Na začetku aplikacije se izvede inicializacija programa, ki jo kličemo s funkcijo Init()
(slika 3.15). Inicializacija poskrbi za nastavitev V/I vrat, inicializacijo in nastavitev LCD-
zaslona ter kreiranje in vpis šumnikov v RAM-pomnilnik LCD-ja. V funkciji na sliki 3.15
35
0000h
0FF7h0FF8h
1FEFh1FF0h
1FFFh
ID
IME
INFO
Slika 3.14: Razdelitev naslovnih lokacij zunanjega EEPROM-pomnilnika 24C64
so definirane tri tabele (3-5 – predstavlja območje številčno označenih vrstic na sliki), ki
vsebujejo vrednosti, katere vpišemo v LCD-pomnilnik, da kreiramo šumnike (znake Č, Š
in Ž) (19–24). Takoj za tem sledi izklop notranjega pazikuža (watchdog) časovnika, A/D
pretvornika in komparatorja (7–9). S tem definiramo V/I vrata, da delujejo kot digitalni
vhodi in izhodi. Funkcija Lcd_Init() (11) inicializira in pripravi LCD-zaslon za
njegovo delovanje, nastavitev kurzorja pa izvedeta ukaza Lcd_Cmd() (12,13).
Komunikacijo I2C nastavimo s funkcijo I2C1_Init(400000) (12). Njen argument
pomeni hitrost komunikacije v Hz, torej 400 kHz. Z Ethernet_Init() (13) in
Ethernet_confNetwork() (14) inicializiramo in nastavimo mikrokrmilnik za delo z
Ethernet komunikacijo.
1 void Init()
2
3 char character1[] = 10,4,14,16,16,
16,14,0;
4 char character2[] = 10,4,31,16,31,
1,31,0;
5 char character3[] = 10,4,31,2,4,8,
31,0;
6
7 WDTCON = 0;
8 ADCON0 = 0;
9 ADCON1 = 0x07;
10
11 Lcd_Init();
12 I2C1_Init (400000);
13 Ethernet_Init(myMacAddr,myIpAddr,
Ethernet_FULLDUPLEX);
14 Ethernet_confNetwork(ipMask,gwIpAddr,
dnsIpAddr);
15
16 Lcd_Cmd(_LCD_CLEAR);
17 Lcd_Cmd(_LCD_UNDERLINE_ON);
18
19 if (EE_Read_Random (0x1FFF0)== 0xFF)
20
21 CustomChar (character1, 1);
22 CustomChar (character2, 2);
23 CustomChar (character3, 3);
24
25
Slika 3.15: Inicializacija programa
36
3.6.5 Izdelava menija
Pri izdelavi menija, ki se prikazuje na zaslonu LCD in služi za upravljanje merilne enote,
smo stremeli k čim bolj univerzalnem krožnem meniju, ki se ga lahko enostavno nadgradi
brez večjega posega v programsko kodo sistema. Podprogram Meni() kličemo iz
glavnega programa, nato pa v podprogramu najprej deklariramo zunanje in prototipne
funkcije, ki se v podprogramu uporabljajo (slika 3.16) ter tabele, ki vsebujejo možnosti
menija (slika 3.17).
Potrebno je omeniti, da je v diplomski nalogi opis delovanja posameznih funkcij omejen na
izbiro slovenskega jezika, podprt pa je tudi angleški jezik.
Ob zagonu menija se na zaslonu najprej prikaže vsebina tabele glavni_meni[][16]
(19), torej možnosti "Nastavitve" in "Zagon aplikacije". Za premikanje po meniju
uporabimo funkciji Premakni() (8) in Beri_tipke() (2). Z izbiro možnosti
"Nastavitve" kličemo funkcijo f_Nastavitve() (5), ki omogoča nastavitev menija v
angleškem ali slovenskem jeziku in zamenjavo lokacije temperaturnih senzorjev. Druga
možnost je "Zagon aplikacije", s katero zaženemo celotno aplikacijo našega sistema.
1 // Deklaracija zunanjih funkcij
2 extern char Beri_tipke();
3
4 // Deklaracija prototipnih funkcij
5 void f_Nastavitve(char polje[][16]);
6 void f_Menjaj();
7 void f_Jezik(char polje[][16]);
8 char Premakni (char *vrstica, char
*stevec_besed, char
*st_besed, char array[]
[16]);
Slika 3.16: Deklaracija zunanjih in prototipnih
funkcij
1 // Deklaracija polj (možnosti menija)
2 char glavni_meni[][16] = "Nastavitve",
"Zagon aplikacije";
3 char nastavitve[][16] = "Zamenjaj
senzor", "Jezik";
4 char jezik[][16] = "Slovenski",
"Angleski";
5 char main_menu[][16] = "Setup",
"Start";
6 char setup[][16] = "Replace sensor",
"Language";
7 char language[][16] = "Slovenian",
"English";
Slika 3.17: Deklaracija tabel
3.6.6 Iskanje senzorjev na vodilu
Podjetje Dallas je za iskanje senzorjev na 1-wire vodilu razvilo iskalni algoritem [9].
Iskanje poteka po principu binarnega drevesa, kjer sledimo vejam, dokler ne pridemo do
37
listov oziroma dokler ne odkrijemo edinstvene 64-bitne kode. Ta postopek ponavljamo
tako dolgo, dokler ne najdemo vseh identifikacijskih številk priključenih senzorjev.
Za potrebe naše aplikacije smo algoritem malo dopolnili. Dodali smo funkcijo
Primerjaj_ROM() (slika 3.18), ki primerja najdeni ID-naslov s tistimi, ki so shranjeni
v pomnilniku EEPROM.
S tem pridobimo informacijo ali je na vodilu priključen nov ali star senzor. V funkcijo se
preneseta dva argumenta, sam ID-naslov in dolžina ID-naslova v zlogih. Najprej se iz prve
lokacije pomnilnika EEPROM prebere prvi zlog shranjenega ID-naslova in se primerja s
prvim zlogom najdenega ID-naslova. Če se vrednosti ujemata, nadaljujemo s primerjanjem
naslednjega zloga najdenega ID-naslova na isti lokaciji. To se ponovi za vseh 8 zlogov ID-
naslova. Če se vseh 8 zlogov ujema, pomeni, da gre za senzor, katerega ID-naslov je že
shranjen v pomnilniku. Pri primerjavi pa lahko ugotovimo, da se zloga med seboj ne
ujemata, kar pomeni, da se najdeni ID-naslov ne nahaja na tej lokaciji, zato je potrebno
preveriti naslednjo lokacijo. To zopet ponavljamo tako dolgo, dokler ne pregledamo
celotnega pomnilnika. Če se najdeni ID-naslov ne ujema z nobenim od tistih, ki so
shranjeni v pomnilniku, pomeni, da je na vodilo priključen nov senzor.
1 char Primerjaj_ROM (char buff[], char
bajt)
2
3 signed char i;
4 unsigned EE_lokacija = 0x0000;
5 char array[8];
6 for (i = 0; i < bajt; i++)
7
8 array[i] = EE_Read_Random(EE_lokacija
+i);
9 if (buff[i] != array[i])
10
11 if (EE_lokacija >= 0x0FF0)
12
13 return (0);
14
15 EE_lokacija = EE_lokacija + 8;
16 i = -1
17
18
19 return (1);
20
Slika 3.18: Funkcija Primerjaj_ROM
Ko najdemo nov senzor, je potrebno njegov ID-naslov shraniti v pomnilnik EEPROM na
eno izmed praznih lokacij. Pri iskanju prazne lokacije v pomnilniku si pomagamo s
funkcijo cal_crc(), ki je opisana v razdelku 3.6.7. Takoj, ko odkrijemo nov senzor,
nastavimo resolucijo senzorjev. Sistem podpira dve vrsti Dallas-ovih temperaturnih
senzorjev, in sicer DS18S20 in DS18B20. Razlika med njimi je samo v resoluciji
prikazovanja izmerjene temperature. Prvi imajo 9-bitno resolucijo, pri drugih pa lahko
38
resolucijo izbiramo med 9, 10, 11 in 12 biti. V naši aplikaciji vsem senzorjem nastavimo 9-
bitno resolucijo. Pri 9-bitni resoluciji se temperatura meri v korakih po 0,5 °C, pri 10-bitni
po 0,25 °C, 11-bitni po 0,125 °C, pri 12-bitni pa je korak 0,0625 °C. Senzorji DS18B20
imajo nastavljeno privzeto 12-bitno resolucijo, kar pomeni, da obeh vrst senzorjev ne
moremo uporabljati skupaj, razen, če jim nastavimo resolucijo na 9 bitov, kar smo storili v
naši aplikaciji. Za to nastavitev skrbi funkcija Init_DS18B20() (slika 3.19), ki je drugo
dopolnilo algoritmu za iskanje senzorjev.
1 void Init_DS18B20(char koda[])
2
3 char i;
4
5 if (koda[0] == 0x28)
6
7 Ow_Reset (&DQ,PIN);
8 Ow_Write (&DQ,PIN,0x55);
9
10 for (i=0; i<8; i++)
11
12 Ow_Write (&DQ, PIN, koda[i]);
13
14 Ow_Write (&DQ,PIN,0x4E);
15 Ow_Write (&DQ,PIN,0x00);
16 Ow_Write (&DQ,PIN,0x00);
17 Ow_Write (&DQ,PIN,0x1F);
18 Ow_Reset (&DQ,PIN);
19 Ow_Write (&DQ, PIN, 0x55
20
21 for (i=0; i < 8; i++)
22
23 Ow_Write (&DQ,PIN,koda[i]);
24
25 Ow_Write (&DQ,PIN,0x48);
26 Ow_Reset (&DQ,PIN);
27 Ow_Write (&DQ,PIN,0x55);
28 for (i=0; i<8; i++)
29
30 Ow_Write (&DQ,PIN,koda[i]);
31
32 Ow_Write (&DQ,PIN,0xB8);
33 Ow_Reset (&DQ,PIN);
34
35 return;
36
Slika 3.19: Nastavitev resolucije senzorjev DS18B20
Zadnja modifikacija algoritma je dodana funkcija Vnesi_ime() (slika 3.20), ki od nas
zahteva, da s pomočjo tipkovnice, vnesemo ime novega senzorja. V tej funkciji sta
definirani dve tabeli, ki vsebujeta znake za izpis na zaslon LCD. Tabela slovenian[]
(1) vsebuje znake slovenske abecede (vključno s šumniki), številke od 0 do 9 in znak
presledek (' '), tabelo english[] (2) pa sestavljajo znaki angleške abecede, številke od 0
do 9 ter znak presledek (' '). Tabeli se glede na izbran jezik, ki ga preverimo na začetku (7,
12), kot argument, preneseta v funkcijo Vnos_imena() (10, 15), pred klicem te funkcije
pa se na LCD-ju izpiše še tekst "Vnesi ime:" (9) ali "Enter name:" (14), odvisno od
izbranega jezika. Poleg tabele v funkcijo prenesemo še število znakov, ki jih tabela vsebuje
ter lokacijo pomnilnika EEPROM, na katero se shrani ime senzorja. S pomočjo funkcije za
39
vnos imena izpisujemo znake na LCD-zaslon in se po zaslonu premikamo. Vnašanje
besedila je izvedeno s petimi tipkami (tipka gor, dol, levo, desno in tipka enter), in sicer po
krožnem sistemu, kar pomeni, da se po izpisu zadnjega znaka ponovno izpiše prvi znak iz
tabele; torej se med znaki pomikamo v krogu (slika 3.21). S tipko gor in dol se pomikamo
po abecedi navzgor oziroma navzdol, tipki levo in desno pa se uporabljata za pomik
kurzorja na LCD-ju med izpisanimi znaki. Ko vnesemo želeno ime senzorja, to potrdimo s
pritiskom na tipko enter in ime senzorja se shrani v pomnilnik na lokacijo, katere naslov
dobimo z vsoto spremenljivke EE_lokacija in vrednostjo odmika 0FF8h (slika 3.22).
Dolžina vnesenega imena je lahko največ osem znakov, kar znese osem zlogov, saj je tudi
dolžina kode enako osem zlogov.
1 char slovenian[37] = 'A','B','C',0x01,
'D','E','F','G','H','I','J','K','L',
'M','N','O','P','R','S',0x02,'T','U',
'V','Z',0x03,'0','1','2','3','4','5',
'6','7','8','9',' ','\0';
2 char english[38] ='A','B','C','D','E',
'F','G','H','I','J','K','L','M','N',
'O','P','Q','R','S','T','U','V','W',
'X','Y','Z','0','1','2','3','4','5',
'6','7','8','9',' ','\0';
3
4 void Vnesi_ime (char EE_lokacija)
5
6 Delay_ms (10);
7 if (EE_Read_Random (0x1FFF0)==0xFF)
8
9 Lcd_Out (1, 1, "Vnesi ime:");
10 Vnos_imena (slovenian, 37,
EE_lokacija);
11
12 if (EE_Read_Random (0x1FFF0)==0xFE)
13
14 Lcd_Out (1, 1, "Enter name:");
15 Vnos_imena (english, 38,
EE_lokacija);
16
17 return;
18
Slika 3.20: Funkcija Vnesi_ime
A B C ČD
9876543
2
Slika 3.21: Krožni sistem pomikanja po tabeli
40
1 case 3:
2
3 besedilo[pozicija] = '\0';
4 for (i = 0; besedilo[i] != '\0'; i++)
5
6 EE_Write_byte (besedilo[i], EE_lokacija + i + 0x0FF8);
7
8 Lcd_Cmd (_LCD_CLEAR);
9
Slika 3.22: Del funkcije Vnos_imena, ki shrani ime senzorja v pomnilnik
3.6.7 Meritev temperature
Pri merjenju temperature smo se zgledovali po primeru, ki je priložen programskemu
orodju mikroC PRO, ki smo ga spremenili in dopolnili glede na naše potrebe (slika 3.23).
Na začetku najprej izračunamo lokacijo senzorja v pomnilniku EEPROM (1).
Spremenljivka senzor vsebuje številko senzorja, od katerega druga enota zahteva
izmerjeno temperaturo. To informacijo dobimo iz GET zahteve, ki jo pošlje nadzorna
enota, in sicer jo izluščimo iz označevalnika objekta (OID). Vsak OID je sestavljen iz
devetih števil, ločenih s piko in imajo obliko 1.3.6.1.4.1.17095.3.x. Številko senzorja nam
sporoča zadnje število, ki je označeno z x, vsa ostala števila pa so vedno ista. Po izračunu
lokacije senzorja je iz te lokacije prebrati njegov ID, to storimo z zanko for (2–6). Na
podlagi ID-ja in funkcije cal_crc(7) preverimo, če senzor resnično obstaja oziroma je
priključen na 1-wire vodilo. Če je, sledi algoritem za zahtevano meritev temperature.
Komunikacijo začnemo z reset ukazom (9). Sledi ukaz "ujemanje ROM" ("MATCH
ROM") (10), za njim pa takoj naslovimo senzor, s katerim želimo komunicirati (11–14).
Merjenje temperature sprožimo z ukazom "Pretvori temperaturo" ("Convert temperature")
(15), za katero mora biti zahtevana zakasnitev (16), da se merjenje temperature izvede,
nato pa se transakcija ponovno vrne na začetek; torej zopet sledita ukaza reset (17) in
"ujemanje ROM" (18) ter naslavljanje senzorja (19–22). Ko je temperatura izmerjena, jo
senzor hrani v svojem pomnilniku, iz katerega jo je potrebno prebrati. Najprej sprožimo
ukaz za branje iz beležke (23), nato pa preberemo MSB- in LSB-temperaturo (24–25).
Izmerjeno temperaturo pretvorimo v zapis, ki ga prepozna MRTG. Algoritem za pretvorbo
(26–41) je relativno preprost. Najprej preverimo družino temperaturnih senzorjev, saj se
41
maskiranje glede na družino senzorjev razlikuje. Temperaturo senzorjev DS18B20
maskiramo z vrednostjo 0x0008 (26–30), DS18S20 pa z vrednostjo 0x0001 (31–35) zato,
da izluščimo cel del izmerjene temperature. Ker MRTG ne podpira decimalnih števil,
vrednost temperature najprej pomnožimo z deset (36), nato preverimo še decimalni del in
ga prištejemo k izmerjeni temperaturi (37–40). Če senzor, od katerega nadzorna enota
zahteva izmerjeno temperaturo, ni priključen na 1-wire vodilo, potem za izmerjeno
temperaturo vstavimo vrednost 2000 (42–45), saj jo bo MRTG pred prikazom izločil, ker
je vrednost višja od vrednosti 1250, kar predstavlja temperaturo 125 °C.
Pretvorjeno temperaturo je potrebno razdeliti v dva zloga v šestnajstiškem zapisu, kar od
nas zahteva sestava UDP-paketa. Algoritem za razdelitev je prikazan na sliki 3.23 (46–48).
Ko so podatki pripravljeni, se tvori odgovor na SNMP–zahtevo in se preko Etherneta
pošlje na PC. Za pošiljanje podatkov preko Etherneta se uporablja podprogram
Ethernet() in je opisan v razdelku 3.6.8.
1 lokacija = (senzor * 8) - 8;
2 for (i=0; i<8; i++)
3
4 ID[i] = EE_Read_Random (lokacija+i);
5 Delay_ms (3);
6
7 if ((cal_crc (ID, 7)) == 0)
8
9 Ow_Reset(&DQ, PIN);
10 Ow_Write(&DQ, PIN, 0x55);
11 for (i=0; i<8; i++)
12
13 Ow_Write (&DQ, PIN, ID[i]);
14
15 Ow_Write(&DQ, PIN, 0x44);
16 Delay_ms(100);
17 Ow_Reset(&DQ, PIN);
18 Ow_Write(&DQ, PIN, 0x55);
19 for (i=0; i<8; i++)
20
21 Ow_Write (&DQ, PIN, ID[i]);
22
23 Ow_Write(&DQ, PIN, 0xBE);
24 temp = Ow_Read(&DQ, PIN);
25 temp = (Ow_Read(&DQ, PIN)<<8)+temp;
26 if (ID[0] == 0x28)
27
28 temp_whole = temp >> 4;
29 temp &= 0x0008;
30
31 if (ID[0] == 0x10)
32
33 temp_whole = temp >> 1;
34 temp &= 0x0001;
35
36 temp_whole = temp_whole * 10;
37 if (temp > 0)
38
39 temp_whole = temp_whole + 5;
40
41
42 else
43
44 temp_whole = 2000;
45
46 bajt = temp_whole/16;
47 bajt2 = (bajt<<4) + temp_whole%16;
48 bajt1 = (temp_whole/16)>>4;
Slika 3.23: Meritev in pretvorba temperature
42
3.6.8 Pošiljanje podatkov na PC
Izmerjeni podatki se pošiljajo preko Etherneta z uporabo protokola SNMP. Protokol za
pošiljanje in sprejemanje podatkov oziroma zahtev uporablja dvoje vrat. To sta vrata 161
in 162. Prva so namenjena sprejemanju in pošiljanju podatkov in zahtev, druga pa se
uporabljajo za pošiljanje pasti.
Po pretvorbi izmerjene temperature, ki je prikazana na sliki 3.23, je podatek pripravljen za
pošiljanje. Ped tem je potrebno tvoriti odgovor na zahtevo. To stori podprogram
Ethernet() (slika 3.24) oziroma funkcija Ethernet_UserUDP (slika 3.25), v kateri pa je
vključena tudi meritev temperature prikazana na sliki 3.23. Ethernet() v neskončni
zanki (3–6) pregleduje, ali je prispel kakšen paket oziroma zahteva – funkcija
Ethernet_doPacket() (5). Če je paket oziroma zahteva prispela, funkcija
avtomatsko preveri vrsto paketa (ARP, ICMP, TCP ali UDP) ter na podlagi vrste kliče
funkcije za odgovor. Funkcija na ARP- in ICMP-zahteve odgovarja samodejno, torej
programerju ni potrebno napisati programa za odgovor, medtem ko je za TCP- in UDP-
zahteve to potrebno. Ko sprejmemo TCP- ali UDP-zahtevo funkcija
Ethernet_doPacket() avtomatsko kliče funkciji Ethernet_UserTCP() oziroma
Ethernet_UserUDP() iz knjižnice programskega jezika. Ker v naši aplikaciji ni
potrebno odgovarjati na TCP-zahteve, slednja vrača vrednost 0, kar označuje, da ni
odgovora na zahtevo. Odgovor na UDP-zahtevo se tvori v Ethernet_UserUDP(), ki je
prikazan na sliki 3.25. V funkcijo se prenesejo štirje argumenti. Prvi argument je IP-
naslov, kamor naj se podatek pošlje. Naslednja argumenta sta izvorna in ciljna vrata. Ciljna
vrata je potrebno vključiti v odgovor zato, ker na njih NMS tudi pričakuje odgovor. To so
vrata, preko katerih NMS pošlje zahtevo. Izvorna vrata pa določajo, iz katerih vrat naj se
podatki pošljejo. V našem primeru so to vrata 161, saj za aplikacijsko plast uporabljamo
protokol SNMP. Četrti argument je dolžina našega odgovora v zlogih, s čimer NMS-ju
povemo kako dolg podatek lahko pričakuje. Z vsemi temi informacijami nato funkcija
Ethernet_sendUDP() tvori UDP-paket, in sicer po standardnih pravilih, ki so za to
določena. Iz prejete zahteve najprej izluščimo njen ID (14–29) ter številko senzorja (30–
34), vse ostale informacije (izvorna in ciljna vrata ter IP-naslov) pa funkcija
Ethernet_doPacket() pridobi avtomatsko, ko ugotovi vrsto zahteve. Sledi tvorjenje
odgovora na zahtevo (36–85), ki se shrani v polje response[] (5). Začetek odgovora se
43
začne s sekvenčnim tipom, kar označuje vrednost 0x30 (36), nato pa sledi dolžina SNMP-
sporočila (37), ki je v naši aplikaciji konstantna in znaša 45 zlogov. Verzija SNMP-paketa
je tipa integer, dolžine enega zloga in vrednosti 0, kar predstavlja protokol SNMPv1 (39–
41). Za tem sledi opis community string-a (42–49). Community string je tipa octet string
(42), njegova dolžina znaša šest zlogov (43), uporabili pa smo privzeto vrednost, torej
"public" (44–49). Naslednji dve informaciji, ki jih vključimo v odgovor, sta tip in dolžina
PDU-ja. Ker tvorimo odgovor na zahtevo, je tip PDU-ja GET-RESPONSE, ki ima kodo
0xA2 (50), njegova dolžina pa je v naši aplikaciji vedno 20 zlogov (51). ID-zahteve je tipa
integer (52) in dolžine štirih zlogov (53), vrednost pa se spreminja in jo pridobimo iz
SNMP-zahteve, ki jo že predhodno preberemo in shranimo v polje requestID[] (14–
29). Sedaj pa jo samo še vključimo v odgovor (54–57). Sledita status napake (59–61) in
indeks napake (62–64), ki ju v naši aplikaciji ne uporabljamo, saj nimamo polno
implementiranega SNMP-agenta. Oba sta tipa integer, dolžine enega zloga ter vrednosti 0,
saj ne sporočamo NMS-ju nobene napake, četudi do nje pride. Naslednja informacija je
"varbind list", ki je sekvenčnega tipa (65) in dolžine 19 zlogov (66), takoj za njo pa sledi
"variable bindings", ki je prav tako sekvenčnega tipa (67), njena dolžina pa je 16 zlogov in
je vedno konstantna (68). Označevalnik objekta (OID) je vedno tipa object identifier (69),
dolžine desetih zlogov, njegova vrednost pa se spreminja samo pri zadnji številki, ki
označuje številko senzorja (71–80). Kot zadnji element, ki ga vključimo v odgovor je
podatek (81–84). Podatek je tipa integer (81) in konstantne dolžine dveh zlogov (82),
vrednost pa se spreminja glede na izmerjeno temperaturo (83–84). Po kreiranju odgovora
ga prenesemo v oddajni pomnilnik s pomočjo funkcije Ethernet_putByte(), in
sicer vsak zlog posamezno, za kar poskrbi zanka for (86–89). Funkcija
Ethernet_UserUDP() zahteva, da ob zaključku vrne vrednost dolžine SNMP-
sporočila v zlogih (90). Dolžina sporočila pa je vedno enaka in znaša 47 zlogov.
1 void Ethernet()
2
3 while (1)
4
5 Ethernet_doPacket();
6
7
Slika 3.24: Sprejemanje zahtev
44
1 unsigned int Ethernet_UserUDP(unsigned
char *remoteHost, unsigned
intremotePort, unsigned int destPort,
unsigned int reqLength)
2
3 char i;
4 char requestID[4];
5 char response[131];
6 char len;
7 char zacasno;
8 char dol_snmp;
9 char senzor;
10
11 for (i = 0; i < reqLength; i++)
12
13 zacasno = Ethernet_getByte();
14 if (i == 17)
15
16 requestID[0] = zacasno;
17
18 if (i == 18)
19
20 requestID[1] = zacasno;
21
22 if (i == 19)
23
24 requestID[2] = zacasno;
25
26 if (i == 20)
27
28 requestID[3] = zacasno;
29
30 if (i == 42)
31
32 senzor = zacasno;
33 break;
34
35
36 response[0] = 0x30;
37 response[1] = 0x2d;
38 dol_snmp = 0x2d;
39 response[2] = 0x02;
40 response[3] = 0x01;
41 response[4] = 0x00;
42 response[5] = 0x04;
43 response[6] = 0x06;
44 response[7] = 0x70;
45 response[8] = 0x75;
46 response[9] = 0x62;
47 response[10] = 0x6c;
48 response[11] = 0x69;
49 response[12] = 0x63;
50 response[13] = 0xA2;
51 response[14] = 0x20;
52 response[15] = 0x02;
53 response[16] = 0x04;
54 response[17] = requestID[0];
55 response[18] = requestID[1];
56 response[19] = requestID[2];
57 response[20] = requestID[3];
59 response[21] = 0x02;
60 response[22] = 0x01;
61 response[23] = 0x00;
62 response[24] = 0x02;
63 response[25] = 0x01;
64 response[26] = 0x00;
65 response[27] = 0x30;
66 response[28] = 0x12;
67 response[29] = 0x30;
68 response[30] = 0x10;
69 response[31] = 0x06;
70 response[32] = 0x0A;
71 response[33] = 0x2b
72 response[34] = 0x06;
73 response[35] = 0x01;
74 response[36] = 0x04;
75 response[37] = 0x01;
76 response[38] = 0x81;
77 response[39] = 0x85;
78 response[40] = 0x47;
79 response[41] = 0x03;
80 response[42] = senzor;
81 response[43] = 0x02;
82 response[44] = 0x02;
83 response[45] = bajt1;
84 response[46] = bajt2;
85 len= 2 + dol_snmp;
86 for (i=0; i<len; i++)
87
88 Ethernet_putbyte (response[i]);
89
90 return(len);
91
Slika 3.25: Odgovor na SNMP-zahtevo
45
3.6.9 Zajemanje podatkov na PC
Zajemanje in prikazovanje podatkov na osebnem računalniku poteka s pomočjo programa
MRTG. Po poslani zahtevi za izmerjeno temperaturo, MRTG pričakuje odgovor v naprej
določenem času, ki se nastavi v konfiguracijski datoteki. Konfiguracijska datoteka je
skupek ukazov, s katerimi MRTG-ju določimo potek njegovega delovanja, oblikujemo
prikaz podatkov itd. Naša aplikacija podpira priključitev stotih senzorjev temperature, za
vsakega pa je v konfiguracijski datoteki določeno, kako naj se izmerjeni podatki prikažejo.
Na sliki 3.27 je prikazana konfiguracijska datoteka enega senzorja, več pa jih je dodanih v
poglavju 6 (priloge). V prvem delu (1–9) se nahajajo globalne nastavitve. Tu izklopimo
verzijo šest protokola IP (3), saj uporabljamo verzijo štiri. Nadalje vključimo MIB-
datoteko (4) in z ukazom RunAsDaemon (5) nastavimo, da se MRTG izvaja ves čas.
Ukaz WorkDir (7) določa pot na disku osebnega računalnika, kamor se shranjujejo
podatki oziroma tvorjeni grafi. Naša aplikacija, ki teče na mikrokrmilniku, ne podpira
polne implementacije SNMP, zato izklopimo datoteko MIB2 (8), saj nimamo
implementiranega podatka "sysUptime" in "sysName". Za prikaz spletne strani smo izbrali
slovenski jezik (9). Z ukazoma PageTop[] (14) in PageFoot[] (15) dodamo tvorjeni
spletni strani naslov in kontakt, ki sta prikazana na sliki 3.26. Nadalje sledi OID-številka
senzorja, od katerega zahtevamo izmerjeno temperaturo, "community name" in IP-naslov,
kamor se pošlje zahteva. To nastavimo z ukazom Target[] (16). MaxBytes[] (19)
določa zgornjo mejo prejetih podatkov. V našem primeru je meja nastavljena na 1250. To
pomeni, da MRTG sprejme in prikaže vse prejete vrednosti do 1250, kar je ekvivalentno
temperaturi 125 °C, ostale pa ignorira, torej jih ne prikaže. Najmanjša vrednost, ki jo
MRTG še lahko sprejme in prikaže, je 0, torej lahko prikazujemo temperaturo od 0 °C do
125 °C. Naslov zavihka v internetnem brskalniku določimo s Title[] (20), naslov grafa
pa s PNGTitle[] (21). Z ukazom Option[] (22) nastavimo vrsto podatkov, ki jih
prikazujemo. V našem primeru prikazujemo temperaturo, zato izberemo nastavitev
gauge. Nastavitve nobanner, nopercent, noo in nolegend določajo, da se ne
prikazujejo reklame, procentualne vrednosti temperature, izhodni podatki in legenda. Nato
sledijo ukazi, s katerimi oblikujemo prikaz podatkov v grafu (23–26). Z YTics[] (23)
nastavimo vrednosti grafa na y-osi, YTicsFactor[]z nastavljeno vrednostjo 0.1 (24),
pa določa prikaz temperature na desetinko natančno. Izmerjena temperatura, se zaradi
46
lažjega pošiljanja preko Etherneta, pomnoži z vrednostjo deset, kar opisuje razdelek 3.6.7.
Nato pa v konfiguracijski datoteki z ukazom Factor[] (25) MRTG-ju določimo, da
prejeto vrednost pomnoži z 0,1 in s tem pridobimo originalni podatek o temperaturi. V
našem primeru prikazujemo samo dnevno in tedensko temperaturo, mesečno in letno pa
izklopimo (26). Legendo, ki se prikaže pod grafom, nastavimo z ukazoma
ShortLegend[] (27) in LegendI[] (28), oznako na y-osi pa z YLegend[] (29).
Timezone[] (30) določa mesto, kjer merimo temperaturo. Ostali ukazi in nastavitve
konfiguracijske datoteke so podrobneje opisane na spletni strani avtorja [17].
Slika 3.26: Primer tvorjene spletne strani
47
1 ### Globalne nastavitve
2
3 EnableIPv6: no
4 LoadMIBs: C:\mrtg\bin
5 RunAsDaemon: yes
6
7 WorkDir: c:\www1
8 NoMib2: Yes
9 Language: slovenian
10
11
12 ### Senzorji
13
14 PageTop[temp1]: <H1>Meritev Temperature
- SENZOR 1</H1>
15 PageFoot[temp1]:Kontakt:<AHREF="mailto:
Mitja Mastnak</A
16 Target[temp1]: 1.3.6.1.4.1.17095.3.1&
1.3.6.1.4.1.17095.3.1:[email protected]
17 SetEnv[temp1]: MRTG_INT_IP="192.168.0.1"
MRTG_INT_DESCR="Realtek-
RTL8139-Family-PCI-Fast-
18 Ethernet-NIC--Packet-Scheduler-Miniport"
19 MaxBytes[temp1]: 1250
20 Title[temp1]: Senzor 1
21 PNGTitle[temp1]: Senzor 1
22 Options[temp1]: gauge,nobanner,nolegend,
nopercent,noo
23 YTics[temp1]: 5
24 YTicsFactor[temp1]: 0.1
25 Factor[temp1]: 0.1
26 Suppress[temp1]: ym
27 ShortLegend[temp1]: °C
28 LegendI[temp1]: Temperatura:
29 YLegend[temp1]: Temperatura (°C)
30 Timezone[temp1]: Maribor
Slika 3.27: Konfiguracijska datoteka enega senzorja
3.7 Izvedba strojnega dela
Shema in tiskano vezje sta bila ustvarjena s programskim paketom Eagle nemškega
podjetja Cadsoft [10]. Razvoj sheme in tiskanega vezja je trajal približno šest dni, saj je
bilo večino gradnikov vezja, pred samo izdelavo merilne enote, uporabljenih v testnih
vezjih; razlika je bila le v velikosti. Za testiranje smo uporabljali navadne through-hole
elemente, pri izdelavi pa zaradi velikosti tiskanih vezij oziroma celotne enote, SMD-
(Surface Mount Devices – elementi za površinsko montažo) in nekaj through-hole
elementov.
Merilna enota je sestavljena iz napajalnega dela, reset vezja, mikrokrmilnika PIC
18F67J60, ki predstavlja jedro sistema, LCD-zaslona, tipkovnice, temperaturnih senzorjev
in 1-wire vodila, vezja za komunikacijo z Ethernetom in vezja za ICSP-programiranje
mikrokrmilnika.
Napajalni del
Enota se napaja iz 9-voltnega enosmernega adapterja, gradniki pa za svoje
delovanje potrebujejo dve različni pozitivni napetosti, 3,3 V oziroma 5 V. Zato sta
48
v tem delu dodana dva pretvornika, in sicer LM7805 in LM1117LD33. Prvi
stabilizira napajalno napetost na 5 V, drugi pa teh 5 V pretvori na 3,3 V. Napajanje
5-ih V potrebujeta LCD-zaslon in 1-wire vodilo, ki je preko dvižnega upora
(pullup) vezano na to napajanje, vsa ostala periferija pa za svoje delovanje
potrebuje napetost 3,3 V. Kot je razvidno iz slike 3.28, je poleg kondenzatorjev, ki
služijo za filtriranje oziroma preprečevanje motenj, dodana še LED-dioda, ki
signalizira stanje naprave (vklop/izklop).
+3V3
+3V3+3V3
+3V3
330n 100n 100n 100n47u 47u
GND GND GNDGND GNDGND GNDGND GND GNDGND
GND
GND
7805T LM1117 3.3V
DC 9V
NAPAJANJE
NAPAJANJE
NAPAJANJE
+5V
+5V+5V
+5V
330
START/STOPC1 C2 C3 C4C5 C6
2
VI1VO
3
IC1
GND ADJ
IN OUT
IC2
123J1
123
JP1
123
JP2
123
JP3
LED1
R1
12
3
T1
+ +
Slika 3.28: Shema napajalnika
Slika 3.29: Tiskano vezje napajalnika
49
C1
C2
C3
C4
C5
C6
IC1
IC2
J1
JP1
JP2
JP3
LED1
R1
T1
Slika 3.30: Razpored elementov na tiskanem vezju
Reset vezje
Glavna naloga tega vezja je resetiranje oziroma ponovni zagon celotne naprave, v
primeru, da pride do nepredvidljivega delovanja ali napak. Sestavljeno je iz reset
tipke in uporov (slika 3.31), ki poskrbita, da je, glede na stanje tipke, linija MCLR
vedno na ustreznem potencialu.
+3V3 +3V3
100n
GNDGND GND
10k
4k7
MCLR
C1
123
JP1
R1
R2RESET
Slika 3.31: Shema reset vezja
Slika 3.32: Tiskano vezje reset vezja
C1
KON_1 R1
R2
RESET
Slika 3.33: Razpored elementov (reset vezje)
50
Mikrokrmilnik PIC 18F67J60
Mikrokrmilnik predstavlja jedro sistema, saj upravlja in nadzira celotno delovanje
naprave. Del vezja, ki omogoča delovanje mikrokrmilnika, je sestavljen po
navodilih proizvajalca [7] in zaradi majhnega števila elementov zelo preprost.
Potrebuje samo napajanje na napajalnih vhodih ter zunanji oscilator izbrane
frekvence, ki je v našem primeru 25 MHz, saj le-ta zagotavlja delovanje Ethernet
modula.
Pri mikrokrmilniškem vezju smo uporabili komercialni izdelek LV18FJ MCU Card
[11], srbskega proizvajalca MikroElektronika [8]. Njegova shema je prikazana na
sliki 3.34.
VCC3.3 VCC3.3 VCC3.3 VCC3.3 VCC3.3VCC3.3 VCC3.3
VCC3.3 VCC3.3 VCC3.3 VCC3.3
100n 100n 100n 100n 100n 100n 100n
10u 10u 10u 10u
10u22p22p
GND GND GND GND GND GND GND
GND
GND GND GND GND
GNDGND
PIC18F67J60
25MHz
2K26
/MCLR/MCLR
GNDGND
GND
GND
GND
GND
GND
GND GND
GND
GND
GND
GND
GND
GNDGND
OSC1
OSC1
OSC2
OSC2
PGCPGC
PGD
PGD
RA0
RA0
RA1
RA1
RA2
RA2
RA3
RA3
RA4
RA4
RA5
RA5
RB0RB0RB1
RB1
RB2RB2
RB3
RB3RB4
RB4
RB5
RB5
RBIAS
RBIAS
RC0
RC0
RC1
RC1
RC2
RC2
RC3
RC3
RC4
RC4
RC5
RC5
RC6
RC6
RC7
RC7
RD0
RD0
RD1
RD1
RD2
RD2
RE0RE0RE1
RE1
RE2
RE2
RE3
RE3
RE4
RE4
RE5
RE5
RF1
RF1
RF2
RF2
RF3
RF3
RF4
RF4
RF5
RF5
RF6
RF6RF7
RF7RG4
RG4
TPIN+
TPIN+
TPIN-
TPIN-
TPOUT+
TPOUT+
TPOUT-
TPOUT-
VCAP
VCAP
VCC3.3
VCC3.3
VCC3.3
VCC3.3VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
VCC3.3
C1 C2 C3 C4 C5 C6 C7
C8 C9 C10 C11
C12C13C14
MCLR7
AVDD
19
AVSS
20
ENVREG
18
OSC1/CLKI39OSC2/CLKO40
RA0/LEDA/AN0
24
RA1/LEDB/AN1
23
RA2/AN2/VREF-
22
RA3/AN3/VREF+
21
RA4/T0CKI
28
RA5/AN4
27
RB0/INT0/FLT03
RB1/INT14
RB2/INT25
RB3/INT36 RB4/KBI044
RB5/KBI143
RB6/KBI2/PGC42
RB7/KBI3/PGD37
RBIAS
53
RC0/T1OSO/T13CKI
30
RC1/T1OSI/E
CCP2/P2A
29
RC2/ECCP1/P1A33RC3/SCK1/SCL134RC4/SDI1/SDA135RC5/SDO136
RC6/TX1/CK1
31
RC7/RX1/DT1
32
RD0/P1B
60
RD1/ECCP3/P3A
59
RD2/CCP4/P3D
58
RE0/P2D2RE1/P2C1
RE2/P2B
64
RE3/P3C
63
RE4/P3B
62
RE5/P1C
61
RF1/AN6/C2OUT
17
RF2/AN7/C1OUT16RF3/AN815RF4/AN914RF5/AN10/CVREF13RF6/AN1112RF7/SS111
RG4/CCP5/P1D8
TPIN+47
TPIN-46
TPOUT+
51
TPOUT-
50
VDD
26
VDD38
VDD
57
VDDCORE/VCAP10
VDDPLL
54
VDDRX48
VDDTX
49
VSS9
VSS
25
VSS41
VSS
56
VSSPLL
55
VSSRX45
VSSTX
52
IC1
1 23 45 67 89 1011 1213 1415 1617 1819 2021 2223 2425 26
JP1
1 23 45 67 89 1011 1213 1415 1617 1819 2021 2223 2425 26
JP2
1 23 45 67 89 1011 1213 1415 1617 1819 2021 2223 2425 26
JP3
1 23 45 67 89 1011 1213 1415 1617 1819 2021 2223 2425 26
JP4
1 4Q1
R1
+ + + +
+
Slika 3.34: LV18FJ MCU Card
51
Vezje za ICSP-programiranje
Ta 6-pinski konektor je namenjen za programiranje mikrokrmilnika v vezju.
+3V3GND
RJ11MCLR
PGCPGD
123456
ICSP
Slika 3.35: Shema ICSP-vezja
LCD-zaslon
Uporabljen je LCD-zaslon dimenzije 2 x 16, sestavljen iz dveh vrstic po 16 znakov.
Njegova naloga je prikazovanje menija, ki služi nastavljanju enote, priključi pa se
ga na 16-pinski konektor. Za nastavljanje kontrasta na LCD-zaslonu služi
nastavljivi upor (trimmer potenciometer) z vrednostjo 4,7 kΩ. Upor 330 Ω omejuje
tok skozi LED-diodo, ki osvetljuje ozadje zaslona.
GND
GND GND
GND
16X2
+5V +5V
10k
330
D4
D5
D6
D7
EN
RS
CONTR
3
D0
7
D1
8
D2
9
D3
10
D4
11
D5
12
D6
13
D7
14
E6
GND
1
NC
15
NC
16
R/W
5RS
4
VCC
2
LCD_ZASLON
31
2
R1
R2
LCD DISPLAY 16x2
Slika 3.36: Shema LCD-zaslona
1-wire vodilo
Temperaturni senzorji so na 1-wire vodilo priključeni paralelno. Za priklop
senzorjev na merilno enoto uporabljamo kabel UTP in RJ45 vtičnice. Vezava RJ45
vtičnice in 1-wire vodila je prikazana na sliki 3.37.
52
1-WIRE_KONEKTOR
GND
+5V
1W_DATA
1122334455667788
RJ45
Slika 3.37: Vezava RJ45 vtičnice
Tipkovnica
Tipkovnica je sestavljena iz petih tipk (slika 3.38). Ena tipka je namenjena za
resetiranje naprave, ostale pa se uporabljajo za navigacijo po meniju in vnašanju
imen. Vezane so tako, da so aktivne na logično 0, dvižni (pullup) upori pa
zagotovijo na vhodih mikrokrmilnika visok logični nivo, kadar so tipke v
neaktivnem stanju.
GND
GND
+5V +5V +5V +5V +5V
+5V
4k7
4k7
4k7
4k7
4k7
DESNO
DOL
ENTER
GOR
1234567KONEKTOR_1
LEVO
R1
R2
R3
R4
R5
Slika 3.38: Shema tipkovnice
53
Slika 3.39: Tiskano vezje tipkovnice
DESNO
DOL
ENTER
GOR
KONEKTOR_1
LEVO
R1
R2
R3
R4
R5
Slika 3.40: Razpored elementov (tipkovnica)
Vezje za komunikacijo z Ethernetom
Ethernet poleg fizičnega nivoja, ki se nahaja že v mikrokrmilniku, potrebuje tudi
nekaj zunanjih komponent, kot so transformatorji, tuljava in upori. Upori, ki
zagotavljajo ustrezno impedanco (100 Ω) podatkovnih linij, so vrednosti 49,9 Ω
(slika 3.41), kot to v navodilih določa proizvajalec [7]. Za povezavo naše merilne
enote z Ethernetom skrbi RJ-45 konektor, ki ima že vgrajene transformatorje in vse
ostale potrebne elemente, ki jih priporoča proizvajalec. Konektor ima vgrajeni tudi
dve LED-diodi, ki sta povezani na mikrokrmilnik, zunaj pa imata vsaka dodan
upor, ki omejuje tok skozi njiju. Ti diodi prikazujeta stanje komunikacije. Ena
prikazuje stanje povezanosti, druga pa sprejemanje in oddajanje podatkov.
Tuljavica, ki je vezana iz priključka TCT, je navita na feritno jedro in služi za
preprečevanje elektromagnetnih motenj.
54
+3V3
+3V3
100n 100n
GNDGND
GND
GND
GND
J00265 ovojev
49R9
49R9
49R9
49R9
1k
1k
CTR
CTR
CTT
CTT
LED_A
LED_A
LED_B
LED_B
TPIN+
TPIN+TPIN+
TPIN+
TPIN-
TPIN-TPIN- TPIN-
TPOUT+
TPOUT+TPOUT+
TPOUT+
TPOUT-
TPOUT-TPOUT-
TPOUT-
C1 C212345678
ETHERNET
CG14
CG25
CTR6
CTT3
LA9
LC10
RA12
RC11
RD+7
RD-8
S1S1
S2S2
TD+1
TD-2
J1
L1
R1
R2
R3
R4
R5
R6
RJ45
Slika 3.41: Shema vezja za Ethernet komunikacijo
Slika 3.42: Tiskano vezje vezja za Ethernet komunikacijo
C1
C2 ETHERNET
J1
L1
R1
R2
R3
R4
R5
R6
Slika 3.43: Razpored elementov (vezje za Ethernet komunikacijo)
55
EEPROM-vezje
EEPROM-vezje je sestavljeno po priporočilih proizvajalca [16]. Dvižna upora R1
in R2 zagotavljata pozitivno napetost na pinih 5 in 6.
24C64
CS1
HOLD7
WP3
4
SCK6SI5
SO2
8
VCC
GND
IC1
12
JP1
12
JP2
R1
R2
Array
EEPROM
Slika 3.44: Shema EEPROM-vezja
Slika 3.45: Tiskano vezje EEPROM-vezja
IC1 JP1
JP2
R1
R2
Slika 3.46: Razpored elementov (EEPROM-vezje)
56
4 SKLEP
Namen te diplomske naloge je bil zasnovati univerzalni sistem za merjenje ter izvesti
sistem za merjenje temperature, s pomočjo katerega bi lahko preko osebnega računalnika
spremljali temperaturo ter ga nadzirali in upravljali na daljavo. Tako kot vsepovsod drugje,
je tudi pri nas imela glavno vlogo cena, vendar ne na račun kakovosti oziroma kvalitete
merilnega sistema. Pri sami zasnovi sistema in izbiri elementov nas je cena privedla do
globljega razmisleka, saj je bilo potrebno za vsak posamezen element pretehtati vse
njegove prednosti in slabosti, ki bi se odražale na končnem sistemu. Ob tem smo spoznali,
da je zasnova izvedbe projekta eden ključnih dejavnikov pri kasnejši realizaciji. Skozi
celotno diplomsko delo smo se srečali tudi s številnimi problemi, a smo jih uspešno rešili.
Večina problemov se je pojavila pri zasnovi izvedbe sistema in pisanju aplikacije za
mikrokrmilnik, nekaj pa tudi čisto osnovnih napak, kar je pogojeno s pomanjkanjem prakse
in izkušenj pri projektiranju obsežnejših sistemov. Ob vseh nastalih težavah in preprekah
ob realizaciji merilnega sistema, mi je ob strani stal mentor, ki mi je s svojim širokim
znanjem in dolgoletnimi izkušnjami na tem področju svetoval in pomagal, da sem našel pot
iz labirinta.
Prihodnje programske izboljšave bodo zajemale predvsem dodatno optimizacijo
programske kode in seveda odpravo morebitnih hroščev, ki so nastali med razvojem, a se
bodo izpostavili tekom uporabe sistema.
Čeprav je bil ta merilnik temperature praktično moj prvi večji projekt, pri katerem sem
uporabil tako zmogljiv mikrokrmilnik in komunikacijo z Ethernethom, bom najverjetneje
svojo inženirsko pot tudi v prihodnosti ohranil v tej smeri.
4.1 Možnosti uporabe
Sistem je bil že v osnovi načrtovan tako, da ima zelo širok spekter uporabe; torej le-ta ni
specifično določena. Uporabi se lahko povsod, kjer je potreba po merjenju in prikazovanju
temperature, ne glede na to, kakšno je okolje, v kateri naprava deluje. Sistem lahko deluje
tako v proizvodnjah, kjer je okolje prašno in umazano, kakor tudi v pisarnah, hišah in celo
v vodi. Napravo na prvem mestu odlikujejo cena, fleksibilnost in funkcionalnost.
Zahvaljujoč 1-wire protokolu se lahko temperatura meri na zelo velike razdalje, ki pa je
57
pogojena z vrsto in kvaliteto kabla, na katerem so priključeni senzorji. Pri uporabi kabla z
neoklopljenimi vpredenimi pari, proizvajalec trdi, da je oddaljenost senzorjev lahko do 300
m.
4.2 Ideje za nadgradnjo
Ena izmed idej je predstavljena že v uvodnem razdelku 1, obstaja pa tudi veliko drugih
možnosti. Trenutno razviti sistem omogoča samo merjenje temperature, ki pa ga je mogoče
nadgraditi tudi z merjenjem drugih fizikalnih količin (tlak, vlažnost, višina …). Lahko se
mu doda regulacija, s katero bi bilo možno nastavljati temperaturo z ventilatorji, grelci ali
drugimi elektromehanskimi elementi. Naprava se lahko nadgradi tudi v strežnik ali pa v
popolnoma samostojno enoto.
• strežnik
Za nadgradnjo v strežnik je potrebno v aplikacijo mikrokrmilnika
implementirati spletno stran ter dodati funkcijo, ki sprejema in odgovarja
na HTTP-zahteve na vratih 80.
• samostojna enota
Sistem je možno nadgraditi v samostojno enoto, ki bi bila zmožna
shranjevanja zgodovine dogodkov, prikazovanja temperature na LCD-
zaslonu, pošiljanja podatkov preko Etherneta … Za shranjevanje podatkov
se lahko uporabi mikro SD pomnilniška kartica, prikazovanje pa lahko
izvedemo z grafičnim LCD-prikazovalnikom občutljivim na dotik. Če je
potreba po regulaciji sistema, se mu enostavno dodajo še digitalni ali
analogni vhodi oziroma izhodi, kateri omogočajo priključitev
najrazličnejših elementov in naprav.
58
5 LITERATURA
[1] MessPC, MessPC ethernet box. [Spletni vir].
Naslov: http://www.messpc.de/ethernetbox-en.php [Dostopano: 14. 1. 2010].
[2] SenzorProbe8. [Spletni vir]. Naslov: http://www.industrialethernet.com/sp8.html.
[Dostopano: 14. 1. 2010].
[3] HW group, HWg-STE ethernet thermometer. [Spletni vir]. Naslov:
http://www.hw-group.com/products/HWg-STE/STE_ip_temperature_sensor_en.html
[Dostopano: 15. 1. 2010].
[4] Dallas Semiconductor, DS18B20 Programmable Resolution 1-Wire Digital
Thermometer. [Spletni vir]. Naslov:
http://datasheets.maxim-ic.com/en/ds/DS18B20.pdf. [Nastanek: 2008]. [Dostopano:
24. 12. 2009].
Dallas Semiconductor, DS18S20 Hi-Precision 1-Wire Digital Thermometer. [Spletni
vir]. Naslov: http://datasheets.maxim-ic.com/en/ds/DS18S20.pdf. [Nastanek: 2010].
[Dostopano: 24. 12. 2009].
[5] Charles E. Spurgeon: Ethernet the definitive guide, O'Reilly & Asocciates Inc.,
Sebastopol 2000.
[6] Wikipedia, Standard IEEE 802.3. [Spletni vir]. Naslov:
http://en.wikipedia.org/wiki/IEEE_802.3. [Dostopano: 11. 2. 2010].
[7] Microchip. PIC18F97J60 Family Datasheet. [Spletni vir]. Naslov:
http://ww1.microchip.com/downloads/en/DeviceDoc/39762e.pdf. [Dostopano: 7. 1.
2010].
[8] MikroElektronika, mikroC PRO for PIC. [Spletni vir]. Naslov:
http://www.mikroe.com/eng/products/view/7/mikroc-pro-for-pic/. [Dostopano: 25.
12. 2009].
[9] Dallas Semiconductor, Application Note 187 – 1-Wire Search Algorithm. [Spletni
vir]. Naslov: http://pdfserv.maxim-ic.com/en/an/AN187.pdf. [Nastanek: 28. 3. 2002].
[Dostopano: 1. 1. 2010]
[10] Cadsoft Computer, Eagle Layout Editor. [Spletni vir]. Naslov:
http://www.cadsoft.de/. [Dostopano: 27. 4. 2010].
[11] Mikroelektronika, LV18FJ MCU Card. [Spletni vir]. Naslov:
59
http://www.mikroe.com/eng/products/view/478/lv18fj-mcu-cards/. [Dostopano: 9. 2.
2010].
[12] Microchip. Application Note 870 – An SNMP Agent for the Microchip TCP/IP
Stack. [Spletni vir]. Naslov:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=18
24&appnote=en012108. [Nastanek: 28. 7. 2003]. [Dostopano: 16. 3. 2010].
[13] J. Brest, V. Žumer: Uvod v programiranje in programski jezik C++, Fakulteta za
elektrotehniko, računalništvo in informatiko, Inštitut za računalništvo, Maribor 2002.
[14] Renato Mikša: Protokol SNMP in namestniški strežnik, diplomsko delo, Maribor
september 2008.
[15] William Stallings: SNMP, SNMPv2, SNMPv3 and RMON 1 and 2, tretja izd.,
Addison Wesley 1999.
[16] STMicroelectronics. M24C64 64Kbit Serial I2C Bus EEPROM. [Spletni vir].
Naslov: http://www.datasheetcatalog.org/datasheets/400/227040_DS.pdf. [Nastanek:
2005]. [Dostopano: 10. 2. 2010].
[17] MRTG, Multi Router Traffic Grapher. [Spletni vir]. Naslov:
http://oss.oetiker.ch/mrtg/index.en.html. [Dostopano: 12. 3. 2010].
60
6 PRILOGE
Inicializacija in glavni program
// Definicije
#define FALSE 0
#define TRUE 1
#define PIN 1 // Pin na katerega so priključeni senzorji
// Ta definicija se uporablja samo pri Ow_Read,
// Ow_Write in Ow_Reset
#define BPIN B1 // Pin na katerega so priključeni senzorji
// Ta pa se uporablja vsepovsod drugje
#define DQ PORTE // Port na katerega so priključeni senzorji
#define DQREG TRISE // Register na katerega so priključeni senzorji
#define Ethernet_HALFDUPLEX 0
#define Ethernet_FULLDUPLEX 1
// LCD povezave
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Deklaracija zunanjih funkcij
extern void Iskanje_senzor();
extern char cal_crc (char buff[], char byte_num);
extern void senzor_ping (char buff[], char byte_number, unsigned naslov);
extern void Meni();
extern void Ethernet();
// Deklaracija notranjih funkcij
void Init();
void Pripravi_EE();
void CustomChar(char *character, char znak);
61
//*****************************************************************************************
// Nastavitev parametrov za omrežje
//
// IP: 192.168.0.2
// GATEWAY: 192.168.0.1
// MASKA: 255.255.255.0
// DNS: 192.168.0.2
// MAC: 00 16 36 9B BC 21
//*****************************************************************************************
// MAC naslov Ethernet vmensika v PIC-u
unsigned char myMacAddr[6] = 0x00, 0x16, 0x36, 0x9B, 0xBC, 0x21;
// IP address PIC-a
unsigned char myIpAddr[4] = 192, 168, 0, 2;
// Gateway IP naslov, kamor pošiljamo podatke (n)
unsigned char gwIpAddr[4] = 192, 168, 0, 1;
// Maska omrežja
unsigned char ipMask[4] = 255, 255, 255, 0;
// DNS IP naslov serverja, kamor se pošiljajo podatki
unsigned char dnsIpAddr[4] = 192, 168, 0, 2;
//*****************************************************************************************
// Splošna inicializacija programa.
// Nastavitev I/O, LCD-ja, I2C, posebnih znakov, etherneta,...
*******************************************************************************************
void Init()
char character1[] = 10,4,14,16,16,16,14,0; // Koda za zapis črke Č
char character2[] = 10,4,31,16,31,1,31,0; // Koda za zapis črke Š
char character3[] = 10,4,31,2,4,8,31,0; // Koda za zapis črke Ž
ADCON1 = 0x07; // Vsi pini so digitalni
CMCON = 0X07; // Izklop primerjalnika
Lcd_Init(); // Inicializacija LCD-ja
Lcd_Cmd(_LCD_CLEAR); // Pobriši LCD
Lcd_Cmd (_LCD_UNDERLINE_ON); // Vklopi mali (underline) kurzor
I2C1_Init (400000); // Inicializacija I2C
// Inicializacija in nastavitev ethernet omrežja
Ethernet_Init (myMacAddr, myIpAddr, Ethernet_FULLDUPLEX);
Delay_ms (2000);
Ethernet_confNetwork(ipMask, gwIpAddr, dnsIpAddr);
Delay_ms (2000);
Ethernet_Enable (_Ethernet_UNICAST);
Delay_ms(2000);
// Pregledamo kateri jezik je izbran. Informacija o izbranem jeziku se nahaja v EEPROM-u
na naslovu 0x1FF0.
// Če je vrednost 0xFF, pomeni, da je bil izbran slovenski jezik.
62
if (EE_Read_Random (0x1FF0) == 0xFF)
// Izbran je slovenski jezik, zato v LCD naložimo šumnike (Č, Š in Ž).
// Pričnemo shranjevati od naslova 0x01 dalje. Če bi shranili na naslov 0x00, se pri
// izpisu na LCD pojavi problem, ker bi compiler v polju zaznal znak null (0).
CustomChar (character1, 1); // Č je na naslovu 0x01
CustomChar (character2, 2); // Š je na naslovu 0x02
CustomChar (character3, 3); // Ž je na naslovu 0x03
//*****************************************************************************************
// Pregledamo, kateri senzorji, ki so trenutno shranjeni v EEPROM-u, se res nahajajo na
// 1wire vodilu. Če katerega izmed tistih ni, tisto lokacijo v EEPROM-u pobrišemo.
//*****************************************************************************************
void Pripravi_EE()
unsigned lokacija = 0x0000; // Lokacija EEPROM-a (na vsaki lokaciji je en ROM – en
// senzor)
char CRC; // Informacija o izračunu CRC-ja
// CRC = 0 (koda je veljavna oziroma lokacija je zasedena
// - polna)
// CRC != 0 (koda ni veljavna oziroma lokacija je prazna)
char polje[8]; // Začasno polje, ki hrani prebrano ID-naslov iz EEPROM-a
// za CRC preverjanje
char byte; // Števec bajtov
// Ponavljamo, dokler ne pregleda celotnega EEPROM-a (vseh lokacij). Od naslova 0x0FF0
// dalje je zadnja lokacija v EEPROM-u, ki je rezervirana za ID-je senzorjev.
while (lokacija <= 0x0FF0)
// Preberi lokacijo iz EEPROM-a (ROM enega senzorja)
for (byte = 0; byte < 8; byte++)
polje[byte] = EE_Read_Random (lokacija + byte);
Delay_ms (3); // Potrebna zakasnitev med bralnimi cikli
// Ko bo prebral vseh 8 bajtov ROM-a (64 bitov), gremo preverjat ali je koda
// pravilna oziroma ali se na tej sploh lokaciji nahaja senzor. To naredimo s
// pomočjo CRC algoritma.
if (byte == 7)
CRC = cal_crc (polje, byte);
if (CRC == 0)
// Pingamo senzor, da ugotovimo njegovo prisotnost
senzor_ping (polje, byte, lokacija);
lokacija = lokacija + 8; // Lokacije povečujemo za 8
63
//*****************************************************************************************
// FUNKCIJA ZA ZAPIS POSEBNIH ZNAKOV V LCD
//*****************************************************************************************
void CustomChar(char *character, char znak)
char i;
// CGRAM se začne na naslovu 0x40. Vsak znak pa zasede 1 bajt. 1. znak je torej na
// naslovu od 0x40 do 0x47, drugi od 0x48 do 0x50,... Mi smo začeli od naslova 0x48
// dalje, ker je drugače problem pri izpisovanju na LCD.
LCD_Cmd(0x40 + znak * 8) ; // Izračun naslova v CGRAM-u
for(i = 0 ; i <= 7 ; i++)
LCD_Chr_Cp(character[i]) ;
LCD_Cmd(_LCD_CLEAR);
//*****************************************************************************************
// GLAVNI PROGRAM
//*****************************************************************************************
void main()
char i, j;
Init(); // Splošna inicializacija programa. Nastavitev I/O, LCD-ja, etherneta,
// šumnikov in ostalih posebnih znakov,...
// Zanka za izpis teksta »Inicializacija...«
for (i = 0; i < 2; i++)
Lcd_Out (1, 2, "Inicializacija");
for (j = 0; j < 4; j++)
Lcd_Out (2, 7+j, ".");
Delay_ms (400);
Lcd_Cmd (_LCD_CLEAR); // Pobrišemo LCD zaslon
Meni(); // Kličemo funkcijo za prikaz menija
Pripravi_EE(); // Najprej pregledamo, kateri senzorji, ki so trenutno shranjeni v
// EEPROM-u, se res nahajajo na 1-wire vodilu. Če katerega izmed
// tistih ni, tisto lokacijo v EEPROM-u pobrišemo.
// Ko pregledamo celoten EEPROM, poženemo rutino za iskanje senzorjev na vodilu
Iskanje_senzor();
64
// Meritev temperature in komunikacija z ethernetom
Ethernet();
Podprogram za iskanje senzorjev na 1-wire vodilu
//*****************************************************************************************
// Ta podprogram najde vse priključene senzorje na 1-wire vodilu
//*****************************************************************************************
// Definicije
#define FALSE 0
#define TRUE 1
#define PIN 1 // Pin na katerega so priključeni senzorji
// Ta definicija se uporablja samo pri Ow_Read, Ow_Write in Ow_Reset
#define BPIN B1 // Pin na katerega so priključeni senzorji
// Ta pa se uporablja vsepovsod drugje
#define DQ PORTE // Port na katerega so priključeni senzorji
#define DQREG TRISE // Register na katerega so priključeni senzorji
// Deklaracije notranjih funkcij, ker jih uporabljamo znotraj glavne fukcije OW_Search
char OWFirst();
char OWNext();
char OWSearch();
// Deklaracija zunanjih funkcij. To so funkcije, ki se nahajajo v drugih datotekah
// (eksterne funkcije).
extern char Primerjaj_ROM (char buff[], char bajt);
extern char cal_crc (char buff[], char byte_num);
extern void Vnesi_ime (unsigned EE_lokacija);
// Globalne spremenljivke
char ROM_NO[8]; // Polje, ki vsebuje 8x8 bitov ROM kode
char LastDiscrepancy; // Podatek na katerem bitu je prišlo do zadnje razlike
bit LastDeviceFlag; // Zastavica, ki določa ali je iskanje končano
// Če je LastDeviceFlag = 1, se iskanje zaključi, saj zastavica
// označuje, da so vsi senzorji odkriti (najdeni)
//*****************************************************************************************
// Glavni funkcija v tem podprogramu
//*****************************************************************************************
void Iskanje_senzor()
char result; // Hrani rezultat o iskanju (TRUE ali FALSE)
// Sprožimo prvo iskanje, torej iskanje prvega senzorja
result = OWFirst();
while (result) // Če je spremenljivka result TRUE pomeni, da iskanje še ni
65
// končano in število senzorjev še ni končno. Če pa je FALSE, se
// while zanka zaključi in s tem tudi iskanje senzorjev
result = OWNext(); // Nadaljujemo z iskanjem senzorjev
return;
//*****************************************************************************************
// Funkcija, ki postavi 1- wire pin na nizko stanje
//*****************************************************************************************
void OW_Low()
DQ.BPIN = 0; // 1-wire pin = 0
DQREG.BPIN = 0; // 1-wire pin izhod
//*****************************************************************************************
// Funkcija, ki postavi 1- wire pin na visoko stanje
//*****************************************************************************************
void OW_High()
DQ.BPIN = 1; // 1-wire pin = 1
DQREG.BPIN = 1; // 1-wire pin vhod
//*****************************************************************************************
// 1-wire Read bit
// Prebere 1 bit iz 1-wire vodila
//*****************************************************************************************
char OW_Read_Bit()
OW_Low();
Delay_us(6);
OW_High();
Delay_us(4);
if (DQ.BPIN == 0)
Delay_us(50);
return (0);
else
Delay_us(50);
return (1);
66
//*****************************************************************************************
// 1- wire Write bit
// Senzorju pošlje vrednost 0 ali 1, odvisno od izbrane smeri
//*****************************************************************************************
void OW_Write_Bit (char bit_value)
if (bit_value == 1)
OW_Low();
Delay_us(6);
OW_High();
Delay_us(64);
else
OW_Low();
Delay_us(70);
OW_High();
Delay_us(10);
//*****************************************************************************************
// Funkcija za nastavitev 9-bitne resolucije DS18B20 senzorjev
//*****************************************************************************************
void Init_DS18B20(char koda[])
char i;
// Preverimo družino senzorja
if (koda[0] == 0x28)
Ow_Reset (&DQ, PIN); // Resetiramo vodilo
Ow_Write (&DQ, PIN, 0x55); // Sprožimo ukaz Match ROM
// Naslovimo senzor
for (i = 0; i < 8; i++)
Ow_Write (&DQ, PIN, koda[i]);
Ow_Write (&DQ, PIN, 0x4E); // Vpisovali bomo v scratchpad
Ow_Write (&DQ, PIN, 0x00); // Register 2
Ow_Write (&DQ, PIN, 0x00); // Register 3
Ow_Write (&DQ, PIN, 0x1F); // V konfiguracijski register vpišemo vrednost 0x1F, kar
// predstavlja 9-bitno resolucijo
// Vrednost registra je potrebno shraniti v EEPROM
Ow_Reset (&DQ, PIN);
Ow_Write (&DQ, PIN, 0x55); // Match ROM
// Naslovimo senzor
67
for (i = 0; i < 8; i++)
Ow_Write (&DQ, PIN, koda[i]);
Ow_Write (&DQ, PIN, 0x48); // Sprožimo ukaz Copy scratchpad
Ow_Reset (&DQ, PIN); // Resetiramo vodilo
Ow_Write (&DQ, PIN, 0x55); // Match ROM
// Naslovimo senzor
for (i = 0; i < 8; i++)
Ow_Write (&DQ, PIN, koda[i]);
Ow_Write (&DQ, PIN, 0xB8); // Sprožimo ukaz Recall EEPROM
Ow_Reset (&DQ, PIN); // Z resetiranjem vodila zaključimo komunikacijo
return;
//*****************************************************************************************
// Funkcija, ki poišče "prvi" senzor na 1-wire vodilu
// Vrne TRUE: Senzor najden, ROM številka --> ROM_NO polje
// FALSE: Ni senzorja
//*****************************************************************************************
char OWFirst()
// Registre postavimo na 0 (resetiramo)
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
return (OWSearch());
//*****************************************************************************************
// Najdi še preostale senzorje na 1-wire vodilu
// Vrne TRUE: Senzor najden, ROM številka --> ROM_NO polje
// FALSE: Ni senzorja, konec iskanja
//*****************************************************************************************
char OWNext()
// Iskanje naj se nadaljuje
return (OWSearch());
//*****************************************************************************************
// Izvaja iskanje senzorjev na 1-wire vodilu z uporabo obstoječih iskalnih stanj.
// Vrne TRUE: Senzor najden, ROM številka --> ROM_NO polje
// FALSE: Ni senzorja, konec iskanja
//*****************************************************************************************
68
char OWSearch()
char id_bit_number;
char last_zero, rom_byte_number;
bit search_result;
bit id_bit, cmp_id_bit;
char rom_byte_mask;
bit search_direction;
unsigned EE_lokacija = 0x0000; // EEPROM naslov kamor se shranjujejo ROM kode
char i; // Začasna spremenljivka
char CRC; // Informacija o izračunu CRC-ja
// CRC = 0 (lokacija je zasedena)
// CRC != 0 (lokacija je prazna)
char polje1[8]; // Začasno polje, ki hrani 8 bajtov prebranih iz
// EEPROM-a za preverjanje praznih in zasedenih
// lokacij
// Inicializacija registrov za iskanje
id_bit_number = 1; // Števec bitov (številka bita)
last_zero = 0; // Indikator, ki pove, pri katerem bitu je bila
// nazadnje izbrana pot 0
rom_byte_number = 0; // Števec pregledanih bajtov (64 bit = 8 byte)
rom_byte_mask = 1; // Maska s katero postavljamo ali brišemo ustrezni bit
// v ROM_NO polju
search_result = 0; // Rezultat iskanja (FALSE oz. 0 = Ni senzorja, TRUE
// oz. 1 = Senzor najden)
// Če zadnji klic za iskanje ni bil zadnji (torej še obstajajo neodkriti senzorji).
if (!LastDeviceFlag)
// Če ni odziva na reset signal pomeni, da na vodilu ni senzorjev.
// 0 - odziv je, 1 - ni odziva
if (Ow_Reset(&DQ, PIN))
// Registre postavimo na 0 (resetiramo)
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
return (FALSE);
// Pošlji ukaz za iskanje (Search ROM)
Ow_Write(&DQ, PIN, 0xF0);
// Zanka, ki izvaja iskanje senzorjev
do
// Preberi 1. in 2. bit (originalni in komplementiran bit)
id_bit = OW_Read_Bit();
cmp_id_bit = OW_Read_Bit();
69
// Preveri, če na vodilu slučajno ni senzorjev
if ((id_bit == 1) && (cmp_id_bit == 1))
break;
else
// Vsi senzorji imajo prebrana bita 0 ali 1
if (id_bit != cmp_id_bit)
search_direction = id_bit; // Izberi pot, ki je enaka vrednosti 1. bita. Ta
// bit se zapiše tudi v ROM_NO polje
else
// Prišlo je do razlike, zato izberemo isto pot (smer) kot pri zadnjem
// iskanju za isti bit
/*
id_bit_number > LastDiscrepancy : Izberi smer 0
id_bit_number = LastDiscrepancy : Izberi smer 1
id_bit_number < LastDiscrepancy : Izberi isto smer kot pri zadnjem
iskanju za isti bit
*/
if (id_bit_number < LastDiscrepancy)
search_direction =((ROM_NO[rom_byte_number] &
rom_byte_mask)>0);
else
// Izbrana pot je 1 ali 0, odvisno od zadnjega iskanja
search_direction = (id_bit_number == LastDiscrepancy);
// Če je bila izbrana pot 0, potem shrani ta položaj v spremenljivko
// LastZero
if (search_direction == 0)
last_zero = id_bit_number;
// Postavi ali zbriši bit v registru rom_byte_number s pomočjo maske
// rom_byte_mask
if (search_direction == 1)
ROM_NO[rom_byte_number] |= rom_byte_mask;
else
ROM_NO[rom_byte_number] &= ~rom_byte_mask;
// Najden bit (smer) pošljemo senzorjem. Tisti senzorji, ki imajo 1. bit enak
// temu, ki smo ga poslali mi, ostanejo v iskanju, drugi pa čakajo na reset
// signal (izpadejo iz igre) in začetek novega iskanja.
OW_Write_bit(search_direction);
// Povečaj števec id_bit_number za številko bita (pozicija bita) in pomakni
// register rom_byte_mask za 1 v levo (pomnožimo z 2)
70
id_bit_number++;
rom_byte_mask <<= 1;
// Če je maska 0 gremo na naslednji byte serijske številke in resetiramo masko.
// Ko pregledamo vseh 8 bitov v 1 bytu je maska zopet 0, ker
// je rom_byte_mask tipa int (8 bitov)
if (rom_byte_mask == 0)
rom_byte_number++; // Poveča število bajtov za 1
rom_byte_mask = 1; // Masko postavi zopet na 1 (na začetek)
while(rom_byte_number < 8); // Ponavljaj za vseh 8 bajtov (64 bitov)
// Če je bilo iskanje uspešno, potem postavi ustrezne zastavice
if (id_bit_number > 64)
// Iskanje je bilo uspešno zato postavi zastavice LastDiscrepancy, LastDeviceFlag
// in search_result
// Primerjamo, če se najdena ROM koda ujema s katero v EEPROM-u
if (Primerjaj_ROM (ROM_NO, 8) == 0) // Če se ROM kodi ne ujemata (vrednost == 0),
// potem gre za nov senzor 8 pomeni število
// bajtov
// Potrebno je najti eno prazno lokacijo v EEPROM-u na katero bomo shranili
// ROM kodo novega senzorja
while (EE_lokacija <= 0x0FF0) // Ponavljamo, dokler ne pregledamo celotnega
// (v bistvu skoraj polovice) EEPROM-a (vseh
// lokacij). Od naslova 0x0FF0 dalje je zadnja
// lokacija v EEPROM-u.
// Preberi lokacijo iz EEPROM-a (ROM enega senzorja)
for (i = 0; i < 8; i++) // i je števec bajtov od 0-7
polje1[i] = EE_Read_Random (EE_lokacija + i);
Delay_ms (3);
// Ko bo prebral vseh 8 bajtov ROM-a (64 bitov), gremo preverjati
// pravilnost kode s CRC-jem
CRC = cal_crc (polje1, 7); // 7 pomeni število
// bajtov od 0-7
if (CRC != 0)
71
// Lokacija je prazna. Na to lokacijo bomo shranili ROM novega
// senzorja in zanj izbrali ime. Potem pa izstopimo iz zanke while in
// nadaljujemo z iskanjem senzorjev.
for (i = 0; i < 8; i++)
EE_Write_byte (ROM_NO[i], EE_lokacija + i);
Delay_ms(3);
// Za najden senzor izberemo ime. V funkcijo prenesemo podatek o
// lokaciji EEPROM-a, kamor smo vpisali ID naslov.
Vnesi_ime(EE_lokacija);
break;
// Lokacija je zasedena oziroma se na njej že nahaja senzor.
// Gremo na naslednjo lokacijo
EE_lokacija = EE_lokacija + 8; // Lokacije povečujemo za 8 (bajtov)
Init_DS18B20(ROM_NO); // Nastavimo resolucijo senzorjev
LastDiscrepancy = last_zero;
// Preveri, če je to zadnji senzor
if (LastDiscrepancy == 0)
LastDeviceFlag = TRUE;
search_result = TRUE;
// Če senzor ni najden, potem resetiraj števce, ker bo naslednje iskanje spet prvo
if (!search_result)
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
search_result = FALSE;
return (search_result);
72
CRC algoritem – preverjanje pravilnosti naslovov ID
//*****************************************************************************************
// Podprogram za CRC preverjanje ID-jev. Podprogram sprejme ID naslov (8
// bajtov) ter število bajtov, ki jih bomo preverjali.
// Kot rezultat pa vrne 0, če je ID v redu, drugače pa vrne neko
// naključno število, ki je različno od 0.
//*****************************************************************************************
char cal_crc (char buff[], char byte_num)
char shift_reg=0, data_bit, sr_lsb, fb_bit, i, j;
for (i=0; i <= byte_num; i++) /* za vsak byte */
for(j = 0; j < 8; j++) /* za vsak bit bit */
data_bit = (buff[i]>>j)&0x01;
sr_lsb = shift_reg & 0x01;
fb_bit = (data_bit ^ sr_lsb) & 0x01;
shift_reg = shift_reg >> 1;
if (fb_bit)
shift_reg = shift_reg ^ 0x8C;
return (shift_reg);
//*****************************************************************************************
// Podprogram s katerim preverimo prisotnost obstoječih (starih)
// senzorjev na vodilu.
//*****************************************************************************************
#define FALSE 0
#define TRUE 1
#define PIN 1 // Pin na katerega so priključeni senzorji
// Ta definicija se uporablja samo pri Ow_Read, Ow_Write in Ow_Reset
#define BPIN B1 // Pin na katerega so priključeni senzorji
// Ta pa se uporablja vsepovsod drugje
#define DQ PORTE // Port na katerega so priključeni senzorji
#define DQREG TRISE // Register na katerega so priključeni senzorji
void senzor_ping (char buff[], char byte_number, unsigned naslov)
char i;
Ow_Reset (&DQ, PIN);
Ow_Write (&DQ, PIN, 0x55); // Nslovimo kateri senzor želimo pingati (Match ROM)
73
// Naslavljanje senzorja
for (i = 0; i <= byte_number; i++)
Ow_Write (&DQ, PIN, buff[i]);
Delay_us (5);
// Izvedemo funkcijo branja, da vidimo, če se senzor odzove (Read Scratchpad)
Ow_Write (&DQ, PIN, 0xBE);
for (i = 0; i <=8; i++) // Scratchpad ima 9 bajtov
// Preberemo 1 bajt iz scratchpada in ga primerjamo z 0xFF
// Ali se je senzor odzval? (vrednost različna od FF)
if (Ow_Read (&DQ, PIN) != 0xFF)
// Ja, senzor se je odzval (vrednost različna od FF), zato nadaljujemo s
// preverjanjem lokacij (izstop iz rutine).
break;
// Ne, senzor se ni odzval. Torej ga ni na vodilu. Smo pregledali že vse bajte? Če
// smo, lahko to lokacijo v EEPROM-u pobrišemo. Prav tako pobrišemo lokacijo v 2.
// polovici EE, kjer je zapisano njegovo ime.
if (i = 8)
for (i = 0; i < 8; i++)
EE_Write_byte (0xFF, naslov + i); // Na to lokacijo zapišemo vrednost FF
// (zbrišemo ID senzorja)
Delay_ms (3);
EE_Write_byte (0xFF, naslov + i + 0x0FF8);
Delay_ms (3);
// 0x0FF8 zato, ker je EE razdeljen na polovico in je začetek 2. polovice na
// naslovu 0x0FF8 (zbrišemo ime senzorja). Spremenljivka naslov nosi podatek
// o lokaciji v EEPROM-u. Povečuje se za 8 (0, 8, 16,...)
return;
Podprogram za medsebojno primerjanje naslovov ID
//*****************************************************************************************
// Podprogram bere ROM-kode iz EEPROM-a (bajt po bajt) in jih primerja z
// ROM kodo, ki jo prenesemo v funkcijo. Kot rezultat pa vrne 1, če je
// ROM koda bila najdena v EEPROM-u, v nasprotnem primeru vrne 0.
//*****************************************************************************************
74
char Primerjaj_ROM (char buff[], char bajt)
signed char i;
unsigned EE_lokacija = 0x0000; // Lokacijo v EEPROM-u nastavimo na začetek
char array[8]; // V to polje shranimo ID prebran iz EEPROM-a
// Primerjamo, če se najdena ROM koda ujema s katero v EEPROM-u
for (i = 0; i < bajt; i++) // i je števec bajtov
// Preberemo bajt iz EEPROM-a
array[i] = EE_Read_Random (EE_lokacija + i);
Delay_ms(3);
// In ga primerjamo z najdenim
if (buff[i] != array[i])
// Smo že pregledali cel EEPROM?
// Od naslova 0x0FF0 dalje je zadnja lokacija v EEPROM-u
if (EE_lokacija >= 0x0FF0)
return (0);
EE_lokacija = EE_lokacija + 8; // Skočimo na začetek naslednje lokacije
i = -1; // Resetiramo števec bajtov. -1 zato, ker se i
// poveča ob koncu stavka for.
return (1); // Senzor se ujema, rezultat je 1.
Podprogram za vnašanje imen senzorjev
//*****************************************************************************************
// Funkcija, v kateri vnesemo ime senzorja s pomočjo tipk (gor, dol, levo, desno in
// enter).
// Funkcionalnost tipk:
// gor - se pomikamo po abecedi navzgor
// dol - se pomikamo po abecedi navzdol
// levo - pomik med znaki levo
// desno - pomik med znaki desno
// enter - potrditev vnosa
//*****************************************************************************************
#define FALSE 0
#define TRUE 1
// Deklaracija zunanjih funkcij
extern char Beri_tipke ();
75
// Inicializacija polja jezikov (znakov abecede)
char slovenian[37] = 'A','B','C',0x01,'D','E','F','G','H','I','J','K','L','M','N','O','P',
'R','S',0x02,'T','U','V','Z',0x03,'0','1','2','3','4','5','6','7','8','9',' ','\0';
char english[38] = 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q',
'R','S','T','U','V','W','X','Y','Z','0','1','2','3','4','5','6','7', '8','9',' ','\0';
char slovenski = FALSE; // Zastavica, ki označuje ali je izbran slovenski jezik
// TRUE – je izbran, FALSE – ni izbran
char angleski = TRUE; // Zastavica, ki označuje ali je izbran angleški jezik
// Funkcija za vnos imena
void Vnos_imena (char crke[], char st_crk, unsigned EE_lokacija)
char i; // Začasni števec
char besedilo[9]; // Polje, ki vsebuje vneseno ime (znake) - 8 znakov in
// znak za konec besede ('\0')
char index = 0; // Index polja znakov ("kazalec" na črko v abecedi)
char pozicija = 1; // Števec, ki označuje pozicijo kurzorja na zaslonu
char izbira; // Hrani informacijo katera tipka je bila pritisnjena
// Pobrišemo polje besedilo
for (i = 0; i < 9 ; i++)
besedilo[i] = 0;
do
Lcd_Chr (2, pozicija, crke[index]); // Izpis trenutne črke
Lcd_Cmd (_LCD_MOVE_CURSOR_LEFT);
// Izpisan znak shranimo tudi v polje besedilo
besedilo[pozicija - 1] = crke[index]; // -1 zaradi tega, ker se pozicija začne
// od 1
izbira = Beri_tipke (); // Pogledamo, katera tipka jepritisnjena
switch (izbira)
case 1: // Tipka dol
// Poišči kakšen index ima trenutni znak v abecedi. To je znak,
// kamor kaže pozicija v polju besedilo oziroma, kjer se nahaja
// kurzor na LCD-ju.
for (i = 0; i < st_crk; i++)
if (crke[i] == besedilo[pozicija - 1])
index = i;
76
// Smo na začetku polja (abecede)?
if (index == 0)
// Da, skočimo na konec (index postavimo na konec)
index = st_crk - 2;
// Izpišemo znak
Lcd_Chr (2, pozicija, crke[index]);
Lcd_Cmd (_LCD_MOVE_CURSOR_LEFT);
break;
index = index - 1; // Ne, nismo na začetku. Zato zmanjšamo index
// za 1.
Lcd_Chr (2, pozicija, crke[index]);
Lcd_Cmd (_LCD_MOVE_CURSOR_LEFT); // Kurzor levo
break;
case 2: // Tipka gor
// Poiščemo kakšen index ima prebrana črka
for (i = 0; i < st_crk; i++)
if (crke[i] == besedilo[pozicija - 1])
// Postavimo index trenutne prebrane črke
index = i;
// Smo na koncu polja?
if (index == st_crk -2)
// Da, skočimo na začetek (index postavimo na začetek)
index = 0;
// Izpišemo znak
Lcd_Chr (2, pozicija, crke[index]);
Lcd_Cmd (_LCD_MOVE_CURSOR_LEFT);
break;
index = index + 1; // Ne, nismo na koncu. Zato povečamo index za
// 1.
Lcd_Chr (2, pozicija, crke[index]);
Lcd_Cmd (_LCD_MOVE_CURSOR_LEFT);
break;
case 3: // Tipka enter
// Imena senzorjev moramo shraniti v EEPROM, da si jih zapomni
// tudi po izklopu napajanja. Prva lokacija je na naslovu 0x0FF8.
besedilo[pozicija] = '\0'; // Na konec besede dodamo znak za
77
// konec besede (ničelni znak)
for (i = 0; besedilo[i] != '\0'; i++)
EE_Write_byte (besedilo[i], EE_lokacija + i + 0x0FF8);
Delay_ms (3);
Lcd_Cmd (_LCD_CLEAR);
break;
case 4: // Tipka levo
if (pozicija == 1) // Smo na začetku (na prvem znaku izbranega
// imena)?
break; // Da, zaključimo (ostanemo na istem mestu) in
// nadaljujemo z branjem tipk
// Pomaknemo kurzor v levo
Lcd_Cmd (_LCD_MOVE_CURSOR_LEFT);
pozicija = pozicija - 1; // Takoj zmanjšamo števec pozicije
// znaka za 1
// Ugotovimo index že izpisane črke, da nadaljujemo od te črke in
// ne od začetka (črka A)
for (i = 0; i < st_crk - 1; i++)
if (besedilo[pozicija-1] == crke[i])
index = i;
break;
case 5: // Tipka desno
if (pozicija == 8) // Omejitev vnosa imena na 8 znakov
break;
// Pomaknem kurzor v desno
Lcd_Cmd (_LCD_MOVE_CURSOR_RIGHT);
pozicija = pozicija + 1; // Takoj povečam števec pozicije znaka
// za 1
Ugotovimo indeks črke.
for (i = 0; i < st_crk - 1; i++)
if (besedilo[pozicija-1] == crke[i])
index = i;
break;
78
index = 0;
break;
while (izbira != 3); // Ponavljaj dokler ni pritisnjena tipka enter (case 3)
return;
//*****************************************************************************************
// Glavna funkcija v tem podprogramu.
// Imena bomo vnašali v jeziku, ki je izbran v nastavitvah. Po privzetem
// načinu je to slovenščina.
//*****************************************************************************************
void Vnesi_ime (unsigned EE_lokacija)
// Preberemo vrednost na naslovu 0x0F Če je vrednost 0xFF, pomeni, da je bil izbran
// slovenski jezik
if (EE_Read_Random (0x1FF0) == 0xFF)
Lcd_Out (1, 1, "Vnesi ime:");
Vnos_imena (slovenian, 37, EE_lokacija);
// Če je vrednost 0xFE, pomeni, da je bil izbran angleški jezik
if (EE_Read_Random (0x1FF0) == 0xFE)
Lcd_Out (1, 1, "Enter name:");
Vnos_imena (english, 38, EE_lokacija);
return;
Podprogram za prikazovanje in navigacijo po meniju
// Deklaracija zunanjih funkcij
extern char Beri_tipke();
// Deklaracija prototipnih funkcij
void f_Nastavitve(char polje[][16]);
void f_Menjaj();
void f_Jezik(char polje[][16]);
char Premakni (char *vrstica, char *stevec_besed, char *st_besed, char array[][16]);
// Deklaracija spremenljivk
char izbira; // Informacija o pritisnjeni tipki
79
char vrstica; // Števec vrstic, v katero naj se na LCD izpiše beseda.
char i, j; // Začasni spremenljivki
char st_besed; // Števec števila besed v polju
char stevec_besed; // Števec izpisanih besed na LCD (iz polja)
// Deklaracija polj (menijske možnosti)
char glavni_meni[][16] = "Nastavitve", "Zagon";
char main_menu[][16] = "Setup", "Start";
char nastavitve[][16] = "Zamenjaj senzor", "Jezik";
char setup[][16] = "Replace sensor", "Language";
char jezik[][16] = "Slovenski", 'A','n','g','l','e',0x02,'k','i','\0';
char language[][16] = "Slovenian", "English";
//*****************************************************************************************
//
// FUNKCIJA ZA PREMIKANJE PO MENIJU
//
//*****************************************************************************************
char Premakni (char *vrstica, char *stevec_besed, char *st_besed, char array[][16])
do
// Preberemo, katera tipka je bila pritisnjena
izbira = Beri_tipke ();
switch (izbira)
// Ali je pritisnjena TIPKA DOL?
case 1:
// Smo na koncu tabele?
if (*stevec_besed == *st_besed -1)
// Ja, resetiramo vse števce in se vrnemo na začetek glavnega menija
Lcd_Cmd (_LCD_CLEAR); // Pobriši LCD
*vrstica = 1; // Števec vrstic postavimo nazaj na 1
*stevec_besed = 0; // Števec besed postavimo postavimo na 0
return 1;
// Ali smo v 1. vrstici?
if (*vrstica == 1)
// Ja, zato se pomaknemo v drugo vrstico in nastavimo vrednosti števcev
Lcd_Cmd (_LCD_SECOND_ROW);
*vrstica = 2;
*stevec_besed = *stevec_besed + 1;
break;
// Ali sem v 2. vrstici?
80
if (*vrstica == 2)
// Ker je bila pritisnjena tipka dol in smo se nahajali v drugi
// vrstici, se je potrebno vrniti nazaj na prvo in resetirati ustrezne
// števce
Lcd_Cmd (_LCD_CLEAR);
*vrstica = 1;
*stevec_besed = *stevec_besed + 1;
return 1; // Izhod iz te funkcije. Izpisati moramo naslednjo besedo
// Ali je pritisnjena TIPKA GOR?
case 2:
// Ali smo v 1. vrstici?
if (*vrstica == 1)
// Smo na začetku tabele?
if (*stevec_besed == 0)
// Ja. Pregledati moramo ali je število besed v tabeli sodo ali
// liho, da na podlagi tega nastavimo števec besed.
if ((*st_besed % 2) == 0)
// Število besed je sodo. Števec besed nastavimo na predzadnjo
// besedo v tabeli ter izpišemo predzadnjo in zadnjo besedo. Nato
// pa se postavimo v 2. vrstico.
*stevec_besed = *st_besed - 2; // -2 zato, ker se besede začno
// šteti od 0
Lcd_Cmd (_LCD_CLEAR);
for (j = 0; j < 2; j++)
for (i = 0; array[*stevec_besed][i] != '\0'; i++)
Lcd_Chr (*vrstica, 1+i, array[*stevec_besed][i]);
*vrstica = *vrstica + 1;
*stevec_besed = *stevec_besed + 1;
Lcd_Cmd (_LCD_SECOND_ROW);
*vrstica = 2;
*stevec_besed = *stevec_besed -1;
break; // Izhod iz stavka switch. Nadaljujemo z branjem tipk.
// Število besed je liho. Števec nastavimo na zadnjo besedo v tabeli
// in jo izpišemo.
*stevec_besed = *st_besed -1;
Lcd_Cmd (_LCD_CLEAR);
for (i = 0; array[*stevec_besed][i] != '\0'; i++)
81
Lcd_Chr (*vrstica, 1+i, array[*stevec_besed][i]);
Lcd_Cmd (_LCD_FIRST_ROW);
break; // Izhod iz stavka switch. Nadaljujemo z branjem tipk.
// Nismo na začetku tabele. Števec besed zmanjšamo za 2 in izpišemo
// predhodni 2 besedi (ker je bila pritisnjena tipka gor).
// Nahajamo se še v 1. vrstici
*stevec_besed = *stevec_besed - 2;
Lcd_Cmd (_LCD_CLEAR);
for (j = 0; j < 2; j++)
for (i = 0; array[*stevec_besed][i] != '\0'; i++)
Lcd_Chr (*vrstica, 1+i, array[*stevec_besed][i]);
*vrstica = *vrstica + 1;
*stevec_besed = *stevec_besed + 1;
Lcd_Cmd (_LCD_SECOND_ROW);
*vrstica = 2;
*stevec_besed = *stevec_besed - 1;
break;
// Ali smo v 2. vrstici?
if (*vrstica == 2)
Lcd_Cmd (_LCD_FIRST_ROW); // Pomakni se v 1. vrstico
*vrstica = 1;
*stevec_besed = *stevec_besed - 1;
break;
// Ali je pritisnjena TIPKA ENTER?
case 3:
Lcd_Cmd (_LCD_CLEAR);
break;
// Ali je pritisnjena TIPKA ENTER?
case 4:
Lcd_Cmd (_LCD_CLEAR);
return;
// Ponavljamo tako dolgo, dokler ni pritisnjena tipka enter
while (izbira != 3);
82
//*****************************************************************************************
// NASTAVITVE
// (podmeni nastavitve)
// Zamenjaj senzor
// Jezik
// Shrani podatke
//*****************************************************************************************
void f_Nastavitve(char polje[][16])
st_besed = 2; // Nastavimo število besed v meniju
vrstica = 1; // Resetiramo števec vrstic
stevec_besed = 0; // Resetiramo števec izpisanih besed
do
for (j = 0; j < 2; j++) // Zanka za izpis dveh vrstic
for (i = 0; polje[stevec_besed][i] != '\0'; i++)
Lcd_Chr (vrstica, 1+i, polje[stevec_besed][i]);
// Smo že na koncu tabele?
if (stevec_besed == st_besed - 1) // -1 zaradi tega, ker začnemo od 0
// Ja, smo na koncu. Najprej povečamo števec za 1 (če je izpisana samo ena
// beseda), ker ga pri izhodu iz zanke for zmanjšamo za 1. Torej se nam
// števec ne spremeni. Nato pa gremo brati tipke.
if (j == 0)
stevec_besed++;
break;
// Smo že izpisali 2 vrstici?
if (vrstica == 2)
break; // Ja, izhod iz zanke for brez povečanja števcev
// Ne, nismo na koncu. Povečamo števec besed in vrstic.
stevec_besed++;
vrstica++;
// Izpisali smo že 2 vrstici ali pa smo na koncu tabele (torej izpisali zadnjo
// vrstico v tabeli)
Lcd_Cmd (_LCD_FIRST_ROW); // Pomik v prvo vrstico
vrstica = 1;
stevec_besed--;
83
// Gremo brati tipke.
izbira = Premakni (&vrstica, &stevec_besed, &st_besed, polje);
// Če je pritisnjen tipka LEVO se vrnemo v GLAVNI MENI
if (izbira == 4)
return;
while (izbira != 3); // Ponavljamo, dokler ni pritisnjena tipka enter
stevec_besed = stevec_besed + 1; // Ker števec začne šteti pri 0, mu je na koncu (ko
// je pritisnjen enter) potrebno prišteti 1.
// Katera beseda iz tabele je bila izbrana?
switch (stevec_besed)
// 1. beseda v tabeli (ZAMENJAJ SENZOR)
case 1:
f_Menjaj (); // Funkcija, ki med seboj zamenja dva senzorja
break;
// 2. beseda v tabeli (JEZIK)
case 2:
if (EE_Read_Random (0x1FF0)== 0xFF)
f_Jezik (jezik); // Izbran jezik je slovenščina
break;
if (EE_Read_Random (0x1FF0)== 0xFE)
f_Jezik (language); // Izbran jezik je angleščina
break;
return;
//*****************************************************************************************
// ZAMENJAJ SENZOR
//
// Funkcija zamenjaj senzor izpiše na LCD vsa shranjena imena v EEPROM-u.
// Nato pa uporabnik izbere eno ime s katerim želi senzor zamenjati.
//*****************************************************************************************
void f_Menjaj ()
char i, j; // Začasni spremenljivki
unsigned EE_naslov1; // Naslov EEPROM-a kamor se vpiše beseda za zamenjavo.
84
char EE_prazen = 0; // Števec praznih lokacij v EEPROM-u
char menjaj_ime; // Informacija katero besedo (senzor) želimo zamenjati
char menjaj_z; // Informacija s katero besedo (senzorjem) želimo
// zamenjati besedo (senzor), na katero kaže
// spremenljivka menjaj_ime
unsigned EE_naslov = 0x0FF8; // Nastavimo začetni naslov v EEPROM-u, kjer so
// shranjena imena senzorjev
char besedilo[100][16]; // Polje v katerega preberemo shranjena imena v
// EEPROM-u. Max št. senzorjev je 100 zaradi omejitve
// EEPROM-a, 16 pa pomeni max. št. znakov
st_besed = 0; // Števec prebranih besed iz EEPROM-a. Označuje
// maksimalno število besed v polju
vrstica = 1; // Resetiramo števec vrstic
stevec_besed = 0; // Resetiramo števec izpisanih besed
// na LCD
// Najprej preberemo v polje vsa shranjena imena iz EEPROM-a. Na koncu vsakega imena
// dodamo še ničelni znak ('\0'), ki označuje konec besede. Pregledamo cel EEPROM,
// razen zadnji dve lokaciji. Ti dve lokaciji sta rezervirani za druge informacije
// (jezik,...).
while (EE_naslov <= 0x1FE8) // 0x1FE8 je zadnja lokacija na kateri je lahko shranjeno
// ime. Zadnji dve lokaciji sta namenjeni drugim
// informacijam (jezik,...)
// V polje besedilo preberemo vsa imena, ki so shranjena v EEPROM-u.
for (i = 0; i < 8; i++)
besedilo[st_besed][i]= EE_Read_Random (EE_naslov + i);
Delay_ms (3);
// Ko je prebrana vrednost enaka FF, pomeni, da smo na koncu besede, zato
// skočimo na naslednjo lokacijo.
if (besedilo[st_besed][i] == 0xFF)
break;
// Če je že prvi prebrani znak iz lokacije enak FF, potem na tem naslovu ni
// shranjenega nobenega imena, zato končamo s pregledovanjem (skočimo na labelo
// loop).
if (besedilo[st_besed][0] == 0xFF)
EE_prazen++; // Povečamo števec praznih lokacij v EEPROM-u
goto loop;
besedilo[st_besed][i] = '\0'; // Na koncu prebrane besede dodamo še ničelni znak,
// ki označuje konec besede.
st_besed++; // Povečamo število prebranih besed
loop: EE_naslov = EE_naslov + 8; // Povečamo naslov na naslednjo lokacijo
85
// Če so vse lokacije v EEPROM-u prazne, potem na vodilu ni senzorjev, kar javimo s
// tekstom »Ni senzorjev«
if (EE_prazen == 100) // 100 je število lokacij v EEPROM-u.
if (EE_Read_Random (0x1FF0) == 0xFF)
Lcd_Out (1, 1, "Ni senzorjev!");
if (EE_Read_Random (0x1FF0) == 0xFE)
Lcd_Out (1, 1, "No sensors!");
Delay_ms (1000);
return;
// Napis, ki se pojavi pred izpisom imen na LCD.
for (i = 0; i < 2; i++)
if (EE_Read_Random (0x1FF0) == 0xFF)
Lcd_Out (1, 1, "Izberi 1. senzor");
if (EE_Read_Random (0x1FF0) == 0xFE)
Lcd_Out (1, 1, "Choose 1. sensor");
for (j = 0; j < 4; j++)
Lcd_Out (2, 7+j, ".");
Delay_ms (400);
Lcd_Cmd (_LCD_CLEAR);
// Ko preberemo vsa shranjena imena, jih izpišemo še na LCD.
do
for (j = 0; j < 2; j++) // Zanka za izpis dveh vrstic
for (i = 0; besedilo[stevec_besed][i] != '\0'; i++)
Lcd_Chr (vrstica, 1+i, besedilo[stevec_besed][i]);
// Smo že na koncu tabele?
if (stevec_besed == st_besed - 1) // -1 zaradi tega, ker začnemo šteti od 0
// Ja, smo na koncu. Najprej povečamo števec za 1 (če je izpisana samo ena
86
// beseda), ker ga pri izhodu iz zanke for zmanjšamo za 1. Torej se nam
// števec ne spremeni. Nato pa gremo brati tipke.
if (j == 0)
stevec_besed++;
break;
// Smo že izpisali 2 vrstici?
if (vrstica == 2)
break; // Ja, izhod iz zanke for brez povečanja števcev
// Ne, nismo na koncu. Povečaj števec besed in vrstic.
stevec_besed++;
vrstica++;
// Izpisali smo že 2 vrstici ali pa smo na koncu tabele (torej izpisali zadnjo
// vrstico v tabeli)
Lcd_Cmd (_LCD_FIRST_ROW); // Pomik v prvo vrstico
vrstica = 1;
stevec_besed--;
// Gremo brati tipke.
izbira = Premakni (&vrstica, &stevec_besed, &st_besed, besedilo);
// Če je pritisnjena tipka LEVO se vrnemo v GLAVNI MENI
if (izbira == 4)
return;
while (izbira != 3); // Ponavljamo, dokler ni pritisnjena tipka enter
menjaj_ime = stevec_besed; // Shranimo podatek kateri senzor želim zamenjati.
// stevec_besed hrani informacijo (številko) katera
// beseda v polju je bila izbrana
// Napis, ki se pojavi pred izpisom imen na LCD.
for (i = 0; i < 2; i++)
if (EE_Read_Random (0x1FF0) == 0xFF)
Lcd_Out (1, 1, "Izberi 2. senzor");
if (EE_Read_Random (0x1FF0) == 0xFE)
Lcd_Out (1, 1, "Choose 2. sensor");
for (j = 0; j < 4; j++)
87
Lcd_Out (2, 7+j, ".");
Delay_ms (400);
Lcd_Cmd (_LCD_CLEAR);
// Še enkrat moramo izpisati vsa prebrana imena, da izberemo, s katerim senzorjem želimo
// zamenjati prej izbrani senzor.
vrstica = 1; // Resetiramo števec vrstic
stevec_besed = 0; // Resetiramo števec izpisanih besed na LCD
do
for (j = 0; j < 2; j++) // Zanka za izpis dveh vrstic
for (i = 0; besedilo[stevec_besed][i] != '\0'; i++)
Lcd_Chr (vrstica, 1+i, besedilo[stevec_besed][i]);
// Smo že na koncu tabele?
if (stevec_besed == st_besed - 1) // -1 zaradi tega, ker začnemo šteti od 0
// Ja, smo na koncu. Najprej povečamo števec za 1 (če je izpisana samo ena
// beseda), ker ga pri izhodu iz zanke for zmanjšamo za 1. Torej se nam
// števec ne spremeni. Nato pa gremo brati tipke.
if (j == 0)
stevec_besed++;
break;
// Smo že izpisali 2 vrstici?
if (vrstica == 2)
break; // Ja, izhod iz zanke for brez povečanja števcev
// Ne, nismo na koncu. Povečamo števec besed in vrstic.
stevec_besed++;
vrstica++;
// Izpisali smo že 2 vrstici ali pa smo na koncu tabele (torej izpisali zadnjo
// vrstico v tabeli)
Lcd_Cmd (_LCD_FIRST_ROW); // Pomik v prvo vrstico
vrstica = 1;
stevec_besed--;
88
// Gremo brati tipke.
izbira = Premakni (&vrstica, &stevec_besed, &st_besed, besedilo);
// Če je pritisnjena tipka LEVO se vrnemo v GLAVNI MENI
if (izbira == 4)
return;
while (izbira != 3);
menjaj_z = stevec_besed; // Podatek s katerim senzorjem želimo zamenjati prej
// izbranega
// Če se vrednosti ujemata, potem smo za zamenjavo izbrali isto ime. Torej, se nič ne
// spremeni. Ostane enako kot je bilo.
if (menjaj_ime == menjaj_z)
return;
// Obe izbrani besedi poiščemo v EEPROM-u, da ugotovimo na kateri lokaciji se nahajata.
// Najprej za prvo besedo. Tisto, katero hočemo zamenjati.
EE_naslov = 0x0FF8;
while (EE_naslov <= 0x1FE8) // Pregledamo vse lokacije, kjer se lahko nahajajo
// imena senzorjev
// Ponavljamo do konca besede
for (i = 0; besedilo[menjaj_ime][i] != '\0'; i++)
// Če se znaka na ujemata, skočimo na naslednjo lokacijo
if (EE_Read_Random (EE_naslov + i) != besedilo[menjaj_ime][i])
EE_naslov = EE_naslov + 8; // Povečamo naslov na naslednjo lokacijo
break;
Delay_ms (3);
// Ko besedo najdemo zaključimo s pregledovanjem
if (besedilo[menjaj_ime][i] == '\0')
break;
// Vse skupaj ponovimo še za drugo besedo. Tisto, s katero hočemo zamenjati prej
// izbrano.
EE_naslov1 = 0x0FF8;
while (EE_naslov1 <= 0x1FE8)
for (i = 0; besedilo[menjaj_z][i] != '\0'; i++)
89
if (EE_Read_Random (EE_naslov1 + i) != besedilo[menjaj_z][i])
EE_naslov1 = EE_naslov1 + 8;
break;
Delay_ms (3);
if (besedilo[menjaj_z][i] == '\0')
break;
// Spodnja koda ne naredi nič drugega kot to, da v EEPROM-u med seboj zamenja dve imeni,
// ki smo jih izbrali. V EEPROM shranimo ime, s katerim želimo zamenjati senzor. In
// sicer na naslov, kjer se nahaja tisti, ki smo ga izbrali za zamenjavo.
for (i = 0; besedilo[menjaj_z][i] != '\0'; i++)
// Znake vpisujemo tako dolgo, dokler ne pridemo do ničelnega znaka, ki označuje
// konec besede
EE_Write_byte (besedilo[menjaj_z][i], EE_naslov + i);
Delay_ms (3);
// Če sta besedi različno dolgi, potem je potrebno pri tisti, ki je krajša in se
// zapisuje na lokacijo, kjer je shranjena daljša beseda, ostanek znakov pobrisati. To
// naredi spodnji stavek if. Če je i (števec zanakov) manjši od 8 (max. št. znakov),
// potem na ta mesta vpišemo vrednost 0xFF, kar označuje prazna mesta v EEPROM-u.
if (i < 8)
for (j = i; j < 8; j++)
EE_Write_byte (0xFF, EE_naslov + j); // krat 8 zato, da dobimo naslov lokacije.
// Npr. če je menjaj_ime = 2, potem je
// naslov 2*8 je 16 (desetiško) oziroma 10
//(hexa), kar je tretja lokacija v EEPROM.
Delay_ms (3);
// V EEPROM shranimo ime, ki smo ga izbrali za zamenjavo. In sicer na naslov, kjer se
// nahaja tisti, s katerim ga želimo zamenjati.
for (i = 0; besedilo[menjaj_ime][i] != '\0'; i++)
EE_Write_byte (besedilo[menjaj_ime][i], EE_naslov1 + i);
Delay_ms (3);
if (i < 8)
for (j = i; j < 8; j++)
90
EE_Write_byte (0xFF, EE_naslov1 + j);
Delay_ms (3);
return;
//*****************************************************************************************
// JEZIK
// (podmeni jezik)
// Funkcija jezik shrani informacijo o izbranem jeziku v EEPROM. Po
// privzetem načinu je izbran jezik slovenščina.
//
// ANGLEŠKI
// SLOVENSKI
//*****************************************************************************************
void f_Jezik (char polje[][16])
st_besed = 2; // Nastavimo število besed v meniju
vrstica = 1; // Resetiram števec vrstic
stevec_besed = 0; // Resetiram števec izpisanih besed (kazalec)
do
for (j = 0; j < 2; j++) // Zanka za izpis dveh vrstic
for (i = 0; polje[stevec_besed][i] != '\0'; i++)
Lcd_Chr (vrstica, 1+i, polje[stevec_besed][i]);
// Smo že na koncu tabele?
if (stevec_besed == st_besed - 1) // -1 zaradi tega, ker začnem šteti od 0
// Ja, smo na koncu. Najprej povečamo števec za 1 (če je izpisana samo ena
// beseda), ker ga pri izhodu iz zanke for zmanjšamo za 1. Torej se nam
// števec ne spremeni. Nato pa gremo brati tipke.
if (j == 0)
stevec_besed++;
break;
// Smo že izpisali 2 vrstici?
if (vrstica == 2)
break; // Ja, izhod iz zanke for brez povečanja števcev
// Ne, nismo na koncu. Povečamo števec besed in vrstic.
91
stevec_besed++;
vrstica++;
// Izpisali smo že 2 vrstici ali pa smo na koncu tabele (torej izpisali zadnjo
// vrstico v tabeli)
Lcd_Cmd (_LCD_FIRST_ROW); // Pomik v prvo vrstico
vrstica = 1;
stevec_besed--;
// Gremo brati tipke.
izbira = Premakni (&vrstica, &stevec_besed, &st_besed, polje);
// Če je pritisnjena tipka LEVO se vrnemo v GLAVNI MENI
if (izbira == 4)
return;
while (izbira != 3);
stevec_besed = stevec_besed + 1; // Ker števec začne šteti pri 0, mu je na koncu (ko
// je pritisnjen enter) potrebno prišteti 1
// Katera beseda iz tabele je bila izbrana?
switch (stevec_besed)
// 1. beseda v tabeli (Slovenščina)
case 1:
// V EEPROM-u na lokaciji 0x1FF0, kjer se nahaja informacija o jeziku,
// postavimo vse bite. Torej:
// 1111 1111 - Slovenski jezik (FF hex)
// 1111 1110 - Angleški jezik (FE hex)
// 1111 1101 - Jekiz x (FD hex)
// 1111 1011 - Jezik y (FB hex)
// Za vsak naslednji jezik pobrišemo naslednji bit od desne proti levi.
// Slovenski jezik ima kodo FF zato, ker so po defaultu to tudi vrednosti
// zapisane v EEPROM-u in je tako slovenski jezik privzeti jezik.
EE_Write_byte (0xFF, 0x1FF0);
break;
// 2. beseda v tabeli (Angleščina)
case 2:
EE_Write_byte (0xFE, 0x1FF0);
break;
92
//*****************************************************************************************
// Glavni meni
//
// Nastavitve
// Zagon Aplikacije
//*****************************************************************************************
void Meni ()
char stevec;
char polje[2][16]; // Število besed = 2, max. št. znakov = 16
zacetek:
st_besed = 2; // Nastavimo število besed v meniju
vrstica = 1; // Resetiram števec vrstic
stevec_besed = 0; // Resetiram števec izpisanih besed
stevec = 0; // Števec črk (znakov) v abecedi oziroma v polju jezika
// Preverimo, če je izbran angleški jezik?
if (EE_Read_Random (0x1FF0) == 0xFE)
// Da, izbran je angleški jezik, zato uporabljamo angleška polja
while (stevec < st_besed)
for (i = 0; main_menu[stevec][i] != '\0'; i++)
polje[stevec][i] = main_menu[stevec][i];
polje[stevec][i] = '\0';
stevec++;
// Ne, je izbran slovenski?
if (EE_Read_Random (0x1FF0) == 0xFF)
// Da, izbran je slovenski jezik, zato uporabljamo slovenska polja
while (stevec < st_besed)
for (i = 0; glavni_meni[stevec][i] !='\0'; i++)
polje[stevec][i] = glavni_meni[stevec][i];
polje[stevec][i] = '\0';
stevec++;
do
for (j = 0; j < 2; j++) // Zanka za izpis dveh vrstic
93
for (i = 0; polje[stevec_besed][i] != '\0'; i++)
Lcd_Chr (vrstica, 1+i, polje[stevec_besed][i]);
// Smo že na koncu tabele?
if (stevec_besed == st_besed - 1) // -1 zaradi tega, ker začnemo šteti od 0
// Ja, smo na koncu. Najprej povečamo števec za 1 (če je izpisana samo ena
// beseda), ker ga pri izhodu iz zanke for zmanjšamo za 1. Torej se nam
// števec ne spremeni. Nato pa gremo brati tipke.
if (j == 0)
stevec_besed++;
break;
// Smo že izpisali 2 vrstici?
if (vrstica == 2)
break; // Ja, izhod iz zanke for brez povečanja števcev
// Ne, nismo na koncu. Povečamo števec besed in vrstic.
stevec_besed++;
vrstica++;
// Izpisali smo že 2 vrstici ali pa smo na koncu tabele (torej izpisali zadnjo
// vrstico v tabeli)
Lcd_Cmd (_LCD_FIRST_ROW); // Pomik v prvo vrstico
vrstica = 1;
stevec_besed--;
// Gremo brati tipke. Ponavljamo dokler ni pritisnjen enter.
while (Premakni (&vrstica, &stevec_besed, &st_besed, polje) != 3);
stevec_besed = stevec_besed + 1; // Ker števec začne šteti pri 0, mu je na koncu (ko
// je pritisnjen enter) potrebno prišteti 1
// Katera beseda iz tabele je bila izbrana?
switch (stevec_besed)
// 1. beseda v tabeli (NASTAVITVE)
case 1:
// Preverimo kateri jezik je izbran in na podlagi tega prenesemo v funkcijo
// pravo polje
if (EE_Read_Random (0x1FF0) == 0xFF)
f_Nastavitve (nastavitve);
Lcd_Cmd (_LCD_CLEAR);
goto zacetek;
94
if (EE_Read_Random (0x1FF0) == 0xFE)
f_Nastavitve (setup);
Lcd_Cmd (_LCD_CLEAR);
goto zacetek;
// 2. beseda v tabeli (ZAGON)
case 2:
// Zagon aplikacije
Lcd_Cmd (_LCD_CLEAR);
break;
return;
Podprogram za merjenje temperature in komunikacijo z Ethernetom
#define PIN 1 // Pin na katerega so priključeni senzorji
#define DQ PORTE // Port na katerega so priključeni senzorji
// Externe funkcije
char cal_crc (char buff[], char byte_num);
// Na TCP zahteve ni potrebno odgovarjati
unsigned int Ethernet_UserTCP(unsigned char *remoteHost, unsigned int remotePort, unsigned
int localPort, unsigned int reqLength, char *canClose)
return(0);
// Odgovor na UDP zahteve
unsigned int Ethernet_UserUDP(unsigned char *remoteHost, unsigned int remotePort, unsigned
int destPort, unsigned int reqLength)
char i; // Začasna spremenljivka
char requestID[4]; // Polj, ki hrani ID zahteve
char response[131]; // Polje za odgovor (max. dolžina je 131 zlogov)
unsigned lokacija; // Hrani naslov začetne lokacije senzorja
unsigned temp; // Izmerjena temperatura
char ID[8]; // Polje, ki vsebuje ID trenutnega senzorja
char bajt; // Začasna spremenljivka pri pretvorbi temperature
95
char bajt1; // Začasna spremenljivka pri pretvorbi temperature
char bajt2; // Začasna spremenljivka pri pretvorbi temperature
char len; // Dolžina odgovora
char zacasno; // Začazna spremenljivka
unsigned temp_whole; // Celi del temperature
char dol_snmp; // Dolžina snmp sporočila
char senzor; // Številka senzorja
// Najprej preverimo kateremu senzorju je zahteva namenjena
for (i = 0; i < reqLength; i++)
// Ethernet_getByte začne brati na začetku SNMP sporočila
zacasno = Ethernet_getByte();
// Sproti shranimo še request ID
if (i == 17)
requestID[0] = zacasno;
if (i == 18)
requestID[1] = zacasno;
if (i == 19)
requestID[2] = zacasno;
if (i == 20)
requestID[3] = zacasno;
if (i == 42)
senzor = zacasno;
break;
lokacija = (senzor * 8) - 8; // Izračun lokacije senzorja
// Preberemo ID senzorja
for (i = 0; i < 8; i++)
ID[i] = EE_Read_Random (lokacija + i);
Delay_ms (3);
// Preverimo, če senzor sploh obstaja. Če obstaja izmerimo temperaturo.
if ((cal_crc (ID, 7)) == 0)
// Sledi priprava senzorja na merjenje
Ow_Reset(&DQ, PIN); // Reset ukaz
Ow_Write(&DQ, PIN, 0x55); // MATCH ROM
96
// Naslovimo senzor s katerim želimo meriti temperaturo
for (i = 0; i < 8; i++)
Ow_Write(&DQ, PIN, ID[i]);
Ow_Write(&DQ, PIN, 0x44); // CONVERT_T
Delay_ms(100); // Potrebna zaksnitev
Ow_Reset(&DQ, PIN); // Reset ukaz
Ow_Write(&DQ, PIN, 0x55); // MATCH ROM
// Naslovimo senzor s katerim želimo meriti temperaturo
for (i = 0; i < 8; i++)
Ow_Write(&DQ, PIN, ID[i]);
Ow_Write(&DQ, PIN, 0xBE); // Ukaz za branje iz beležke (READ_SCRATCHPAD)
temp = Ow_Read(&DQ, PIN); // Preberemo MSB zlog temperature
temp = (Ow_Read(&DQ, PIN) << 8) + temp; // Preberemo LSB zlog temperature
// Sledi pretvorba temperature.
// Glede na družino senzorjev (verzija S ali B) maskiramo digitalno vrednost
// temperature z različnima vrednostima.
if (ID[0] == 0x28) // Verzija DS18B20
temp_whole = temp >> 4;
temp &= 0x0008;
if (ID[0] == 0x10) // Verzija DS18S20
temp_whole = temp >> 1;
temp &= 0x0001;
// Rezultat meritve pomnožimo z deset, zaradi prikaza v MRTG-ju
temp_whole = temp_whole * 10;
// Pogledamo še decimalni del in ga prištejemo izmerjeni temperaturi
if (temp > 0)
temp_whole = temp_whole + 5;
// Če pa ne obstaja, pa za izmerjeno temperaturo vstavimo vrednost 2000, saj jo bo MRTG
// zavrnil, ker je v config datoteki nastavljena maksimalna meja 1250, kar predstavlja
// temperaturo 125 °C.
else
temp_whole = 2000;
97
// Sedaj pretvorimo izmerjeno temperaturo v dva bajta hexa vrednosti
bajt = temp_whole / 16;
bajt2 = (bajt << 4) + temp_whole % 16;
bajt1 = (temp_whole / 16) >> 4;
// Tvorjenje odgovora na sprejeto zahtevo
// Začetek SNMP paketa
response[0] = 0x30; // Začetek paketa se začne s sekvenco (tip 0x30)
response[1] = 0x2d; // Dolžina celotne sekvence (SNMP paketa) - vedno 45
// zlogov
dol_snmp = 0x2d; // Shranimo dolžino SNMP paketa
// Verzija SNMP paketa
response[2] = 0x02; // Tip za verzijo SNMP. V tem primeru je to INTEGER.
response[3] = 0x01; // Dolžina podatka (SNMP verzije) – 1 zlog
response[4] = 0x00; // SNMP verzija. V tem primeru je to SNMP v1, kar
// označuje vrednost 0
// Community string
response[5] = 0x04; // Tip za community string. V tem primeru je to OCTET
// STRING
response[6] = 0x06; // Dolžina community string-a – 6 zlogov
response[7] = 0x70; // Vrednost community string-a, to je "public" - 'p'
response[8] = 0x75; // 'u'
response[9] = 0x62; // 'b'
response[10] = 0x6c; // 'l'
response[11] = 0x69; // 'i'
response[12] = 0x63; // 'c'
// PDU
response[13] = 0xa2; // Tip PDU-ja. V tem primeru je tip Get-Response, ki ima
// kodo a2
response[14] = 0x20; // Dolžina PDU-ja - vedno 32 zlogov
// Request ID
response[15] = 0x02; // Tip za request ID. To je INTEGER
response[16] = 0x04; // Dolžina request ID-ja - 4 zloge
response[17] = requestID[0]; // Vrednost request ID-ja. Dobimo ga iz SNMP zahteve
response[18] = requestID[1];
response[19] = requestID[2];
response[20] = requestID[3];
// Error status
response[21] = 0x02; // Tip za Error status - INTEGER
response[22] = 0x01; // Dolžina Error status-a - 1 bajt
response[23] = 0x00; // Vrednost Error status-a
// Error index
response[24] = 0x02; // Tip za Error index
response[25] = 0x01; // Dolžina Error index-a
response[26] = 0x00; // Vrednost Error index-a
// Varbind list
response[27] = 0x30; // Tip za varbind list - sekvenca
response[28] = 0x12; // Dolžina te sekvence (varbind list)
// je vedno 19 bajtov ali 12 hexa
98
// Variable bindings
response[29] = 0x30; // Tip za variable bindings
response[30] = 0x10; // Dolžina za variable bingings – vedno 16 bajtov
// OID
response[31] = 0x06; // Tip za OID. V tem primeru je to tip
// OBJECT INDENTIFIER, kar označuje vrednost 0x06
response[32] = 0x0a; // Dolžina OID-ja - 10 bajtov
response[33] = 0x2b; // Vrednost OID-ja (številka) – 1.3.6.1.4.1.17095.3.x
response[34] = 0x06;
response[35] = 0x01;
response[36] = 0x04;
response[37] = 0x01;
response[38] = 0x81; // Tu je številka 17095. Število je potrebno spraviti v 2
// zloga
response[39] = 0x85;
response[40] = 0x47;
response[41] = 0x03;
response[42] = senzor;
// Podatek
response[43] = 0x02; // Tip za vrednost, ki jo pošljemo nazaj (temperatura)
response[44] = 0x02; // Dolžina vrednosti - vedno 2 bajta
response[45] = bajt1; // Vrednost (izmerjena temperatura), ki jo hočemo poslati
// za prikaz
response[46] = bajt2;
len= 2 + dol_snmp; // Dolžina celotnega odgovora = dolžina snmp sporočila +
// 2 bajta (na začetku SNMP odgovora)
// V pomnilnik naložimo celoten odgovor, ki se nato pošlje na PC
for (i=0; i<len; i++)
Ethernet_putbyte (response[i]);
return(len);
// Funkcija, ki v neskončni zanki preverja za prispele zahteve
void Ethernet(char text[])
while (1)
// Poglejmo, če je prispela kakšena zahteva?
Ethernet_doPacket();
99
Konfiguracijska datoteka orodja MRTG
Konfiguracijska datoteka obsega le sedem temperaturnih senzorjev, saj bi bil v nasprotnem
primeru njen obseg prevelik za diplomsko nalogo.
# Created by
# cfgmaker [email protected] --global "WorkDir: c:\www" --output asd.cfg
### Global Defaults
EnableIPv6: no
LoadMIBs: C:\mrtg\bin
RunAsDaemon: yes
#LogFormat: rrdtool
#PathAdd: C:\rrdtool\rrdtool\Release
WorkDir: c:\www1
NoMib2: Yes
Language: slovenian
#SnmpOptions: timeout => 2
#SnmpOptions: retries => 1
### Senzorji
#Senzor 1
PageTop[temp1]: <H1>Meritev temperature - SENZOR 1</H1>
PageFoot[temp1]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp1]: 1.3.6.1.4.1.17095.3.1&1.3.6.1.4.1.17095.3.1:[email protected]
SetEnv[temp1]: MRTG_INT_IP="192.168.0.1" MRTG_INT_DESCR="Realtek-RTL8139-Family-PCI-Fast-
Ethernet-NIC---Packet-Scheduler-Miniport"
MaxBytes[temp1]: 1250
Title[temp1]: Senzor 1
YTics[temp1]: 5
YTicsFactor[temp1]: 0.1
Options[temp1]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp1]: ym
ShortLegend[temp1]: °C
LegendI[temp1]: Temperatura:
PNGTitle[temp1]: Senzor 1
Factor[temp1]: 0.1
YLegend[temp1]: Temperatura (°C)
Timezone[temp1]: Maribor
#Senzor 2
PageTop[temp2]: <H1>Meritev temperature - SENZOR 2</H1>
100
PageFoot[temp2]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp2]: 1.3.6.1.4.1.17095.3.2&1.3.6.1.4.1.17095.3.2:[email protected]
MaxBytes[temp2]: 1250
Title[temp2]: Senzor 2
YTics[temp2]: 5
YTicsFactor[temp2]: 0.1
Options[temp2]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp2]: ym
ShortLegend[temp2]: °C
LegendI[temp2]: Temperatura:
PNGTitle[temp2]: Senzor 2
Factor[temp2]: 0.1
YLegend[temp2]: Temperatura (°C)
Timezone[temp2]: Maribor
#Senzor 3
PageTop[temp3]: <H1>Meritev temperature - SENZOR 3</H1>
PageFoot[temp3]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp3]: 1.3.6.1.4.1.17095.3.3&1.3.6.1.4.1.17095.3.3:[email protected]
MaxBytes[temp3]: 1250
Title[temp3]: Senzor 3
YTics[temp3]: 5
YTicsFactor[temp3]: 0.1
Options[temp3]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp3]: ym
ShortLegend[temp3]: °C
LegendI[temp3]: Temperatura:
PNGTitle[temp3]: Senzor 3
Factor[temp3]: 0.1
YLegend[temp3]: Temperatura (°C)
Timezone[temp3]: Maribor
#Senzor 4
PageTop[temp4]: <H1>Meritev temperature - SENZOR 3</H1>
PageFoot[temp4]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp4]: 1.3.6.1.4.1.17095.3.4&1.3.6.1.4.1.17095.3.4:[email protected]
MaxBytes[temp4]: 1250
Title[temp4]: Senzor 4
YTics[temp4]: 5
YTicsFactor[temp4]: 0.1
Options[temp4]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp4]: ym
ShortLegend[temp4]: °C
LegendI[temp4]: Temperatura:
PNGTitle[temp4]: Senzor 4
Factor[temp4]: 0.1
YLegend[temp4]: Temperatura (°C)
101
Timezone[temp4]: Maribor
#Senzor 5
PageTop[temp5]: <H1>Meritev temperature - SENZOR 3</H1>
PageFoot[temp5]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp5]: 1.3.6.1.4.1.17095.3.5&1.3.6.1.4.1.17095.3.5:[email protected]:
MaxBytes[temp5]: 1250
Title[temp5]: Senzor 5
YTics[temp5]: 5
YTicsFactor[temp5]: 0.1
Options[temp5]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp5]: ym
ShortLegend[temp5]: °C
LegendI[temp5]: Temperatura:
PNGTitle[temp5]: Senzor 5
Factor[temp5]: 0.1
YLegend[temp5]: Temperatura (°C)
Timezone[temp5]: Maribor
#Senzor 6
PageTop[temp6]: <H1>Meritev temperature - SENZOR 3</H1>
PageFoot[temp6]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp6]: 1.3.6.1.4.1.17095.3.6&1.3.6.1.4.1.17095.3.6:[email protected]:
MaxBytes[temp6]: 1250
Title[temp6]: Senzor 6
YTics[temp6]: 5
YTicsFactor[temp6]: 0.1
Options[temp6]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp6]: ym
ShortLegend[temp6]: °C
LegendI[temp6]: Temperatura:
PNGTitle[temp6]: Senzor 6
Factor[temp6]: 0.1
YLegend[temp6]: Temperatura (°C)
Timezone[temp6]: Maribor
#Senzor 7
PageTop[temp7]: <H1>Meritev temperature - SENZOR 3</H1>
PageFoot[temp7]: Kontakt: <A HREF="mailto:[email protected]">Mitja Mastnak</A
Target[temp7]: 1.3.6.1.4.1.17095.3.7&1.3.6.1.4.1.17095.3.7:[email protected]:
MaxBytes[temp7]: 1250
Title[temp7]: Senzor 7
YTics[temp7]: 5
YTicsFactor[temp7]: 0.1
Options[temp7]: gauge, nobanner, nopercent, noo, nolegend
Suppress[temp7]: ym
102
ShortLegend[temp7]: °C
LegendI[temp7]: Temperatura:
PNGTitle[temp7]: Senzor 7
Factor[temp7]: 0.1
YLegend[temp7]: Temperatura (°C)
Timezone[temp7]: Maribor
Kosovnica uporabljenih elementov
Napajalnik
Oznaka Vrednost Ime elementa Ohišje/ Knjižnica
Velikost
C1 330n C-EUC0805 C0805 rcl
C2 100n C-EUC0805 C0805 rcl
C3 100n C-EUC0805 C0805 rcl
C4 100n C-EUC0805 C0805 rcl
C5 47u CPOL-EUSMCC SMC_C rcl
C6 47u CPOL-EUSMCC SMC_C rcl
IC1 7805T 7805T TO220H linear
IC2 LM1117 3.3V LD117AS33TR SOT223 v-reg
J1 DC 9V DCJ0303 DCJ0303 con-jack
JP1 NAPAJANJE PINHD-1X3 1X03 pinhead
JP2 NAPAJANJE PINHD-1X3 1X03 pinhead
JP3 NAPAJANJE PINHD-1X3 1X03 pinhead
LED1 LED3MM LED3MM led
R1 330 R-EU_R0805 R0805 rcl
T1 START/STOP 320-916 320-916 switch
Tipkovnica
Oznaka Vrednost Ime elementa Ohišje/ Knjižnica
Velikost
DESNO TIPKA_1POL TIPKA_1POL TIPKA_1POL switch
DOL TIPKA_1POL TIPKA_1POL TIPKA_1POL switch
103
ENTER TIPKA_1POL TIPKA_1POL TIPKA_1POL switch
GOR TIPKA_1POL TIPKA_1POL TIPKA_1POL switch
KONEKTOR_1 PINHD-1X7 1X07 pinhead
LEVO TIPKA_1POL TIPKA_1POL TIPKA_1POL switch
R1 4k7 R-EU_R0805 R0805 rcl
R2 4k7 R-EU_R0805 R0805 rcl
R3 4k7 R-EU_R0805 R0805 rcl
R4 4k7 R-EU_R0805 R0805 rcl
R5 4k7 R-EU_R0805 R0805 rcl
Vezje za Ethernet komunikacijo
Oznaka Vrednost Ime elementa Ohišje/ Knjižnica
Velikost
C1 100n C-EUC0805 C0805 rcl
C2 100n C-EUC0805 C0805 rcl
ETHERNET PINHD-1X8 1X08 pinhead
J1 J0026 J0026 PJ-J0 con-pulse
L1 5 ovojev BS75 BS75 inductor
R1 49R9 R-EU_R0805 R0805 rcl
R2 49R9 R-EU_R0805 R0805 rcl
R3 49R9 R-EU_R0805 R0805 rcl
R4 49R9 R-EU_R0805 R0805 rcl
R5 1k R-EU_R0805 R0805 rcl
R6 1k R-EU_R0805 R0805 rcl
Reset vezje
Oznaka Vrednost Ime elementa Ohišje/ Knjižnica
Velikost
C1 100n C-EUC0805 C0805 rcl
JP1 PINHD-1X3 1X03 pinhead
R1 10k R-EU_R0805 R0805 rcl
104
R2 4k7 R-EU_R0805 R0805 rcl
RESET TIPKA_1POL TIPKA_1POL TIPKA_1POL switch
EEPROM-vezje
Oznaka Vrednost Ime elementa Ohišje/ Knjižnica
Velikost
IC1 24C64 25C040P DIL8 microchip
JP1 PINHD-1X2 1X02 pinhead
JP2 PINHD-1X2 1X02 pinhead
R1 10k R-EU_R0805 R0805 rcl
R2 10k R-EU_R0805 R0805 rcl
105
106