logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8] Strowanie 10 diodami led w zależoności od zmiennej

klops_mops 10 Sie 2008 15:07 2492 25
  • #1 5426356
    klops_mops
    Poziom 17  
    Witam!

    Mam pewien problem, otóż na Atmedze8 chciałbym zrobić następującą rzecz:
    W programie (Bascom AVR) mam zmienną "wartosc", zmienna ta ma rożne wartości od 0 do 30. Chciałbym by w zależności od wartości tej zmiennej zapalały mi się po kolei diody led (tworzyły skalę). I gdy wartość osiągnie 30 i więcej to zapalą się wszystkie diody... Niestety nie wiem jak to wykonać... Za pomocą instrukcji warunkowych?

    Z góry dziękuję za pomoc
  • #2 5426451
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Coś co możesz zastosować jest w tym temacie.

    Pozdrawiam,
    Dr.Vee
  • #3 5426765
    klops_mops
    Poziom 17  
    Niestety nie jestem aż tak bardzo 'rozwinięty' w dziale mikrokontrolerów, by zrozumieć tan algorytm... Nadal nie wiem jak to wykonać, jak się w ogóle za to zabrać...
  • #4 5426833
    BoskiDialer
    Poziom 34  
    No to robisz proste zapalenie diod w zależności od wartości progowych:
    - jeśli wartość większa lub równa 3, to zapalasz pierwszą diodę
    - jeśli wartość większa lub równa 6, to zapalasz drugą diodę (pierwszy warunek też będzie spełniony, więc już masz dwie)
    - itd.. wszędzie jako 'else' możesz dać zgaszenie diody, lub zgaszenie wszystkich przed samymi warunkami. Jeśli skala miała by być logarytmiczna, to wartości progowe będą trochę inne.
  • #5 5426838
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    2 sposoby:

    1) instrukcje warunkowe (da się zrobić dla 10 diod, dla 100 to już masakra ;) )
    zgas_wszystkie_diody();
    if zmienna > prog_diody_0 then zapal_diode(0) end if;
    if zmienna > prog_diody_1 then zapal_diode(1) end if;
    if zmienna > prog_diody_2 then zapal_diode(2) end if;
    ...


    2) aż się prosi, żeby 1) przepisać w pętli z progami umieszczonymi w tablicy:
    tablica_progow[liczba_diod] = {prog_1, prog_2, ... , prog_10 };
    
    zgas_wszystkie_diody();
    i = 0;
    while i < liczba_diod do
       if zmienna > tablica_progow[i] then
           zapal_diode(i);
       end if;
       i = i + 1;   
    end while; 
    


    Oczywiście prog_1, prog_2 itd zamieniasz na konkretne wartości.

    Tłumaczenie pseudokodu na język BASIC pozostawiam Tobie ;)

    Pozdrawiam,
    Dr.Vee
  • #6 5426960
    klops_mops
    Poziom 17  
    Ok to już rozumiem i sobie poradzę... A jeszcze mam jedno pytanie - jak wykonać taki efekt:
    http://www.youtube.com/watch?v=PXr-0NK0qvI&feature=related

    Chodzi mi o zapalanie się segmentów wyświetlacza w zależności od obrotów...

    Zrobić to też jak te diody (przez if....) i użyć LOCATE czy jest jakiś inny sposób?
  • #7 5427225
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    Po prostu zamiast używać zapal_diode() wypisuj na wyświetlacz kolejny znak, a zamiast zgas_wszystkie_diody() zapełniaj pierwszą linię wyświetlacza spacjami.

    Dodatkowe znaki musisz sobie oczywiście sam zdefiniować.

    Pozdrawiam,
    Dr.Vee
  • #8 5427316
    dawid512
    Poziom 32  
    Select case rozwiąże twój problem.
  • #9 5427459
    klops_mops
    Poziom 17  
    Ok, czyli by zapalać te 10 LEDów, to:

    
    Select Case X
        Case 1 To 4 : set portd.0
        Case 1 To 8 : set portd.0; set portd.1;
        Case 1 To 12 : set portd.0; set portd.1; set portd.2;
        Case 1 To 16 : set portd.0; set portd.1; set portd.2; set portd.3;
        Case 1 To 20 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4;
        Case 1 To 24 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4; set portd.5;
        Case 1 To 28 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4; set portd.5; set portd.6;
        Case 1 To 32 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4; set portd.5; set portd.6; set portd.7;
        Case 1 To 36 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4; set portd.5; set portd.6; set portd.7; set portc.2;
        Case 1 To 40 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4; set portd.5; set portd.6; set portd.7; set portc.2; set portc.1;
          End Select
    
    
    + muszę dodać jeszcze reset potrx.x każdego portu nie używanego (by był efekt cofania)
    


    Dobrze rozumie?
  • Pomocny post
    #10 5427488
    dawid512
    Poziom 32  
    Cytat:
    Case 1 To 28 : set portd.0; set portd.1; set portd.2; set portd.3; set portd.4; set portd.5; set portd.6; 


    Po pierwsze bez srednika na koncu bo to nie C.
    Nie sadzisz ze lepiej by bylo wpisac np. PORTD = &B11110000.
  • #11 5427547
    klops_mops
    Poziom 17  
    Rzeczywiście tak będzie o wiele łatwiej....

    Tylko że nigdy nie mogę zrozumieć budowy tego... Wydaje mi się, że są to końcówki portu od 1 do 7 i ustawione to 1, a 0 to stan niski, tak?
  • #12 5427571
    dawid512
    Poziom 32  
    Od 7 do 0 a 1 to stan wysoki czyli 5v a 0 to zero;P
  • #13 5427581
    klops_mops
    Poziom 17  
    Okej... Dzięki za pomoc...

    Jutro będę próbował czy działa... ;D A co gdy mi portów zabraknie?;D
    Bo mam też inne urządzenia (przyciski, lcd, czujniki)...

    Atmega16/32?
  • Pomocny post
    #14 5427593
    dawid512
    Poziom 32  
    Wtedy albo np. mega16 lub ekspander np. PCF8574 na I2C ;)
  • #15 5427612
    klops_mops
    Poziom 17  
    Okej.. Jutro będę próbował... Wielkie dzięki za pomoc...

    A co do I2C to będę próbował za pośrednictwem tej magistrali zrobić zegarek na PCF8583 (bo ponoć na samej Atmedze ciężko uzyskać dokładność.... Więc pewnie też będę miał problemy... No ale to już na inny temat...

    Pozdrawiam
  • #16 5428676
    maly_elektronik
    Poziom 23  
    Proponuje instrukcje warunkowe :) Mogą one znajdować się w pętli :D
    W C to by była prosta instrukcja warunkow switch(x){}; ale w Bascomie to pewnie na if(warunek) than xxx
    PS Na atmedze da sie zrobić całkiem przyzwoity zegarek :) Tylko na timerze 16 bitowym :) I wystarczy dobry kwarc zewnętrzny i dobrze dobrane kondensatorki i poślizg zegara na miesiąc to ok 10s
  • #17 5430603
    klops_mops
    Poziom 17  
    Witam!

    Próbowałem... Niestety mi nie wyszło...

    Próbuję załączyć na początku 5 LEDów na porcie C (tylko ten mam wolny), w tym celu zrobiłem coś takiego:
    
    Aa = 24
       Select Case Aa
        Case 0 : Portc = &B00000000
        Case 40 To 31 : Portc = &B00111110
        Case 31 To 22 : Portc = &B00111100
        Case 22 To 13 : Portc = &B00111000
        Case 13 To 4 : Portc = &B00110000
        Case 4 To 0 : Portc = &B00100000
    End Select
    


    Na początku deklaracje portów jako wyjścia:
    
    Config Portc =  &B11111111
    


    Gdy zrobię gdzieś w środku programu takie coś:
    
    Set portc.5 
    

    To wszystko ładnie działa....

    Niestety nie wiem co robię źle... Skończyły mi się pomysły (jak na mój poziom wiedzy na temat AVRów)

    Proszę o pomoc...

    Pozdrawiam
  • #18 5430639
    dawid512
    Poziom 32  
    Cytat:
    Config Portc =  &B11111111


    Jak już to:
    DDRC = &B11111111
    lub
    CONFIG PORTC = OUTPUT


    Wez nazwij ta zmienna po ludzku.
    Ta zmnienna nie ulega zmianom?

    Cytat:
    Case 13 To 4


    Pasowaloby zeby to szlo w gore :P

    A tu:
    Cytat:
    Select Case Aa
        Case 0 : Portc = &B00000000
        ...
        Case 4 To 0 : Portc = &B00100000 


    Jedno wyklucza drugie...
  • #19 5430722
    klops_mops
    Poziom 17  
    Ok zmienię.....


    Tak ulega zmianom....

    EDIT: Poztym w tej instrukcji nie moge dac liczb przecinkowych....
  • #20 5436271
    klops_mops
    Poziom 17  
    Witam!!

    Już mi wszystko ładnie działa, oprócz jednej rzeczy... Otóż wyjścia na porcie C mi działają, lecz gdy dam wyjście na port B (6,7) to już nie chce... Wszystko robię tak samo jak z portem C...

    Teraz mam jeszcze pytanie odnośnie EAGLA - zrobiłem taki prosty schemat, przekształciłem na PCB i chciałbym to wydrukować, bym mógł przenieść to na laminat za pomocą metody termotransferowej, lecz nie wiem jak ukryć inne rzeczy i pozostawić tylko punkty lutownicze i ścieżki, bez opisów itp.

    Poniżej zdjęcie - chciałbym tylko wydrukować punkty lutownicze i ścieżki.

    Pozdrawiam
  • #21 5436412
    grafiksaba
    Poziom 11  
    MENU GÓRNE -> VIEW->DISPLAY HIDE LAYERS
    musisz wyłączyć warstwy które nie chcesz drukować
    i nie zapomnij wydrukować wszystko jako czarno-białe (bez półtonów, jest taka opcja w zakładce print chyba pod hasłem BLACK a może solid musisz sprawdzić)
  • Pomocny post
    #22 5437030
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    No i nie zapomnij o tym, że do termotransferu ścieżki muszą być w lustrzanym odbiciu (opcja mirror).

    Pozdrawiam,
    Dr.Vee
  • #23 5437187
    klops_mops
    Poziom 17  
    Ok, wykonałem pierwszy w życiu schemat w Eaglu i jutro go wydrukuje i będę próbował tą metodą termotransferu.

    Mógłby ktoś zobaczyć czy wszystko się zgadza (plik w załączniku), będę drukował z programu w tym samym stanie co na PDFie... Poniżej schemat według którego zrobiłem PCB.. Wszystko ok?

    Wiem że są to dla Was sprawy banalne, ale każdy od czegoś zacząć musi...

    Pozdrawiam

    EDIT: Nasunęło mi się jeszcze jedno pytanie odnośnie zasilania - mam źródło prądowe 6V a Atmega ma 5V, to dać jakiś rezystor, czy może budować jakiś prosty układ na tranzystorze? Ps. zasilanie to 4x1,5V Może macie jakieś swoje inne sposoby na zasilanie tej Atmegi z baterii?
  • #24 5437355
    Utul
    Poziom 13  
    Witam
    Powinno być OK
    Tylko zdaje mi się że pady masz troszke za małe.
  • #25 5439299
    dawid512
    Poziom 32  
    Co do zasilania to podłącz diode w szereg z atmega oczywiście w kierunku przewodzenia, wystapi spadek napiecia ok. 0,7V.
  • #26 5442498
    klops_mops
    Poziom 17  
    Witam!

    Mój kolejny problem to:

    Na porcie D mam zdefiniowane wejścia i wyjścia.. Gdy mam tylko wyjścia to wejścia działają ok..

    
    Config Portd.0 = Output                                     ' wyswietlacz podswietlanioe
    Config Portd.2 = Input
    Config Portd.3 = Input
    Config Portd.1 = Input
    Config Portc = Output
    Config Portd.6 = Output
    Config Portd.7 = Output
    Config Portd.4 = Output 
    


    Potem wykorzystuje wejścia gdy na końcówce portu jest stan niski..
    
       If Pind.2 = 0 Then
       Waitms 100
       Cls
       Locate 1 , 4
       Lcd "PODSWIETLANIE"
       Locate 3 , 6
       Lcd "WYLACZONE"
       Wait 2
       Cls
       Reset Portd.0
       End If
    
       If Pind.3 = 0 Then
       Waitms 100
       Set Portd.0
       Cls
       Locate 1 , 4
       Lcd "PODSWIETLANIE"
       Locate 3 , 6
       Lcd "WLACZONE"
       Wait 2
       Cls
       End If
    
       If Pind.1 = 0 Then
       Cls
       Locate 2 , 1
       Lcd "____________________"
       Locate 4 , 1
       Lcd Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4) ; Chr(4)
       Locate 3 , 1
       Lcd "|"
       Locate 3 , 20
       Lcd "|"
       Else
    
    endif
    


    I gdy mam zdefiniowane wyjścia to nie wiem czemu ale na wyswietlaczu pojawia sie ze podswoetlanie wlaczone....

    potem wyjścia wykorzystuję tak:
    
    Stan = 0
    
    Select Case Aa
        Case 48 To 100 : Portc = &B00111111 ; Set Portd.6 ; Set Portd.7 ; Set Stan
        Case 42 To 47 : Portc = &B00111111 ; Set Portd.6 ; Set Portd.7 ; Reset Stan
        Case 36 To 41 : Portc = &B00111111 ; Set Portd.6 ; Reset Stan
        Case 30 To 35 : Portc = &B00111111 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan
        Case 24 To 29 : Portc = &B00111110 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan
        Case 18 To 23 : Portc = &B00111100 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan
        Case 12 To 17 : Portc = &B00111000 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan
        Case 6 To 11 : Portc = &B00110000 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan       ' 76543210
        Case 1 To 5 : Portc = &B00100000 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan
        Case 0 : Portc = &B00000000 ; Reset Portd.6 ; Reset Portd.7 ; Reset Stan
    End Select
    
    If Stan = 1 Then
    Do
    Set Portd.4
    Waitms 100
    Reset Portd.4
    Loop
    Else
    Reset Portd.4
    End If
    


    Co robię źle?

    Ps. Port c mam cały zajety na wyjście... Port B - LCD

    Z góry dziękuję za pomoc

    Dodano po 15 [minuty]:

    Może dać jakieś rezystory na te wejścia?
REKLAMA