Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[AVR][C] 7* DS18B20 na osobnych pinach.Jak?

adambehnke 24 Jan 2012 14:20 2914 16
Computer Controls
  • #1
    adambehnke
    Level 24  
    Witam
    Jako że niedawno dopiero rozpoczęłem naukę C to proszę mi wybaczyć to pytanie.
    Otóż mam urządzenie (już pracujące ale program pisany w Bascom) , które posiada 7 układów DS18B20 i odczytując temperaturę z nich , steruje odpowiednio przekaźnikami i przepustnicą .Dodatkowo komunikuje się poprzez RS485 i innymi modułami (pracuje jako SLEAVE) . Master cyklicznie wysyła komendy , moduły po rozpoznaniu że master mówi do niego zdają "raport" w postaci wysłanego string-a.

    Kiedy projektowałem owe urządzenie przyświecał mi jeden podstawowy cel jakim jest pominięcie seriali czujników. Chodzi o to że każdy DS mam podpięte do osobnego pinu procesora. Zależało mi na tym żeby w urządzeniu mieć podpisane wejścia czujników (jak np. kominek,bojler,przepustnica itd.) , i w razie awarii czujnika po prostu odpinam stary i wpinam w to miejsce nowy który zacznie pracować natychmiastowo po resecie urządzenia i nie bedę musiał znowu kombinować z odczytem seriala i dopasowywania go w programie.

    Zatem pytanie brzmi:

    W jaki sposób (możliwie najprostszy) mogę zrealizować odczyt tych DS-ów.
    Wiem że są gotowe odpowiednie biblioteki w C ale albo służą do odczytu pojedyńczego układu albo wielu sztuk ale na jednej linii.
    Owszem mogę pokombinować i przerobić którąś z bibliotek ale zapewne jest prostszy sposób. A jako że dopiero raczkuję w C to problem jest w tym momencie "zaporowy".

    Nie chodzi mi o gotowca lecz o drobne wskazówki umożliwiające mi wybrnięcie w tego problemu.
  • Computer Controls
  • Helpful post
    #2
    kozak_sc
    Level 23  
    Tak na prawdę sprawa jest prosta. Użyj gotowej biblioteki jedno-pinowej i dopisz dodatkowy argument typu char (np nr_czujnika). Podłącz wszystkie czujniki do jednego portu. W przypadku zerowania pinu daj PORT&=~(1<<nr_czujnika) a w przypadku ustawiania jedynki PORT|=1<<nr_czujnika i po sprawie.
  • Helpful post
    #3
    piti___
    Level 23  
    Możesz również zrobić tak:

    Code:

    void select_bus(unsigned char bus_nr)
    {
       if(bus_nr == 1)
       {
          ddr_reg  = (unsigned char *)0x31;          // DDRD
          bus_pin  = (1<<5);
          port_reg = (unsigned char *)0x32;          // PORTD   
          pin_reg  = (unsigned char *)0x30;          // PIND
       }                   
       else
       {
          ddr_reg  = (unsigned char *)0x34;          // DDRC         
          bus_pin  = (1<<0);
          port_reg = (unsigned char *)0x35;          // PORTC   
          pin_reg  = (unsigned char *)0x33;          // PINC
       }
    }

    #define DDR_DQ_OUT       *ddr_reg |= (bus_pin);
    #define DDR_DQ_IN        *ddr_reg &=~(bus_pin);

    #define DQ_OUT_1         *port_reg |= (bus_pin);
    #define DQ_OUT_0         *port_reg &=~(bus_pin);
    #define DQ_IN            ((*pin_reg) & (bus_pin))


    Zaletą tego rozwiązania jest to że procesor nie musi każdorazowo przesuwać 1 na odpowiednią pozycję. Nie wiem ile ta operacja może zająć ale na wolniej pędzonych procesorach 1wire rozjedzie się przy tych przesunięciach. Gdy timingi robione są pojedynczymi "nop'ami".
  • Computer Controls
  • #4
    gaskoin
    Level 38  
    Lini ow nie ustawia się pullupem tylko rezystorem który jest podciągnięty do 5 V !
  • Helpful post
    #5
    Electix
    Level 21  
    Twoja koncepcja może być trudna w realizacji. Czy ten program który napisałeś w bascomie obsługiwał 7 niezależnych czujników 1-W na 7 niezależnych pinach µkontrolera? Czy teraz taką koncepcję sobie wymyśliłeś?

    Jest na pewno układ który umożliwiłby Ci taką realizację, dodatkowo odciążając µikrokontroler od żonglowania serialami czujników i generacji zależności czasowych, które w przypadku 1-W są stosunkowo restrykcyjne.
    DS2482-800

    W wypadku - n czujników 1-W na n niezależnych liniach, w zasadzie bez sensu jest korzystanie z 1-W. Podłącz 8 czujników analogowych do wejścia ADC i w o wiele prostszy sposób rozwiążesz swoją koncepcję, jeżeli na takową się upierasz.

    Albo zastosuj jedną magistralę 1-W, ale dopisz sobie jakąś funkcję, która w łatwy sposób będzie rozpoznawać serial nowo podłączonego czujnika i będzie pozwalała na przypisanie go do konkretnego pomieszczenia...
  • #6
    adambehnke
    Level 24  
    O to chodzi że w bascomie to działa bez problemu. Przed każdym rozkazem konwersji konfiguruję na nowo pin do którego podpięty jest DS , a potem po ~750ms go odczytuję.
    I tak kolejno 7 sztuk.
    Ale w C to już takie proste się nie wydaje.
    Urządzenie jak pisałem jest już wykonane i pracuje. Ale dodaję do sieci RS485 kolejne moduły i muszę zmienić oprogramowanie w tym sterowniku na napisane w C gdyż ja osobiście mam duże problemy w Bascomie z sieciąRS485... Zapewne problemem są timingi.

    W zasadzie jest opcja aby wszystkie DS-y pracowały na jednej linii(mała prosta przeróbka na PCB przy gniazdach czujników) , ale muszę się pozbyć identyfikacji seriali .
    I tu już klapa. Nie mogę sobie pozwolić na to aby w przypadku awarii czujnika ponownie grzebać w programie.
    To musi działać tak że odpinam uszkodzony czujnik i wpinam nowy. Potem restart modułu i wszystko działa.

    Układzik DS2482-800 wygląda obiecująco ale w tym module już nie ma możliwości aby go zastosować.
  • Helpful post
    #7
    Electix
    Level 21  
    Jeżeli zbyt często nie odczytujesz czujników, to można w sumie pobawić się w przełączanie magistrali 1-W pomiędzy pinami µkontrolera. Ale to jest moim skromnym zdaniem straszna strata czasu i mocy obliczeniowej. Bo w przypadku jednej magistrali, wysyłasz raz komendę konwersji do wszystkich czujników i potem po 750ms po kolei z każdego odczytujesz temperaturę.

    Gdy rozbijesz to na kilka niezależnych magistral z pojedynczymi czujnikami, musisz siedem razy wydać polecenie konwersji i siedem razy odczytywać. To zajmuje czas mikrokontrolera, a Ty chcesz jeszcze obsługiwać transmisję tych danych.

    Ja Ci powiem, że kiedyś zrobiłem sterownik do grzejników na 8 DS'ach do tego przekaźniki wykonawcze sterowałem też przez 1-W korzystając z układów DS2413 (adresowalny przełącznik). ATmega8 obsługiwała też RTC i klawiaturę i LCD, wszystko napisałem w bascomie i działało... Jedyny mankament to taki że zajęło całą pamięć. Ale była procedura konfiguracyjna, która uruchamiała się przy pierwszym starcie systemu i po kolei podłączało się układy 1-W, wykrywała ona ich adres, po czym można był przypisać urządzenie do konkretnego pomieszczenia...
  • #8
    adambehnke
    Level 24  
    Wydaje mi się że trzeba będzie dorobić w menu modułu opcję do przypisywania czujników. To będzie chyba najprostsze. Nie dość że wszystkie DS-y będą pracować na jednej magistrali to dodatkowo będę mógł użyć gotowych bibliotek i cały program się uprości. No może poza menu.
  • #9
    Electix
    Level 21  
    Jak sobie to dobrze zaplanujesz, to naprawdę uprości Ci to sprawę. Pisząc w C będziesz miał więcej narzędzi ku temu, żeby fajnie sobie takie menu zbudować. Ja pamiętam że ten projekt porzuciłem, bo wkurzyły mnie strasznie ograniczenia bascoma. No i ten kod wynikowy po kompilacji, to była masakra...

    Dla przykładu, to co opisałem wyżej w bascomie zajęło mi cały FLASH w medze8. Teraz pracuję nad programem na ARM (język C), który obsługuje 8 kanałów ADC, robi pomiar częstotliwości na 4 kanałach, steruje dwoma silnikami krokowymi, wyświetlaczem graficznym 240x128 z panelem dotykowym i mierzy czas i przeprowadza na bieżąco obliczenia DSP na danych z ADC. I program ten po kompilacji zajmuje uwaga! niecałe 4k :)
  • #11
    Electix
    Level 21  
    Nie ma się czego bać. A C, choć na pierwszy rzut oka dziwny w składni, okazuje się bardzo wdzięcznym i elastycznym językiem programowania. Jeżeli zaopatrzysz się w dobrą książkę, to myślę że bez trudu osiągniesz cel.

    Na pewno będziesz musiał zapoznać się z tablicami i wskaźnikami. Brzmi strasznie i wielu straszy ich zawiłością i trudnością w zrozumieniu. Ale uwierz mi, tak nie jest. Bascoma, to fakt, nauczyłem się w jeden dzień. Ale jak przyszło mi rozwiązać poważniejsze algorytmy, to strasznie wyklinałem na ten język. I zabrałem się za C, który wyglądał strasznie w tych swoich skrótowych zapisach. Ale jak zacząłem go poznawać, to się zauroczyłem. Bo w końcu mogłem pisać programy tak jak chciałem, a nie tak jak mi to narzucał język... Nagrodą za cierpliwość w nauce C, jest zdecydowanie efektywniejszy i mniejszy kod wynikowy. I większa wiedza o procesorze. Bo programując w C, niestety nie obejdziesz się bez manualu do procka.

    polecam książki:
    Język C. Nowoczesne programowanie
    Język C. Szkoła programowania

    A w tej pozycji nawet znajdziesz przykład, jak skonstruować menu w C na AVR :)
    Język C dla mikrokontrolerów AVR. Od podstaw do zaawansowanych aplikacji
  • Helpful post
    #12
    mirekk36
    Level 42  
    adambehnke wrote:

    I tu już klapa. Nie mogę sobie pozwolić na to aby w przypadku awarii czujnika ponownie grzebać w programie.
    To musi działać tak że odpinam uszkodzony czujnik i wpinam nowy. Potem restart modułu i wszystko działa..


    Nie chcę się upierać, że odczyty wszystkich czujników na jednej magistrali to najlepszy sposób ale kurka wodna ;) .... dla mnie większym problemem, i wcale nie z uwagi na programowanie, byłaby właśnie zabawa z dawaniem czujników na oddzielnych pinach. Toż pomija się podstawową zaletę magistrali 1wire w ten sposób.

    A poza tym kto powiedział, że jeśli wszystkie są na jednej magistrali to w przypadku awarii czujnika trzeba grzebać w programie ???????? ;) To to już mnie zadziwiło na maxa. Zrobiłem już wiele urządzeń tego typu, w tym np ostatnimi czasy sieć modułów pracujących w magistrali RS485 z których każdy ma podpięte 4 czujniki DS18B20 albo DS18S20. I gdyby tak trzeba było jak piszesz - to wolałbym sobie w głowę strzelić niż używać tych czujników ;)

    Co za problem? przecież wystarczy przypisać numery wykrytych czujników na magistrali i zapisać je sobie w EEPROM procka i po zawodach. A w przypadku awarii czujnika i konieczności wymiany nie ma najmniejszego problemu. No owszem - trzeba wejść sobie w jakieś Menu na wyświetlaczu LCD albo jeszcze lepiej podłączyć się komputerem do modułu i to jeszcze np przez Bluetooth i już pięknie z programu na PC podmienić numerek czujnika tzn uszkodzony na nowy....

    Fakt, nie ma tego, że tak jak napisałeś podmieniam czujnik, restart i działa - no ale czy takie urządzenie nie ma innych rzeczy do skonfigurowania. Można to nawet centralnie przez RS485 zrobić.

    Proszę bardzo poniżej przykład mojego jakiegoś tam projektu z elektrody, gdzie widać jak na Menu na wyświetlaczu LCD 2x16 robię swobodną żonglerkę pomiędzy czujnikami , podmianami i to obojętnie jakiego typu czy DS18B20 czy DS1820 czy DS18S20 !!!

    https://www.elektroda.pl/rtvforum/topic1430008.html

    na dole postu masz filmik - zobacz jak to rozwiązałem - oczywiście programowane w C

    Ale czy to oznaczać by miało, że zrobienie w C obsługi takich czujników na oddzielnych pinach to miałby być większy problem ??? Skąd ?

    Tyle że ja w bibliotece, którą opisywałem w książce ale także mocno ją zmodyfikowałem, wręcz wyciąłem taką możliwość uznając, że ja nigdy z niej nie skorzystam. Masz jednak podanego autora tej biblioteki i jak ją sobie zassiesz z netu w oryginale to - masz w niej także możliwości do wyboru czy chcesz korzystać z jednej magistrali czy z wielu magistral. Przypomnę autora:

    Author: Peter Dannegger

    Dodano po 1 [minuty]:

    adambehnke wrote:
    Electix wrote:
    Pisząc w C będziesz miał więcej narzędzi ku temu, żeby fajnie sobie takie menu zbudować


    Właśnie tego się boje gdyż w C jestem jeszcze cienki jak "d... węża" :D


    No ale spokojnie, bo najgorzej to się wychodzi jak się chce wszystko od razu ;) ... spokojnie i powoli - a będziesz robił Menu jakie ci się wymarzy.
  • #13
    adambehnke
    Level 24  
    Dziękuję za wypowiedzi. Zdecydowałem że podepnę wszystkie czujniki pod jedną magistralę a skojarzenia czujników z funkcjami za jakie mają odpowiadać zrobię w menu ale także poprzez rs485.
    Zrobię tak jak należy. Fakt że moja koncepcja miała być prosta ale zawsze będę miał możliwość dołożenia czujnika bez rozbudowy PCB. Wystarczy mała przeróbka kodu i po sprawie.
    Co prawda dla mnie teraz "mała przeróbka" jest całkiem gigantyczna ale krok po kroku dojdę do tego.

    Co do książki : to czy przeoczyłem czy nie ma w niej wzmianki o Watchdog-u ?
  • Helpful post
    #14
    mirekk36
    Level 42  
    adambehnke wrote:

    Co do książki : to czy przeoczyłem czy nie ma w niej wzmianki o Watchdog-u ?


    Jest ale tylko bardzo króciutka i teoretyczna wzmianka, na stronie 53. Jest to dość prosty moduł mikrokontrolera - taki jakby timer, który jak wystartuje i doliczy do końca to BUM czyli reset procka. A jak nie chcemy resetu to wciąż musimy w programie resetować ten timer żeby nie doliczył do końca ;) ... Oczywiście czas można regulować w zakresie - no właśnie w takim zakresie jaki podaje PDF dla konkretnego procka. Trza zajrzeć.... jak coś ci sprawia problem to ew dopytaj .
  • #15
    piti___
    Level 23  
    gaskoin wrote:
    Lini ow nie ustawia się pullupem tylko rezystorem który jest podciągnięty do 5 V !


    Dzięki przeładowaniu linii "jedynką" z portu można uzyskać magistralę kilkuset metrową. Nawet przy slocie odczytu ow pomagam podciągnąć linię jedynką z portu przez us i dopiero ustawiam port na wejście.
  • Helpful post
    #16
    mmacura
    Level 18  
    Przeglądnij sobie notę aplikacyjną
    "AVR318: Dallas 1-Wire master on tinyAVR and megaAVR devices"
    na stronie Atmela.
    Obsługuje do 8 linii 1-Wire na jednym porcie.

    Marek