Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Computer Controls
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Czujnik temperatury na mikrokontrolerze, przesył radiowy

22 Lut 2007 17:26 3024 11
  • Poziom 10  
    Witam

    Mam za zadanie wykonać projekt, którego zaliczenie będzie przepustką na następny semestr studiów. Studiuję informatykę i niestety nie mam doświadczenia w tego typu rzeczach.

    Mój pomysł na projekt to urządzenie, które będzie radiowo przesyłać temperaturę z ogrzewania centralnego z piwnicy a jego wyniki będą wyświetlane piętro wyżej na wyświetlaczu LCD.
    Ja wyobrażam sobie to tak, że cyfrowy czujnik temperatury będzie podłączony do mikrokontrolera, ten z kolei do modułu nadajnika radiowego. Moduł odbiorczy umieszczony piętro wyżej podłączony będzie do mikrokontrolera, który będzie sterował wyświetlaniem temperatury na LCD. Do mikrokontrolera zamierzam podłączyć jeszcze jakąś diodę, która będzie sygnalizowała przekroczenie danej temperatury.
    Jeśli chodzi o czujnik temperatury to znalazłem czujnik cyfrowy DS1820. Nie wiem czy jest to trafny wybór do tego typu urządzenia, dlatego bardzo proszę o pomoc. Jeśli chodzi o mikrokontroler to chce wybrać 8051 lub AVR. Nie mogę natomiast znaleźć odpowiedniego modułu nadawczo-odbiorczego, który będzie przesyłał kilka bajtów; znalazłem jedynie kilkukanałowe, a to za mało by przesłać wartość temperatury. Nad wyborem wyświetlacza LCD jeszcze się nie zastanawiałem, ale myślę, że z tym nie będzie aż tak wielkiego problemu.
    Bardzo proszę o komentarze i sugestie dotyczące mojego pomysłu, a także doboru odpowiednich elementów.
    Z góry dziękuję za każdą cenną wskazówkę.
  • Computer Controls
  • Poziom 16  
    No przeciez mozesz zastosowac dowolny zestaw nadajnik-odbiornik, bo wystarczy ci tylko jeden kanal, gdy dane bedziesz przesylac szeregowo zakodowane np. w kodzie Manchester. Takie gotowe urzadzenia znajdziesz np. w sklep.avt.pl czy soyter.pl.

    Co do procesora, to wybierz AVR, jesli chcesz go zaprogramowac w C, a '51 dla assemblera. Chociaz w sumie do nadajnika wystarczylby jakis malutki 8-pinowy procek, a takie sa tylko AVRy.

    LCD chyba nie bedzie potrzebny w odbiorniku - jesli to ma wyswietlac tylko temperature, to wyswietlacz LED bedzie jak znalazl.
  • Computer Controls
  • Poziom 42  
    zamiast DS1820 kup sobie lepiej DS18B20 i dostaniesz go taniej np na allegro albo w innych sklepach. ;) ja na allegro kupiłem te czujniczki po 5zł

    co do odbiorników i nadajników telecontrolli to spokojnie do takiego celu wystarczą aczkolwiek trzeba zwrócić uwagę, na sposób przesyłania danych przez nie - nie na darmo w ich notach widzisz poza układem - coś takiego jak decoder i encoder ..... oczywiście można to zastąpić własnym protokołem przesyłania danych bo puszczanie sygnału ze zwykłego UARTa może się słabo sprawdzić. Jednak po zastosowaniu własnego sposobu kodowania danych np typu Menchester - albo jak niektórzy piszą zastosowania najniższych z możliwych prędkości transmisji nawet ponoć przez UARTa da radę ;)

    pozdrówka
  • Poziom 10  
    mirekk36 napisał:
    zamiast DS1820 kup sobie lepiej DS18B20


    Czym różni się DS18B20 od DS1820? bo google nie daje mi odpowiedzi.

    mirekk36 napisał:
    trzeba zwrócić uwagę, na sposób przesyłania danych przez nie - nie na darmo w ich notach widzisz poza układem - coś takiego jak decoder i encoder ..... oczywiście można to zastąpić własnym protokołem przesyłania danych bo puszczanie sygnału ze zwykłego UARTa może się słabo sprawdzić. Jednak po zastosowaniu własnego sposobu kodowania danych np typu Menchester - albo jak niektórzy piszą zastosowania najniższych z możliwych prędkości transmisji nawet ponoć przez UARTa da radę

    Chciałbym podkreślić, iż jestem początkującym w tej dziedzinie, dlatego też nie do końca rozumiem. Przez UART rozumiem raczej wykorzystanie portu szeregowego, a nie komunikację radiową. Wiem na czym polega kodowanie Manchester, tylko nie wiem w jaki sposób będę mógł wysłać i przechwycić dane.
  • Poziom 42  
    DS18B20 jest nowszy, ma zdaje się przede wszystkim większą dokładność tzn rozdzielczość odnośnie pomiaru temperatury a poza tym jest chyba już tańszy od poprzednika a jeśli się mylę to napewno tańsza jest tan nowsza wersja na allegro niż tam gdzie ty podałeś.

    ... piszesz, że jesteś początkujący ale znasz już kodowanie Menchester - to znaczy, że nie jesteś aż tak bardzo początkujący - sporo już wiesz ;) ....

    ... piszesz też, że chciałbyś przesyłać dane drogą radiową - dlatego wspomniałem o tym co najczęściej wydaje się być najprostszą metodą czyli możliwość przesłania danych w ten sposób, że wysyłamy dane na port TxD UART - dalej trafiają one do nadajnika radiowego, są transmitowane do odbiornika radiowego a po drugiej stronie wpadają nam znowu na wejście UART RxD ;) .... jednak właśnie z tym - tak wprost mogą być komplikacje stosując takie ndajniczki. Dlatego wspomniałem o tym, że można zrobić własny protokół wysyłania danych - a po to stosuje się np kod Menchester ponieważ zapewnia on tzw kodowanie bifazowe sygnału, które umożliwia przesyłanie całych paczek danych (np bajtów) minimalnie narażonych na uszkodzenia po drodze. Z tego względu został on (ten rodzaj kodowania) użyty np w standardzie przesyłania danych przez podczerwień w tak popularnych pilotach jak firmy Philips - gdzie znany jest jako kodowanie RC5. Jak zapewne wiesz - dzięki temu piloty mogą nawet różnić się w pewnym tak naprawdę dosyć szerokim zakresie tolerancji częstotliwości nadawania jeśli chodzi o nadajnik i odbiornik a jednak dane z pilotów do telewizora docierają praktycznie zawsze w bardzodobrym i nie naruszonym stanie - a przesyłanych jest ok 13bitów zakodowanej informacji.

    ..... jeśli więc używałeś kiedyś kodowania RC5 do sterowania podczeriwenią to zrobienie tego z tym , że tym razem nie na podczerwieni a na drodze radiowej nie powinno nastręczyć tobie żadnego problemu. Oczywiście możesz sposób kodowania RC5 zmienić na swój własny i przesyłać inne ilości bajtów w paczce - w zależności od tego ile będziesz potrzebował. Dzięki temu na pewno uzyskasz bardzo zadowalające wyniki jeśli chodzi o zasięg a co najważniejsze dobre prędkości transmisji o ile takie będą ci potrzebne.

    .... piszesz, że nie wiesz jak będziesz mógł przechwycić dane - hmmm proponuję ci zajrzeć na stronkę:
    http://www.ustr.net/infrared/infrared1.shtml
    i zapoznać się dokładnie z tym tematem, tam jest to w piękny i przejrzysty sposób pokazane jak zrobić z kolei odbiornik podczerwieni dla RC5 - jeśli to złapiesz - to masz już 99% sukcesu - potem jeszcze tylko troszkę własnej inwencji .... wbrew pozorom nie jest to trudne ..hmmmm chociaż zależy jakim językiem programowania się posługujesz? jeśli asemblerem albo C to żaden problem ale jeśli tylko Bascom to być może będzie to nie do przejścia

    pozdrawiam
  • Użytkownik usunął konto  
  • Poziom 36  
    ->kol. Marc-in
    Szanowny Kolego. Jeśli możesz nie stosuj, proszę częstotliwości 433MHz.
    Dlaczego ? Przeczytasz (m.in.) w:
    https://www.elektroda.pl/rtvforum/viewtopic.php?t=662431&highlight=
    Rozumiem, że to praca na zaliczenie, ale gdy okaże się że takich urządzeń
    ktoś na podstawie twojego prototypu, dokumentacji popełni więcej, to będzie
    przykra sprawa i nie do odkręcenia.
  • Poziom 10  
    Jeśli chodzi o podłączenie czujnika DS1820 do AVR'a to które rozwiązanie jest lepsze? Znalezione przeze mnie rozwiązania znajdują się pod n-cym adresem: http://www.marcin.cba.pl/projekt/2_sposoby.JPG

    Jednocześnie bardzo proszę o wyjaśnienie dlaczego któreś z tych rozwiązań jest lepsze.
  • Poziom 10  
    Podłączyłem do odbiornika wyświetlacz LED, zrobiłem wyświetlanie multipleksowe. Teraz szukam programu odczytującego temperaturę z jednego czujnika DS18B20 w języku C. Niestety dotychczasowe poszukiwania nie poskutkowały, więc proszę o pomoc. Wiem, że w internecie można znaleźć pełno kodów źródłowych, ale większość z nich ma błędy i większość jest pisana pod wyświetlacz LED, na dodatek w większości są wykorzystane biblioteki, których nie można zdobyć. Mi wystarczy funkcja, który zwróci wartość typu float (mam wyświetlacz 4-cyfrowy więc wystarczy 1 cyfra po przecinku).

    EDIT2: Znalazłem coś takiego:

    Code:

    #include <avr/delay.h>
    #include <avr/1wire.c>

    void main(void)
    {
    uint8_t a, b, c;
    uint16_t e;
    sbi(DDRB,0);
    sbi(PORTB,0);
    cbi(PORTB,0);
    cbi(DDRB,0);

    while(1)
    {
    onewire_reset();
    _delay_ms(50);
    onewire_write(0xCC); //SKIP ROM
    onewire_write(0x44); //READ SCRATCHPAD

    _delay_ms(50);
    _delay_ms(50);
    _delay_ms(50);
    onewire_reset();
    _delay_ms(50);
    onewire_write(0xCC); //SKIP ROM
    onewire_write(0xBE); //READ SCRATCHPAD
    a = onewire_read();
    b = onewire_read();
    c = a & (0x0F); // wartości
    dziesiętne (po przecinku)
    a >>= 4;
    b <<= 4;
    a = a | b;
    e = 625 * c;



    write_text(" ");
    lcd_powrot();
    char str[5];
    sprintf(str, "%d", a);
    write_text(str);
    write_text(".");
    sprintf(str, "%d", e/100);
    write_text(str);
    write_char(223);
    write_text("C");

    }
    while(1);
    }

    ---------
    1wire.c:

    #include "1wire.h"
    #define sbi(ADDRESS,BIT) (ADDRESS |= (1<<BIT))
    #define cbi(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))

    void _delay(unsigned int useconds)
    {
    unsigned int s;
    for(s=0;s<useconds; s++)
    ;
    }

    unsigned char onewire_reset(void)
    {
    unsigned char i = 200;
    sbi(DDRB, 0);
    sbi(PORTB, 0);
    _delay_us(10);
    cbi(PORTB, 0);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    _delay_us(50);
    sbi(PORTB, 0);
    _delay_us(50);
    cbi(DDRB, 0);
    _delay_us(50);
    while(i--)
    {
    if (bit_is_clear(PINB, 0))
    {


    return ONEWIRE_OK;
    }

    _delay_us(1);
    }

    return ONEWIRE_BUS_ERROR;

    }

    //y=-1.5x+40.5
    //x zegar
    //y wywołanie
    //czyli dla zegara 14.7456MHz
    //wywołanie 18us
    //w=18us

    //y=-0.77x+24.47
    //x - zegar
    //y - opoznienie
    //czyli dla zegara 14.7456MHz
    //opoznienie 13us
    //o=13us

    //liczenie opóźnienia
    //np 480
    //(480-18)/13=35,53 piszemy delay(36);



    void onewire_write_bit(unsigned char bit)
    {
    sbi(DDRB,0);
    cbi(PORTB,0);
    if(bit == 1) sbi(PORTB,0); else cbi(PORTB,0);
    _delay_us(50);
    _delay_us(50);
    sbi(PORTB,0);
    cbi(DDRB,0);

    }

    unsigned char onewire_read_bit(void)
    {
    sbi(DDRB,0);
    cbi(PORTB,0);
    sbi(PORTB,0);
    cbi(DDRB,0);
    _delay_us(15);
    if (bit_is_clear(PINB,0)) return(0); else return(1);
    cbi(DDRB,0);
    }

    void onewire_write(unsigned char val)
    {

    unsigned char i;
    unsigned char temp;
    for (i=0; i<8; i++) // writes byte, one bit at a time
    {
    temp = val>>i; // shifts val right 'i' spaces
    temp &= 0x01; // copy that bit to temp
    onewire_write_bit(temp); // write bit in temp into
    }
    _delay_us(50);
    _delay_us(50);
    }

    unsigned char onewire_read(void)
    {
    unsigned char i;
    unsigned char value = 0;
    for (i=0;i<8;i++)
    {
    if(onewire_read_bit()) value|=0x01<<i;
    _delay_us(50);
    _delay_us(50);
    }
    return(value);
    }

    ---------------------
    1wire.h

    //#include <avr/io.h>
    //#include "delay.h"
    #ifndef __1WIRE_H
    #define __1WIRE_H

    #define ONEWIRE_OK 0
    #define ONEWIRE_BUS_ERROR 1

    unsigned char onewire_reset(void);
    void onewire_write_bit(unsigned char bit);
    unsigned char onewire_read_bit(void);
    void onewire_write(unsigned char byte);
    unsigned char onewire_read(void);
    //unsigned char onewire_wait(void);

    #endif


    EDIT: Czy poprzez wyrażenie "a + e/1000" uzyskam temperaturę, którą będę mógł przesłać do odbiornika na wyświetlacz LED?