Histereza aTtiny13

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Histereza aTtiny13

Post autor: Dawid2379 » 27 mar 2013, 19:05

Zrobiłem układ wykorzystania ADC ze strony "Mikrokontrolery jak zacząć'':
http://mikrokontrolery.blogspot.com/201 ... ienie.html


Różnice:
-zmieniłem podłączenie pinów
-zmieniłek kod pod aTtiny13
-zamias rezystora podłączonego do potencjometru dałem termistor aby ten przełączał diody

Moje pytytanie czy aby uC nie powinien zmieniać stanu diody bez jej mrygania, powolnego zaświecania się? Jest to wada uC? A może kodu?
Film
http://www.youtube.com/watch?v=fY2zAwDo ... e=youtu.be
Załączniki
ADC_ATMEGA8_schemat1.gif
(12.89 KiB) Pobrany 8141 razy

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 28 mar 2013, 3:14

Zmieniłeś mikrokontroler i nie pokazujesz programu, a to może okazać się bardzo istotne.
Wskazałeś schemat z artykułu, ale czy na pewno masz swojego Tiny podłączony odpowiednio?
Jak masz zaprogramowane fusebity?
Pokaż więc swój schemat i program.

Awatar użytkownika
Artyliusz
Użytkownik
Posty: 305
Rejestracja: 06 sty 2013, 14:10
Lokalizacja: Z Polski
Kontakt:

Post autor: Artyliusz » 28 mar 2013, 3:27

Jakiego rodzaju użyłeś termistora?

Sądzę, że wina leży po stronie kodu, gdyż termistor może zmieniać swoją wartość i w tym przypadku dzielnika rezystancyjnego może być tak wyliczony, że łatwo waha się się wartość do ADC.

Poza tym na filmiku widać, że jedna dioda świeci cały czas, a dopiero później włącza się druga.
W kodzie mamy takie coś:

Kod: Zaznacz cały

if(ADC<350)//jeśli wynik ADC mniejszy od 350 gasi obydwie diody  
  {  
    PORTB  &=~ (1<<LED1);  
    PORTB  &=~ (1<<LED2);  
  }  
  else if(ADC<700)//jeśli 700>ADC>=350 LED1 świeci  
  {  
    PORTB  |= (1<<LED1);  
    PORTB  &=~ (1<<LED2);  
  }  
  else //jeśli ADC>=700 świecą obydwie diody   
                {  
    PORTB  |= (1<<LED1);  
    PORTB  |= (1<<LED2);  
Widocznie wynik konwersacji najpierw waha się między 700, a później przekracza tę wartość i świecą dwie diody. Nie uwzględniłeś jaką wartość normalną ma mieć termistor (np. w temperaturze pokojowej) i potem wyliczyć odpowiednio dzielnik i dopiero po tym ustalać progi dla ADC. I faktem jest, że nie ma histerezy.
Poza tym z tego co pamiętam to to termistor ma pewną bezwładność na początku i jego charakterystyka nie jest liniowa. O ile nie zmieniałeś programu to jest przystosowany do rezystora, który jest liniowy.

Możesz spróbować na początku zwiększyć progi ADC.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 28 mar 2013, 12:20

Sory powinienem od razu pokazać.
Zegar ustawiony na 4,8Mhz
Termistor 10k (taka mała czarna kuleczka z zakresem -30 st. do +100 st.
Myślałem o tym termistorze i przy podgrzewaniu zapalniczką diody szybko sie zpalają.

Reakcja przy ogniu zapalniczki:
http://www.youtube.com/watch?v=XEk3ST9G ... e=youtu.be

Kod, schemat oraz zdjęcie:

Kod: Zaznacz cały

#include <avr/io.h>  
  
#define LED1 PB1    //definicja LED1 (do którego pinu podłączony LED1)  
#define LED2 PB2    //definicja LED2 (do którego pinu podłączony LED2)  
#define KLAWISZ PB0 //definicja KLAWISZ (do którego pinu podłączony klawisz)  
#define ADCIN PB4   //definicja ADCIN (wejście ADC)  
  
int main(void)  
{  
  //Uruchomienie ADC, wewnętrzne napiecie odniesienia, tryb pojedynczej konwersji, preskaler 128, wejście PIN5, wynik do prawej  
  ADCSRA =   (1<<ADEN) //ADEN: ADC Enable (uruchomienie przetwornika)  
  
   //ADPS2:0: ustawienie preskalera, preskaler= 64  
   |(1<<ADPS1)  
   |(1<<ADPS2);  
      
  
  ADMUX  =  (1<<REFS0) //REFS1:0: Reference Selection Bits   
         //Internal 2.56V Voltage Reference with external capacitor at AREF pin  
    |(1<<MUX1); //Input Channel Selections (ADC5 - Pin 5 )  
  
  //ustawienie wejśc/wyjść  
  DDRB  |= (1<<LED1) | (1<<LED2); //Ustawienie pinów sterujących diodami jako wyjścia   
  DDRB  &=~ (1<<KLAWISZ);         //Ustawienie pinu klawisza jako wejście  
  DDRB &=~ (1<<ADCIN);            //Ustawienie Wejścia ADC  
  
  PORTB |=  (1<<KLAWISZ);         //Pull_up klawisz  
  
  for(;;)//pętla główna   
  {  
    if(!(PINB & (1<<KLAWISZ)))//jeśli klawisz wciśniety  
    {  
    ADCSRA |= (1<<ADSC); //ADSC: uruchomienie pojedynczej konwersji  
   
    while(ADCSRA & (1<<ADSC)); //czeka na zakończenie konwersji  
   
  if(ADC<800)//jeśli wynik ADC mniejszy od 800 gasi obydwie diody  
  {  
    PORTB  &=~ (1<<LED1);  
    PORTB  &=~ (1<<LED2);  
  }  
  else if(ADC<850)//jeśli 850>ADC>=800 LED1 świeci  
  {  
    PORTB  |= (1<<LED1);  
    PORTB  &=~ (1<<LED2);  
  }  
  else //jeśli ADC>=850 świecą obydwie diody   
                {  
    PORTB  |= (1<<LED1);  
    PORTB  |= (1<<LED2);  
  }  
    }  
  }  
}  
Załączniki
P8110128.JPG
Bez tytułu.png
Bez tytułu.png (4.02 KiB) Przejrzano 13026 razy
Ostatnio zmieniony 28 mar 2013, 13:22 przez Dawid2379, łącznie zmieniany 1 raz.

Awatar użytkownika
Artyliusz
Użytkownik
Posty: 305
Rejestracja: 06 sty 2013, 14:10
Lokalizacja: Z Polski
Kontakt:

Post autor: Artyliusz » 28 mar 2013, 13:15

Na szybko sobie coś trochę policzyłem i u Drzaśka w miarę wzrostu napięcie na wejściu zapala się kolejna dioda, aż w końcu po przekroczeniu napięcia wejścia 1,75V zapalają się dwie diody. Normalnie jego dzielnik z wartościami jak na schemacie daje 2,5V (licząc dla Vcc=5V).

U Ciebie z wartościami wyjściowymi dzielnik daje prawie 3,5V. Czyli po przekroczeniu wartości 850, tj. 2,125V na wejście - zapalają się obydwie diody.

Możliwe, że masz termistor typu NTC, a więc rezystancja zmniejsza się ze wzrostem temperatury. Najlepiej jak pomierzysz miernikiem jego rezystancję i co wychodzi z dzielnika na pomiar.
Z grubsza zakładając, że jego rezystancja (termistora) zmniejszy się po połowę na 5k to wasz wartość na wyjściu dzielnika ok. 4V. Musisz uważać, abyś nie przekroczył wartości Vcc.
Poniekąd moje założenia się zgadzają, przynajmniej ja tak myślę, i po podgrzaniu termistora zmalała rezystancja i od razu napięcie wejścia na nóżkę pomiarową wzrosło powyżej wartości 850 czyli 2, 125V i zapaliły się diody dwie.

Przyznam, że jeszcze nie bawiłem się ADC i moje obliczenia jak i wiedza w tym zakresie mogły być mylne i porobiłem tylko bigosu.
Porób jakieś pomiary miernikiem.

Edycja:
Widzę teraz załączony obrazek termistora i z załączonego obrazka wnioskuję, że jest to typu NTC.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 28 mar 2013, 13:31

Tak, skoro NTC to termistor w którym spada rezystancja wraz ze wzrostem temperatury to jest to. Wczoraj to sprawdzałem.
Tak czy siak co z tym powolnym właczaniem sie diody, moze powinienem dodac jakies filtry, no nie wiem...
badając termistor przy ogniu bardzo szybko sie zmienia jego rezystancja wiec uC powinien nagle włączyc diode..
Zobacz jeszcze film jaki dodałem przed chwilą i reakcje przy ogniu.

edit: całość zasilana 5V z USB
zrobiłem pomiar nóżki ADC-pierwsza dioda zapala się przy 0,65V druga przy 0,72V

Awatar użytkownika
Artyliusz
Użytkownik
Posty: 305
Rejestracja: 06 sty 2013, 14:10
Lokalizacja: Z Polski
Kontakt:

Post autor: Artyliusz » 28 mar 2013, 14:05

Powolne włączanie? Chodzi Tobie o to coś w rodzaju PWM obserwowane przy prawej diodzie? Mnie się wydaje, że to właśnie wychodzi z tej szybkiej zmiany stanu pinu kontrolującego diodę, gdyż zmienia się za każdym razem jak wynik ADC oscyluje w granicach progu i co widzisz to prawie PWM. Taka moja teoria. Albo się nie zrozumieliśmy.

Włączył przecież nagle diody. Musisz wziąć pod uwagę bezwładność termistora i przyjrzeć się jego charakterystyce, oraz pamiętać, że przekonwertowanie pomiaru ADC też coś trwa.
Na filmie jeśli był włączony równie z zapalniczką to po 3 sekundach zapala się pierwsza dioda, a 7 sekund po niej druga. To jest wolno?
Ale widzisz teraz, że jak szybko zachodzi zmiana rezystancji to już nie ma oscylowania przy wartościach progowych i nie ma migania.
Bo wcześniej miałeś taki efekt, że raz na trochę przekroczyło wartości progową, później się wróciło, potem na trochę dłużej i się wróciło i później jeszcze na dłużej i się wróciło i miałeś prawie takie sterowanie wypełnieniem, a więc długością stanu na nóżce.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 28 mar 2013, 14:31

No dokładnie o takie mryganie, faktem jest że szybko się włączyły przy zapalniczce ale w poprzednim filmie termistor po prostu połorzyłm na grzejniku, i zanim się załączyła dioda migał jak przy kodzie do kingt ridera :) Właśnie widziałem kilka charakterystyk, wszędzie wzrost temperatury jest wprost proporcjonalny do malenia rezystancji, zakladając że go podgrzewamy, mierzymy ma np oporność 5550Ohm po jednej sekundzie ma 5200Ohm. i teraz skoro dioda włączyła sie przy 5550Ohm nie powinna wyłączyć sie przy 5200Ohm, a tak jest. ADC skoro raz juz załącza diodę nie może wyłączyc jej juz po przekroczeniu tej wartosci przy której włączył diode a potem zas załączyć??
Ja osobiście mam wrażenie że cos się dzieje w uC

edit: może nie mam super sprzetu ale widac jak płynnie podawane jest napiecie na nóżke ADC i to tylko przy termistorze przyłożonym do grzejnika:

http://www.youtube.com/watch?v=zIdEyXtR2yc
Ostatnio zmieniony 28 mar 2013, 14:53 przez Dawid2379, łącznie zmieniany 1 raz.

Awatar użytkownika
Artyliusz
Użytkownik
Posty: 305
Rejestracja: 06 sty 2013, 14:10
Lokalizacja: Z Polski
Kontakt:

Post autor: Artyliusz » 28 mar 2013, 14:52

Skoro położyłeś na grzejnik to ma też znaczenie jaką powierzchnią stykał, bo mógł pobierać ciepło i je oddawać.

5,550k mija 1s - 5,2k
Przy 5,550k zapala się dioda.
Dawid2379 pisze: teraz skoro dioda włączyła sie przy 5550Ohm nie powinna wyłączyć sie przy 5200Ohm, a tak jest. ADC skoro raz juz załącza diodę nie może wyłączyc jej juz po przekroczeniu tej wartosci przy której włączył diode a potem zas załączyć??
Rezystancja może maleć, ale niespodziewanie wzrosnąć, bo np. powierzchnia nie jest równo ogrzewana.
Wartość progu osiągnięta, warunek spełniony, zapala się dioda. Ale potem warunek tego progu nie jest już spełniany, ale progu niżej tak i wedle kodu dioda reaguje odpowiednio.

Mówimy o pierwszym filmiku, tak?
Dawid2379 pisze: ADC skoro raz juz załącza diodę nie może wyłączyc jej juz po przekroczeniu tej wartosci przy której włączył diode a potem zas załączyć??
Twój kod pozwala przecież wyłączyć diodę i włączyć ją.
Termistor się podgrzewa, maleje rezystancja, ale też się ochładza, oddaje ciepło i rezystancja wzrasta, ale z powodu, że więcej tego ciepła przyjmuje niż oddaje to w końcu już się nagrzeje tak, że więcej ciepła nie przyjmie.
Oddaje z tego powodu, że z jednej strony przyłożony do grzejnika pobiera ciepło oddawane przez grzejnik, ale z drugiej strony jest temperatura powietrza, do której może znów oddać te ciepło.

Jakby nie był do niczego przyłożony i znajdował się w pokoju, gdzie temperatura wzrasta stopniowo to by równo przyjmował ciepło i obniżał rezystancję, bo nie ma gdzie te ciepło dobrze oddać, bo jest przez nie obtoczony.

Tak to sobie trochę kolokwialnie tłumaczę. :lol:

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 28 mar 2013, 14:56

Wyżej przesłałem filmik jak wzrasta napiecie na ADC dzieki termistorowi przyłożonemu do grzejnika. Termistor jest na grzejniku, cieplo otacza go w całości jego powierzchni.

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 29 mar 2013, 12:58

Dawid2379 pisze:Tak czy siak co z tym powolnym właczaniem sie diody, moze powinienem dodac jakies filtry, no nie wiem...
Oczywiście możesz zrobić filtr programowy, np. proste uśrednianie ostatnich x pomiarów.
Dopiero tak obliczoną wartość podstawiać do warunków programu.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 29 mar 2013, 13:20

Zastanowiłem sie jeszcze raz nad tym co pisał Artyliusz. Faktycznie zmiana napiecia na termistorze jest płynna ale trzeba czasu aby wzoslo napiecie np o 0,5V . Setne Vollta może procesor w bardzo krótkim przedziale czasowym różnie odczytywać. Cieszyłbym sie jakby ktos to potwierdził. Że konwersacja pomiaru może trwać, i czy generalnie powolnie narastajace nnapiecie może powodować takie załączanie się Ledów jak widać na filmie???

Zrobiłem jeszcze experyment z fotodiodą. Ona w porównaniu do termistora zmienia napiecie na końcówce ADC w ułamku sekundy o nawet 1V, zaslaniając fotodiode tylko reką od strony okna. Ledy błyskawicznie się gasza i zapalają.

Dondu czy jest na blogu może jakis przykład realizacji programowego filtru. Nie za bardzo wiem jak mam sie za to zabrać

Artyliusz Twoje obliczenia są trafne tylko musisz podstawic 1,1V jako napiecie odniesienie poniewaz takie ma moje aTtiny13

Awatar użytkownika
Artyliusz
Użytkownik
Posty: 305
Rejestracja: 06 sty 2013, 14:10
Lokalizacja: Z Polski
Kontakt:

Post autor: Artyliusz » 29 mar 2013, 14:19

Nie eksperymentowałem jeszcze z ADC, ale zamierzam. Spójrz na to, tu jest też ile czasu trwa konwersacja pomiaru http://mikrokontrolery.blogspot.com/201 ... tania.html oczywiście musisz pod swój procek to podciągnąć.
Dawid2379 pisze:Artyliusz Twoje obliczenia są trafne tylko musisz podstawic 1,1V jako napiecie odniesienie poniewaz takie ma moje aTtiny13
Strasznie mnie to zastanawiało czemu mi wyszły takie duże wyniki z porównania do Twoich pomiarów i wszystko nawet kilka razy potem liczyłem i nie mogłem się błędu dopatrzyć, a zapomniałem, że na ATtiny robiłeś i że ma inną wartość napięcia odniesienia. Chociaż kusiło mnie, aby ściągnąć notę i spojrzeć, tylko się czymś innym zająłem później. Teraz wychodzą bardziej zbliżone wyniki.
Dawid2379 pisze:Setne Vollta może procesor w bardzo krótkim przedziale czasowym różnie odczytywać.
Szkoda, że nie masz wyświetlacza, bo tak by można było lepiej przedstawić co się dzieje. Bardzo jest ciekawe to zjawisko "pływania" pomiaru. Jednak do końca nie jest łatwo ustalić czy to wina termistora, programu lub napięcia odniesienia, które też się może zmieniać od temperatury.
dondu pisze:Oczywiście możesz zrobić filtr programowy, np. proste uśrednianie ostatnich x pomiarów.
Dopiero tak obliczoną wartość podstawiać do warunków programu.
Myślę, że można zrobić to następująco:
Naciśnięcie przycisku powoduje wykonanie przykładowo 5 pomiarów. Te pięć pomiarów można potem dodać do siebie otrzymując sumę i dzieląc przez ich ilość, czyli przez 5, przez co uzyskujesz średni wynik. Potem ten wynik podstawiasz do warunku porównania "if". Powinno to zredukować pływanie wyników. Obliczanie najlepiej zrealizować w prostej funkcji, która zwraca zmienną do warunku.
Oczywiście te 5 pomiarów to przykład.

Awatar użytkownika
dondu
Użytkownik
Posty: 211
Rejestracja: 24 maja 2005, 9:47
Lokalizacja: Śląskie
Kontakt:

Post autor: dondu » 29 mar 2013, 23:38

Dawid2379 pisze:Dondu czy jest na blogu może jakis przykład realizacji programowego filtru. Nie za bardzo wiem jak mam sie za to zabrać
Chyba nie ma, ale Artyliusz ładnie wyjaśnił co należy zrobić.

Najlepszym rozwiązaniem jest zastosowanie tablicy o np. 5 elementach czyli tzw. bufora cyklicznego. Kolejne pomiary wpisujesz do kolejnych miejsc w tablicy. Jeżeli dojdziesz do końca tablicy, to następny pomiar wpisujesz do pierwszej komórki tablicy, itd.

W ten sposób, będziesz miał w tablicy zawsze 5 ostatnich pomiarów. Wtedy w dowolnym momencie możesz policzyć średnią sumując pomiary z tablicy i dzieląc przez ich ilość.

Taki sposób liczenia jest filtrem dolnoprzepustowym i ładnie uśrednia ostatnie pomiary. W zależności od odstępów czasu pomiędzy pomiarami oraz Twoich potrzeb możesz bufor skrócić (np. do 3 elementów) lub wydłużyć (np. do 10). W ten sposób zmieniasz parametry filtru.
Artyliusz pisze:Szkoda, że nie masz wyświetlacza, bo tak by można było lepiej przedstawić co się dzieje.
Może zrobić to za pomocą RS-232 (jeżeli ma w komputerze) i terminala: http://mikrokontrolery.blogspot.com/201 ... minal.html

EDIT:
Zapomniałem, że to ATtiny13 więc RS-232 nic nie da ... ale jeżeli masz pod ręką coś większego np ATmega8, to możesz poćwiczyć na niej a dopiero później okrojony kod przenieść na ATtiny.

Awatar użytkownika
Dawid2379
Użytkownik
Posty: 318
Rejestracja: 17 lis 2010, 19:42
Lokalizacja: Kluczbork
Kontakt:

Post autor: Dawid2379 » 03 kwie 2013, 14:38

Tak kombinuje jak koń pod górke. Jak zsumować wartości z tablicy a potem je podzielic?

Kod: Zaznacz cały

int tablica_1 [5];
  
     for(uint8_t i=0;i<5;i++)
	{  
		      ADCSRA |= (1<<ADSC);                        
                           while(ADCSRA & (1<<ADSC));                
	                      {					
                              tablica_1[i] = ADC;
                              }                           
   }

ODPOWIEDZ