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

Arduino PRO mini (328) - rejestrator temperatury z wielu czujników DS18B20

tzok 18 Aug 2015 21:50 2997 10
  • #1
    tzok
    Moderator of Cars
    Potrzebuję zaprojektować datalogger do rejestrowania temperatury z czujników DS18B20 (kilkunastu, może kilkudziesięciu).

    Logger ma zapisywać dane na karcie SD, musi posiadać zegar RTC, może ale nie musi posiadać wyświetlacz LCD i klawiaturę 4x4 (sądzę, że było by to obsługiwane przez osobny moduł PRO mini sprzężony przez UART). Najważniejsze jest jednak, to że kabel z czujnikami musi być wymienny i jak najtańszy (będzie jednorazowy).

    Na razie wymyśliłem sobie to tak, żeby kabel z czujnikami miał we wtyku EEPROM I²C, który przechowywałby liczbę oraz adresy kolejnych czujników na kablu (muszę znać kolejność czujników od "najbliższego" do "najdalszego"). Nie bardzo mam jednak pomysł jak go odczytywać (z uwagi na ograniczoną ilość pamięci RAM).

    Kolejny problem to zarządzanie zasilaniem (raz w wariancie bez wyświetlacza i klawiatury, raz z). Nie można użyć zwykłego wyłącznika, przed wyłączeniem zasilania trzeba się upewnić, że plik jest zamknięty i/lub poczekać na koniec zapisu i zamknięcie pliku. Obecnie pilnuję aby wyłączać zasilanie lub wcisnąć reset po zgaśnięciu LEDa, który jest wpięty w linię SCL karty SD.

    Obecnie kod wygląda tak (zlepek z przykładów, ale działa, tyle że adresy czujników zapisane są na stałe):
    Code: c
    Log in, to see the code


    Znalazłem też bibliotekę Sleep_n0m1 ale tak jest chyba lepiej, bo można łatwo dodać wybudzanie przerwaniem sprzętowym (z przycisku), co można by wykorzystać do zamknięcia logu i wyłączenia loggera.
  • Helpful post
    #2
    Anonymous
    Anonymous  
  • #3
    tzok
    Moderator of Cars
    Adresy nie mogą być zapamiętane w ATMedze, musi to być zewnętrzny EEPROM jako część kabla, bo kable będą wymienne. Niestety kabel z czujnikami będzie tracony w trakcie badania, będzie więc jednorazowy, zostanie tylko logger i wtyk z EEPROMem. Logggerów będzie kilka, kabli dużo więcej. Po wstępnych próbach widzę, że konieczne będzie w nim zapamiętanie również danych kalibracyjnych, bo czujniki DS18B20 mają spory rozrzut i będą wymagały wstępnej kalibracji. O ile wartość temperatury nie jest dla mnie krytyczna, to dwa czujniki umieszczone w takiej samej temperaturze muszą dawać taki sam odczyt.

    Czujniki mogę skanować i rozpoznawać kolejność chwytając każdy z nich na ok 15 sek, to wystarczy do wyraźnej zmiany rejestrowanej temperatury.
  • #5
    tzok
    Moderator of Cars
    EEPROM nie musi być na 1-WIRE, obecnie używam I2C. Program w zasadzie już działa tylko muszę dorobić obsługę przerwania wyzwalanego przyciskiem (INT1), które ustawi flagę zakończenia działania, poczeka na koniec pętli, zamknięcie pliku i wyłączy zasilanie (a przynajmniej zawiesi program i głęboko uśpi procesor). Jest tylko jeden problem - zostało mi 581 bajtów RAMu...

    Code: c
    Log in, to see the code


    Mam też pytania:
    - Od którego momentu timer watchdoga rozpoczyna odliczanie tej 1 sekundy?
    - Czy ten timer generuje przerwania co 1 sekundę bez względu na cokolwiek? Jeśli tak to jak zapobiec wywoływaniu tych przerwań w trakcie wykonywania pętli? Tzn. wykonuje się dokładnie jedno przerwanie po 1s od wywołania funkcji enterSleep(), po wybudzeniu timer jest zatrzymywany aż do ponownego wywołania tej funkcji.
    - Nie lepiej przenieść licznik wywołań przerwania WDT do ISR (jeśli jest mniejszy niż zadany, np. 15 od razu ma iść dalej spać, jeśli jest równy zadanej wartości ma wyłączyć WDT i powrócić do głównej pętli programu). Ktoś może mnie naprowadzić jak to zrobić i czy w ogóle tak się da?
  • #6
    Anonymous
    Anonymous  
  • #7
    tzok
    Moderator of Cars
    Chciałem tylko wiedzieć czy przerwanie wywołuje się raz czy cyklicznie ale już sprawdziłem, że cyklicznie.

    Tu jest wszystko ładnie opisane, jakby ktoś szukał: http://gammon.com.au/interrupts

    8 sekund mi nie wystarczy, usypiam procesor na 15 sekund, ale w finalnym projekcie będzie to 30 s lub nawet minuta.

    ***

    Code: c
    Log in, to see the code


    Wersja prawie finalna. Parę słów wyjaśnienia odnośnie sterowania zasilaniem (bo nie do końca mi się podoba). Zasilanie włącza się i wyłącza bistabilnym przełącznikiem kołyskowym. Przełącznik, kiedy jest załączony, podaje masę na Arduino i peryferia przez diodę prostowniczą. Sygnał wyłączenia (3/INT1) jest brany sprzed diody, kiedy przełącznik zostanie wyłączony pojawia się tam stan wysoki z rezystora podciągającego. Zatrzask zasilania to tranzystor BUZ-11, którego bramka jest sterowana z pinu 4 (5V od chwili zainicjowania programu) i podciągnięta do masy (źródła) przez rezystor 10kΩ. Masa na Arduino i peryferia idzie z drenu. Źródło jest podłączone bezpośrednio do masy zasilania.
  • #8
    dondu
    Moderator on vacation ...
    tzok wrote:
    8 sekund mi nie wystarczy, usypiam procesor na 15 sekund, ale w finalnym projekcie będzie to 30 s lub nawet minuta.

    Wtedy należy:
    - zastosować programowy licznik przerwań,
    - lub wykorzystać zewnętrzny układ, co zapewne jest nieakceptowalnym rozwiązaniem.
  • #9
    tzok
    Moderator of Cars
    Jest programowy licznik przerwań, działa dobrze. Precyzja odmierzania czasu nie jest tu absolutnie krytyczna.

    Mógłby ktoś mi coś podpowiedzieć na temat realizacji zatrzasku zasilania? W/g mnie powinno być ok i nawet działa, ale w stanie wyłączenia na bramce jest ponad 2,5V i układ pobiera 2mA.

    Arduino PRO mini (328) - rejestrator temperatury z wielu czujników DS18B20



    Edit

    Code: c
    Log in, to see the code


    ***

    Finalna (mam nadzieję) wersja programu:
    Code: c
    Log in, to see the code


    Proszę jeszcze tylko o jakieś wskazówki do zatrzasku zasilania. Chcę mieć zwykły, bistabilny włącznik zasilania oraz układ, który podtrzyma zasilanie po wyłączeniu przełącznika tak długo jak program będzie tego potrzebował. Obecne rozwiązanie działa, ale po wyłączeniu zasilania na pinie Arduino, który steruje MOSFETem jest napięcie ok 3V...