Przerwania INT0 i INT1


Witam,

Próbuje napisać program do sterowania "inteligentnym" oświetleniem schodów, tzn. oświetlenie ma się zapalać w zależności od tego z której strony będzie się wchodziło na schody od dołu do góry luz z góry na dół. Moim problemem jest to, że chciałbym wykorzystać przerwania zewnętrzne INT0 i INT1 pochodzące z czujników ruchu. Nie za bardzo wiem jak to zrobić jak powinien wyglądać program obsługi tych przerwań. Czy mógłby mi ktoś pomóc i napisać jakiś prosty program obsługujący przerwania zewnętrzne z INT0 i INT1 tak zeby na wyjściu zapaliła się dioda? Pomogło by mi to w rozwiązaniu mojego problemu bo bym sobie to już potem próbował dostosować do swojej aplikacji oraz było by to pomocne dla mnie w lepszym zrozumieniu działania przerwań zewnętrznych.




Portret użytkownika EDC

Odp. Przerwania INT0 i INT1

Nie napisałeś kolego w jakim języku chcesz to napisać. Jeśli w BASCOM to mogę Ci pomóc.

Wejścia zewnętrznych przerwań musisz w mikrokontrolerze skonfigurować czyli wybrać czy reagować mają na opadające zbocze, wzrastające czy może na cały czas gdy dany stan się utrzymuje. Zazwyczaj będzie to "Falling" czyli opadające. Impuls masy wywoła sygnał przerwania.
Potem musisz te przerwanie włączyć a na samym końcu włączyć przerwania ogólnie wszystkie.
Trzeba tez poinstruować mikrokontroler co ma zrobić gdy wykryje przerwanie. Do tego służy instrukcja OnINTx - i tu etykieta podprogramu do którego ma skoczyć.
Port pod wejście przerwania ustawiasz jako wejście i jeśli wybierasz wyzwalanie masą to podciągasz go wewnętrznym rezystorem żeby był w stanie wysokim.
Program obsługi przerwania powinien być jak najkrótszy i zawsze kończy się powrotem do miejsca w którym został wywołany. Najlepiej jeśli w obsłudze przerwania zaznaczysz tylko jakoś jego zaistnienie ustawiajac flage lub zmienną, ale do przykładu może być tak.

                     $regfile = "attiny2313.dat"
$crystal = 8000000
 
Config Portb = &B11111111 : Portb = &B11111111              'cały portB jako wyjście
Config Portd = &B00000000 : Portd = &B11111111              'cały portD jako wejscie i podniesiony do stanu 1
Config Porta = &B00000000 : Porta = &B11111111
 
Config Int0 = Falling                                       'wyzwalanie opadającym zboczem
Enable Int0                                                 'właczenie tego przerwania
On Int0 Sensor1                                             'wskazanie gdzie ma skoczyć (Sensor1 to nazwa)
 
Config Int1 = Falling
Enable Int1 : On Int1 Sensor2                               'to samo dla drugiego wejscia tylko zapisane inaczej
                                                              'przypisanie nazw pomaga przy wiekszych projektach
Led_a Alias Portb.0                                         ' i innym zrozumieć Twój kod gdy prosisz o rade
Led_b Alias Portb.1
 
Enable Interrupts                                           'właczenie wszystkich przerwań
 
'***** START *****
Do
' tutaj Twój kod
Loop
'*****  END  *****
End
 
 
Sensor1:                                                    'tu skacze gdy wykryje INT0
 
Reset Led_a                                                 'włacza diode A
Set Led_b                                                   'wyłacza diode B
Return                                                      'powrót do głównej pętli
 
Sensor2:
 
Set Led_a
Reset Led_b
Return

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Próbuje programować w miarę

Próbuje programować w miarę możliwości. Wykorzystuje do tego Bascoma. Dzięki wielkie za ten program jestem pewien, że jak go uruchomie i zacznę testować to mi się wiele wyjaśni.

Portret użytkownika EDC

Odp. Przerwania zawnętrzne

Tam za dużo do testowania nie ma :D Po podaniu impulsu masy na jedno z wejść INT mikrokontroler zapala odpowiednią diodę i gasi drugą. I tak na przemian.
Ważniejsze byłoby żebyś napisał na jakim mikrokontrolerze testujesz.
W nocie aplikacyjnej Twojego procesora trzeba sprawdzić na którym pinie są wejścia.
Możesz też napisać ile ma być punktów światła i jak widzisz funkcjonalne ich działanie.

Tak jak pisałem ten program u góry jest tylko dla przykładu jak włączyć przerwania zewnętrzne.
Przerwania są po to by procesor nie przeoczył jakiegoś zdarzenia gdy jest czymś zajęty, a najczęściej nie jest. Najczęściej wystarczy że z jakąś częstotliwością sprawdza stan portów.

Wydaje mi się że najwięcej czasu to zajmie logika programu :P Przemyśl jak ma się zapalać, jak gasić i co z tym gdyby ktoś zawrócił na schodach albo na schody weszły dwie osoby z dwóch stron lub jedna za drugą w odstępach czasu. Policz stopnie, zmierz czas przejścia schodów. Na wszelki wypadek przemyśl w programie "czasówke" jakby sterownik nie wykrył zejścia ze schodów.
Można podpatrzeć gotowe rozwiązania wpisując "sterowniki schodowe" w wyszukiwarke. Tu na forum jest jeden, nieskończony, projekt takiego sterownika z płynnym rozjaśnianiem się diod.
.. Pomysł jest ważny. Na pomoc w napisaniu możesz liczyć :D

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Testuje na Atmega8 z

Testuje na Atmega8 z wykorzystaniem płytki testowej ZL2AVR. Zakładam 8 punktów oświetlenia. Chciałem żeby się zapalały po kolei w zależności od kierunku wchodzenia/schodzenia ze schodów z jakąś zwłoką czasową. Zrobiłem pierwszą wersje programu lecz nie wykorzystuje w niej przerwań zewnętrznych. Na próby napisania programu z przerwaniami zewnętrznymi narazie nie mam czasu. W tym programie zastosowałem taką właśnie czasówkę która jest odpowiedzialna za gaszenie oświetlenia gdyby ktoś zawrócił ze schodów lub licznik zliczył więcej impulsów z czujnika przy wchodzenia niż przy schodzeniu, a co do rozwiązania kwestii jednoczesnego wchodzenia dwóch osób z dwóch stron to nie wiem jak wykonać. Gdy do takiej sytuacji dojdzie podczas trającego cyklu zapalania/gaszenia oświetlenia nie zostanie to wykryte przez to że w tym czasie nie będzie aktywny drugi czujnik. W programie wpisałem funkcję włącznika schodowego która powoduje zapalanie/gaszenie wszystkich punktów świetlnych jednocześnie. Zastosowałem fotorezystor aby nie dochodziło do załączania oświetlenia w przypadku gdy było by wystarczająco jasno.

$regfile = "m8def.dat"                                      'wybór mikroprocesora
$crystal = 8000000                                          'zadeklarowanie wartości rezonatora kwarcowego
 
'konfiguracja wejść i wyjść
Config Portd = &B11111111                                   'portd jako wyjścia dla podłączenia lampek ozdobnych schodów
Portd = &B11111111                                          ' stan wysoki na wszystkich wyjściach
 
Config Portb = &B11100000                                   'portb jako wejścia - podłączamy do nich czujniki oraz włączniki schodowe
Portb = &B11111111                                          'stan wysoki na wszystkich wejściach
 
'konfiguracja wewnętrznego przetwornika A/C
Config Adc = Single , Prescaler = Auto , Reference = Avcc
 
'konfiguracja Timera2
Config Timer2 = Timer , Prescale = 256                      'timer2 działa jako timer i będzie odmierzał czas
Enable Timer2                                               'uruchomienie przerwań od Timer2
On Timer2 Prztimer2                                         'przerwanie wywyływane poprzez przepełnienie Timer2
 
'deklaracja zmiennych wykorzystywanych przez Timer2
Dim Dziel(3) As Byte                                        'zmienna tablicowa
Dim Flaga_1s As Bit                                         'flaga ustawiana co 1s
Dim Flaga_100ms As Bit                                      'flaga ustawiana co 100ms
Dim Flaga_60s As Bit                                        'flaga ustawiana co 60s
 
'deklaracja zmiennych wykorzystywanych przez przetwornik A/C
Dim Wart_ac As Word                                         'wartość odczytana z przetwornika A/C
Dim V As Single                                             'wartość napięcia z przetwornika A/C
 
'deklaracja zmiennej określającej wartość opóźnienia zapalania poszczególnych świateł
Dim Czas_led As Integer
 
'deklaracja zmiennych pomocniczych
Dim Zmienna1 As Byte
Dim Zmienna2 As Byte
Dim Licznik1 As Byte                                        'licznik zliczający osoby wchodzące od dołu schodów
Dim Licznik2 As Byte                                        'licznik zliczający osoby wchodzące od góry schodów
 
'nadanie aliasów dla czujników i włączników
S1 Alias Pinb.0                                             'czujnik ruchu zapalający oświetlenie od dołu
S2 Alias Pinb.1                                             'czujnik ruchu zapalający oświetlenie od góry
S3 Alias Pinb.2                                             'włącznik schodowy
 
'nadanie wartości początkowych zmiennym
Zmienna1 = 0
Zmienna2 = 0
Licznik1 = 0
Licznik2 = 0
Czas_led = 500
Flaga_100ms = 0
Flaga_1s = 0
Flaga_60s = 0
 
Start Adc                                                   'uruchomienie przetwornika A/C
Enable Interrupts                                           'odblokowanie globalnego systemu przerwań
 
'******POCZĄTEK PĘTLI GŁÓWNEJ******
Do
 
If S3 = 0 Then                                              'jeśli włączony włącznik schodowy to
 
   Do                                                       'początek pętli pomocniczej
 
      If S3 = 0 Then                                        'gdy włącznik schodowy włączony nadal to
         Portd = &B00000000                                 'zapal jednocześnie wszystkie światła
 
      Else                                                  'jeśli włącznik jest wyłączony to
         Portd = &B11111111                                 'gaś jednocześnie wszystkie światła
         Zmienna1 = 0                                       'zeruj zmienne
         Zmienna2 = 0
         Licznik1 = 0
         Licznik2 = 0
   Exit Do                                                  'koniec pętli pomocniczej
 
      End If                                                'koniec warunku
   Loop                                                     'koniec pętli pomocniczej
End If                                                      'koniec warunku
 
Wart_ac = Getadc(0)                                         'odczytanie wartości z przetwornika A/C - portc.0
V = Wart_ac * 0.0049                                        'obliczenie wartości napięcia (wartość odczytana razy stała zależna od tego ilu bitowy jest przetwornik)
 
   If V >= 2.5 Then                                         'gdy napięcie jest większe bądz równe 2,5V - sygnał z czujnika oświetlenia - fotorezystor
      Portd = &B11111111                                    'gaś wszystkie światła
      Zmienna1 = 0                                          'zeruj zmienne
      Zmienna2 = 0
      Licznik1 = 0
      Licznik2 = 0
   Else                                                     'jeśli napięcie jest mniejsze niż 2,5V to wykonuj dalszą cześć programu
 
      If Flaga_60s = 1 Then                                 'jesli ustawiono flagę odmierzająca 60s to (ktoś był na schodach ale zawrócił i przeciął drugi raz wiązkę tego samego czujnika)
         Flaga_60s = 0                                      'zeruj flage_60s
         Licznik1 = 0                                       'zeruj licznik1
         Licznik2 = 0                                       'zeruj licznik2
         Portd = &B11111111                                 'zgaś wszystkie światła jednocześnie
      End If                                                'koniec warunku
 
 
      If Flaga_100ms = 1 Then                               'jeśli flaga odmierzająca 100ms jest ustawiona to
         Flaga_100ms = 0                                    'zeruj flagę
         Gosub Sterowanie                                   'skocz do podprogramu sterowanie
      End If                                                'koniec warunku
 
   End If                                                   'koniec warunku sprawdzającego natężenie oświetlenia - jeśli jest jasno to nie zadziała oświetlenie ozdobne schodów, a gdy jest ciemno to się będzie załączało
Loop
'******KONIEC PĘTLI GŁÓWNEJ******
 
End
'******KONIEC PROGRAMU******
 
'******POCZĄTEK PODPROGRAMU ODPOWIEDZIALNEGO ZA STEROWANIE ZAPALANIEM OŚWIETLENIA******
Sterowanie:
 
 Do                                                         'początek pętli pomocniczej odpowiedzialnej za zapalanie od dołu do góry
 
   If S1 = 0 And Portd = &B11111111 Then                    'przecięta wiązka czujnika na dole i światła zgaszone to
      Gosub Zapal_od_dolu                                   'skocz do podprogramu zapalającego oświetlenie od dołu do góry
   End If                                                   'koniec warunku
 Exit Do                                                    'wyjdz z pętli pomocniczej
 Loop                                                       'koniec pętli pomocniczej
 
 Do                                                         'początek pętli pomocniczej odpowiedzialnej za gaszenie od dołu do góry
 
   If S2 = 0 And Licznik1 = 1 Then                          'przecięta wiązka czujnika na górze i wartość licznika1 jest równa 1 to
      Gosub Gas_od_dolu                                     'skocz do podprogramu gaszącego oświetlenie od dołu do góry
   End If                                                   'koniec warunku
 Exit Do                                                    'wyjdz z pętli pomocniczej
 Loop                                                       'koniec pętli pomocniczej
 
 Do                                                         'początek pętli pomocniczej odpowiedzialnej za zapalanie od góry do dołu
   If S2 = 0 And Portd = &B11111111 Then                    'przecięta wiązka czujnika na górze i światła zgaszone to
      Gosub Zapal_od_gory                                   'skocz do podprogramu zapalającego oświetlenie od góry do dołu
   End If                                                   'koniec warunku
 Exit Do                                                    'wyjdz z pętli pomocniczej
 Loop                                                       'koniec pętli pomocniczej
 
 Do                                                         'początek pętli pomocniczej odpowiedzialnej za gaszenie od góry do dołu
   If S1 = 0 And Licznik2 = 1 Then                          'przecięta wiązka czunika na dole i wartość licznika2 jest równa 1 to
      Gosub Gas_od_gory                                     'skocz do podprogramu gaszącego oświetlenie od góry do dołu
   End If                                                   'koniec warunku
 Exit Do                                                    'wyjdz z pętli pomocniczej
 Loop                                                       'koniec pętli pomocniczej
 
 If S1 = 0 Then                                             'przecięta wiązka czujnika to
 Dziel(3) = 0                                               'zeruj trzecią komórkę tablicy odpowiedzialną za gaszenie oświetlenia gdy nikogo nie ma na schodach lub nie zostałą przecięta wiązka drugiego czujnika przez 60s
 Incr Licznik1                                              'zwiększ o jeden wartość licznika1
 End If                                                     'koniec warunku
 
 If S2 = 0 Then                                             'przecięta wiązka czujnika to
 Dziel(3) = 0                                               'zeruj trzecią komórkę tablicy odpowiedzialną za gaszenie oświetlenia gdy nikogo nie ma na schodach lub nie zostałą przecięta wiązka drugiego czujnika przez 60s
 Decr Licznik1                                              'zmniejsz o jeden wartość licznika1
 End If                                                     'koniec warunku
 
 If S2 = 0 Then                                             'przecięta wiązka czujnika to
 Dziel(3) = 0                                               'zeruj trzecią komórkę tablicy odpowiedzialną za gaszenie oświetlenia gdy nikogo nie ma na schodach lub nie zostałą przecięta wiązka drugiego czujnika przez 60s
 Incr Licznik2                                              'zwiększ o jeden wartość licznika2
 End If                                                     'koniec warunku
 
 If S1 = 0 Then                                             'przecięta wiązka czujnika to
 Dziel(3) = 0                                               'zeruj trzecią komórkę tablicy odpowiedzialną za gaszenie oświetlenia gdy nikogo nie ma na schodach lub nie zostałą przecięta wiązka drugiego czujnika przez 60s
 Decr Licznik2                                              'zmniejsz o jeden wartość licznika2
 End If                                                     'koniec warunku
 
Return                                                      'wyjście z podprogramu
'******KONIEC PODPROGRAMU******
 
'******PRZERWANIE OD TIMERA2******
Prztimer2:                                                  'nazwa przerwania
 Timer2 = 131                                               'wpisanie wartości poczatkowej do timera2
  Incr Dziel(1)                                             'zwiększ o jeden pirwszą komórkę zmiennej tablicowej dziel(1)
  If Dziel(1) = 25 Then                                     'liczy 25 przerwań czyli 100ms i ustawia flage
    Dziel(1) = 0                                            'zeruj pierwszą komórkę zmiennej tablicowej
    Set Flaga_100ms                                         'ustaw flage- odmierzono 100ms
    Incr Dziel(2)                                           'zwiększ o jeden drugą komórkę zmiennej talbicowej
    If Dziel(2) = 10 Then                                   'liczy 10 razy po 25 przerwań (100ms) czyli 1s
      Dziel(2) = 0                                          'zeruj drugą komórkę zmiennej tablicowej
      Set Flaga_1s                                          'ustaw flagę- odmirzeono 1s
      Incr Dziel(3)                                         'zwiększ o jeden trzecią komórkę zmiennej tablicowej
         If Dziel(3) = 55 Then                              'liczy 60 razy po 5 przerwań (1s) czyli 60s
         Dziel(3) = 0                                       'zeruj trzecią komórke zmiennej tablicowej
         Set Flaga_60s                                      'ustaw flagę-odmierzono 60s
         End If                                             'koniec warunku
    End If                                                  'koniec warunku
  End If                                                    'koniec warunku
Return                                                      'wyjście z podprogramu
'******KONIEC PRZERWANIA OD TIMERA2******
 
'******PODPROGRAM ZAPALANIA OŚWIETLENIA OD DOŁU******
Zapal_od_dolu:
 
Portd = &B11111111
Waitms Czas_led
Portd = &B11111110
Waitms Czas_led
Portd = &B11111100
Waitms Czas_led
Portd = &B11111000
Waitms Czas_led
Portd = &B11110000
Waitms Czas_led
Portd = &B11100000
Waitms Czas_led
Portd = &B11000000
Waitms Czas_led
Portd = &B10000000
Waitms Czas_led
Portd = &B00000000
Waitms Czas_led
 
Incr Licznik1                                               'zwiększ o jeden wartość licznika1
 
Return                                                      'wyjście z podprogramu
'******KONIEC PODPROGRAMU ZAPALANIA OŚWIETLENIA OD DOŁU******
 
'******PODPROGRAM GASZENIA OŚWIETLENIA OD DOŁU******
Gas_od_dolu:
 
Portd = &B00000000
Waitms Czas_led
Portd = &B00000001
Waitms Czas_led
Portd = &B00000011
Waitms Czas_led
Portd = &B00000111
Waitms Czas_led
Portd = &B00001111
Waitms Czas_led
Portd = &B00011111
Waitms Czas_led
Portd = &B00111111
Waitms Czas_led
Portd = &B01111111
Waitms Czas_led
Portd = &B11111111
Waitms Czas_led
 
Decr Licznik1                                               'zmniejsz o jeden wartość licznia1
If Licznik1 = 255 Then                                      'jeśli licznik1 = 255
Licznik1 = 0                                                'zeruj licznik
End If                                                      'koniec warunku
 
Return                                                      'wyjście z podprogramu
'******KONIEC PODPROGRAMU GASZENIA OŚWIETLENIA OD DOŁU******
 
'******PODPROGRAM ZAPALANIA OŚWIETLENIA OD GÓRY******
Zapal_od_gory:
 
Portd = &B11111111
Waitms Czas_led
Portd = &B01111111
Waitms Czas_led
Portd = &B00111111
Waitms Czas_led
Portd = &B00011111
Waitms Czas_led
Portd = &B00001111
Waitms Czas_led
Portd = &B00000111
Waitms Czas_led
Portd = &B00000011
Waitms Czas_led
Portd = &B00000001
Waitms Czas_led
Portd = &B00000000
Waitms Czas_led
 
Incr Licznik2                                               'zwiększ o jeden wartość licznika2                                             '
 
Return                                                      'wyjście z podprogramu
'******KONIEC PODPROGRAMU ZAPALANIA OŚWIETLENIA OD GÓRY******
 
'******PODPROGRAM GASZENIA OŚWIETLENIA OD GÓRY******
Gas_od_gory:
 
Portd = &B00000000
Waitms Czas_led
Portd = &B10000000
Waitms Czas_led
Portd = &B11000000
Waitms Czas_led
Portd = &B11100000
Waitms Czas_led
Portd = &B11110000
Waitms Czas_led
Portd = &B11111000
Waitms Czas_led
Portd = &B11111100
Waitms Czas_led
Portd = &B11111110
Waitms Czas_led
Portd = &B11111111
Waitms Czas_led
 
Decr Licznik2                                               'zmniejsz o jeden wartość licznika2
If Licznik2 = 255 Then                                      'jeśli licznik2 = 255
Licznik2 = 0                                                'zeruj licznik2
End If                                                      'koniec warunku
 
Return                                                      'wyjście z podprogramu
'******KONIEC PODPROGRAMU GASZENIA OŚWIETLENIA OD GÓRY******

Takim małym niedociągnięciem w tym programie jest to że wykorzystuje waitms co powoduje, że nie jest ustawiana flaga_60s po upłynięciu równych 60s. Myślałem jak by to można było poprawić i niestety nie wymyśliłem nic więcej jak to żeby wykorzystać do tego Timer2 tylko jak to zrobić w programie aby co 500ms dochodziło do zapalania/gaszenia kolejnego punktu oświetlenia. Ostatnio również przyszło mi do głowy jak zrobić taki "wyłącznik" jak by się znudziło komuś to oświetlenie i chciał korzystać tylko z oświetlenia głównego sufitowego według mnie to można to zrobić przez odłączenia od zasilania sterownika ale może jakaś możliwość programowa lub coś innego Ci przychodzi do głowy.

A to płynne rozjaśnianie się diod to jak się wykonuje bo wcześniej nie myślałem żeby to oświetlenie w ten sposób się zapalało, a teraz jak o tym myślę to wydaje mi się to ciekawe i sensowne.

Portret użytkownika EDC

"Inteligentne" oświetlenie schodów

Proszę. To szkielet sterownika oświetlenia schodów, podjazdów itp. Rozwiązanie programowego rozjaśniania i kolejnego włączania diod odgapiłem z projektu tu na forum. Mój jest pomysł na sterowanie tym. Program bazuje na tym w jakim aktualnie znajduje się stanie i na tej podstawie podejmuje działania. Jeśli więc na dole czujnik włączy oświetlenie to po kolei będzie włączał diody aż zapali wszystkie. Wtedy pamięta że uruchomiony był od dołu i w tej kolejności zgasi oświetlenie jeśli ktoś przejdzie schody lub po 120 sekundach. Analogicznie w drugą stronę. To szkielet, jak napisałem na początku. Teraz można dodać do niego mierzenie natężenia światła dziennego lub inne "ciekawostki" bo program zajmuje tylko 23% flasha.
Jeśli masz juz uruchomiony przetwornik ADC to możesz dodać potencjometr i wartość odczytaną z ADC wpisywac do Timera co da regulację szybkości rozpalania. Można w ten sposób sterować też Timeout`em.
Kluczowe wartości dla ułatwienia ich edycji są zapisane na początku listingu. Tak więc nie muszą to być "stałe" a zmienne.
Zauważ że program nie staje nigdy w miejscu i dopisując coś zrób podobnie np. dopisując jakiś status.
ADC najlepiej chyba czytać kilkakrotnie i uśredniać. Jeśli już da jakiś wynik np. "Jest dzień" to warto na jakimś programowym liczniku zrobić tak że dopiero kiedy dany odczyt powtórzył się kilkanaście razy to ma nastapić reakcja. Uchroni to przed reakcją na oświetlenie czujnika latarką lub flashem aparatu i nieprzewidzianych anomalii.
Program napewno trzeba "dopieścić". Sam nie mam takiej potrzeby, a nawet schodów :P
Może kiedys podjazd w stylu amerykanskym zrobie :D

$regfile = "m8def.dat"
$crystal = 8000000
 
'konfiguracja wejść i wyjść
Config Portd = &B11111111                                   'portd jako wyjścia dla podłączenia lampek ozdobnych schodów
Portd = &B11111111                                          ' stan wysoki na wszystkich wyjściach
 
Config Portb = &B11100000                                   'portb jako wejścia - podłączamy do nich czujniki oraz włączniki schodowe
Portb = &B11111111
 
Config Timer0 = Timer , Prescale = 256
Enable Timer0 : On Timer0 Zegar
Const Timer0_load = 132
 
Config Timer2 = Timer , Prescale = 8
Enable Timer2 : On Timer2 Software_pwm
Const Timer2_load = 130
 
'nadanie aliasów dla czujników i włączników
S1 Alias Pinb.0                                             'czujnik ruchu zapalający oświetlenie od dołu
S2 Alias Pinb.1                                             'czujnik ruchu zapalający oświetlenie od góry
S3 Alias Pinb.2
 
Led1 Alias Portd.7
Led2 Alias Portd.6
Led3 Alias Portd.5
Led4 Alias Portd.4
Led5 Alias Portd.3
Led6 Alias Portd.2
Led7 Alias Portd.1
Led8 Alias Portd.0
 
Dim Licznik As Byte
Dim Iled1 As Byte , Iled2 As Byte , Iled3 As Byte , Iled4 As Byte
Dim Iled5 As Byte , Iled6 As Byte , Iled7 As Byte , Iled8 As Byte
 
Dim Status As Byte , Dzielnik As Byte , Flaga_100ms As Bit
Dim Timeout As Word
 
Const Oczekiwanie = 0
Const Oswietl_z_dol = 1
Const Oswietl_z_gor = 4
Const Zgas_w_dol = 6
Const Zgas_w_gore = 3
Const Oswietlone_z_dol = 2
Const Oswietlone_z_gor = 5 
 
Const Timeout_time = 1200                                   'w setkach milisekund
 
Enable Interrupts
 
Do
 
If Flaga_100ms = 1 Then
   Flaga_100ms = 0
Select Case Status
 
 Case Oczekiwanie
 
  If S1 = 0 Then Status = Oswietl_z_dol
  If S2 = 0 Then Status = Oswietl_z_gor
 
 Case Oswietl_z_dol
 
  If Iled1 < 255 Then Incr Iled1
  If Iled1 = 255 Then If Iled2 < 255 Then Incr Iled2
  If Iled2 = 255 Then If Iled3 < 255 Then Incr Iled3
  If Iled3 = 255 Then If Iled4 < 255 Then Incr Iled4
  If Iled4 = 255 Then If Iled5 < 255 Then Incr Iled5
  If Iled5 = 255 Then If Iled6 < 255 Then Incr Iled6
  If Iled6 = 255 Then If Iled7 < 255 Then Incr Iled7
  If Iled7 = 255 Then If Iled8 < 255 Then Incr Iled8
  If Iled8 = 255 Then
     Status = Oswietlone_z_dol
     Timeout = Timeout_time                                 'czas na przejscie schodow
  End If
 
Case Oswietlone_z_dol
 
 If Timeout > 0 Then Decr Timeout
 If S2 = 0 Then Timeout = 0                                 'jesli przed Timeout`em ktos przejdzie schody
 If Timeout = 0 Then Status = Zgas_w_gore
 
Case Zgas_w_gore
 
  If Iled1 > 0 Then Decr Iled1
  If Iled1 = 0 Then If Iled2 > 0 Then Decr Iled2
  If Iled2 = 0 Then If Iled3 > 0 Then Decr Iled3
  If Iled3 = 0 Then If Iled4 > 0 Then Decr Iled4
  If Iled4 = 0 Then If Iled5 > 0 Then Decr Iled5
  If Iled5 = 0 Then If Iled6 > 0 Then Decr Iled6
  If Iled6 = 0 Then If Iled7 > 0 Then Decr Iled7
  If Iled7 = 0 Then If Iled8 > 0 Then Decr Iled8
  If Iled8 = 0 Then Status = Oczekiwanie
 
 
Case Oswietl_z_gor
 
  If Iled8 < 255 Then Incr Iled8
  If Iled8 = 255 Then If Iled7 < 255 Then Incr Iled7
  If Iled7 = 255 Then If Iled6 < 255 Then Incr Iled6
  If Iled6 = 255 Then If Iled5 < 255 Then Incr Iled5
  If Iled5 = 255 Then If Iled4 < 255 Then Incr Iled4
  If Iled4 = 255 Then If Iled3 < 255 Then Incr Iled3
  If Iled3 = 255 Then If Iled2 < 255 Then Incr Iled2
  If Iled2 = 255 Then If Iled1 < 255 Then Incr Iled1
  If Iled1 = 255 Then
     Status = Oswietlone_z_gor
     Timeout = Timeout_time
  End If
 
Case Oswietlone_z_gor
 
 If Timeout > 0 Then Decr Timeout
 If S1 = 0 Then Timeout = 0
 If Timeout = 0 Then Status = Zgas_w_dol
 
Case Zgas_w_dol
 
  If Iled8 > 0 Then Decr Iled8
  If Iled8 = 0 Then If Iled7 > 0 Then Decr Iled7
  If Iled7 = 0 Then If Iled6 > 0 Then Decr Iled6
  If Iled6 = 0 Then If Iled5 > 0 Then Decr Iled5
  If Iled5 = 0 Then If Iled4 > 0 Then Decr Iled4
  If Iled4 = 0 Then If Iled3 > 0 Then Decr Iled3
  If Iled3 = 0 Then If Iled2 > 0 Then Decr Iled2
  If Iled2 = 0 Then If Iled1 > 0 Then Decr Iled1
  If Iled1 = 0 Then Status = Oczekiwanie
 
 
End Select
 
End If
 
Loop
End
 
Software_pwm:
Timer2 = Timer2_load
 
 Incr Licznik
 If Licznik = 100 Then Licznik = 0
 
 If Licznik > Iled1 Then Set Led1 Else Reset Led1
 If Licznik > Iled2 Then Set Led2 Else Reset Led2
 If Licznik > Iled3 Then Set Led3 Else Reset Led3
 If Licznik > Iled4 Then Set Led4 Else Reset Led4
 If Licznik > Iled5 Then Set Led5 Else Reset Led5
 If Licznik > Iled6 Then Set Led6 Else Reset Led6
 If Licznik > Iled7 Then Set Led7 Else Reset Led7
 If Licznik > Iled8 Then Set Led8 Else Reset Led8
Return
 
Zegar:
Timer0 = Timer0_load
 
 Incr Dzielnik
 If Dzielnik = 25 Then
   Dzielnik = 0
   Set Flaga_100ms
 End If
Return

Życzę miłego dnia. Jeśli byłoby więcej czujników to logikę można rozbudować :)

PS. W Twoim programie widać błędne podejście do ADC. Jeśli nie potrzebujesz przedstawić odczytu z ADC użytkownikowi to nie potrzebujesz tych przeliczeń ze zmienna Single. Po prostu 5V to 1024 ..więc 2,5V to około 500. To porównujesz i wystarczy ;)

EDYTOWANO : Poprawiłem kilka błedów które rzuciły mi się w oczy po zamieszczeniu kodu.
Flaga była 1 jest 0
Poprawiony dzielnik Timera0
Poprawiona kolejnośc w Case Select
Poprawiona obsługa PWM
Poprawione pod płytę ZL2AVR

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Super dzięki wielkie za ten

Super dzięki wielkie za ten "szkielet". Co do tego sterowania czasem zapalania oświetlenia to jeśli dobrze rozumiem to wartość nastawioną na potencjometrze mam podać na ADC i wartość odczytaną z ADC następnie przypisać do Timer2_load?

Portret użytkownika jacek1987-1987

Mam pytanie co oznaczają

Mam pytanie co oznaczają cyfry po znaku równości w:
Const Oczekiwanie = 0
Const Oswietl_z_dol = 1
Const Oswietl_z_gor = 2
Const Zgas_w_dol = 3
Const Zgas_w_gore = 4
Const Oswietlone_z_dol = 5
Const Oswietlone_z_gor = 6

są to wartości które odpowiadają za coś konkretnego czy np. zmiana jakiejś wartości na inną spowoduje, że będzie to działało wtedy w jakiś inny sposób? Próbuje ogarnąć ten "szkic" i tak nie mogę zrozumieć skąd się wzięły akurat takie wartości

Portret użytkownika EDC

Sterownik schodowy

Const to stała w programie. Definiując je na początku mogę ich używać "po nazwach" co daje większą czytelność kodu dla każdego innego i dla mnie po czasie :)
Tak naprawde mógłbym napisać że "Status = 4" i tylko ja wiedziałbym co to znaczy. Status = Zgas_w_gore jest czytelniejszy a dla procesora oznacza 4. Zmiana tych wartości nic nie zmieni jeśli zawierać się bedą w przedziale do 255 i każda z nich będzie inna bo tutaj to unikatowe znaczniki. Używanie Const nic nie kosztuje a nawet własnie skraca kod gdy do jakiejś stałej odwołujemy sie więcej razy. Z każdego statusu możesz w każdym momencie przerzucić na inny i przy kolejnym przejściu pętli juz nowy bedzie brany pod uwagę. To są kolejne liczby, tu akurat, więc dopisując jakiś stan wybierz 7..8 itd.
Natomiast zmiana wartości Timeout_time u góry w programie, czyli w jednym miejscu, spowoduje że wszędzie gdzie zostanie użyta zostanie zmieniona w całym programie. Nie trzeba biegać po całym programie i szukać opóźnień. Zmieniasz raz i masz zmienione :P
Co do regulacji czasów potencjometrem.. Jeśli możesz to skompiluj to co juz jest do procka i przetestuj bo ja, prawdę powiedziawszy nie mam na czym :D
Napisz potem w jakim tempie sie rozswietlają diody, o ile chciałbys zwiększyć regulację. Właśnie Timer2_load nie powinno się ruszać bo on steruje oświetleniem a nie prędkością rozświetlania. Jeśli czas rozświetlania, czas Timeout`u i próg oświetlenia miałyby być regulowane to trzeba będzie ciut przepisać program.

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Ten szkic nie reaguje na

Ten szkic nie reaguje na żadne sygnały podawane z przycisków. Podejrzewam, że to może być przez to że nigdzie się nie odwołuje do zapalania poszczególnych pinów portu D. Chyba, że się mylę i gdzieś to jest w programie zapisane, a mi się wydaje, że tego nie ma

Portret użytkownika EDC

Sterownik schodowy

Program pracuje w stałej pętli, ale wyzwalany jest tylko co 100ms gdy ustawiona jest Flaga_100ms.
Flaga_100ms jest ustawiana gdy 250 razy przepełni się Timer0 który przepełnia sie co 4ms.
I tu chyba pierwszy błąd bo 250x4=1000. W przerwaniu zdejmij jedno zero ;)
Warunek ustawionej flagi tworzy "element opóźnienia" w programie.
Gdy warunek ustawionej flagi jest spełniony kontroler ma podjąć działania zależne od wartości zmiennej "Status".
Jeśli wynosi ona 0 czyli oczekiwanie to zwarcie pinu b.0 lub b.1 powoduje zmianę wartości zmiennej Status na 1 lub 2.
Przy kolejnym przejściu przez pętlę powinien wziąć już nową wartość zmiennej Status pod uwagę.
Jedyny pomysł jaki przychodzi mi teraz do głowy to to, że w funkcji Select Case wartości muszą wzrastać po kolei co jest w tym przypadku moim niedopatrzeniem.
Spróbuj zmienić ten fragment. Jeśli się nie pomyliłem to są poukładane po kolei.

Const Oczekiwanie = 0
Const Oswietl_z_dol = 1
Const Oswietl_z_gor = 4
Const Zgas_w_dol = 6
Const Zgas_w_gore = 3
Const Oswietlone_z_dol = 2
Const Oswietlone_z_gor = 5 

Jeśli już ma zapalić diody to jak najbardziej odwołuje się do portu D ale poprzez wartość Iled każdej z diod. Wartość ta jest zwiększana przy każdym przejściu pętli. Od wielkosci tych zmiennych Iled zależy współczynnik wypełnienia który jest sprawdzany w przerwaniu Software_pwm. Wiec jeśli bedzie np. wynosił dla jakiejś diody 50 to bedzie porównywany z aktualna wartością zmiennej Licznik która tez sie zmienia od 0 do 100. Tu widze kolejny bug który należałoby sprawdzić. Teoretycznie powinno świecić ale można potem spróbowac wartość licznik zwiększyć by uzyskać większy stopień regulacji. Przerwanie Software_pwm dokonuje sie bardzo szybko więc niezauważenie zwiększa wartość zmiennej Licznik.
Najpierw spróbuj z tą kolejnością. Drugim testem może być pominięcie warunku "If Flaga_100ms = 1"
W zależności od tego czy diody na płytce uruchomieniowej sterujesz plusem lub masą to trzeba tak ustawić Set i Reset w obsłudze przerwania Software_pwm

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Po zmiane tej kolejności przy

Po zmiane tej kolejności przy długim trzymaniu przycisku zaczyna gasnąć powoli jedna dioda i tyle. a po usunieciu tego warunku na ustawiabie flagi podczas trzymania przycisku dioda cały czas na zmiene się włącza/ wyłącza a po puszczeniu świeci

Portret użytkownika EDC

Sterownik schodowy

Wartość Iled każdej diody po starcie wynosi 0. Nie powinny więc w ogóle świecić.

If Licznik < Iled1 Then Set Led1 Else Reset Led1

zamień na
If Licznik < Iled1 Then Reset Led1 Else Set Led1

..i tak do ósmego Ileda.
Pewnie wystarczyłoby zmienić znak "<" na ">"

Tego If`a z Flaga_100ms wstaw z powrotem. Możesz też testowo wyłączyc Timeout wstawiając "'" przed tymi liniamii

If Timeout > 0 Then Decr Timeout

-

BARTek
Moja strona

Portret użytkownika EDC

Sterownik schodowy - błąd w PWM!

Kolego widze błąd kolejny :)
W obsłudze Software_pwm był błąd. Przed instrukcjami Else w każdym przypadku było Led1 zamiast kolejne diody!
Jako że mam taką możliwość to wszystkie poprawki naniosłem do pierwszego kodu. Ściągnij najlepiej nowy w całości.

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Program teraz już działa z

Program teraz już działa z tym, że rozświetlanie diod trwa długo ale próbowałem zmieniać wartość Timer0_load i po zmianach rozświetlanie przebiegało znacznie szybciej. Diody na mojej płytce w stanie spoczynku są lekko rozświetlone. Dla programu nie ważne ile osób wejdzie na schody bo i tak pierwsza osoba która z nich zejdzie spowoduje rozpoczęcie sekwencji gaszenia oświetlenia. Co do regulacji czasu rozświetlania za pomocą potencjometru to wartość z ADC w takim razie ma być podawana na timer0_load czy dobrze rozumiem? a żeby odmierzać wtedy ustaloną wartość czasu np. 1s to trzeba by było wykorzystać kolejny timer?

Portret użytkownika EDC

Sterownik schodowy z regulacją czasów.

Tak jak pisałem wcześniej program trzeba było trochę przepisać. Żeby zawsze liczył tak samo czasu Timera0 nie ruszałem. Jedynie program podzielony został na część która ze stałą częstotliwością jest w pętli co 100ms a część odpowiedzialna za rozświetlanie jest w podprogramie który wywoływany jest z częstotliwością zależną od nastaw potencjometru na ADC2. Czasem Timeout`u steruje ADC1, a czułością oświetlenia ADC0.
Teraz obsługa przerwania nie ustawia flagi a zajmuje się odczytem napięcia z trzech portów i zwiększaniem wartości potrzebnych do odmierzania czasów.
Odczytując napięcia robi to dziesięć razy po czym uśrednia. Maksymalnie może zrobić ponad 60 pomiarów do uśredniania i ustawiane jest to wartością Max_pomiar na początku. Zapis "  Suma(i + 1) = Suma(i + 1) + Probka " jest dlatego że do tablic można zapisywać wartości dopiero od jedności, nie zera.
Gdy już nazbiera pomiarów i je uśredni zgłasza gotowość i wtedy wartości sa przypisywane zmiennym. Można więc przyspieszyć rozświetlanie sie diod bo można zmniejszyć wartość zmiennej Speed. Regulowany jest też Timeout i badane nasłonecznienie.
Światło dzienne nie wyłacza nigdy oświetlenia a jedynie nie pozwala go włączyć. Zabezpiecza to przed zgaszeniem światła jakimś błyskiem.
Co do ilości osób na schodach to radzę Ci jej nie liczyć. Lepiej chyba zrezygnowac z gaszenia świateł po przejściu schodów, a w momencie gdy ktos jest na schodach i wchodzi kolejna osoba automatycznie odnawiać Timeout.

$regfile = "m8def.dat"
$crystal = 8000000
 
'konfiguracja wejść i wyjść
Config Portd = &B11111111                                   'portd jako wyjścia dla podłączenia lampek ozdobnych schodów
Portd = &B11111111                                          ' stan wysoki na wszystkich wyjściach
 
Config Portb = &B11100000                                   'portb jako wejścia - podłączamy do nich czujniki oraz włączniki schodowe
Portb = &B11111111
 
Config Portc = &B11111000 : Portc = &B00000000
 
Config Timer0 = Timer , Prescale = 256
Enable Timer0 : On Timer0 Zegar
Const Timer0_load = 132
 
Config Timer2 = Timer , Prescale = 8
Enable Timer2 : On Timer2 Software_pwm
Const Timer2_load = 130
 
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
 
Dim Probka As Word , Suma(3) As Word , Pomiar As Byte , Wynik(3) As Word
Dim Zmierzono As Bit , I As Byte
Const Max_pomiar = 10
 
'nadanie aliasów dla czujników i włączników
S1 Alias Pinb.0                                             'czujnik ruchu zapalający oświetlenie od dołu
S2 Alias Pinb.1                                             'czujnik ruchu zapalający oświetlenie od góry
S3 Alias Pinb.2
 
Led1 Alias Portd.7
Led2 Alias Portd.6
Led3 Alias Portd.5
Led4 Alias Portd.4
Led5 Alias Portd.3
Led6 Alias Portd.2
Led7 Alias Portd.1
Led8 Alias Portd.0
 
Dim Licznik As Byte
Dim Iled1 As Byte , Iled2 As Byte , Iled3 As Byte , Iled4 As Byte
Dim Iled5 As Byte , Iled6 As Byte , Iled7 As Byte , Iled8 As Byte
Const Iled_max = 200
 
Dim Status As Byte , Dzielnik As Byte , Speed As Byte , Speed_counter As Byte
Dim Timeout As Word , Timeout_time As Word
 
Const Oczekiwanie = 0
Const Oswietl_z_dol = 1
Const Oswietl_z_gor = 4
Const Zgas_w_dol = 6
Const Zgas_w_gore = 3
Const Oswietlone_z_dol = 2
Const Oswietlone_z_gor = 5
 
Enable Interrupts
'******* START ********
Do
If Zmierzono = 1 Then
   Zmierzono = 0
  Timeout_time = Wynik(2)                                   'do 102 sekund (1024/10)
  Speed = Wynik(3) / 40                                     'predosc rozswietlania/gaszenia od 1 do 25
End If
 
If Dzielnik >= 25 Then
   Dzielnik = 0
 
Select Case Status
 
Case Oczekiwanie
 
 If Wynik(1) < 500 Then                                     'jesli nie świeci słońce
  If S1 = 0 Then Status = Oswietl_z_dol
  If S2 = 0 Then Status = Oswietl_z_gor
 End If
 
Case Oswietlone_z_dol
 
 If Timeout > 0 Then Decr Timeout
 If S2 = 0 Then Timeout = 0                                 'jesli przed Timeout`em ktos przejdzie schody
 If Timeout = 0 Then Status = Zgas_w_gore
 
Case Oswietlone_z_gor
 
 If Timeout > 0 Then Decr Timeout
 If S1 = 0 Then Timeout = 0
 If Timeout = 0 Then Status = Zgas_w_dol
 
End Select
 
End If
 
If Speed_counter >= Speed Then
   Speed_counter = 0
   Gosub Sterowanie
End If
Loop
End
'******* KONIEC ********
Software_pwm:
Timer2 = Timer2_load
 
 Incr Licznik
 If Licznik = 100 Then Licznik = 0
 
 If Licznik > Iled1 Then Set Led1 Else Reset Led1
 If Licznik > Iled2 Then Set Led2 Else Reset Led2
 If Licznik > Iled3 Then Set Led3 Else Reset Led3
 If Licznik > Iled4 Then Set Led4 Else Reset Led4
 If Licznik > Iled5 Then Set Led5 Else Reset Led5
 If Licznik > Iled6 Then Set Led6 Else Reset Led6
 If Licznik > Iled7 Then Set Led7 Else Reset Led7
 If Licznik > Iled8 Then Set Led8 Else Reset Led8
Return
 
Zegar:
Timer0 = Timer0_load
 
 Incr Dzielnik
 Incr Speed_counter
 
 Incr Pomiar
  For I = 0 To 2
    Probka = Getadc(i)
    Suma(i + 1) = Suma(i + 1) + Probka
  Next I
 
  If Pomiar >= Max_pomiar Then
     Pomiar = 0
    For I = 1 To 3
    Wynik(i) = Suma(i) / Max_pomiar
    Suma(i) = 0
    Next I
    Set Zmierzono
  End If
 
Return
 
Sterowanie:
 
Select Case Status
 
    Case Oswietl_z_dol
 
  If Iled1 < Iled_max Then Incr Iled1
  If Iled1 = Iled_max Then If Iled2 < Iled_max Then Incr Iled2
  If Iled2 = Iled_max Then If Iled3 < Iled_max Then Incr Iled3
  If Iled3 = Iled_max Then If Iled4 < Iled_max Then Incr Iled4
  If Iled4 = Iled_max Then If Iled5 < Iled_max Then Incr Iled5
  If Iled5 = Iled_max Then If Iled6 < Iled_max Then Incr Iled6
  If Iled6 = Iled_max Then If Iled7 < Iled_max Then Incr Iled7
  If Iled7 = Iled_max Then If Iled8 < Iled_max Then Incr Iled8
  If Iled8 = Iled_max Then
     Status = Oswietlone_z_dol
     Timeout = Timeout_time                                 'czas na przejscie schodow
  End If
 
     Case Zgas_w_gore
 
  If Iled1 > 0 Then Decr Iled1
  If Iled1 = 0 Then If Iled2 > 0 Then Decr Iled2
  If Iled2 = 0 Then If Iled3 > 0 Then Decr Iled3
  If Iled3 = 0 Then If Iled4 > 0 Then Decr Iled4
  If Iled4 = 0 Then If Iled5 > 0 Then Decr Iled5
  If Iled5 = 0 Then If Iled6 > 0 Then Decr Iled6
  If Iled6 = 0 Then If Iled7 > 0 Then Decr Iled7
  If Iled7 = 0 Then If Iled8 > 0 Then Decr Iled8
  If Iled8 = 0 Then Status = Oczekiwanie
 
     Case Oswietl_z_gor
 
  If Iled8 < Iled_max Then Incr Iled8
  If Iled8 = Iled_max Then If Iled7 < Iled_max Then Incr Iled7
  If Iled7 = Iled_max Then If Iled6 < Iled_max Then Incr Iled6
  If Iled6 = Iled_max Then If Iled5 < Iled_max Then Incr Iled5
  If Iled5 = Iled_max Then If Iled4 < Iled_max Then Incr Iled4
  If Iled4 = Iled_max Then If Iled3 < Iled_max Then Incr Iled3
  If Iled3 = Iled_max Then If Iled2 < Iled_max Then Incr Iled2
  If Iled2 = Iled_max Then If Iled1 < Iled_max Then Incr Iled1
  If Iled1 = Iled_max Then
     Status = Oswietlone_z_gor
     Timeout = Timeout_time
  End If
 
     Case Zgas_w_dol
 
  If Iled8 > 0 Then Decr Iled8
  If Iled8 = 0 Then If Iled7 > 0 Then Decr Iled7
  If Iled7 = 0 Then If Iled6 > 0 Then Decr Iled6
  If Iled6 = 0 Then If Iled5 > 0 Then Decr Iled5
  If Iled5 = 0 Then If Iled4 > 0 Then Decr Iled4
  If Iled4 = 0 Then If Iled3 > 0 Then Decr Iled3
  If Iled3 = 0 Then If Iled2 > 0 Then Decr Iled2
  If Iled2 = 0 Then If Iled1 > 0 Then Decr Iled1
  If Iled1 = 0 Then Status = Oczekiwanie
 
End Select
 
Return

Daj znać jak działa ;) i jakby co napisz co jeszcze by się przydało.
PS. Diody pełnym blaskiem świeca już od wartości 100. Potem czekasz jeszcze 155 do rozpoczęcia rozświetlania kolejnej. Jeśli chcesz skrócić ten czas pomiędzy to trzeba zmienić wszystkie wartości "255" na mniejsze. To własnie byłoby dobre zastosowanie dla stałej gdyby zamiast 255 wpisac stałą. Zmieniłbyś u góry i załatwione.

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

wszystkie diody lekko pulsują

wszystkie diody lekko pulsują w czasie gdy nic nie zadaje na przyciski. obecnie dysponuje tylko dwoma potencjometrami to nie wiem czy takie obiektywne te testy będą. Ale z tego co udało mi się zauważyć przy zastosowaniu tylko tych dwóch potencjometrów to regulacja prędkości rozświetlania jest strasznie czuła i delikatne skręcenie potencjometru powoduje duże skoki w wartości odczytywanej przez ADC. Regulacja nasłonecznienia działa raczej poprawnie. ADC2 odpowiada za to jak szybko jest wykonywany program?

Portret użytkownika EDC

Regulacje sterownika

Tak ADC2 to max 1024. Podzielone przez 40 daje max 25. Przedtem tez było własnie 25 x 4ms = 100ms. Zmniejszenie więc wartości o jeden to już wykonywanie co 96ms. Można pomyśleć nad innym rozwiązaniem albo to taki potencjometr jak ostatnio kupiłem za 25gr i przerywały :) Sa potencjometry precyzyjne jeszcze ;) Co do mrugania..to może czytanie kolejnych ADC trzeba będzie rozbić jak przy tramsmisji microwire i multipleksowanych wyświetlaczach ;)
Mam nadzieje że masz ta wersję z "Config PortC" bo w Twoim projekcie brakowało.

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Masz racje w moim programie z

Masz racje w moim programie z postu 4 nie ma konfiguracji portu C.

Portret użytkownika EDC

Sterownik schodowy z regulacją czasów ver.2

Przemyślałem kilka rzeczy, bo nie na wszystko wpada się od razu ;)
Teraz nie dość, że nie mierzy w przerwaniu to mierzy tylko wtedy gdy nic nie robi, czyli gdy czeka. Do tego PWM włączone jest tylko na czas rozjaśniania i ściemniania. Po zakończeniu tych operacji port przyjmuje stała wartość.
Niepotrzebny jest Bit "Zmierzono". Program dalej zajmuje 30%
Spróbuj. Diody nie mają prawa drgnać w spoczynku :D

 $regfile = "m8def.dat"
$crystal = 8000000
 
'konfiguracja wejść i wyjść
Config Portd = &B11111111                                   'portd jako wyjścia dla podłączenia lampek ozdobnych schodów
Portd = &B11111111                                          ' stan wysoki na wszystkich wyjściach
 
Config Portb = &B11100000                                   'portb jako wejścia - podłączamy do nich czujniki oraz włączniki schodowe
Portb = &B11111111
 
Config Portc = &B11111000 : Portc = &B00000000
 
Config Timer0 = Timer , Prescale = 256
Enable Timer0 : On Timer0 Zegar
Const Timer0_load = 132
 
Config Timer2 = Timer , Prescale = 8
Enable Timer2 : On Timer2 Software_pwm
Const Timer2_load = 130
 
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
 
Dim Probka As Word , Suma(3) As Word , Pomiar As Byte , Wynik(3) As Word
Dim I As Byte
Const Max_pomiar = 10
 
'nadanie aliasów dla czujników i włączników
S1 Alias Pinb.0                                             'czujnik ruchu zapalający oświetlenie od dołu
S2 Alias Pinb.1                                             'czujnik ruchu zapalający oświetlenie od góry
S3 Alias Pinb.2
 
Led1 Alias Portd.7
Led2 Alias Portd.6
Led3 Alias Portd.5
Led4 Alias Portd.4
Led5 Alias Portd.3
Led6 Alias Portd.2
Led7 Alias Portd.1
Led8 Alias Portd.0
 
Dim Licznik As Byte
Dim Iled1 As Byte , Iled2 As Byte , Iled3 As Byte , Iled4 As Byte
Dim Iled5 As Byte , Iled6 As Byte , Iled7 As Byte , Iled8 As Byte
Const Iled_max = 200
 
Dim Status As Byte , Dzielnik As Byte , Speed As Byte , Speed_counter As Byte
Dim Timeout As Word , Timeout_time As Word
 
Const Oczekiwanie = 0
Const Oswietl_z_dol = 1
Const Oswietl_z_gor = 4
Const Zgas_w_dol = 6
Const Zgas_w_gore = 3
Const Oswietlone_z_dol = 2
Const Oswietlone_z_gor = 5
 
Enable Interrupts
'******* START ********
Do
 
If Dzielnik >= 25 Then
   Dzielnik = 0
 
Select Case Status
 
Case Oczekiwanie
 
 If Wynik(1) < 500 Then                                     'jesli nie świeci słońce
  If S1 = 0 Then
   Status = Oswietl_z_dol
   Enable Timer2
  Elseif S2 = 0 Then
   Status = Oswietl_z_gor
   Enable Timer2
  End If
 End If
 
  Incr Pomiar
  For I = 0 To 2
    Probka = Getadc(i)
    Suma(i + 1) = Suma(i + 1) + Probka
  Next I
 
  If Pomiar >= Max_pomiar Then
     Pomiar = 0
    For I = 1 To 3
    Wynik(i) = Suma(i) / Max_pomiar
    Suma(i) = 0
    Next I
    Timeout_time = Wynik(2)                                 'do 102 sekund (1024/100milisekund)
    Speed = Wynik(3) / 40                                   'predosc rozswietlania/gaszenia od 1 do 25
  End If
 
 
Case Oswietlone_z_dol
 
 If Timeout > 0 Then Decr Timeout
 If S2 = 0 Then Timeout = 0                                 'jesli przed Timeout`em ktos przejdzie schody
 If Timeout = 0 Then
  Status = Zgas_w_gore
  Enable Timer2
 End If
 
Case Oswietlone_z_gor
 
 If Timeout > 0 Then Decr Timeout
 If S1 = 0 Then Timeout = 0
 If Timeout = 0 Then
  Status = Zgas_w_dol
  Enable Timer2
 End If
 
End Select
 
End If
 
If Speed_counter >= Speed Then
   Speed_counter = 0
   Gosub Sterowanie
End If
Loop
End
'******* KONIEC ********
Software_pwm:
Timer2 = Timer2_load
 
 Incr Licznik
 If Licznik = 100 Then Licznik = 0
 
 If Licznik > Iled1 Then Set Led1 Else Reset Led1
 If Licznik > Iled2 Then Set Led2 Else Reset Led2
 If Licznik > Iled3 Then Set Led3 Else Reset Led3
 If Licznik > Iled4 Then Set Led4 Else Reset Led4
 If Licznik > Iled5 Then Set Led5 Else Reset Led5
 If Licznik > Iled6 Then Set Led6 Else Reset Led6
 If Licznik > Iled7 Then Set Led7 Else Reset Led7
 If Licznik > Iled8 Then Set Led8 Else Reset Led8
Return
 
Zegar:
Timer0 = Timer0_load
 
 Incr Dzielnik
 Incr Speed_counter
 
 
Return
 
Sterowanie:
 
Select Case Status
 
    Case Oswietl_z_dol
 
  If Iled1 < Iled_max Then Incr Iled1
  If Iled1 = Iled_max Then If Iled2 < Iled_max Then Incr Iled2
  If Iled2 = Iled_max Then If Iled3 < Iled_max Then Incr Iled3
  If Iled3 = Iled_max Then If Iled4 < Iled_max Then Incr Iled4
  If Iled4 = Iled_max Then If Iled5 < Iled_max Then Incr Iled5
  If Iled5 = Iled_max Then If Iled6 < Iled_max Then Incr Iled6
  If Iled6 = Iled_max Then If Iled7 < Iled_max Then Incr Iled7
  If Iled7 = Iled_max Then If Iled8 < Iled_max Then Incr Iled8
  If Iled8 = Iled_max Then
     Status = Oswietlone_z_dol
     Timeout = Timeout_time                                 'czas na przejscie schodow
     Disable Timer2
     Portd = 0
  End If
 
     Case Zgas_w_gore
 
  If Iled1 > 0 Then Decr Iled1
  If Iled1 = 0 Then If Iled2 > 0 Then Decr Iled2
  If Iled2 = 0 Then If Iled3 > 0 Then Decr Iled3
  If Iled3 = 0 Then If Iled4 > 0 Then Decr Iled4
  If Iled4 = 0 Then If Iled5 > 0 Then Decr Iled5
  If Iled5 = 0 Then If Iled6 > 0 Then Decr Iled6
  If Iled6 = 0 Then If Iled7 > 0 Then Decr Iled7
  If Iled7 = 0 Then If Iled8 > 0 Then Decr Iled8
  If Iled8 = 0 Then
   Status = Oczekiwanie
   Disable Timer2
   Portd = 255
  End If
 
     Case Oswietl_z_gor
 
  If Iled8 < Iled_max Then Incr Iled8
  If Iled8 = Iled_max Then If Iled7 < Iled_max Then Incr Iled7
  If Iled7 = Iled_max Then If Iled6 < Iled_max Then Incr Iled6
  If Iled6 = Iled_max Then If Iled5 < Iled_max Then Incr Iled5
  If Iled5 = Iled_max Then If Iled4 < Iled_max Then Incr Iled4
  If Iled4 = Iled_max Then If Iled3 < Iled_max Then Incr Iled3
  If Iled3 = Iled_max Then If Iled2 < Iled_max Then Incr Iled2
  If Iled2 = Iled_max Then If Iled1 < Iled_max Then Incr Iled1
  If Iled1 = Iled_max Then
     Status = Oswietlone_z_gor
     Timeout = Timeout_time
     Disable Timer2
     Portd = 0
  End If
 
     Case Zgas_w_dol
 
  If Iled8 > 0 Then Decr Iled8
  If Iled8 = 0 Then If Iled7 > 0 Then Decr Iled7
  If Iled7 = 0 Then If Iled6 > 0 Then Decr Iled6
  If Iled6 = 0 Then If Iled5 > 0 Then Decr Iled5
  If Iled5 = 0 Then If Iled4 > 0 Then Decr Iled4
  If Iled4 = 0 Then If Iled3 > 0 Then Decr Iled3
  If Iled3 = 0 Then If Iled2 > 0 Then Decr Iled2
  If Iled2 = 0 Then If Iled1 > 0 Then Decr Iled1
  If Iled1 = 0 Then
   Status = Oczekiwanie
   Disable Timer2
   Portd = 255
  End If
 
End Select
 
Return

-

BARTek
Moja strona

Portret użytkownika jacek1987-1987

Program działa dobrze tylko

Program działa dobrze tylko słabo zauważalna jest ta regulacja szybkością rozjaśniania diod. Po za tym wszystko super wielkie dzięki za pomoc i za te programy.

Portret użytkownika EDC

Odp. Sterownik schodowy

Można jeszcze "oszukać przeznaczenie" :D
Do wartości Timer0_load dodać "w pamięci" 25.
132+25=157 i tę wartość zapisać jako stałą Timer0_load
W obsłudze przerwania zapisac tak:

Timer0 = Timer0_load - Speed

Zmniejszając wartość mniej odejmujesz od wartości wstępnie ładowanej do Timera. Rozsynchronizuje to zegar tak że trzeba będzie dodac wartości Timeout.
Nie wiem też czy da się to zapisać w tej jednej linii. Może pomocnicza zmienna by się przydała. Można próbowac ;)
Można też spróbowac tak:
Iled_max = Wynik(3) /4
If Iled_max < 100 Then Iled_max = 100

Skróci to odstępy pomiędzy kolejnymi diodami. Oczywiście trzeba "zakomentowac" na próbe zapis Const Iled_max = 200 i zadeklarować taką zmienną. Każdy z tych pomysłów możesz próbować odzielnie i zobaczyć który najlepiej pasuje. Razem będą chyba zbyt drastyczne :D

-

BARTek
Moja strona