logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[C][atmega8] Problem z ds18b20

max10 04 Paź 2010 12:33 3003 6
REKLAMA
  • #1 8582019
    max10
    Poziom 12  
    Witam

    Od paru tygodni próbuję uruchomić termometr na atmega8. Teoretycznie działa ale tylko do 70 stopni C, powyżej wyświetla 0,0. Korzystam z rklibavr. Proszę o pomoc

    Zamieszczam kod
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/eeprom.h>
    #include <string.h>
    
    #include <stdlib.h>
    #include "delay.h"
    #include "ds18x20.h"
    #include "ds18x20.c"
    #include <hd44780.c>
    
    
    char 					strvolt[7];
    uint8_t 				gSensorIDs[OW_ROMCODE_SIZE];
    uint8_t 				tekst[20];
    volatile float 		    f_value;
    uint16_t 				decicelsius;
    uint8_t 				diff, crc_m, start_m, i, subzero, cel, cel_frac_bits;
    	
    int main( void )
    {
    	
    
    	LCD_Initalize();
    
    
    	#ifndef OW_PORT
    		OW_set_bus(&PORTC,0);
      #endif
    
    	
    	while(1)
    	{
    
    		
          DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL) ;
          delayms( DS18B20_TCONV_12BIT );
          DS18X20_read_meas_single( DS18B20_ID, &subzero, &cel, &cel_frac_bits );
          decicelsius = DS18X20_temp_to_decicel( subzero, cel, cel_frac_bits ); 
    		
          LCD_Clear();
    		
          LCD_WriteText("Temp:");
    	  LCD_GoTo(6,0);
      	  f_value=(float)decicelsius/10;
    	  dtostrf(f_value,1,1,strvolt);
    	  LCD_WriteText(strvolt);
    	  LCD_WriteText(" 'C");
    		
    		
    	}
    		
    }
    
  • REKLAMA
  • #2 8582039
    bednyk
    Poziom 13  
    Wklej cały program, z tego co podałeś ciężko będzie wywnioskować co jest źle. Masz wywołania funkcji ale funkcji brak - nikt nie jest jasnowiedzem.
  • REKLAMA
  • #3 8582060
    max10
    Poziom 12  
    Termometr zaczął działać poprawnie. Teraz mam problem z podpięciem drugiego czujnika. Wykorzystuję bibliotekę rklibavr. Program w tej chwili wygląda tak :
    
    
    #include <avr/io.h>
    #include <inttypes.h>
    #include <util/delay.h>
    
    #include <stdlib.h>
    #include <string.h>
    
    #include <spin_delay.h>
    
    
    #include <stdint.h>
    #include <hd44780.c>
    
    //#include <avr/signal.h>
    #include "ds18x20.h"
    #include "delay.h"
    #include "onewire.h"
    #include "ds18x20.c"
    #include "onewire.c"
    #include "delay.c"
    
    
    #ifndef OW_PORT
    		OW_set_bus(&PORTC,0);
    #endif
    volatile int16_t 		decicelsius2;
    char 					strvolt[7];
    uint8_t 				gSensorIDs[OW_ROMCODE_SIZE];
    uint8_t 				tekst[20];
    volatile float 		    f_value;
    uint16_t 				decicelsius;
    uint8_t 				diff, crc_m, start_m, i, subzero, cel, cel_frac_bits;
    	
    int main( void )
    {
    	
    
    	LCD_Initalize();
    
    
    	#ifndef OW_PORT
    		OW_set_bus(&PORTC,0);
      #endif
    
    	DS18X20_find_sensor(&diff, &gSensorIDs[0]);
    	while(1)
    	{
    
    	i = gSensorIDs[0]; // family-code for conversion-routine
          DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL) ;
          delayms( DS18B20_TCONV_12BIT );
          DS18X20_read_meas_single( i, &subzero, &cel, &cel_frac_bits );
          decicelsius = DS18X20_temp_to_decicel( subzero, cel, cel_frac_bits ); 
    		
          LCD_ClearLine(0);
    		
          LCD_WriteText("wew:");
    	  LCD_GoTo(6,0);
      	  f_value=(float)decicelsius/10;
    	  dtostrf(f_value,1,1,strvolt);
    	  LCD_WriteText(strvolt);
    	  LCD_WriteText(" 'C");
    	  
    	  
    	  
    	  
    	  i = gSensorIDs[1]; // family-code for conversion-routine
          DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL) ;
          delayms( DS18B20_TCONV_12BIT );
          DS18X20_read_meas_single( i, &subzero, &cel, &cel_frac_bits );
          decicelsius = DS18X20_temp_to_decicel( subzero, cel, cel_frac_bits ); 
    		
          LCD_ClearLine(1);
    	  LCD_GoTo(0,1);
          LCD_WriteText("zew:");
    	  LCD_GoTo(6,1);
      	  f_value=(float)decicelsius/10;
    	  dtostrf(f_value,1,1,strvolt);
    	  LCD_WriteText(strvolt);
    	  LCD_WriteText(" 'C");
    		
    		
    	}
    		
    }
    
    
    
  • REKLAMA
  • #4 8586677
    max10
    Poziom 12  
    Jest ktoś w stanie mi pomóc odpalić 2 czujniki ds18b20 ?
  • REKLAMA
  • #5 8591295
    y0yster
    Poziom 19  
    Możesz odpalić 2 czujniki na jednej linii co jest częścią idei onewire lub też wykorzystać drugi pin do podpięcia kolejnego czujnika.

    Wady i zalety:

    Co do pierwszego rozwiązania zaleta jest taka, że wykorzystujesz tylko jeden pin od uC. Niestety aby poprawnie wszystko działało należało by, abyś znał ID każdego z czujników i "wołał go po imieniu" na magistrali. Co za tym idzie musisz najpierw odczytać ID każdego z nich. Również możesz zastosować algorytm (jest dostępny na stronie producenta), który umożliwia wywołanie wszystkich urządzeń, ale pojawia się problem z identyfikacją, który to który (w sensie fizycznym) ;). To właśnie, już będziesz musiał sam określić w programie.

    Wspomniałem także o drugiej możliwości. Zaleta jest taka, że nie musisz znać ID. Po prostu odwołujesz się do niego i już. Utrudnienie jest takie jak już opisałem wyżej. Potrzebujesz kolejnego wolnego pinu.
  • #6 8591929
    poorchava
    Poziom 18  
    Z tym id to jest coś takiego, że jak master (uC) wysyła reset, to potem musi nadać bodajże 64-bitowy kod identyfikacyjny czujnika, żeby czujnik wiedzial, że to do niego master wysyła informacje. Jak spodziewamy się większej ilości czujników, to wtedy master odpytuje czujniki jakie maja numery, a czujniki odpowiadają w jakiejśtam kolejności. natomiast jak masz jeden czujnik na jednej magistrali 1w, to master tylko pyta czujnik jaki ma numer. Szczegóły są w datasheecie ds18b20. Jak ma być prosciej, to chyba lepiej będzie podlaczyc drugi czujnik do innego pinu uC.
  • #7 8592011
    duke_luke
    Poziom 15  
    Wklejam funkcje których ja używam i działają w porządku. W moim wypadku jest to osiem czujników na jednej linii więc dla innej wartości też raczej nie będzie problemu. ID pobieram tylko przy jednym czujniku obecnym na magistrali.

    
    unsigned char get_onewire_id(void)
    {
    
    int n;
    
    RESET_PULSE(we);
    onewire_send_byte(0x33);   
    for (n=0;n<8;n++) 
    	{
    	id[n] = onewire_read_byte(); 
    	}
    
    return id;
    }
    


    
    char get_temp_from_id(unsigned char id[])
    {
       char temp1=0, temp2=0;
       int i;
       RESET_PULSE(we);                            // WYSŁANIE IMPULSU ZERUJĄCEGO
       onewire_send_byte(0x55);                    // WYSŁANIE KOMENDY MATCH ROM
       for (i=0;i<8;i++) onewire_send_byte(id[i]); // WYSTAWIENIE ADRESU NA MAGISTRALĘ
       onewire_send_byte(0x44);                    // WYSŁANIE KOMENDY CONVERT T
    
       _delay_ms(750); // CZAS KONWERSJI TEMPERATURY
    
       RESET_PULSE(we);                           // WYSŁANIE IMPULSU ZERUJĄCEGO
       onewire_send_byte(0x55);                   // WYSŁANIE KOMENDY MATCH ROM
       for (i=0;i<8;i++) onewire_send_byte(id[i]);// WYSTAWIENIE ADRESU NA MAGISTRALĘ
       onewire_send_byte(0xBE);                   // WYSŁANIE KOMENDY READ SCRATCHPAD
       
       temp1 = onewire_read_byte(); // POBRANIE LSB TEMPERATURY
       temp2 = onewire_read_byte(); // POBRANIE MSB TEMPERATURY
       RESET_PULSE(we);             // ZAKOŃCZENIE ODCZYTU SCRATCHPADA
       float buf=0;
       buf=(float)(temp1+(temp2*256))/16; // KONWERSJA TEMPERATURY
       dtostrf(buf,1,1,temperatura);      // NA STRING
       return temperatura; // ZWRÓĆ TEMPERATURĘ
       
    }
    


    Mam nadzieję, że to Ci pomoże, pozdrawiam.
REKLAMA