Operacje na sygnale PWM.

Pytania, kody i porady dotyczące nie tylko Bascom.
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Operacje na sygnale PWM.

Post autor: Oldman » 19 cze 2019, 12:37

Zanim przejdę do sedna to chciałbym się z Wami przywitać bo to mój pierwszy post na tym forum. Zarejestrowałem się tu bo jesteście chyba ostatnim żywym forum poświęconym Bascomowi. No może jest jeszcze Elektroda ale sami wiecie... :roll:
Ale do rzeczy:
Projekt jest związany z modelarstwem RC, które jest moim drugim hobby zaraz za elektroniką.
Na dowolne wejście 8-nóżkowca (np. Attiny25) podaję sygnał RC, czyli impulsy o długości od 1ms do 2ms powtarzane co ok. 20ms. Nazwijmy go KanałA.
Na drugie wejście (najlepiej INT0) podaję podobny sygnał ale z innego kanału. Niech to będzie KanałB. Długość tego sygnału muszę zmierzyć ale z tym nie mam problemu.
Jeżeli długość impulsu w KanałB jest większa od 1,5ms to KanalA jest przekazywany do wyjścia bez zmian. Ale jeśli impuls będzie krótszy od 1,5ms to na wyjściu ma się pojawić sygnał "Neutrum" (1,5ms).
Krótko mówiąc: chcę mieć możliwość wyłączenia silnika za pomocą pstryczka niezależnie od wychylenia drążka gazu.
Poradźcie jak najprościej przekazać sygnał z wejścia do wyjścia bez zniekształceń mając na uwadze, że w przerwaniu INT0 układ będzie mierzył KanałB.
Rozpatruję też zastosowanie zewnętrznego klucza z bramek NAND (4011) a wtedy Attiny by tylko otwierał i zamykał przejście i dołączał sygnał "Neutrum".
Uprzedzam, że stosowanie mikserów w nadajniku odpada bo ja ten sygnał z drążka gazu (KanałA) potrzebuję w modelu jeszcze do czegoś innego ;)
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Operacje na sygnale PWM.

Post autor: niveasoft » 19 cze 2019, 12:55

Po krótkim zastanowieniu...Tiny25, Tiny45 i Tiny85 mają dwa Timery, oraz PCINT na każdym pinie.
Jeden Timer ustawiłbym na generowanie sygnału PWM a drugim, po dobraniu jakiegoś preskalera mierzyłbym obydwa sygnały A i B w przerwaniach od PCINT.
Chodzi o to, że PCINT generuje się od każdej zmiany stanu na pinie. Czyli zawsze będziesz wiedział że akurat zmienił się stan na którymś z dwóch pinów wejściowych. Wystarczy odjąć od odczytanej poprzednio wartości Timera nowa wartość i już masz pomiar długości impulsu. Nie mierzyłbym impulsu w przerwaniu INT0. Szkoda czasu i można zgubić inny impuls.
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Operacje na sygnale PWM.

Post autor: Oldman » 19 cze 2019, 13:37

Dziękuję za szybką odpowiedź. To forum rzeczywiście żyje!
Ciekawa sugestia z tym PCINT. Zawsze stosowałem z rozbiegu i przyzwyczajenia przerwania INT. Przyjrzę się bliżej tej opcji.
Wiem, że Attiny25 (45, 85) ma dwa Timery 8-bitowe ale chciałem uniknąć wykrywania zbocza , pomiarów itd. dla sygnału KanałA. Nie interesuje mnie jego wartość tylko muszę go najwierniej przesłać z wejścia do wyjścia. Chyba jednak zastosuję dodatkowo 4011. Jest to jedna kość więcej ale chyba mniejsza szansa na błędy w głównym sygnale i znaczne odciążenie mikroprocesora. Sygnał "Neutrum" chyba wygeneruję programowo, z tym nie powinno być problemu.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Operacje na sygnale PWM.

Post autor: niveasoft » 19 cze 2019, 14:09

Wierne przekazanie jest dość proste. Piszesz:
  1. Do
  2. PORTB.0 = PINB.1
  3. Loop
i gotowe...
Teraz możesz to zawrzeć w warunku, że ma tak robić tylko kiedy Neutrum niepotrzebne ->Else Generuj Neutrum programowo.
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Operacje na sygnale PWM.

Post autor: Oldman » 19 cze 2019, 14:33

Proste jak budowa cepa :)
Muszę teraz pokombinować z tym PCINT żeby przerwanie od INT0 nie zakłóciło kręcenia się tej pętelki. A podprogram z obliczeniami i całą resztą umieścić w czasowej "martwej strefie".
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Operacje na sygnale PWM.

Post autor: niveasoft » 19 cze 2019, 15:29

Pobawiłem się chwilę bo takie małe zadanka to lubię jak krzyżówki :D
U mnie generuje 1.5ms w odstępach 20ms jeśli w ciągu 20ms nie zobaczy impulsu dłuższego od 1.5ms na drugim pinie.
Pomyślałem że tu przerwań nie potrzeba. Może się przyda ;)
Tymczasem wracam do swoich zajęć.
W zależności od tego jak skalibrowany będzie OSCCAL to może trzeba będzie doregulować te "19" przy Divider na inna wartość.
  1. $regfile = "attiny85.dat"
  2. $crystal = 8000000
  3. $hwstack = 40
  4. $swstack = 4
  5. $framesize = 32
  6.  
  7. Config Portb = &B001000                                     'PB3 wyjście
  8.  Portb = &B110111
  9.  
  10. Sig_out Alias Portb.3
  11. Sig_a Alias Pinb.2
  12. Sig_b Alias Pinb.4
  13.  
  14. Dim Divider As Word
  15. Dim 20ms As Byte , Pulse_out As Byte
  16. Dim Puls_b As Byte , Pulse_timeout As Byte
  17. Dim Mode_op As Byte
  18.  
  19. Do
  20.  
  21.  If Divider < 19 Then
  22.   Incr Divider
  23.  Else                                                       'ok 0.1ms
  24.   Divider = 0
  25.  
  26.  
  27.      If Sig_b = 1 Then
  28.       If Puls_b < 15 Then
  29.        Incr Puls_b
  30.       Else
  31.        Pulse_timeout = 0
  32.        Mode_op = 0
  33.       End If
  34.      Else
  35.       If Pulse_timeout < 190 Then
  36.        Incr Pulse_timeout
  37.        Puls_b = 0
  38.       Else
  39.        Mode_op = 1
  40.       End If
  41.      End If
  42.  
  43.  
  44.    If Mode_op = 1 Then
  45.  
  46.      'software 1.5ms every 20ms
  47.      '---------------------------
  48.      If 20ms = 0 Then
  49.       20ms = 200
  50.       Pulse_out = 15
  51.       Set Sig_out
  52.      Else
  53.       Decr 20ms
  54.       If Pulse_out > 0 Then
  55.        Decr Pulse_out
  56.        If Pulse_out = 0 Then Reset Sig_out
  57.       End If
  58.      End If
  59.      '---------------------------
  60.  
  61.    End If
  62.  
  63.  End If
  64.  
  65.  If Mode_op = 0 Then Sig_out = Sig_a
  66. Loop
Nie masz wymaganych uprawnień, aby zobaczyć pliki załączone do tego posta.
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Operacje na sygnale PWM.

Post autor: Oldman » 19 cze 2019, 19:21

Ciekawe podejście do tematu. Wszystko w pętli głównej :o
Przetestuję to jak tylko skończę inny projekt. Też w temacie RC :)
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Operacje na sygnale PWM.

Post autor: Oldman » 23 cze 2019, 10:54

Przedstawiam moje rozwiązanie tego zadania. Na razie z przerwaniem od INT0 i prymitywnym generowaniem impulsu "Neutrum" 1500us. Chciałem przetestować samą ideę, teraz czas na dopieszczanie. Muszę np. dołożyć ręczną korektę długości "Neutrum". Jako, że myślę o dołożeniu jeszcze jednego podprogramu (też z pomiarem długości impulsu) chcę wykorzystać PCINT, choć na razie nie wiem jak to ogarnąć z Timerem 8-bitowym.
  1. $regfile = "attiny25.dat"
  2. $crystal = 1000000
  3. Dim A As Bit
  4. Dim P As Byte
  5.  
  6. Config Portb = &B11110011                                   'PB0 wyj , PB2 to wejście A(INT0), PB3 to wej B
  7.        Portb = &B11100000
  8.  
  9. 'Config Watchdog = 256
  10. 'Start Watchdog
  11.  
  12. Config Timer1 = Timer , Prescale = 8                        'krok 8us, przepełnienie co 2,0480ms
  13.  
  14. Enable Interrupts
  15. Enable Int0
  16.   Config Int0 = Rising
  17.   On Int0 Pomiar Nosave
  18.  
  19. Do
  20. 'Reset Watchdog
  21.   If A = 0 Then
  22.      Portb.0 = Pinb.3
  23.   End If
  24. Loop
  25. End
  26.  
  27.  Pomiar:
  28.    $asm                                                     'to efekt działania "NoSaveTool"
  29.   !PUSH R16
  30.   !PUSH R17
  31.   !PUSH R21
  32.   !PUSH R23
  33.   !PUSH R24
  34.   !PUSH R26
  35.   !PUSH R30
  36.   !PUSH R31
  37.   !IN R24, SREG
  38.   !PUSH  R24
  39.   $end Asm
  40.  
  41.  
  42.     Timer1 = 0                                              ' pomiar długości impulsu wejściowego
  43.     Waitus 200                                              'te 200us to bufor czasowy żeby wystarczyło Timera
  44.     Start Timer1
  45.     While Pinb.2 = 1
  46.     Wend
  47.     Stop Timer1
  48.     P = Timer1
  49.     If P < 190 Then                                         'gdy pstryczek w nadajniku wyłączony
  50.          A = 1
  51.          Portb.0 = 1
  52.          Waitus 1500                                        'to generuj sygnał neutrum
  53.          Portb.0 = 0
  54.       Else
  55.          A = 0                                              'gdy pstryczek włączony  to przekazuj sygnał z wejścia do wyjścia
  56.     End If
  57.  
  58.   $asm
  59.   !POP  R24
  60.   !OUT SREG, R24
  61.   !POP R31
  62.   !POP R30
  63.   !POP R26
  64.   !POP R24
  65.   !POP R23
  66.   !POP R21
  67.   !POP R17
  68.   !POP R16
  69.   $end Asm
  70.  
  71.  Return
I jeszcze taka ciekawostka:
Da się użyć polecenia np. "Waitus T" gdzie T to zmienna typu Byte lub Word, ale nie wiem dlaczego uzyskujemy impuls 4 razy dłuższy niż wartość tej zmiennej. Może ktoś mnie oświeci dlaczego tak się dzieje.
Awatar użytkownika
niveasoft
Posty: 1216
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Operacje na sygnale PWM.

Post autor: niveasoft » 23 cze 2019, 11:58

Hmmm. Dotknij klawiatury F1 ->Help w Bascom. Wybierz temat "Waitus" ...ale dobrze, przytaczam wycinek, proszę
When the loop is set to 1, the minimum delay is 21 uS. In this case you can better use a NOP that generates 1 clock cycle delay.

At 4 MHz the minimum delay is 5 uS. So a waitus 3 will also generate 5 uS delay.

Above these values the delay will become accurate.
Awatar użytkownika
Oldman
Posty: 61
Rejestracja: 19 cze 2019, 11:15

Re: Operacje na sygnale PWM.

Post autor: Oldman » 23 cze 2019, 13:32

Dzięki za odzew ale to co przytoczyłeś to oczywiście znam. I nie wyjaśnia tej "ciekawostki". Ja mówię o dużo większych wartościach. Weź przetestuj sobie co wygeneruje Waitus dla T = 300, albo T = 800. Fusebity fabryczne.
Aktualizacja: Tak jak przy problemach z taktowaniem (mój drugi wątek) tak i w tym przypadku za dziwne działanie Waitms odpowiedzialny był uszkodzony procesor. Teraz wszystko śmiga jak należy.
ODPOWIEDZ