Skocz do zawartości

Kod do DS18B20 - co jest źle?


Pomocna odpowiedź

Napisano

Witam. Napisałem kod w języku C żeby uruchomić popularny czujnik DS18B20. Przepisałem z zrozumieniem na tyle ile potrafiłem kod znaleziony w sieci, został trochę zmodyfikowany. Dodałem wyświetlanie temperatury z zmiennej po przecinku na LCD.

#define F_CPU 8000000UL
#include <HD44780.h>
#include <HD44780.c>
#include <ds18b20.c>
#include <ds18b20.h>
#include <stdio.h>

int main(void) {
	LCD_Initalize();
	char bufor[100];
	uint8_t temp;
    LCD_Clear();

    int a, b;
    double c = temp;
	c+=0.5;
	a=c;
	c-=a-0.5;
	c=c*10+0.5;
	b=c;

    while (1) {
    	temp=ds18b20_gettemp();
		LCD_GoTo(0,0);
		LCD_WriteText("Temp: ");
		sprintf(bufor, "%d,%d", a, b);
	    LCD_GoTo(6,0);
        LCD_WriteText(bufor);
        LCD_GoTo(14,0);
        LCD_WriteData(223);
        LCD_GoTo(15,0);
        LCD_WriteText("C");
	}
}

Czasem kompilacja przebiega poprawnie a innym wypluwa warning:
../main.c: In function 'main':
../main.c:17:12: warning: 'temp' is used uninitialized in this function [-Wuninitialized]
double c = temp;

W obu przypadkach wyświetla się to samo:
Temp: 0,10 C

(edytowany)

Dobrze, To jak ma wyglądać ta część kodu? To miało być do wyświetlenia wartości przed i po przecinku. Rozdzielone. Jak to należy ująć?

Edytowano przez bluzman
3 godziny temu, bluzman napisał:

../main.c:17:12: warning: 'temp' is used uninitialized in this function [-Wuninitialized]

specyfika języka C, gwarantowane jest zerowanie zmiennych statycznych "static" i globalne powinny też być zerowane ale zmienne lokalne powinieneś inicjalizować sam. Zależy to też w dużej mierze od samego kompilatora ale dobrym zwyczajem jest inicjalizowanie wszystkich zmiennych jawnie.

Być może nie rozwiąże to Twojego problemu z czujnikiem ale warn na pewno zniknie 😉

13 godzin temu, Belferek napisał:

Co tu pisać jak już wiele na ten temat napisano - zobacz

Tutaj jest opis dla Arduino ja mam uC i potrzebuję naprawy błędów w czystym C.

13 godzin temu, atMegaTona napisał:

Być może nie rozwiąże to Twojego problemu z czujnikiem ale warn na pewno zniknie 😉

Tu miałeś rację, zniknęło i do końca nie rozwiązałem problemu. Nie wiem czy o to Ci chodziło ale napisałem tak:

int main(void) {
	LCD_Initalize();
	char bufor[100];
	uint8_t temp;
    LCD_Clear();

    while (1) {
    	temp=ds18b20_gettemp();
    	   int a, b;
    	    double c = temp;
    	    c+=0.5;
    		a=c;
    		c-=a-0.5;
    		c=c*10+0.5;
    		b=c;
    	LCD_GoTo(0,0);
		LCD_WriteText("Temp: ");
		sprintf(bufor, "%d,%d", a, b);
reszta...

Teraz zmienia się to co jest przed przecinkiem a po przecinku wyświetla cały czas ,10

Nie rozumiem dlaczego przyczepiłeś się tak do tego %d. Przejrzałeś w ogóle repertuar znaków formatujących?

https://pl.wikibooks.org/wiki/C/printf

Przecież masz tam także opcje wypisywania typów float i pochodnych w formacie stałoprzecinkowym (w odróżnieniu od postaci z wykładnikiem po 'E'), gdzie po prostu określasz szerokość pola i liczbę miejsc po przecinku (dla %d także jest możliwe określenie szerokości pola). Naprawdę podejrzewasz, że miliony programistów tak by się męczyły z tym liczeniem i kombinowaniem "%d,%d" przy każdej liczbie wypisywanej w konkretnym miejscu z jakimś założonym wyrównaniem położenia?

(edytowany)
11 minut temu, marek1707 napisał:

Przecież masz tam także opcje wypisywania typów float i pochodnych w formacie stałoprzecinkowym

Cytując manuala do avr-glibc (podkreślenie moje):

Cytat

For floating-point conversions, if you link default or minimized version of vfprintf(), the symbol ? will be output and double argument will be skiped

Więcej na ten temat: https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#gaa3b98c0d17b35642c0f3e4649092b9f1

Ponieważ włączenie pełen wersji printf to o ile pamiętam ponad kilobajt kodu więcej - w wielu przypadkach opłaca się wyświetlać floata jako dwa inty.

Tyle że tak jak kolega wątkotwórca to się nie robi...

Edytowano przez ethanak
50 minut temu, bluzman napisał:

Tutaj jest opis dla Arduino ja mam uC i potrzebuję naprawy błędów w czystym C.

Nie chcę się czepiać ale czy ATmega328 to nie uC?

temp=ds18b20_gettemp();
int a, b;
double c = temp;
c+=0.5;
a=c;
c-=a-0.5;
c=c*10+0.5;
b=c;

Swoją drogą nie rozumiem tego kodu - może to przez koronawirusa - mógłbyś wyjaśnić po co takie karkołomne obliczenia?

(edytowany)
3 godziny temu, bluzman napisał:

Tu miałeś rację, zniknęło i do końca nie rozwiązałem problemu. Nie wiem czy o to Ci chodziło ale napisałem tak:

 Miałem na myśli:

uint8_t temp = 0;

I ja też nie rozumiem co maja na celu te przeliczenia i przypisania. Na moje oko nie ma to sensu, ale cóż, sztuka to sztuka 😄

Edytowano przez Gość

Przyznam się - z samej ciekawości napisałem według tego "algorytma" krótki programik w C i odpaliłem na swoim pececie. Większych bzdur niż wyniki dawno nie widziałem...

Przepisz to najlepiej punkt po punkcie od nowa to sam zauważysz co jest nie tak. Najgorzej jest kiedy nie wyrzuca błędów a działa nieprawidłowo. W niektórych przypadkach lepiej sprawdzić 10 razy niż raz się pomylić.

Może wytłumacz własnymi słowami jaki cel ma to dodawanie i odejmowanie 0.5 od tego uinta.

 

5 godzin temu, Belferek napisał:

Nie chcę się czepiać ale czy ATmega328 to nie uC?

Tak ale nie w tym rzecz czy to uC w Arduino czy czymś innym tylko o składnię języka i w ogóle jaki język jest używany.

Przypominam, że C jest podzbiorem C++...  i 100% tego co się pisze w C zadziała w C++. Błedy w C będą również błędami w C++.

Aha, i nie ma języka Arduino.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...