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

[Atmega16][C]dwupunktowy termometr ds18b20 ,definicja pliku ds18b20.h

mirek1968 17 Kwi 2012 01:12 13088 40
Najlepsze odpowiedzi LABEL_AI_GENERATED

Jak przerobić działający program z jednym DS18B20, żeby obsługiwał dwa czujniki na osobnych pinach ATmega16 i wyświetlał jednocześnie temperaturę zewnętrzną i wewnętrzną na LCD 2x16?

Aby obsłużyć dwa DS18B20 na PA0 i PA2, trzeba przerobić bibliotekę tak, żeby funkcje przyjmowały port i pin procesora jako argument, bo sama zmiana pliku `.h` nie wystarczy [#10803260][#10812961] Najlepiej wywoływać osobno odczyt i konwersję dla każdego czujnika oraz w `main.c` przypisać jeden sensor do PA0, a drugi do PA2 i osobno wpisać oba wyniki na LCD [#10812961] W odpowiedzi padł też gotowy, przerobiony projekt z `onewire.c/.h`, w którym można mierzyć temperaturę z wielu czujników, o ile każde wywołanie jest skierowane na odpowiedni port i pin [#10812961] Jeśli kiedyś chcesz podłączyć kilka DS18B20 do jednej linii 1-Wire, trzeba już obsługiwać ich 64-bitowe adresy ROM zamiast `skip ROM`; adres można wpisać w `.h` albo trzymać w EEPROM [#10860237]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 10802967
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Mam prośbę jak zdefiniować dwa czujniki ds18b20 na osobnych pinach atmegi16 w języku c ,tak aby temperatura zew i wewn były ciągle wyświetlane na lcd2X16.Chodzi mi o modyfikacje już działającego mi programu z jednym czujnikiem.Poniżej wstawiam mój działający plik.h na pinie PA0,proszę o pomoc.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
    Poprawiłem temat na zgodny z regulaminem p. 3.1.15.
    Regulamin Forum napisał:
    Tytuł wpisu powinien zawierać markę, model oraz skrótowy opis usterki.
    LordBlick
  • REKLAMA
  • #2 10803260
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Witam,

    Modyfikacja samego pliku nagłówkowego nie starczy. Funkcje muszą przyjmować jako jeden z argumentów pin procesora na którym jest DS, ewentualnie drugie wyjście-podwójny zestaw funkcji-jeden dla pierwszego DS'a drugi dla drugiego, ale to rozwiązanie bardzo nieekonomiczne.

    Pozdrawiam,
    Marcin
  • #3 10803274
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Ale w jaki sposób dopisać do mojego pliku.h te drugie wyjście?

    Dodano po 48 [minuty]:

    W głównym programie main.c jest odczyt z czujnika ds18b20 podpiętego do pinu PA0 a na chwilę obecną temperatura zew i wew jest czytana z tego samego czujnika bo nie potrafię zdefiniować drugiego czujnika na pinie PA2.Czy mam stworzyć nowy olik z rozszerzeniem .h? np:ds18b20x.h? czy w jaki inny sposób.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #4 10812961
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Cały program jest do napisania od nowa.
    Ulżę Ci w Twej niedoli :). Napisałem program - jeszcze nie do końca sfinalizowany - ale czyta temperaturę z DS-a poprawnie. Funkcje przyjmują port i pin na którym jest DS.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W pliku .h zmieniasz tylko prędkość kwarcu.

    [/code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Przykład użycia:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Na tym kodzie możesz podpiąć tyle czujników ile masz portów w uP.
    Kod jest w miarę komentowany więc powinieneś się połapać co i jak.
    Jeśli znajdziesz jakieś błędy w działaniu/kodzie pisz, wszystko nie było dokładnie testowane.
    Będę wdzięczny.

    Pozdrawiam,
    Marcin
  • #5 10814506
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Bardzo dziękuję Ci za zainteresowanie moim problemem i konkretną odpowiedź z przykładem programu.Jeśli dobrze zrozumiałem te moje pliki ds18b20.c oraz ds18b20.c zostały teraz zastąpione Twoimi plikami onewire.c i onewire.h .
    W moim main.c podanym powyżej używałem zmienne "ds18b20_Read" oraz "ds18b20_ConvertT" z mojego pliku ds18b20.h pokazanych w poprzednich moich wpisach.Przyznam się że nie wiem jakich zmiennych mam teraz użyć do mojego pliku main.c Bardzo bym Cię prosił jeszcze żebyś spojrzał do mojego pliku main.c i pomógł mi zastosować twoje zmienne tak żebym mógł wyświetlić temperaturę zewnętrzną i wewnętrzną .W skrócie chodzi mi żebyś pomógł mi zmodyfikować mój konkretny plik main.c biorąc pod uwagę że w obecnej chwili LCD pokazuje mi temperaturę wewn i zewn z jednego czujnika.Moje doświadczenie jest bardzo malutkie dlatego proszę o dalszą pomoc.
    pozdrawiam Mirek
  • #6 10820136
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Jest jeszcze jedna rzecz którą muszę wiedzieć ;). Jeśli mam coś wyświetlić na wyświetlaczu, korzystając z Twojego kodu jako bazy, potrzebuję Twojej biblioteki do obsługi LCD. Ewentualnie podeślę Ci gotową moją bibliotekę do LCD i napiszę kompletny kod.
    Wybór należy do Ciebie :)

    Co do zmiennych to unikamy na AVR floatów. Operacje na nich zajmują wieki i wpierniczają sporo flash, procesorowe oczywiście :D, Moje funkcje nie posiadają żadnych floatów - u Ciebie można użyć floatów bo procesor "nie wiele robi" poza pomiarem temperatury, jednak nie polecam wejdzie Ci to w nawyk - zamiast 1.2 lepiej dać 12 (1.2*10) a przy wyświetlaniu wstawić na "sucho" kropkę.

    Będę potrzebował jeszcze informacji na temat Twojego hardware - może jakiś schemat połączeń?? ewentualnie opis co jest podłączone do jakich pinów w uP.
  • #7 10820863
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Tak wygląda moje pliki do obsługi LCD z rozszerzeniem .h i .c

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod




    Kod: C / C++
    Zaloguj się, aby zobaczyć kod



    Po za tym przesyłem Ci obrazek mojego układu testowego który sam sobie kiedyś zrobiłem na podstawie wzoru od mojego krewnego.Na tej płytce uczę się podstaw c-avr.Założyłem ten temat na elektrodzie z powodu chęci zrobienia sobie termometru dwupunktowego do mojego autka tak żeby mi pokazywał na początku komunikat powitalny a potem przechodził do wyświetlenia jednoczesnego pomiaru temperatury zewnętrznej i wewnętrznej ,myślałem także w przyszłości dołożyć sobie zegar czasu rzeczywistego oraz pomiar wartości napięcia akumulatora ale nie jestem jeszcze na takim etapie żebym sam sobie poradził ze wszystkim.Wejścia które chciałbym wykorzystać do czujników temperatury to PA0 i wolne mojej płytce testowej PA2.Poniżej jest adres mojej płytki testowej.

    [Atmega16][C]dwupunktowy termometr ds18b20 ,definicja pliku ds18b20.h

    Pozdrawiam serdecznie i czekam na dalszą pomoc:-)
    Mirek
  • #8 10821141
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    Czemu filtrujesz ten układ tylko w 1/10 ? :)
  • REKLAMA
  • #10 10822421
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Dzięki "dondu" za cenne uwagi co do pinu AVcc ,przyznam się że nie wiedziałem o ich znaczeniu-muszę to zmienić na mojej płytce.Jeśli chodzi o uwagę o filtrowaniu 1/10 to nie do końca wiem o co chodzi?:-).
    Proszę o więcej szczegółów "gaskoin".
  • REKLAMA
  • Pomocny post
    #11 10822464
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    kondensatory 100n powinieneś jeszcze dorzucić na piny zasilania układów + w pobliże regulatora.
  • #13 10823372
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Tak dzięki dondu ,przeczytałem ten link i zastosuję filtrowanie zasilania procesora atmega16 poprzez kondensatory 100n oraz pinu AVcc na mojej płytce.Jeszcze raz dzięki .Na razie jednak głównym moim problemem jest realizacja wyświetlania temperatury zewnętrznej i wewnętrznej jednocześnie na LCD używając pinów PA0 i PA2 i dwóch czujników ds18b20.Powyżej we wcześniejszych moich postach zamieszczone są wszystkie moje pliki w języku c.Każda konkretna pomoc w modyfikacji moich plików będzie mile widziana.Jak dotąd mój LCD wyświetla temperaturę z jednego czujnika i proszę wszystkich szanownych fachowców w c-avr o dalszą pomoc:-)
    Mirek
  • #14 10823897
    dondu
    VIP Zasłużony dla elektroda
    Posty: 13906
    Pomógł: 1292
    Ocena: 809
    Ponieważ zmieniłeś swój pierwszy post, czyli problemem pozostaje to?:

    mirek1968 napisał:
    W skrócie chodzi mi żebyś pomógł mi zmodyfikować mój konkretny plik main.c biorąc pod uwagę że w obecnej chwili LCD pokazuje mi temperaturę wewn i zewn z jednego czujnika.
  • #15 10825886
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Nie zmieniałem raczej treści mojego problemu w pierwszym poście.
    Głównie chodzi mi o to że w podanych powyżej działających kodach c. wyświetla mi się temperatura zew i wew z jednego czujnika który wisi na pinie PA0 bo nie potrafię zaadoptować drugiego czujnika np. na wolnym pinie PA2 lub ewentualnie jeśli tak lepiej na jednej linii 1-wire wykorzystując tylko jeden pin PA0.
    Zależy mi tylko na tym żeby ktoś mi pomógł zmodyfikować te moje pliki tak żebym mógł wyświetlać pomiar z dwóch czujników ds18b20.Sam tego problemu nie rozwiążę dlatego poprosiłem na tym forum o pomoc i liczę na nią .:-)
    Na tym forum wstawiłem wszystkie działające na mojej płytce testowej pliki i jej schemat.
  • Pomocny post
    #16 10827860
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Witam ponownie,

    Nie będę się rozwodził nad kondensatorami bo temat nie ten, ale koledzy mają racje :)

    Poniżej obiecany kod, a raczej cały projekt w Avr Studio 4 - to miał być program termostatu 4-kanałowego jednak jeszcze czeka w kolejce na finalizacje :) Przerobiłem main'a dla Twoich potrzeb. Powinno być ok, jeśli nie będzie to kwestia przypisania pinów do funkcji.
    Programik tylko mierzy i wyświetla "suchą" temperaturę bez st. Celsjusza chyba nawet, wystarczy trochę powiększyć tablicę w ram na znaki i na sztywno dopisać [*C], ewentualnie skorzystać z funkcji locateXY i umieścić odpowiednie znaki w odpowiednim miejscu na LCD.

    Pozdrawiam,
    Marcin
    Załączniki:
    • 4channelThermostat.rar (51.05 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #17 10829019
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Dziękuję Szumlus za działający program.Udało mi się wstawić na stałe napis temp zew i wew ale brakuje mi miejsca na LCD i nie potrzebna mi jest dokładność do trzech miejsc po przecinku-wolałbym jedno miejsce tylko.Co mam zmienić żeby była jedna liczba po przecinku przy pomiarze bo wtedy mógłbym wstawić jeszcze *C.
    I jeszcze jedno pytanie zamiat *C jak napisać rzeczywisty symbol stopni C(czyli taki mały kwadracik przed C.
    Proszę o odpis i jeszcze raz bardzo dziękuję za konkretną pomoc.
    pozdrawiam
    Mirek:-)
  • #18 10830086
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Zmieniasz w tej funkcji poniżej ostatnią daną wejściową i zmieniasz dokładność:
    np.
    OW_FormatRawTemperature(CharBuffer,CurrentTemp2,1);

    Co do kwadracika to musisz znać jego symbol w wersji cyfrowej :) Ja niestety nie znam. Trzeba przeglądnąć tabele znaków HD4478 sprawdzić czy jest taki znak, jeśli jest wysyłamy do sterownika jego wartość w postaci bajta. Jeśli nie będzie to trzeba zdefiniować :)
  • REKLAMA
  • #19 10832531
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Nie wiem dlaczego ale pierwsza cyfra po przecinku w wyświetlaniu temperatury tzn. dziesiętna część stopnia nie zmienia się i jest ciągle 0 .Natomiast liczby setne i tysięczne zmieniają się i są ok.Zauważyłem problem z pierwszą po przecinku dopiero dziś:-)
    Jak na razie to jeszcze nie udało mi się wyświetlić st C.Pewnie muszę więcej przy tym posiedzieć.:-)
  • #20 10833827
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Możliwe że znalazłeś bug'a w sofcie xD.
    Jak będę miał chwilkę to sprawdzę w czym tkwi problem.
    Poczytaj jeszcze datasheet DS'a. Może to zależeć od typu czujnika.
    Ja testowałem wszystko na ds18s20 a ten ma rozdzielczość 0.0625 stopnia.
    Jeśli masz inny rozdzielczość pomiaru może być inna i niepoprawnie przelicza moja funkcja konwersji do tablicy znaków.
  • #21 10835519
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Mam czujniki o symbolu ds18b20,pewnie różnią się od Twoich,nie wiem tylko gdzie i co zmienić żeby było poprawne wyświetlanie dziesiątek części stopnia po przecinku.
    Ale pewnie jak tylko znajdziesz troszkę czasu to mi pomożesz:-)
  • #22 10855166
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Mam prośbę o pomoc.W jaki sposób wykorzystać odczytany numer ID ROM CODE z mojego czujnika ds18b20.
    Odczytałem go pewnym programem z sieci i mam coś takiego na LCD:
    28776CBB02000079 jest to 16- bitowy kod ale nie wiem jak go dalej wykorzystać w w programie termometru na magistrali 1-wire tym razem wykorzystując jeden tylko pin procesora.Ogólnie chodzi mi o to że teraz np: podłączę do mojej płytki testowej drugi czujnik ds18b20 i odczytam inny kod 16-bitowy to jak to wykorzystać w programie.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    /*
    Plik ds18b20.h

    (xyz.isgreat.org)
    */

    #ifndef DS18B20_H
    #define DS18B20_H

    /* DS18B20 przylaczony do portu PD7 AVRa */
    #define SET_ONEWIRE_PORT PORTA |= _BV(0)
    #define CLR_ONEWIRE_PORT PORTA &= ~_BV(0)
    #define IS_SET_ONEWIRE_PIN PINA & _BV(0)
    #define SET_OUT_ONEWIRE_DDR DDRA |= _BV(0)
    #define SET_IN_ONEWIRE_DDR DDRA &= ~_BV(0)

    char ds18b20_ConvertT(void);
    char ds18b20_Read(unsigned char []);
    void OneWireStrong(char);
    unsigned char OneWireReset(void);
    void OneWireWriteByte(unsigned char);
    unsigned char OneWireReadByte(void);
    unsigned char OneWireReadTimeSlot(void);


    #endif
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Poniżej podałem plik ds18b20.h i proszę o modyfikację tego pliku wykorzystując odczytane kody ID czujników w postaci 16-bitów tak jak opisałem wyżej.
    Chciałbym dodaj jeszcze że docelowo chodzi mi odczyt i wyświetlenie na LCD temperatury z dwóch czujników podłączonych do magistrali 1-wire wykorzystując jeden pin procesora odróżniając jeden od drugiego poprzez różny kod ID.
  • #23 10860237
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Mój program nie uwzględnia podłączenia dwóch czujników do jednej linii.
    Trzeba by przerobić funkcję odczytów tak aby nie ignorować adresów (opcja/komenda skip ROM powoduje ominięcie adresowania).
    Adres w DS ma 64 bity a nie jak kolega napisał 16 bit.
    Trzeba by go gdzieś wprowadzać po odczycie. Można na etapie kompilacji w plik np. .h lecz zmiana czujnika wiązać się będzie z rekompilacją programu. Lepiej umieścić go w EEPROM przez zapis z poziomu programatora lub lepiej dodać funkcję "uczenia się" adresu nowego czujnika. Temat dość obszerny.
    Zerknę na temat, lecz dopiero w drugiej połowie przyszłego tygodnia wcześniej nie dam rady ;/.
  • #24 10861477
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Mam do Ciebie prośbę Szumlus cofnijmy się do Twojego przed ostatniego postu ,chodzi mi o to czy szukałeś może błędu w programie dotyczącego tego że nie wyświetla mi części dziesiętnej temperatury bo gdyby mi dobrze wszystko wyświetlało to bym nie kombinował z 1-wire tylko poprzestał bym na Twoim projekcje wykorzystując dwa piny procesora(tzn.każdy pin na osobny czujnik).
    Co do rozdzielczości czujnika ds18b20 to jest to samo co u Ciebie i nie wiem w czym tkwi błąd.
    Mam czujniki o symbolu ds18b20,pewnie różnią się od Twoich,nie wiem tylko gdzie i co zmienić żeby było poprawne wyświetlanie dziesiątek części stopnia po przecinku.
    Ale pewnie jak tylko znajdziesz troszkę czasu to mi pomożesz:-)
  • #25 10903124
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Mam pytanie dotyczące łączenia instrukcji programów w całość .
    Chodzi mi o to że robię sobie termometr w którym odczytam sobie temperaturę wewnętrzną ,zewnętrzną a także napięcie swojego akumulatora i czas,datę z układu DS1307.W jaki sposób połączyć kilka plików to ze sobą w sposób profesjonalny?
    Czy wszystko ująć w jednej pętli "while"?.ale wtedy są opóźnienia w realizacji programu które nie są wpisane na początku pętli programowej.
    Poniżej przedstawiam mój program w którym mam na początku komunikat powitalny potem odczyt temperatury i pomiar napięcia akumulatora proszę o poprawienie błędów w łączeniu instrukcji lub o inne cenne uwagi i przykłady poprawnego łączenia najlepiej na przykładzie mojego działającego main.c .
    W przedstawionym poniżej programie mam podzielone na kawałki i wymieszane części programu na termometr i woltomierz bo nie wiedziałem jak mam to zrobić profesjonalnie.Proszę o cenne konkretne rady.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    /*
    Plik main.c

    KURS AVR-GCC cz.5
    Wyswietlacz alfanumeryczny LCD HD44780
    (schemat i opis dzialania w artykule)

    uklad atmega16 (16MHz)
    */
    #define F_CPU 16000000L
    #define VREF 5.00
    #define ADCIN PA1
    #include <avr/io.h>
    #include <util/delay.h>
    #include <stdio.h>
    #include "hd44780.h"
    #include "ds18b20.h"

    char str[17]="Temp zew";



    int main(void)
    {


    DDRB = 0b11111101; // linie PB0,2,3,4,5,6,7 są wyjściami ,linia PB1 jest wejściem//
    PORTB = 0b00001010; // podświetlenie LCD poprzez PB3//

    /* Napisy przechowujemy w tablicach */
    char str1[] = "SKODA";
    char str2[] = " FABIA";
    char str3[] = "HATCHBACK CLAS";
    char str4[] = "U=";

    //Komunikat powitalny//


    /* Funkcja inicjalizuje wyswietlacz */
    lcd_init();


    // Wlacza wyswietlanie z widocznym kursorem
    LCD_DISPLAY(LCDDISPLAY|LCDCURSOR);

    //Ustawia kursor w pozycji:
    //pierwszy wiersz, szosta kolumna
    LCD_LOCATE(5,0);

    // Wysyla do wyswietlacza jeden znak
    LCD_WRITE_DATA('W');
    _delay_ms(300);

    LCD_WRITE_DATA('I');
    _delay_ms(300);

    LCD_WRITE_DATA('T');
    _delay_ms(300);

    LCD_WRITE_DATA('A');
    _delay_ms(300);

    LCD_WRITE_DATA('M');


    _delay_ms(800);

    // Ukrywa kursor
    LCD_DISPLAY(LCDDISPLAY);

    LCD_CLEAR;
    LCD_LOCATE(2,0);

    //Funkcja lcd_puts wysyla do
    //wyswietlacza ciag znakow
    lcd_puts(str1);
    _delay_ms(1000);

    lcd_puts(str2);
    _delay_ms(1000);

    LCD_LOCATE(1,1);
    lcd_puts(str3);
    _delay_ms(1000);

    LCD_CLEAR;
    LCD_LOCATE(0,0);

    lcd_puts("Nr.Rejestracyjny");
    _delay_ms(1000);

    LCD_LOCATE(4,1);
    lcd_puts("SRC 38YS ");

    // Czeka 2.5 sek.
    _delay_ms(1000);

    // Czysci ekran
    LCD_CLEAR;


    //Woltomierz//

    char wynik[]=" ";//bufor tekstowy, wyczyszczenie bufora
    float adc;//zmienna do obliczeń napięcia



    //Inicjalizacja ADC
    ADCSRA = (1<<ADEN) //Bit 7 - ADEN: ADC Enable (uruchomienie przetwornika)
    |(1<<ADPS0)
    |(1<<ADPS1)
    |(1<<ADPS2); //ADPS2:0: ADC Prescaler Select Bits
    //(ustawienie preskalera) preskaler= 128

    ADMUX = (1<<REFS0) //Bit 6 - REFS0:1: Reference Selection Bits
    ///VCC jako napięcie referencyjne with external
    //capacitor at AREF pin
    | (1<<MUX0); //Input Channel Selections (ADA1 - Pin 1 )

    DDRA &=~ (1<<ADCIN); //Ustawienie Wejścia ADC



    //Termometr//


    /* Zmienna przechowuje aktualną wartość temperatury */
    double temp;
    /* W tablicy zapisywane będą dane odczytane z układu ds18b20 */
    unsigned char ds18b20_pad[9];

    /* Funkcja inicjalizuje wyświetlacz */
    lcd_init();
    /* Włącza wyświetlanie */
    LCD_DISPLAY(LCDDISPLAY);
    /* Czyści ekran */
    LCD_CLEAR;

    /* Wyświetla tytuł */
    LCD_LOCATE(0,0);
    lcd_puts(str);

    while(1)
    {

    //Woltomierz//

    ADCSRA |= (1<<ADSC);//ADSC: Uruchomienie pojedynczej konwersji

    while(ADCSRA & (1<<ADSC));//czeka na zakończenie konwersji

    adc=ADC*VREF/1024; //przeliczenie wartości na napięcie
    sprintf(wynik,"%1.1fV",adc*3); //konwersja na łańcuch znakowy
    LCD_LOCATE(9, 1);
    lcd_puts(str4);
    LCD_LOCATE(11, 1); //Ustawienie kursora w pozycji (1,1)
    lcd_puts(wynik); //Wyświetlenie wyniku
    _delay_ms(500); //opóźnienie


    //Termometr//

    /* Funkcja 'ds18b20_ConvertT' wysyła do układu ds18b20
    polecenie pomiaru */

    if(ds18b20_ConvertT())

    {

    /* 750ms - czas konwersji */
    _delay_ms(750);

    /* Odczyt z układu ds18b20, dane zapisywane są w tablicy ds18b20_pad.
    Dwie pierwsze pozycje w tablicy to kolejno mniej znaczący bajt i bardziej
    znaczący bajt wartość zmierzonej temperatury */
    ds18b20_Read(ds18b20_pad);

    /* Składa dwa bajty wyniku pomiaru w całość. Cztery pierwsze bity mniej
    znaczącego bajtu to część ułamkowa wartości temperatury, więc całość
    dzielona jest przez 16 */
    temp = ((ds18b20_pad[1] << 8) + ds18b20_pad[0]) / 16.0 ;

    /* Formułuje komunikat w tablicy 'str' */
    sprintf(str,"%4.1f\xdf""C", temp);

    LCD_LOCATE(9,0);
    /* Wysyła komunikat do wyświetlacza */
    lcd_puts(str);
    }

    }

    }
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #26 10909994
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Ave,

    Przepraszam ,że tak późno ale nie dało rady wcześniej ;/.

    Poniżej obiecany kod, temperatura wyświetlana już poprawnie.
    Podmieni kolega tylko zawartość pliku onewire.c
    [code]
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Odnośnie kolejnego postu zrobię edit poźniej i odpowiem ;].
  • #27 10914465
    mirek1968
    Poziom 13  
    Posty: 162
    Ocena: 1
    Dzięki Szumlus:-)
    Układ działa ok poza wyświetlaniem opisu st C.
    Jest natomiast inny problem przelatuje mi kursor od lewej do prawej strony i jest to widoczne na wyświetlaczu LCD podczas wyświetlanie temperatury.
    Nie wiem z czym jest to związane,może jakiś czas odświeżania odczytu jest nie odpowiedni a jeśli tak to który czas?
    pozdrawiam Mirek
  • #28 10915030
    baracuda2
    Poziom 13  
    Posty: 166
    Ocena: 23
    dzisiaj testowałem pliki od Szumulusa na atmedze16 i ni wiem czy to wina mojego mikrokontrolera ale np na portach PA1, PA2 temperatura albo wskazywała ok 60 stopni albo np na pinach PA5 6 stopni (w pomieszczeniu ok 20 stopni). Na portach PA0 , PB0 otrzymany wynik jest w granicach błędu. Drugie pytanie jak mogę porównywać temperatury , w tej wersji wynik mamy otrzymywany w char (do zapisu max i in temperatury).
  • #29 10918503
    Szumlus
    Poziom 17  
    Posty: 124
    Pomógł: 27
    Trzeba prawdopodobnie tylko wyłączyć kursor.
    Funkcja void LCD_SendCommand(unsigned char ucCommand) komendy zdefiniowane l pliku .h LCD
    Ewentualnie spróbuj pobawić się kontrastem może uda się go ustawić tak aby nie było bardzo widać przejścia kursora podczas odświeżania.

    Co do porównania temperatur w bibliotece onewiere.c jest funkcja OW_CompareRawTemperature. Rzuć na nią okiem, ja ją jeszcze sprawdzę - nigdy jej jeszcze nie używałem - działa w ten sposób ze pobiera temperaturę z ds (8 bit temperatura w liczbach całkowitych o 4 bity ułamka) i porównuje z dwiema zmiennymi (twoja temp w liczbach całkowitych oraz twoja temperatura część ułamkowa). W zależności od wyniku porównania zwraca 0,1 lub -1. Funkcja póki co na pewno nie działa z temperaturami ujemnymi!

    Może trochę wszystko na około, ale to tylko z jednego względu - chciałem uniknąć używania float'ów.
    Zjadają bardzo dużo czasu oraz Flash'u procesora.
    Jeśli jednak ktoś robi nie wiele poza pomiarem i wyświetlaniem temperatury może użyć float'a, sporo operacji - takich jak np. porównywanie liczb - się uprości z punktu widzenia piszącego kod. Do konwersji float'a do string'u jest odpowiednia funkcja w bibliotekach GCC.

    Odnośnie niepoprawnie działającego kodu na niektórych pinach uP to nie mam pojęcia dlaczego ;/ Może faktycznie coś u Ciebie jest nie tak. Pierwszy raz się z tym spotykam.
    A procesor robi coś poza pomiarem temperatury i wyświetlania?
    Może z timingami coś nie tak - niech kolega sprawdzi w plikach .h projektów czy F_CPU poprawnie ustawione.

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono problem zdefiniowania dwóch czujników DS18B20 na osobnych pinach mikrokontrolera ATmega16 w języku C, aby jednocześnie wyświetlać temperatury zewnętrzną i wewnętrzną na wyświetlaczu LCD 2x16. Użytkownik prosił o pomoc w modyfikacji istniejącego kodu, który obsługiwał tylko jeden czujnik. Odpowiedzi sugerowały, że konieczne jest wprowadzenie zmian w pliku nagłówkowym oraz funkcjach, aby umożliwić obsługę dwóch czujników. Wskazano również na potrzebę unikania użycia zmiennych typu float ze względu na ograniczenia procesora. Użytkownicy dzielili się przykładami kodu oraz wskazówkami dotyczącymi poprawnego wyświetlania temperatury, w tym symbolu stopni Celsjusza. Problemy z odczytem temperatury na różnych pinach oraz z wyświetlaniem wartości na LCD również były omawiane.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA