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

[atmega32][c]adc free running mode

goral09 27 Gru 2011 17:11 2158 11
  • #1 27 Gru 2011 17:11
    goral09
    Poziom 8  

    Witam,
    Stworzyłem układ, gdzie do PINA0 podłączyłem fotorezystor w dzielniku napięcia z 10kOhm. Ma to działać na takiej zasadzie, że jeśli wartość napięcia spadnie poniżej poziomu X chcę aby zapaliła się dioda na PINC0. Teoretycznie działa, ale tylko teoretycznie gdyż raz działa a raz nie. Tzn jeśli zgaszę lampkę dioda ładnie mryga ale po zapaleniu raz się wyłącza(prawidłowa) a raz świeci ciągłym światłem. Oto mój kod:

    Code:

    /*
     * proba1.c
     *
     * Created: 2011-12-25 23:36:30
     *  Author: goral
     */

    #include <avr/io.h>
    #include <avr/delay.h>
    #define F_CPU 1000000UL

    void InicjalizujADC()
    {
       //Konfiguracja ADC
       //Ustalanie napiecia odniesienia
       ADMUX |= 1<<REFS0;
       //8-bit lub 10-bit
       ADMUX |= 1<<ADLAR; //8bit
       //Uruchamianie preskalera
       //100/5 = 20 | 10/2 = 5
       ADCSRA |= 1<<ADPS2;
       //Wlaczanie opcji ADC
       ADCSRA |= 1<<ADEN;
       //
       ADCSRA |= 1<<ADATE;
       //Wlaczenie free running mode
       SFIOR = 0;
       
    };   
    int main(void)
    {   
       
       DDRC |= 1<<PORTC0;
       InicjalizujADC();
       volatile int adcResult;   
       //Odpal pierwsza konwersje ADC
       ADCSRA |= 1<<ADSC;
       while(1)
        {
          adcResult = (int)ADCH;
          if(adcResult<100){
             _delay_ms(100);
             PORTC ^= 1<<PORTC0;   
          }
       }
    }

    0 11
  • #3 27 Gru 2011 18:07
    goral09
    Poziom 8  

    Chodzi o to aby dioda mrugała jedynie wtedy jesli wartość odczytana jest mniejsza od 100, w innym wypadku w ogóle ma nie świecić.

    EDIT.
    W porządku, działa prawidłowo. Wytłumacz mi proszę jeszcze, czemu bez tej instrukcji 'else...' raz jest ok a raz źle. Nie ma domyślnie 0?

    0
  • Pomocny post
    #4 27 Gru 2011 18:13
    snnaap
    Poziom 25  

    dioda podłączona do portu minusem?

    if(adcResult<100){
    _delay_ms(100);
    PORTC ^= 1<<PORTC0;
    } else
    PORTC |=(1<<PORTC0)

    Dodano po 4 [minuty]:

    PORTC ^= 1<<PORTC0;
    zmienia stan portu na przeciwny

    czyli jeżeli dioda w poprzednim obiegu zapali się a w następnym warunek nie zostanie spełniony to dioda pozostanie zapalona i na odwrót jeżeli w poprzednim obiegu dioda zgasła a w następnym warunek nie zostanie spełniony dioda pozostanie zgaszona.

    0
  • #5 27 Gru 2011 18:14
    goral09
    Poziom 8  

    Rozumiem rozumiem. Dziwne bo miałem tą instrukcję wpisaną a mimo wszystko nie działało jak trzeba... Pewnie gdzie indziej tkwił wtedy błąd. Dzięki za pomoc, 'podziękowanie' poszło. Temat uważam za zamknięty.

    0
  • #7 27 Gru 2011 18:17
    goral09
    Poziom 8  

    Czy można zrealizować to efektywniej? Docelowo będzie to działało z lampką 230V a układ będzie ustalał odpowiednie oświetlenie na z góry wybranej wartości.

    0
  • #9 27 Gru 2011 18:30
    goral09
    Poziom 8  

    Znalazłem wzór na natężenie oświetlenia (lux) w zależności od napięcia. Będę odczytywał napięcie z dzielnika napięcia na wejściu ADC i na tej podstawie określał to natężenie. Jeśli oświetlenie słoneczne będzie generować np 500lx a wartość docelowa na stanowisku ma być np 700lx to lampka podłączona do sieci będzie wysterowana tak aby suma oświetlenia pochodzącego od słońca i lampki wynosiła te 700lx. Tak, sterowane fazowo.

    0
  • #10 27 Gru 2011 18:39
    snnaap
    Poziom 25  

    No pomysł fajny, z realizacją też nie powinno być ciężko.
    Oczywiście służę pomocą, w zakresie jakim potrafię.
    główne trzy rzeczy jakie musisz robić to pomiar światła, detekcja zera sieci oraz odpowiednie opóźnienie we włączeniu triaka.

    0
  • #11 27 Gru 2011 18:49
    goral09
    Poziom 8  

    Detekcje zera sieci mam już chyba rozgryzioną, czekam na części. Pomiar światła odbywa się za pomocą wspomnianego fotorezystora połączonego w dzielnik 10kOhm, na pinie mierzę spadek napięcia na fotorezystorze. Zrobię 10bitową rozdzielczość co da mi 0,0049V dokładności, czytałem że fotorezystor jest dość czuły na wpływ temperatury, może zamienię to potem na fotodiodę. Wzór to:
    $$Lx = \frac{2500-500V_0}{10V_0}$$

    gdzie V_0 to zmierzone napięcie, wzór dla dzielnika z 10kOhm. O ile mi się uda spróbuję porównać to z prawdziwym luksomierzem.

    0
  • #12 27 Gru 2011 18:54
    snnaap
    Poziom 25  

    Ale tak przemyślawszy temat to chyba źle robisz ze chcesz użyć freerun mode.
    Jeżeli to ja bym był autorem zastosował bym następujący algorytm:
    1. zero sieci generuje przerwanie.
    2. w obsłudze przerwania odczytuje ADCH
    3. wyliczam opóźnienie dla włączenia triaka
    4. czekam wyliczone późnienie
    5. włączam triaka
    6. puszczam jedną konwersję

    Pozdrawiam

    0