Fórum témák
- • Milyen zsebrádiót vegyek,amivel a gyenge rádióadókat is tudom fogni?
- • Számítógép hiba, de mi a probléma?
- • Alternativ HE találkozó(k)
- • LCD TV probléma
- • Erősítő mindig és mindig
- • Mosógép vezérlők és általános problémáik
- • Kaputelefon
- • Robotfűnyíró vagy fűnyíró robot
- • Felajánlás, azaz ingyen elvihető
- • Crystal radio - detektoros rádió
- • Általános antennás kérdések, válaszok
- • Elfogadnám, ha ingyen elvihető
- • Tápegységgel kapcsolatos kérdések
- • Napelem alkalmazása a lakás energia ellátásában
- • Androidos okos telefonok
- • Elektromos fűnyíró probléma
- • Motorgyújtás
- • XBOX kiegészítők, javítások átalakítások
- • Oszcillátor építése rajzok
- • Szünetmentes táp javítása, élesztése
- • Érdekességek
- • Magas nyomású tisztító működése, javítása
- • Rádióamatőrök topikja
- • Hangsugárzó építés, javítás - miértek, hogyanok
- • Nyák nyomtató kérdések
- • Tápegység
- • Theremin
- • Börze
- • Inverter javítás
- • V-FET és SIT erősítő kapcsolások
- • Digitális mérleg
- • Parkside akkuk javìtása
- • Briggs töltés
- • Erősítő építése elejétől a végéig
- • Vásárlás, hol kapható?
- • 3D nyomtatás
- • Laptop javítás, tuning
- • Kapcsolóüzemű táp 230V-ról
- • Transzformátor készítés, méretezés
- • Elektromos kerékpár, robogó házilag
- • Relé kérdés
- • PIC - Miértek, hogyanok haladóknak
- • Erősítőhöz való hangsugárzó védelem (koppanásgátló)
- • Autórádió (fejegység) problémák, kérdések, válaszok
- • Arduino
- • Oszcilloszkóp, avagy hogyan kell használni?
- • Analóg oszcilloszkóp javítása
- • Akkumulátor töltő
- • Dansk 3f-T3535, és minden, ami vele kapcsolatos
- • Klíma szervizelés, javítás
- • PC-ről vezérlés
- • Labortápegység készítése
- • Videoton EA 6383 s (tuning)
- • Rossz pénztárgép
- • METEX műszer
» Több friss téma
|
Fórum » DS18B20 hőmérő-szenzor
Itt a kódrészletem
/*Header******************************************************/
// LCD module connections
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
// End LCD module connections
const unsigned short TEMP_RESOLUTION = 9;
char *text = " 00.0";
unsigned temp;
int homerseklet = 0, i = 0;
char felirat[]={' ','H','o','m','e','r','s','e','k','l','e','t'};
const char character[] = {7,5,7,0,0,0,0,0};
void CustomChar(char pos_row, char pos_char) {
char i;
Lcd_Cmd(64);
for (i = 0; i<=7; i++) Lcd_Chr_CP(character[i]);
Lcd_Cmd(_LCD_RETURN_HOME);
Lcd_Chr(pos_row, pos_char, 0);
}
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
// check if temperature is negative
if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}
// extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;
// convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;
text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
// extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// convert temp_fraction to characters
text[4] = temp_fraction/1000 + 48; // Extract thousands digit
// Display temperature on LCD
Lcd_Out(2, 5, text);
homerseklet = atoi(text);
if(homerseklet > 35)
{
PORTB.B6 = 1;
}
else
PORTB.B6 = 0;
}
void InitMain() {
OSCCON = 0x71; // set int-osc 8 Mhz
while ((OSCCON & 0x4)!=0x4); // wait for clock stable
delay_ms (500);
}
void Move_Delay() { // Function used for text moving
Delay_ms(10); // You can change the moving speed here
}
void main() {
InitMain();
INTCON = 0x00;
INTCON2 = 0x00;
INTCON3 = 0x00;
RCON = 0x00;
PIE1 = 0x00;
PIE2 = 0x00;
PIR1 = 0x00;
PIR2 = 0x00;
ADCON1 = 0x06; //all to digital inputs
TRISA = 0x00;
TRISB = 0x00;
TRISC = 0x00;
TRISD = 0x00;
TRISE = 0x00;
PORTA = 0xFF;
PORTB = 0x00;
PORTC = 0x00;
PORTD = 0xFF;
PORTE = 0x00;
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn the cursor off
//--- main loop
do {
//--- perform temperature reading
Ow_Reset(&PORTD, 7); // Onewire reset signal
Ow_Write(&PORTD, 7, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTD, 7, 0x44); // Issue command CONVERT_T
Delay_ms(750);
Ow_Reset(&PORTD, 7);
Ow_Write(&PORTD, 7, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTD, 7, 0xBE); // Issue command READ_SCRATCHPAD
temp = Ow_Read(&PORTD, 7);
temp = (Ow_Read(&PORTD, 7) << 8) + temp;
Lcd_Chr(2,11, 'C');
CustomChar(2,10);
Display_Temperature(temp);
Delay_ms(200);
} while (1);
}
Találtam egy ilyet és nekem a -0.5 jelenik meg.
Kivettem a szenzort működés közben és akkor is -0.5 fokot ír ki. A kapcsolási rajzon pedig a következő a ds1820 első lábát a földre húztam, a második lábát az rd7 re és ezt az adat lábat pedig plusz még felhúztam egy 1k ellenállással 5V-ra a harmadik lábát pedig 5v-ra. Tehát olyan mint ha nem is lenne hőszenzor.
1K-ig akkor szoktak lemenni, ha nagyon hosszú a vezeték és zajos. 2k2...4k7 -ig szoktam használni a felhúzót.
Az adatvonal írása után iktass be 2...6us-nyi szünetet, próbaképpen.
Az az ow_write nevu rutin hol van?
Szoval en pont az idozito reszt nem talalom ebben, ami szerintem a kulcsa.
Abban idoziteni ugyis hulyeseg, hogyha nem tudod, mit fordit a fordito. Az ASM-hez nem ertesz?
Itt nem ms-os kesleltetesek vannak am...
Az, hogy a tobbi dologgal eltertel, csak fokozza a hibak valoszinuseget.
De ez a forráskód működik 16f818-al. Az asm-hez nem értek csak a C-hez valamennyire.
(#) |
doup hozzászólása |
Okt 30, 2011 |
![](/pic/post_ranknd.png) |
/ |
![](/pic/post_rankyd.png) |
|
Egyébként nem lehet hogy a configurációs biteknél rontok el valamiit?
Akkor csak az idozites lesz a gond.
Probald ezt is 4MHz-en futtatni.
Az is belso oszcis volt? Mert ha kvarcos, akkor itt is pont annyi kell.
De ha nem tudod, mit is csinalsz, akkor kinszenvedes lesz a tovabbi modositas.
Abbol, hogy a szenzort kiveve sem ad ertelmes jelet, lathatod, hogy a kommunikacioval lesz valami.
A masiknal minden ugyanaz volt, mint itt?
Persze, a config bit is lehet. Ellenorizd az azonos funkcioju biteket a ket adatlap alapjan. Nncs sok...
Az is belső oszcis volt. Minden ugyan az volt mint itt.
Jo, akkor felezd meg a frekit, hogy itt is 4 legyen.
void InitMain() {
OSCCON = 0x60; // set int-osc 4 Mhz
while ((OSCCON & 0x4)!=0x4); // wait for clock stable
delay_ms (500);
}
Így megfeleztem. De sajna így sem megy. Egyre jobban nem értem pedig minden ugyan az. A config bitekkel lesz valami. Vagy most már fogalmam sincs.
Van-e esetleg megszakitas benne? Mert az oda tud csapni az idoziteseknek a foprogramban.
Egyaltalan eljut a programod a beolvasasig? (pontosabban a masodik beolvasasig)?
De meg egyszer mondom, ha nem erted, mit csinalsz, akkor csak sotetben tapogatozol. Nem netes kodreszleteket kellene bemasolnod, hanem megerteni, hogy melyik bit miert all ugy, ahogy.
Esetleg prbald meg attenni valamelyik portB bitre, mondjuk B2-re...
Az osccon regiszternel pl szerintem az utolso elotti bit 1 legyen. Nem tudom, az elozoleg hasznalt pic-nel ott lehetett-e allitani valamit.
nalam, ami mukodik, ott B'11100010'-ra van allitva az OSCCON.
Aztan nem tudom a a watchdog timert bekapcsolva hagytad-e pl.
Kikapcsoltam a watchdog timert.
Es a tobbi felvetesre esetleg valami?
Igy kicsit nehez lesz beszelgetni.
Szandekosan csinalod?
Én hexában adom meg az előzőnél OSCCON = 0x60; ez volt beállítva. Megszakítás a programomban abszolút nincs szerintem. De ugyan azt a programot raktam bele a 18f4550-be csak a portokat állítottam át mint a 16f818-ba. A configurációs biteket pedig a csatolt fájlban látod.
Mondd, tenyleg nem akarod megerteni?
AZ EGY MASIK PIC VOLT!!!!!!!!! Regebbi sorozat, masik szamu is.
Ha elozoleg automata, benzines kocsid volt. akkor nem fogod erteni, hogy ennek a dizelesnek meg valtoja van es a benzin tonkreteszi???
Hanem hajtogatod, de az elozot igy kellett vezetni es ezzel tankoltam???
Probald ki, amiket irtam.
Szamold at a binarist hexaba.
Assembly betetet tudsz hasznalni a programodban?
Szia, én is ezzel a pic és szenzor kombinációval bírkózok de sajna nekem sem megy. Te jutottál már valamire vele?
Köszönöm fáradalmadat sikerült megoldani a problémát.
De leirhatnad - ha mar ennyit kuzdottunk vele -, hogy hogyan, mi volt a gond.
A configurációs bitek beállításával volt a gond. Mellékletben csatoltam hogy mivel működik.
Hali
A C nyelvű forráskódot is megosztanád velünk? én is küzdöttem már vele, csak sikerélmény hiányában félretettem. Vagy a fenti az változatlan?
Üdv.
C forráskód a következő!
// LCD module connections
sbit LCD_RS at LATB0_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_EN at LATB1_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D4 at LATB2_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D5 at LATB3_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D6 at LATB4_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D7 at LATB5_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections
// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20: 9 (default setting; can be 9,10,11,or 12)
// 18B20: 12
const unsigned short TEMP_RESOLUTION = 9;
char *text = "000.0000";
unsigned temp;
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
// check if temperature is negative
if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}
// extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;
// convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;
else
text[0] = '0';
text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
// extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// convert temp_fraction to characters
text[4] = temp_fraction/1000 + 48; // Extract thousands digit
text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit
text[6] = (temp_fraction/10)%10 + 48; // Extract tens digit
text[7] = temp_fraction%10 + 48; // Extract ones digit
// print temperature on LCD
Lcd_Out(2, 5, text);
}
void main() {
ADCON1 |= 0x0F; // Configure AN pins as digital
CMCON |= 7; // Disable comparators
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, " Temperature: ");
// Print degree character, 'C' for Centigrades
Lcd_Chr(2,13,178); // different LCD displays have different char code for degree
// if you see greek alpha letter try typing 178 instead of 223
Lcd_Chr(2,14,'C');
//--- main loop
do {
//--- perform temperature reading
Ow_Reset(&PORTD, 0); // Onewire reset signal
Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTD, 0, 0x44); // Issue command CONVERT_T
Delay_ms(450);
Ow_Reset(&PORTD, 0);
Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTD, 0, 0xBE); // Issue command READ_SCRATCHPAD
temp = Ow_Read(&PORTD, 0);
temp = (Ow_Read(&PORTD, 0) << 8) + temp;
//--- Format and display result on Lcd
Display_Temperature(temp);
Delay_ms(500);
} while (1);
}
Ez 18f4550 és ds1820 szenzorral működik.
Bocsi ez a forrás a helyes!
// LCD module connections
sbit LCD_RS at LATB0_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_EN at LATB1_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D4 at LATB2_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D5 at LATB3_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D6 at LATB4_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_D7 at LATB5_bit; // for writing to output pin always use latch (PIC18 family)
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections
// Set TEMP_RESOLUTION to the corresponding resolution of used DS18x20 sensor:
// 18S20: 9 (default setting; can be 9,10,11,or 12)
// 18B20: 12
const unsigned short TEMP_RESOLUTION = 9;
char *text = "000.0000";
unsigned temp;
void Display_Temperature(unsigned int temp2write) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
// check if temperature is negative
if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}
// extract temp_whole
temp_whole = temp2write >> RES_SHIFT ;
// convert temp_whole to characters
if (temp_whole/100)
text[0] = temp_whole/100 + 48;
else
text[0] = '0';
text[1] = (temp_whole/10)%10 + 48; // Extract tens digit
text[2] = temp_whole%10 + 48; // Extract ones digit
// extract temp_fraction and convert it to unsigned int
temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
// convert temp_fraction to characters
text[4] = temp_fraction/1000 + 48; // Extract thousands digit
text[5] = (temp_fraction/100)%10 + 48; // Extract hundreds digit
text[6] = (temp_fraction/10)%10 + 48; // Extract tens digit
text[7] = temp_fraction%10 + 48; // Extract ones digit
// print temperature on LCD
Lcd_Out(2, 5, text);
}
void InitMain() {
OSCCON = 0x71; // set int-osc 4 Mhz
while ((OSCCON & 0x4)!=0x4); // wait for clock stable
delay_ms (500);
}
void main() {
InitMain();
ADCON1 |= 0x0F; // Configure AN pins as digital
CMCON |= 7; // Disable comparators
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear LCD
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
Lcd_Out(1, 1, " Temperature: ");
// Print degree character, 'C' for Centigrades
Lcd_Chr(2,13,178); // different LCD displays have different char code for degree
// if you see greek alpha letter try typing 178 instead of 223
Lcd_Chr(2,14,'C');
//--- main loop
do {
//--- perform temperature reading
Ow_Reset(&PORTD, 0); // Onewire reset signal
Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTD, 0, 0x44); // Issue command CONVERT_T
Delay_ms(900);
Ow_Reset(&PORTD, 0);
Ow_Write(&PORTD, 0, 0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTD, 0, 0xBE); // Issue command READ_SCRATCHPAD
temp = Ow_Read(&PORTD, 0);
temp = (Ow_Read(&PORTD, 0) << 8) + temp;
//--- Format and display result on Lcd
Display_Temperature(temp);
Delay_ms(500);
} while (1);
}
Hali!
Kösz, ez MicroC nem Mlab. Jó látom?
Üdv.
Sziasztok
Csináltam egy gk-ba való külső hőmérőt ds18s20-al.
Most ki akarom egészíteni egy belső hőméréssel.
Ha egy adatvonalra teszem a két szenzort akkor csak úgy tudok rájuk hivatkozni, hogy először kiolvasom az azonosítójukat és ez alapján?
Ha jól tudom a "search rom" parancsal lehet egyszerre több eszköz azonosítóját is keresni, de akkor viszont a master eszköz honnan fogja tudni, hogy melyik melyik?
Üdv
Sziasztok!
Én ds1821-el "high res" próbálkozok hetek óta. Tizedes pontossággal szeretnék hőmérsékletet mérni. Látszólag minden rendben van. De. Ha ha pl hűl a hőmérő, a következőket mutatja: 21,1 21,0 20,9 20,4 20,3 ... Tehát ,9 után mindig ,4 érték következik.
A kódot mikropascalban készítettem. Beillesztem ide. A kódban hőmérséklet*10 értéket állítom elő, mert majd rádión küldöm tovább. Arra gondolok, hogy a count_per_c és a count_remain kiolvasásánál lehet a gond, mert ezek az adatok 9 bitesek. A mikropascalos ow_read pedig csak 8 bitet olvas egyszerre. Ezért kétszer olvasok és a 2 byteból állítom össze az adatot. Szerintetek jó ez így, vagy mi lehet a baj?
procedure meassure;
var
tmp: word;
count_remain : word;
count_per_c : word;
tiz: word;
temp:word;
elojel: integer;
begin
//--- perform temperature reading
Ow_Reset(PORTC, 1); // Onewire reset signal
Ow_Write(PORTC, 1, 0xEE); // Issue command CONVERT_T start
tmp:=0;
while tmp shr 7 <>1 do
begin
delay_us(100);
Ow_Reset(PORTC, 1); // Onewire reset signal
Ow_Write(PORTC, 1, 0xAC); // várakozás a konverzióra
tmp := Ow_Read(PORTC, 1);
end;
//Delay_us(520); //750 volt
Ow_Reset(PORTC, 1);
Ow_Write(PORTC, 1, 0x22); // Issue command CONVERT_T stop
delay_us(100);
Ow_Reset(PORTC, 1);
Ow_Write(PORTC, 1, 0xAA); // Issue command READ_SCRATCHPAD
delay_us(100);
temp := Ow_Read(PORTC, 1);
temp := (Ow_Read(PORTC, 1) shl 8) + temp;
//temp:= 231;
elojel:=1;
if temp shr 7 = 1 then
begin
elojel:=-1;
temp:=temp or 65280;
temp:=(not temp) + 1;
end;
//-> tizedesek
count_remain:=0;
count_per_c:=0;
Ow_Reset(PORTC, 1);
delay_us(100);
Ow_Write(PORTC, 1, 0xA0);
count_remain :=Ow_Read(PORTC, 1);
count_remain := (count_remain shl 8) + Ow_Read(PORTC, 1);
Ow_Reset(PORTC, 1);
delay_us(100);
Ow_Write(PORTC, 1, 0x41);
delay_us(300);
Ow_Write(PORTC, 1, 0xA0);
delay_us(100);
count_per_c := Ow_Read(PORTC, 1);
delay_us(100);
//tmp:=Ow_Read(PORTC, 1);
count_per_c := Ow_Read(PORTC, 1);
//-> tizedesek
ho:=(elojel*temp*10);
ho:=ho+floor(((count_per_c-count_remain)*10)/count_per_c)-5;
end;
Sziasztok!
A minap egy DS18B20 beüzemelésével próbálkoztam és érdekes dologba futottam. A szenzort külső tápról járattam, felhúzásnak a gyári 4.7 kohm-ot használtam. A gond az az volt, hogy nem akart hőmérséklet konverziót végrehajtani. A skip rom és a read scratchpad működött, tehát a progi, amit írtam, az jó. Elkezdtem neten olvasgatni és valaki másnak is ilyesmi problémája volt, csak ő parazita tápos módban használta. Neki azt tanácsolták, hogy a felhúzó ellenállás túl nagy és emiatt nem kap elég áramot a szenzor, így nem tud konverziót végrehajtani. Gondoltam egy próbát megér és kicseréltem a 4.7 kohm-ot egy 1 kohm-ra és láss csodát, működött. A kérdésem az az lenne, hogy mi lehetett a gond? A kábeleim nem hosszabbak 2-3 cm-nél. A táp direktbe van bekötve, terhelhetősége 1 A, szóval elvileg van elég energia a rendes tápvonalon is. Nem érzékelhette a rendes tápvonalat? Bár ahogy az adatlapban néztem a táp felépítését eléggé faék jellegű. Összességében most működik, csak érdekel, hogy miért nem volt jó a gyári ajánlás.
|
|