Scout77
-= lekker belangrijk =-
Ik probeer dus een DS18B20 uit te lezen met een 16F648a om er in een later stadium een 433mhz zender aan te hangen die de info naar mijn server stuurt. Vervolgens wil ik dan een netwerk met een aantal van die dingen maken zodat ik draadloos op verschillende plekken in mijn huis de temperatuur te meten en in een later stadium ook andere sensoren uit te lezen.
Als eerste stap probeer ik de temperatuur van een DS18B20 uit te lezen en dat op een LCD weer te geven. Ik ben nu bezig in MikroC en in de help van MikroC staat een voorbeeld, maarja ... die is voor een andere PIC en heb deze dus aangepast maar verder dan "temperature: 0.000" komt er momenteel niet op het display te staan.
-Wel of geen DS18B20 maakt geen verschil.
-In het schema in de help staat een pullup weerstand van 10K maar in de app. note van dallas zelf staat 4.7K, helaas maakt het geen verschil.
-De + en - zitten ook goed want omdraaien heeft ook geen zin, geen rook maar denk dat ik er wel een gesloopt heb.
Enige wat ik me kan bedenken is dat er een foutje zit in het toewijzen van de poorten, ik heb de sensor nu aan poort A1 hangen. Ook ADCON1 commando begrijp ik niet helemaal, volgens mij heeft de sensor een digitale i/o port nodig maar heeft hij dat nu met die TRISA ... of heb ik dat mis?
// Set TEMP_RESOLUTION to the corresponding resolution of your DS18x20 sensor:
// 18S20: 9
// 18B20: 12 (default setting; can be 9,10,11,or 12)
const unsigned short TEMP_RESOLUTION = 12;
const int RES_FACTOR_1[4] = {5000, 2500, 1250, 625};
const unsigned int RES_FACTOR_2[4] = {0x0001, 0x0003, 0x0007, 0x000F};
const unsigned int RES_FACTOR_3[4] = {0x8000, 0xC000, 0xE000, 0xF000};
unsigned temp;
unsigned short j, RES_SHIFT;
void Display_Temperature(unsigned int temp) {
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
unsigned int temp_whole, temp_fraction;
unsigned short i;
char text[8];
// Isolate the fraction and make it a 4-digit decimal integer (for display)
temp_fraction = temp & RES_FACTOR_2[RES_SHIFT - 1];
temp_fraction = temp_fraction * RES_FACTOR_1[RES_SHIFT - 1];
//portc = temp_fraction;
// Handle the whole part of temperature value
temp_whole = temp;
// Is temperature negative?
if ((temp_whole & 0x8000) != 0u) i = 1; // Yes, i = 1
else i = 0; // No, i = 0
//PORTC = i; // geen idee wat dit doet, maar heb ik niet nodig op mijn PIC
// Remove the fractional part
temp_whole >>= RES_SHIFT;
// Correct the sign if necessary
if (i) temp_whole |= RES_FACTOR_3[RES_SHIFT - 1];
//portd = temp_whole;
IntToStr(temp_whole, text); // Convert whole part to string
Lcd_Out(2, 4, text); // Print whole part on LCD
Lcd_Chr_Cp('.'); // Print dot to separate fractional part
IntToStr(temp_fraction, text); // Convert fractional part to string
// Add leading zeroes (we display 4 digits fractional part)
if (temp_fraction < 1000u) Lcd_Chr_Cp('0');
if (temp_fraction < 100u) Lcd_Chr_Cp('0');
if (temp_fraction < 10u) Lcd_Chr_Cp('0');
Lcd_Out_Cp(text); // Print fractional part on LCD
Lcd_Chr_Cp(223); // Print degree character
Lcd_Chr_Cp('C'); // Print 'C' for Centigrades
}//~
void main() {
//ADCON1 = 0xFF; // Configure RA5 pin as digital I/O (Deze code werkt niet op mijn 16f468a)
PORTA = 0xFF;
TRISA = 0x0F; // PORTA is input
PORTB = 0;
TRISB = 0; // PORTB is output
// Initialize LCD on PORTB and prepare for output
Lcd_Init(&PORTB);
Lcd_Cmd(Lcd_CURSOR_OFF);
Lcd_Out(1, 1, " Temperature: ");
do { // main loop
Ow_Reset(&PORTA,1); // Onewire reset signal
Ow_Write(&PORTA,1,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTA,1,0x44); // Issue command CONVERT_T
Delay_us(120);
Ow_Reset(&PORTA,1);
Ow_Write(&PORTA,1,0xCC); // Issue command SKIP_ROM
Ow_Write(&PORTA,1,0xBE); // Issue command READ_SCRATCHPAD
Delay_ms(400);
j = Ow_Read(&PORTA,1); // Get temperature LSB
temp = Ow_Read(&PORTA,1); // Get temperature MSB
temp <<= 8; temp += j; // Form the result
Display_Temperature(temp); // Format and display result on LCD
Delay_ms(500);
} while (1);
}//~!
[\code]
Erik
In order to succeed you must fail, so that you know what not to do the next time.
Probeer eerst eens je ID code van je sensor alleen uit te lezen. Ik heb namelijk ook problemen gehad met m'n DS1820. Allereerst las ik de ID code van een i-button uit wat prima ging. Daarna probeerde ik zo'n temperatuur sensor uit
welke ook via het 1-wire protocol werkt en dit werkte niet. Ik heb dit toen opgelost door een bepaalde timing( weet niet meer welke) iets te verhogen, schijnbaar is die sensor wat kritischer qua timings.
Ook ADCON1 commando begrijp ik niet helemaal, volgens mij heeft de sensor een digitale i/o port nodig maar heeft hij dat nu met die TRISA ... of heb ik dat mis?
Met ADCON stel je de poort in als Digital I/O of ADC
Met Tris kies je of de poorten in of uitgangen zijn.
DS18B20 heeft 1wire digital IO dus vandaar dat ze
met ADCON de ADC uitschakelen en DIG IO aanzetten.
mijn oplossing in basic
------------------------------------------
Cls ' Clear LCD screen
ALL_DIGITAL = TRUE
Symbol dq = PORTA.5 ; inlees poort ds1820
OWrite dq,1,$cc,$44]
DelayMS 30
ORead dq, 4, [c]
OWrite dq, 1, [$cc, $be]
ORead dq, 2,[temp.LowByte,temp.HighByte,c ,c,c,c,c,cperd]
cls ; maak lcd schoon
temp4=(((temp>>1)*100)-25)+(((cperd-c)*100)/cperd); bereken hoge resolutie