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

[C]Atmega8 i ds18b20 - problem z termometrem

ZjemCiKapcie 27 Gru 2010 09:23 2317 3
  • #1 8917574
    ZjemCiKapcie
    Poziom 10  
    Witam!
    Mam problem z termometrem, otóż wyświetla mi dodatkowe cyferki na wyświetlaczu (dołączam zdjęcie, żeby było wiadomo o co chodzi). Cały listing programu wzięty jest z tego kursu:
    http://hobby.abxyz.bplaced.net/index.php?pid=4&aid=8
    po małych, sporych modyfikacjach, otóż termometr miał działać również jako alarm do pieca CO (żeby nie zagotować wody) dlatego funkcję main przerobiłem w całości (obsługa lcd i ds nie ruszana poza zmianą nazwy portu).
    Pisałem wcześniej na forum diody (ponieważ kurs dotyczy bezpośrednio tego forum) ale mnie stamtąd wygonili xD
    W załącznikach pseudo algorytm samej idei działania programu oraz foto - jak wygląda problem.

    Edit:
    Zapomniałem dodać że dodatkowe cyferki pojawiają się co ~24h, po resecie procka jest normalnie

    Przed tym jak wygonili mnie z poprzedniego forum powiedzieli mi że program się sam zapętla co zawiesza procek i wyświetla takie "krzaki", z mojego punktu widzenia program nie mógł się zapętlić ponieważ ani razu jeszcze nie uruchomił się alarm.
    Teraz dlaczego zrobiłem wszystko na kilku funkcjach a nie w jednej, otóż miałbym problemy z tym żeby buzzer włączał się tylko po przekroczeniu danej temp a później kolejny raz po ponownym jej przekroczeniu, zwykły if by tu nie pomógł

    Generalnie rozwiązaniem problemu byłby chyba dodanie przed każdym zaktualizowaniem temperatury - "LCD clear", ale wtedy musiałbym wyświetlać górny napis w każdej funkcji...
    I tutaj moje pytanie, dlaczego tak się dzieje i może jakieś pomysły jak to rozwiązać? W ostateczności, przerobię cały kod tak żeby było wszystko w jednej funkcji ale to chyba niezbyt dobre rozwiązanie gdyż kod będzie się powtarzał a co za tym idzie będzie dość spory, a w planach miałem dodać pomiar temp zewnętrznej...

    No i moja modyfikacja, dodaje sam main, obsługa lcd i ds chyba nikogo nie interesuje...

    #include <stdio.h>
    #include <avr/io.h>
    #include <util/delay.h>
    #include "hd44780.h"
    #include "ds18b20.h"
    #define F_CPU 1000000L
    
    
    
    char str[17]="  Temp. pieca   ";
    double temp;
    
    /***funkcja jesli temp<90****/
    int tempok(void)
    {
    	while(1)
    	{
    	mierzetemp();
    	if(temp>=87.0)
    		{
    		tempmax();
    		}
    		
    	}
      
    }
    /****************************/
    
    
    /*****funkcja jesli temp>90***/
    	int tempmax(void)
    	{
    	DDRC=0xff;
    		PORTC=0b00000110;
    		_delay_ms(200000);
    		_delay_ms(200000);
    		_delay_ms(200000);
    		_delay_ms(200000);
    		
    	while(1)
    		{
    		PORTC=0b00000100;
    		_delay_ms(200);
    		PORTC=0b00000000;
    		mierzetemp();
    		if(temp<86.0)
    			{
    			tempok();
    			}
    		}
    	}
    	/************************/
    
    
    /**funkcja mierzy temp z czujnika**/
    int mierzetemp(void)
    {
      unsigned char ds18b20_pad[9];
      
      
         if(ds18b20_ConvertT())
        {
           _delay_ms(750);
           ds18b20_Read(ds18b20_pad);      
           temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;
           sprintf(str,"%4.1f\xdf""C", temp);
    	   LCD_CLEAR; 
           LCD_LOCATE(5,1);
           lcd_puts(str);
        }
    }
    /************************************/
    
    
    
    /********glowna funkcja*****/
    int main(void)
    {
    
    DDRC=0xff;
    
      unsigned char ds18b20_pad[9];
      lcd_init();
      LCD_DISPLAY(LCDDISPLAY);  
      LCD_CLEAR;           
      LCD_LOCATE(0,0);
      lcd_puts(str);
      
      tempok();
    
    }
    /**************************/
  • Pomocny post
    #2 8921216
    michalko12
    Specjalista - Mikrokontrolery
    1. Napisz program od nowa bez wywołań rekurencyjnych
    2. Napisz program od nowa bez wykorzystania liczb zmiennoprzecinkowych
    3. Napisz program od nowa bez wykorzystania funkcji sprintf
    4. Co to jest LCD_CLEAR? Makro czy funkcja? Jeśli funkcja to czegoś brakuje przy jej wywołaniach.
  • Pomocny post
    #3 8921678
    gdL
    Poziom 27  
    Zła struktura, nieskończona rekurencja. Funkcje powinny zwracać wartość int.
    
    
    int tempok() {
       while(1) {
          if (xxx) {
          tempmax();
          }
       }
    }
    
    int tempmax() {
       while(1) {
          if (xxx) {
          tempok();
          }
       }
    
    }
    
    int main() {
    tempok(); 
    }
    



    Struktura powinna być np taka :
    
    void tempmax() {
    //zrób coś
    }
    
    void tempok() {
    //zrób coś innego
    }
    
    int mierzetemp() {
    //prosze, daj mi temp Deesku.
    return temp;
    }
    
    int main() {
    int histereza=0;
       while(1) {
       temp = mierzetemp();
          if (temp>86+histereza) {
          histereza=-1;
          tempmax();
          } else {
          histereza=1;
          tempok();      
          }
       _delay_ms(200000);
       }
    return 0;
    }
    


    Nie używaj typów zmiennoprzecinkowych (to już było wspomiane przez Kolegę), wykorzystaj rozpiętość zmiennej int, albo przekazuj osobno część ułamkową i całkowitą w char'ach. Takie moje sugestie, powinno być lepiej i bez błędów.
  • #4 8927801
    ZjemCiKapcie
    Poziom 10  
    Ok dzięki Panowie za odpowiedź, dzisiaj spróbuje przerobić kod ;)
    pozdrawiam
REKLAMA