Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

AVR: pomiar temperatury i wilgotności

Gdy przechowujemy owoce, warzywa czy drewno ważna jest kontrola temperatury i wilgotności. Zmiany wyżej wymienionych wartości powyżej dozwolonych progów mogą prowadzić do strat.

Poniższy projekt obejmuje tylko pomiar obu wartości fizycznych i alarmowanie. Niestety brak środków przeszkodził w realizacji układu automatycznej regulacji(chłodnica i nawilżacz).
Układ przeznaczony jest dla prywatnej przechowalni jabłek.

Układ pomiarowy

Sercem układu jest układ Atmel Mega32(jednak warto rozważyć mniejsze wersję atmel mega a nawet atiny) taktowany wewnętrznym zegarem 8 MHz.

Do pierwszego wejścia a/c przyłączony został termometr oparty o układ KTY81-210. Jest to układ już opisywany prze zemnie kiedyś. Termometr ten działa na zasadzie zmiany rezystancji w zależności od temperatury.

W takim wypadku wystarczy zbudować dzielnik napięcia składający się z rezystora i KTY81-210. Następnie wykonujemy pomiar napięcia na dzielniku,z czego otrzymujemy opór jaki jest na KTY81-210, po czym za pomocą wielomianu czwartego stopnia dokonujemy aproksymacji temperatury. Wielomian można uzyskać poprzez spisanie z dokumentacji układu zależności temperatury od oporu(zbiór punktów) a następnie za pomocą gnu octave lub excela uzyskujemy żądany wielomian .

Wadą tego typu układów jest stosunkowo duża niedokładność ,a wykorzystanie aproksymacji wielomianowej wiąże się w tym przypadku z koniecznością użycia liczb typu float co niestety znacznie obciąża CPU.

Pomiar wilgotności wykonywany jest za pomocą układu SY-230.

Układ należy zasilić napięciem 5V(nóżki 1 i 3) a na nóżce numer 2 w zależności od wilgotności pojawi się odpowiednie napięcie. W dokumentacji układu znajduje się krzywa opisująca zależność napięcia od wilgotności. Podobnie jak poprzednio spisujemy parę pkt. (im więcej tym lepiej) i dokonujemy aproksymacji. W tym wypadku jest to zależność liniowa(policzy każdy arkusz kalkulacyjny) co oznacza że możemy skorzystać z operacji na liczbach całkowitych(typ int) co znacznie mniej obciąża CPU.

Ponadto układ wyposażono w standardowy wyświetlacz 2x16. Cztery diody LED(2 czerwone i 2 niebieskie), dwie służą do sygnalizacji przekroczenia maksimum a dwie minimum mierzonych wartości. Ponadto na płytce znajdują się dwa przyciski umożliwiające zmianę nastaw alarmów. Napięcie zasilania jest jednocześnie nap. Odniesienia dla przetworników a/c. Oczywiście układ wyposażono w złącze programistyczne.

Oprogramowanie

Jeśli idzie o oprogramowanie Nie będę tu przytaczał samych aproksymacji czy pomiaru a/c. Są one dość standardowe.
Ponieważ chciałem aby pomiędzy kolejnymi odświeżeniami ekranu(2 sekundy) możliwa była praca układu(czyli nie używam _delay_ms w while), konieczne było zastosowanie timera. Użyłem do tego Timera 0
(8-bitowego, zlicza do 255 i wywołuje przerwanie). Układ czasowy jest taktowany zegarem F_CPU/1024 = 7182 Hz . Czyli przerwanie jest wywoływane co 0,032 s. Co wymusza zastosowanie wewnętrznego licznika w przerwaniu aby możliwe było otrzymanie odświeżania co około 2 s.

ISR(TIMER0_OVF_vect) { timer_adc++; // if (timer_adc == 62) { glob_bool.b2 = 1; timer_adc = 0;}}

Wykorzystuję tu pola bitowe aby nie marnować pamięci. W dużym uproszczeniu pole bitowe jest to taka konstrukcja która pozwala na prosty dostęp do poszczególnych bitów(grup) w danym słowie. Przykład definicji pola poniżej(dla zmiennej 8-bitowej).

typedef struct{ uint8_t b0:1; // zarezerwowane dla Przycisku 1 uint8_t b1:1; //zarezerwowane dla Przycisku 2 uint8_t b2:1;// timer dla adc uint8_t b3:1; uint8_t b4:1; uint8_t b5:1; uint8_t b6:1; uint8_t b7:1; } volatile IO;

Zmiennej b0 przydzielam jeden bit pamięci(ale mógłbym np. 4), co oznacza że może przechowywać tylko wartość 0 lub 1.
Wracając do samego odświeżania. Gdy w nieskończonej pętli while program wykryje zmianę bitu b2 na 1 wtedy odświeża ekran(i dokonuje pomiaru), zeruje b2 i przechodzi dalej.

Ponieważ układ wyposażony jest w dwa przyciski konieczne jest wyeliminowanie drgania styków co osiągam za pomocą użycia Timera1(16 bitowego). Co parędziesiąt milisekund wywoływany jest timer który sprawdza czy nie przyciśnięto przycisku. Jeśli tak się stało dodaje on do zmiennej debouncing_key, wartość jeden. Gdy osiągnie on wartość 21(czyli upłynie paręset ms) ustawiamy bit b0 lub b1(w zależności od przycisku, b0 zmiana menu, b1 dodanie wartości do nastawy alarmu). W nieskończonej pętli while wywołujemy odpowiednie odświeżenie ekranu i dodanie jedynki do aktualnej nastawy alarmu.

ISR(TIMER1_OVF_vect) { if (!(PIND & _BV(PD2))) { debouncing_key++; if (debouncing_key == 21) { glob_bool.b0 = 1; debouncing_key = 0; } } else if (!(PIND & _BV(PD3))) { debouncing_key++; if (debouncing_key == 21) { glob_bool.b1 = 1; debouncing_key = 0;}}}

Gdy nastawa alarmu przekroczy maksymalna wartość, przypisywana jest jej minimalna możliwa wartość.

Ponadto układu „pilnuje” 2 sekundowy watchdog.

Rozbudowa

Układ jest w obecnej postaci mało zaawansowany. Jeśli posiadałbym agregat chłodzący i nawilżać skusiłbym się na następująca rozbudowę:

  • Dołożenie przekaźników odpalających chłodnicę i nawilżacz.
  • Użycie w pomiarze a/c trybu Low Noise. Tryb ten pozwala na zmniejszenie szumów od procesora atmegi. Konkretnie usypiamy rdzeń, dokonujemy pomiaru i wybudzamy go. Pierwotnie zaimplementowałem go niemniej Atmel Studio sobie z niewiadomych przyczyn nie radziło z tym trybem a nawet Timerami... Ostatecznie skorzystałem z eclipse + wtyczka, ale nie uruchomiłem ponownie trybu low noise ponieważ włożyłem tam już klasyczny pomiar :).
  • Można pomyśleć o dołączeniu np. modułu radiowego/bluettoth i dzięki temu możemy uzyskać pogląd na pomiary wprost z PC.
Poniżej kod w C + powyższy artykuł.KLIK!ERRATA: W kodzie źródłowym jest drobny chochlik, zmienna odpowiedzialna za temperaturę ma typ uint16_t a powinna mieć int16_t. Uniemożliwia to pomiar ijemnych temperatur. 

oprogramowanie programowanie hobby

Komentarze

0 nowych
PAMPKIN   10 #1 18.11.2014 08:14

Zawsze się cieszę, gdy pojawiają się wpisy na temat prac natury elektronicznej, i moim celem nie jest krytykowanie , tylko raczej motywowanie do poprawy/rozwoju. Zaczynam czepianie się ;) co to za schemat? popraw proszę czytelność, kilka minut w Eaglu więcej i będzie OK! Płytka z gardła wyjęta czy co? Kolego postaw na jakość, a nie byle jakość i jakoś to będzie!. Stracisz więcej czasu, ale nie pieniędzy. Jeśli uważasz, że to projekt dla siebie i dlatego taki troszkę na kolanie zrobiony, to go nie pokazuj.

Który to plik z kodem? Wszytko trzeba szukać! Piszesz o Atmel Studio, a kod z Eclipsa? Dużo bałaganu z tym. Kod przeglądałem w notepadzie i szkoda, że brak komentarzy.

Ogólnie OK!

dr.boczek   7 #2 18.11.2014 08:28

podoba mi się, widać, że masz spore doświadczenie w programowaniu AVR

  #3 18.11.2014 11:42

@PAMPKIN: A co na płytce stykowej było by o'k przynajmniej Chłopak trochę Chlorkiem i pisakiem się pobawił Ja bym nie krytykował...

revcorey   6 #4 18.11.2014 15:04

@PAPKIN, ja to sobie to od dla siebie robię i przy okazji udostępniam. Płytka jak płytka, rozplanować sobie można ją różnie. Pokazuję przykład a każdy może sobie jak chce rozłożyć elementy itd. :)
"Który to plik z kodem? Wszytko trzeba szukać! Piszesz o Atmel Studio, a kod z Eclipsa?"
Kompletny projekt eclipse(standardowo eclipse eksportuje je do .zip), z plikami C(.c i .h) nie bardzo rozumiem czego trzeba szukać?. Napisałem wyżej że robiłem w atmel studio ale ponieważ powodowało dziwne problemy(i działa wolniej) przerzuciłem wszystko do Eclipse 4.
" Jeśli uważasz, że to projekt dla siebie i dlatego taki troszkę na kolanie zrobiony, to go nie pokazuj. "
A widziałeś tu jakiś elektroniczny projekt robiony tak na ziher? DP to taka jaskinia hobbystów :) Z drugiej strony widziałem w przemyśle partyzantkę elektroników także nie jest źle :P

"Chlorkiem i pisakiem się pobawił Ja bym nie krytykował..."
Brałem normalnie przez papier kredowy, były dwie wersję płytki(jedna miała błąd). Niestety ta druga wyszła dużo gorzej i sporo poprawek pisakiem. Tych nawiercanych nie lubię, a stykowe do prototypownia są fajne.

Autor edytował komentarz.
PAMPKIN   10 #5 18.11.2014 16:09

@revcorey: Moim zamiarem, jak już wcześniej napisałem krytyka, tylko nazwijmy to tak: krytyka motywacyjna do lepszej pracy lub produktu.

Co do dokumentacji i programu: udostępniłeś link do folderu w OneDrive, a nie konkretnego plik i stąd stwierdzenie, że trzeba szukać właściwego pliku.

dobreprogramy.pl to serwis przede wszystkim o oprogramowaniu, a nie platforma developerska z zakresu zarówno oprogramowania jak i elektroniki. Dlatego ja i powtórzę to jeszcze, JA uważam, że jeśli się tutaj coś prezentuje to wersji "na ziher", patrz projekty cyrlla.

Partyzantką drugiego Apple nie zbudujesz! Właśnie ta partyzantka pokazuje dlaczego nie jesteśmy jako kraj w takim miejscu na świecie a nie innym. Sugeruję nie mylić partyzantki z zaradnością, tylko traktować jako powielanie "bylejakości".

Nic nie mam do płytek zarówno uniwersalnych jak i stykowych.

revcorey   6 #6 18.11.2014 17:03

Po wejściu na onedrive automatycznie masz zaznaczony odpowiedni plik nicn ie musisz szukać.

Cyryll fajnie robi wpisy tylko że on to ma dostęp do drukarki 3d i zwykłego CNC(nie tego którego złożył) i korzystał z gotowych urządzeń typu bananpi. To jest ta jedna drobna różnica :)

Ujmę to tak. Zaprojektowałem układ i wykonałem. Nie bardzo rozumiem też do końca co rozumiesz pod pojęciem płytka z gardła wyjęta? Jest standardowy wygląd laminatu z elementami przewlekanymi. Generalnie powinienem tylko go zamknąć standardowej czarnej obudowie. Uściślij to porozmawiamy, przyznaję sam schemat jest nieco mniej czytelny.

"Partyzantką drugiego Apple nie zbudujesz! "
Stary a czy ja buduję apple? Fakt faktem ciekawe w życiu rzeczy robiłem i też wiem że wielkie koncerny potrafią robić cuda na kiju.

Autor edytował komentarz.
  #7 18.11.2014 19:02

"Użycie w pomiarze a/c trybu Low Noise. Tryb ten pozwala na zmniejszenie szumów od procesora atmegi. Konkretnie usypiamy rdzeń, dokonujemy pomiaru i wybudzamy go. Pierwotnie zaimplementowałem go niemniej Atmel Studio sobie z niewiadomych przyczyn nie radziło z tym trybem a nawet Timerami..."

Czy mógłby kolega nieco uściślić co, jak i dlaczego?

Przecież Atmel Studio to tylko narzędzie. Jego toolchain (zmodyfikowany AVR-GCC) dokona kompilacji i linkowania. To co będzie wykonywał procesor to połączenie widzimisie programisty i optymalizacji toolchain-a. Jednakże rozpisanie sobie wszstkiego na niskim poziomie - poprzez bezpośredni dostęp do IORAM połączone z wykorzystanie przerwań nie jest żadnym problemem w języku C. Zatem od strony programowej nie widzę przeszkód.

Też pisałem aplikację do podobnego sterownika. Nie korzystałem z gotowego czujnika tylko z taniutkiego SYH-1S. Trudność polegała na jego zasileniu przebiegiem AC f=500Hz 1Vpp i do tego pomiar. Rozwiązanie tego okazało się dość proste: Timer1 generuje dwa przebiegi PWM w przeciwfazie, a przerwania z przepełnienia i porównań, oraz z ADC same sobie napędzają proces akwizycji danych zsynchronizowany z PWM. Front-end czujnika opierał się tylko na trzech rezystorach i jednym kondensatorze. Dlatego jestem pewien, że pomiar w trybie Low Noise też jest do opanowania.

Jeśli zaś chodzi o symulację, to programowa odziedziczyła swoje wady po AVR Studio i jak na razie nie widać żadnych zmian. Jednakże mając do dyspozycji ATmega32 masz dostępny JTAG. Wystarczyło go podłączyć (kosztem LCD bo okupuje PORTC) i przenióśłbyś się na wyższy poziom symulacji sprzętowo-programowej. Wystarczyłby AVR Dragon; chyba, że dysponujesz JTAG ICE 3.

"Wykorzystuję tu pola bitowe aby nie marnować pamięci."
Większe marnotrawstwo widzę przy całej litanii obliczeń na zmiennych typu float. :-) Może w przyszłości warto pomyśleć nad przeskalowaniem tego do uint32 i drukowaniu tylko przecinka w odpowiednim miejscu?

PAMPKIN   10 #8 18.11.2014 20:00

@revcorey: Napisałem że ogólnie jest OK! Tego się trzymaj, chciałem Ci tylko podpowiedzieć na co powinieneś zwrócić uwagę, i tyle. Nie mam zamiaru Cię zniechęcać, tylko raczej zmusić do rozwoju.

Źle to ująłem, z tym drugim Apple'm, chodziło mi raczej "Just Like Apple".

Nie jestem hejterem, raczej lajkerem. Pozdrawiam. Czekam na nowe dzieła.

Autor edytował komentarz.
revcorey   6 #9 18.11.2014 21:22

"Większe marnotrawstwo widzę przy całej litanii obliczeń na zmiennych typu float. :-) Może w przyszłości warto pomyśleć nad przeskalowaniem tego do uint32 i "
I też o tym wspomniałem że to marnotrawstwo :) w lini
"a wykorzystanie aproksymacji wielomianowej wiąże się w tym przypadku z koniecznością użycia liczb typu float co niestety znacznie obciąża CPU."
Akurat wartości wielomianu wyszły takie jakie wyszły i tu wolałem użyć float(int z kolei użyłem przy wilgotności), aczkolwiek zgadzam się że np. w aplikacji produkcyjnej gdzie mielibyśmy większy program(powiedzmy na wyjściu 8 przekaźników i dodatkowe pomiary) to jest w przypadku 8-bitowców nie dopuszczalne(mały arm pomimo braku fpu by to spokojnie łyknął).
"Czy mógłby kolega nieco uściślić co, jak i dlaczego? "
Tu jest zagadka. Jakiś czas temu sobie testowałem low noise na płytce stykowej i atmel studio. I było ok a tymczasem założyłem projekt to tego układu i ani low noise nie działał ani timery i zmarnowałem trochę czasu na szukanie błędu który nie istniał(m.in dałem sobie klasyczny pomiar a/c). Przeniosłem projekt do eclipse na linuksie i gra gitara aczkolwiek stwierdziłem że nie ma co usuwać działającego pomiaru i wrzucać low noise. Sam low noise to tylko ustawienie rejestrów, wywołanie uśpienia,pomiar(przerwanie) i wybudzenie. Parę lini w sumie.
Sam czujnik kupowałem w robotroniku we wrocławiu i ten był najtańszy.
". Wystarczyłby AVR Dragon; chyba, że dysponujesz JTAG ICE 3. "
Mam starego avr usb 2. W sumie mam STM32F4 discovery z jtag to tam sobie mogę jakieś poważniejsze rzeczy testować.

Autor edytował komentarz.
etch   1 #10 21.11.2014 10:10

@revcorey, jeśli to dla Ciebie nie problem to odezwij się do mnie proszę na maila - przydałaby mi się Twoja pomoc...
sorry, że w komentarzu, ale nie widzę nigdzie opcji wysłania prywatnej wiadomości :)

piotr.infinity@gmail.com