Przeróbka driverka AK-47
Przeróbka driverka AK-47
Witam
Jakiś czas temu, dzięki Calineczce , wpadł w moje łapki driverek o oznaczeniu AK-47, czyli popularny SKU6190.
W temacie Nowe wcielenie , podjęliśmy z Darkiem dyskusję na temat rozdzielenia sterowania LEDem przez dwa niezależne systemy AMC 350mA i 700mA. W związku z tym, że moja wiedza programistyczna nie wystarcza do odpowiedniego ograniczenia prądu PWM, tak więc postanowiłem zrobić to sprzętowo. Wygląda to tak, że w niższych trybach jest sterowany PWM tylko jeden AMC czyli LED dostaje 350mA, w wyższych trybach, LED może dostawać 700mA i na końcu 1050mA.
Pozostawiony jeszcze został jeden tryb "mrygacza" ale prąd został mu ograniczony do 700mA.
Podwaliny pod nowe rozwiązanie zostały położne rozwiązaniem z tematu Nowe spojrzenie czyli tryby w górę i w dół. Tu już była prosta droga do realizacji kontroli napięcia na akumulatorze.
Został opracowany następujący schemat:
Kiedy napięcie spadnie poniżej progu 3V (dokładnie 2,95V), automatycznie zostaje obniżony tryb na ciemniejszy. Kiedy i to będzie za mało, sytuacja się powtórzy, aż do momentu zejścia do najniższego trybu.
Kiedy jednak i tutaj dojdziemy do granicy napięcia, LED zacznie mrygać.
W projekcie jest jeszcze samoczynne wyłączenie latarki, ale myślę, że użytkownik, któremu latarka zacznie tak wołać o "papu" powinien sam zareagować, choć mogę się mylić . Jest jeszcze do rozwiązania sprawa długości kodu, niestety zbliżyłem się niebezpiecznie do 1kB.
Driverek dysponuje czterema trybami ciągłymi i jednym ostrzegawczym mrygaczem.
Niestety założenia projektowe i kłopoty w trakcie testów doprowadziły do konieczności wykonania kilku drobnych zmian w oryginalnym układzie.
Oto poprawiony schemat połączeń, który teraz wygląda tak:
a tu dla porównania oryginalny układ połączeń:
.
Procesorek ATtiny13V otrzymał nowe oprogramowanie, które to poniżej zamieszczam.
Jest to co prawda jeszcze wersja robocza, ale w pełni funkcjonalna, zmiany wymaga jedynie wartość wzorcowa do porównania minimalnej wartości napięcia.
Oto kod źródłowy napisany w BASCOM AVR
'ATtiny 13V 9,6MHz divide 8
'ADC1 pomiar napięcia zasilania (Uz - 0,6)/4
'PB0 - OC0A drugi kanał PWM 2 x AMC
'PB1 - OC0B pierwszy kanał PWM 1 x AMC
'PB3 - we klik
Dim B As Byte 'licznik klików
Dim C As Byte 'zmienna pomocnicza
Dim L As Byte 'wskaźnik trybu
Dim T As Eram Byte 'pamięć trybu
Dim U1 As Word 'zmierzone napięcie ogniwa, napięcie średnie
Dim U As Word 'suma 8 pomiarów
Config Pinb.0 = Output 'wy PWMA 700mA
Config Pinb.1 = Output 'wy PWMB 350mA
Config Pinb.2 = Input 'we ADC
Config Pinb.3 = Input 'we sterujące
L = T 'odczyt trybu startowego
Goto Wlacz 'ustalenie wartości PWM
Pwm:
Config Adc = Single , Prescaler = 8 , Reference = Internal 'konfig przetwornika
Gosub Nap 'pierwszy pomiar = szmelc
U = 0
For C = 1 To 7
Gosub Nap
U = U + U1
Next C
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 'konfig PWM, start pwm
Pocz:
Do
For C = 1 To 200 'pętla odczekująca na zapis trybu po zmianie
Gosub Klik
Waitms 4
Gosub Napiecie 'sprawdzanie napięcia aku
Powrot:
Next C
If T <> L Then Goto Pamiec 'zapis trybu do eprom jeśli się zmienił
Loop
Zmiana: 'rozpoznanie klików
B = 0 'zerowanie licznika klików
Stop Adc 'zatrzymanie przetwornika ADC, redukcja prądu
Zegar: 'pomiar czasu klika
For C = 1 To 100
If Pinb.3 = 1 Then Goto Pomiar
Waitms 1
Next C
Kierunek:
If B = 1 Then Goto Plus
If B = 2 Then Goto Minus
Goto Pwm
Plus: 'tryb w górę
Incr L
Goto Wlacz
Minus: 'tryb w dół
Decr L
Wlacz: 'ustalenie wartości pwm dla trybu
If L > 5 Then L = 1
If L < 1 Then L = 5 'sprawdzanie zakresu trybów
If L = 1 Then Goto Tryb1 'skok do podprogramu trybu
If L = 2 Then Goto Tryb2
If L = 3 Then Goto Tryb3
If L = 4 Then Goto Tryb4
If L = 5 Then Goto Migacz
Goto Pwm
Pamiec: ' zapamiętanie aktualnego trybu
T = L
Mryg:
Config Timer0 = Timer 'potwierdzenie zapamiętania
Reset Portb.0
Reset Portb.1
Waitms 10
Goto Pwm
Pomiar: 'sprawdzanie min czsu przerwy
If C < 10 Then Goto Pwm
B = B + 1
Waitms 4
For C = 1 To 50
If Pinb.3 = 0 Then Goto Zegar 'oczekiwanie na kolejny klik
Waitms 1
Next C
Goto Kierunek
Tryb1:
Pwm0a = 0
Pwm0b = 1
Goto Pwm
Tryb2:
Pwm0a = 0
Pwm0b = 40
Goto Pwm
Tryb3:
Pwm0a = 2
Pwm0b = 255
Goto Pwm
Tryb4:
Pwm0a = 255
Pwm0b = 254
Goto Pwm
Migacz:
Config Timer0 = Timer
Reset Portb.1
Do
Set Portb.0
For C = 1 To 5 'czas załączenia
Gosub Klik
Gosub Napiecie
Waitms 1
Next C
Reset Portb.0
For C = 1 To 50 'czas przerwy
Gosub Klik
Waitms 1
Next C
Loop
Napiecie: 'pomiar napięcia baterii
Gosub Nap
U = U + U1 'uzupełnienie 8 pomiaru
U1 = U
Shift U1 , Right , 3 'wylicznie średniej wartości, dzielenie przez 8
U = U - U1 'odjęcie średniej wartości
If U1 < 505 Then Goto Dol ' sprawdzanie min napięcia aku (tu dzielnik 10k /3k)
Return
Dol:
If L > 1 Then Goto Minus 'obniżenie trybu jeśli większy niż 1
Goto Mryg 'mruganie co 8 s, jeśli tryb już jest 1
Nap:
U1 = Getadc(1) 'pomiar napięcia aku
Return
Klik:
If Pinb.3 = 0 Then Goto Zmiana 'sprawdzenie stanu pinb3
Return
End
A na koniec zdjęcie prototypu używanego przy testach oprogramowania:
Pozdrawiam
PS: Jako, że trochę przy tym posiedziałem, nie zezwalam na użycie całości oraz fragmentów kodu w celach komercyjnych!
Wykorzystanie w celach hobbystycznych jest dozwolone w każdej formie.
Jakiś czas temu, dzięki Calineczce , wpadł w moje łapki driverek o oznaczeniu AK-47, czyli popularny SKU6190.
W temacie Nowe wcielenie , podjęliśmy z Darkiem dyskusję na temat rozdzielenia sterowania LEDem przez dwa niezależne systemy AMC 350mA i 700mA. W związku z tym, że moja wiedza programistyczna nie wystarcza do odpowiedniego ograniczenia prądu PWM, tak więc postanowiłem zrobić to sprzętowo. Wygląda to tak, że w niższych trybach jest sterowany PWM tylko jeden AMC czyli LED dostaje 350mA, w wyższych trybach, LED może dostawać 700mA i na końcu 1050mA.
Pozostawiony jeszcze został jeden tryb "mrygacza" ale prąd został mu ograniczony do 700mA.
Podwaliny pod nowe rozwiązanie zostały położne rozwiązaniem z tematu Nowe spojrzenie czyli tryby w górę i w dół. Tu już była prosta droga do realizacji kontroli napięcia na akumulatorze.
Został opracowany następujący schemat:
Kiedy napięcie spadnie poniżej progu 3V (dokładnie 2,95V), automatycznie zostaje obniżony tryb na ciemniejszy. Kiedy i to będzie za mało, sytuacja się powtórzy, aż do momentu zejścia do najniższego trybu.
Kiedy jednak i tutaj dojdziemy do granicy napięcia, LED zacznie mrygać.
W projekcie jest jeszcze samoczynne wyłączenie latarki, ale myślę, że użytkownik, któremu latarka zacznie tak wołać o "papu" powinien sam zareagować, choć mogę się mylić . Jest jeszcze do rozwiązania sprawa długości kodu, niestety zbliżyłem się niebezpiecznie do 1kB.
Driverek dysponuje czterema trybami ciągłymi i jednym ostrzegawczym mrygaczem.
Niestety założenia projektowe i kłopoty w trakcie testów doprowadziły do konieczności wykonania kilku drobnych zmian w oryginalnym układzie.
Oto poprawiony schemat połączeń, który teraz wygląda tak:
a tu dla porównania oryginalny układ połączeń:
.
Procesorek ATtiny13V otrzymał nowe oprogramowanie, które to poniżej zamieszczam.
Jest to co prawda jeszcze wersja robocza, ale w pełni funkcjonalna, zmiany wymaga jedynie wartość wzorcowa do porównania minimalnej wartości napięcia.
Oto kod źródłowy napisany w BASCOM AVR
'ATtiny 13V 9,6MHz divide 8
'ADC1 pomiar napięcia zasilania (Uz - 0,6)/4
'PB0 - OC0A drugi kanał PWM 2 x AMC
'PB1 - OC0B pierwszy kanał PWM 1 x AMC
'PB3 - we klik
Dim B As Byte 'licznik klików
Dim C As Byte 'zmienna pomocnicza
Dim L As Byte 'wskaźnik trybu
Dim T As Eram Byte 'pamięć trybu
Dim U1 As Word 'zmierzone napięcie ogniwa, napięcie średnie
Dim U As Word 'suma 8 pomiarów
Config Pinb.0 = Output 'wy PWMA 700mA
Config Pinb.1 = Output 'wy PWMB 350mA
Config Pinb.2 = Input 'we ADC
Config Pinb.3 = Input 'we sterujące
L = T 'odczyt trybu startowego
Goto Wlacz 'ustalenie wartości PWM
Pwm:
Config Adc = Single , Prescaler = 8 , Reference = Internal 'konfig przetwornika
Gosub Nap 'pierwszy pomiar = szmelc
U = 0
For C = 1 To 7
Gosub Nap
U = U + U1
Next C
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 'konfig PWM, start pwm
Pocz:
Do
For C = 1 To 200 'pętla odczekująca na zapis trybu po zmianie
Gosub Klik
Waitms 4
Gosub Napiecie 'sprawdzanie napięcia aku
Powrot:
Next C
If T <> L Then Goto Pamiec 'zapis trybu do eprom jeśli się zmienił
Loop
Zmiana: 'rozpoznanie klików
B = 0 'zerowanie licznika klików
Stop Adc 'zatrzymanie przetwornika ADC, redukcja prądu
Zegar: 'pomiar czasu klika
For C = 1 To 100
If Pinb.3 = 1 Then Goto Pomiar
Waitms 1
Next C
Kierunek:
If B = 1 Then Goto Plus
If B = 2 Then Goto Minus
Goto Pwm
Plus: 'tryb w górę
Incr L
Goto Wlacz
Minus: 'tryb w dół
Decr L
Wlacz: 'ustalenie wartości pwm dla trybu
If L > 5 Then L = 1
If L < 1 Then L = 5 'sprawdzanie zakresu trybów
If L = 1 Then Goto Tryb1 'skok do podprogramu trybu
If L = 2 Then Goto Tryb2
If L = 3 Then Goto Tryb3
If L = 4 Then Goto Tryb4
If L = 5 Then Goto Migacz
Goto Pwm
Pamiec: ' zapamiętanie aktualnego trybu
T = L
Mryg:
Config Timer0 = Timer 'potwierdzenie zapamiętania
Reset Portb.0
Reset Portb.1
Waitms 10
Goto Pwm
Pomiar: 'sprawdzanie min czsu przerwy
If C < 10 Then Goto Pwm
B = B + 1
Waitms 4
For C = 1 To 50
If Pinb.3 = 0 Then Goto Zegar 'oczekiwanie na kolejny klik
Waitms 1
Next C
Goto Kierunek
Tryb1:
Pwm0a = 0
Pwm0b = 1
Goto Pwm
Tryb2:
Pwm0a = 0
Pwm0b = 40
Goto Pwm
Tryb3:
Pwm0a = 2
Pwm0b = 255
Goto Pwm
Tryb4:
Pwm0a = 255
Pwm0b = 254
Goto Pwm
Migacz:
Config Timer0 = Timer
Reset Portb.1
Do
Set Portb.0
For C = 1 To 5 'czas załączenia
Gosub Klik
Gosub Napiecie
Waitms 1
Next C
Reset Portb.0
For C = 1 To 50 'czas przerwy
Gosub Klik
Waitms 1
Next C
Loop
Napiecie: 'pomiar napięcia baterii
Gosub Nap
U = U + U1 'uzupełnienie 8 pomiaru
U1 = U
Shift U1 , Right , 3 'wylicznie średniej wartości, dzielenie przez 8
U = U - U1 'odjęcie średniej wartości
If U1 < 505 Then Goto Dol ' sprawdzanie min napięcia aku (tu dzielnik 10k /3k)
Return
Dol:
If L > 1 Then Goto Minus 'obniżenie trybu jeśli większy niż 1
Goto Mryg 'mruganie co 8 s, jeśli tryb już jest 1
Nap:
U1 = Getadc(1) 'pomiar napięcia aku
Return
Klik:
If Pinb.3 = 0 Then Goto Zmiana 'sprawdzenie stanu pinb3
Return
End
A na koniec zdjęcie prototypu używanego przy testach oprogramowania:
Pozdrawiam
PS: Jako, że trochę przy tym posiedziałem, nie zezwalam na użycie całości oraz fragmentów kodu w celach komercyjnych!
Wykorzystanie w celach hobbystycznych jest dozwolone w każdej formie.
Ostatnio zmieniony niedziela 17 sty 2010, 00:14 przez Pyra, łącznie zmieniany 1 raz.
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Dzięki
To teraz kilka zdjęć z przeróbki układu docelowego.
Tutaj pacjent jeszcze zdrowy. Po lewej stronie procka widać miejsce na zworkę do przełączania grup, po zmianie tu będzie wlutowany R4. Do góry procka po między 1 i 2 nóżką licząc od prawej trzeba przeciąć ścieżkę łączącą AMC.
Tutaj już po większości przeróbek. Widać przylutowany R4 oraz R3, który jest przylutowany jednym końcem do ścieżki. Ścieżkę w tym miejscu (przelotka do gwiazdki) trzeba odrapać z ochronnego lakieru i pocynować. Widać też wlutowany kondensator 100µF po prawej stronie diody, którą trzeba było nieco przesunąć w kierunku procesora. Kondensator ładnie pasuje na pady lutownicze od diody i masowy od zworki zmiany grup, opisanej "R5". Do pada "+" LEDa został również przylutowany cienki krosik, który trzeba połączyć z wolnym końcem R3.
A tu już gotowy układ, który trzeba tylko zaprogramować i skalibrować wartość napięcia przełączania trybów, dokonując zmian wartości oznaczonej w listingu na czerwono. Widać zworkę z cyny łączącą nóżkę procesora nr 5 (PWM0a) z wejściami VCC dwóch AMCków
Pozdrawiam
To teraz kilka zdjęć z przeróbki układu docelowego.
Tutaj pacjent jeszcze zdrowy. Po lewej stronie procka widać miejsce na zworkę do przełączania grup, po zmianie tu będzie wlutowany R4. Do góry procka po między 1 i 2 nóżką licząc od prawej trzeba przeciąć ścieżkę łączącą AMC.
Tutaj już po większości przeróbek. Widać przylutowany R4 oraz R3, który jest przylutowany jednym końcem do ścieżki. Ścieżkę w tym miejscu (przelotka do gwiazdki) trzeba odrapać z ochronnego lakieru i pocynować. Widać też wlutowany kondensator 100µF po prawej stronie diody, którą trzeba było nieco przesunąć w kierunku procesora. Kondensator ładnie pasuje na pady lutownicze od diody i masowy od zworki zmiany grup, opisanej "R5". Do pada "+" LEDa został również przylutowany cienki krosik, który trzeba połączyć z wolnym końcem R3.
A tu już gotowy układ, który trzeba tylko zaprogramować i skalibrować wartość napięcia przełączania trybów, dokonując zmian wartości oznaczonej w listingu na czerwono. Widać zworkę z cyny łączącą nóżkę procesora nr 5 (PWM0a) z wejściami VCC dwóch AMCków
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
- Calineczka
- Posty: 7578
- Rejestracja: niedziela 11 lis 2007, 20:19
- Lokalizacja: Wejherowo
- Kontakt:
Bo to fajny driverek jest Stwierdziłem, że skoro i tak są dwa kanały PWM, to czemu nieElSor pisze:Nie ukrywam ze chcialem juz od jakis 2 miechow zrobic to samo z ta roznica ze 2 AMCki bylyby sterowane 1/0 bez PWMa.
A Twój pomysł ma jedną dziurkę, pomiędzy 350mA (jeden na max PWM) a 700mA (dwa załączone na stałe), też tak chciałem na początku zrobić.
Do mnie RG-C2 i świecące gumki wyłącznika tez od połowy listopada lecąElSor pisze:Pytanie tylko gdzie sa moje driverki wyslane pod koniec listopada
Dzięki wszystkim za słowa pochwały
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Wlasnie stwierdzilem ze taki problem to nie problem bo prady jakie by mnie interesowaly to i tak bylyby 1A 700mA 350mA oraz ~80mA i ~5mA (Turbo, Hi, Mid, Lo, Moon) - kwestia potrzeb i upodobanPyra pisze:A Twój pomysł ma jedną dziurkę, pomiędzy 350mA (jeden na max PWM) a 700mA (dwa załączone na stałe), też tak chciałem na początku zrobić.
Pyra, gratuluję pomysłu i wykonania. Bardzo estetyczna przeróbka, no i nowatorska.
Zastanawia mnie tylko jakie zadanie spełnia dzielnik R3/R4? Rozumiem, że ma związek z detekcją zaniku zasilania, ale jakie ma to zalety w porównaniu do bezpośredniego podpięcia + zasilania do PB3? Od razu zastrzegam, że pytam jako kompletny elektroniczny laik
Zastanawia mnie tylko jakie zadanie spełnia dzielnik R3/R4? Rozumiem, że ma związek z detekcją zaniku zasilania, ale jakie ma to zalety w porównaniu do bezpośredniego podpięcia + zasilania do PB3? Od razu zastrzegam, że pytam jako kompletny elektroniczny laik
No tak Ja pierwotnie chciałem mieć trzy tryby, w tym jeden programowalny i tak LO, program, HI, ze względu na to, że z reguły, Hi i Lo zostają nieruszane, a dostosowuje się mid. Ale na razie zaniechałem pomysłu, gdyż stwierdziłem, że cztery jasności powinny wystarczyć do wszystkich zastosowań, a "podróżowanie" po trybach w górę i w dół, ułatwia nastawienie właściwego.ElSor pisze:Wlasnie stwierdzilem ze taki problem to nie problem bo prady jakie by mnie interesowaly to i tak bylyby 1A 700mA 350mA oraz ~80mA i ~5mA (Turbo, Hi, Mid, Lo, Moon) - kwestia potrzeb i upodoban
Podpięcie portu bezpośrednio pod napięcie zasilania, balansuje na granicy parametrów ATtiny, zgodnie z dokumentacją zakres napięcia na wejściach powinien zawierać się w granicach -0,5V do VCC+0,5V, biorąc pod uwagę, że na zasilaniu procka mamy diodę, tak więc balansowali byśmy na granicy, niby nic się stać nie powinno, ale wolałem nie ryzykować. Pierwotnie dołożyłem rezystor 10k na wejściu, ale tryby nie chciały się zmieniać od zaniku zasilania, ale gdy zwierałem port do masy działało OK, Trudno mi powiedzieć jednoznacznie, być może pojemność wejściowa w połączeniu z rezystorem doprowadzała do zablokowania sygnału wysokiego na wejściu W każdym razie postanowiłem wtedy, że trzeba ten problem rozwiązać za pomocą dzielnika, co:ElSor pisze:Zastanawia mnie tylko jakie zadanie spełnia dzielnik R3/R4? Rozumiem, że ma związek z detekcją zaniku zasilania, ale jakie ma to zalety w porównaniu do bezpośredniego podpięcia + zasilania do PB3?
primo - pozwoli na ograniczenie napięcia wejściowego na porcie
secundo - będzie zwierać do masy port w stanie beznapięciowym.
Zerknięcie w notę i mamy już
VL - 0,5V - 0,2VCC
VH - 0,6VCC - VCC+0,5V
Z tego wynika,m że napięcie rozpoznawane jako stan wysoki na porcie może mieć wartość około 2/3 VCC, a nawet mniej, bo VCC = Vbat - 0,6V (bo mamy diodę na zasilaniu).
W prototypie dałem dzielnik 10k / 22k, ale ze względu na brak w moich zapasach rezystora 22k w rozmiarze 603, zastosowałem 33k, który to doskonale spełnia swoje zadanie.
Został przez to zwiększony pobór prądu przez układ o około 100µA, ale nie zauważyłem znaczącego skrócenia czasu podtrzymania napięcia przez kondensator 100µF.
Trudno mi powiedzieć w jaki sposób tą sprawę rozwiązał df , być może w ogóle nie miał takiego problemu, ale ja niestety musiałem tak to rozwiązać. Zresztą te rezystorki się tam znakomicie komponują
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Dziękuję Pyra za szczegółowe wyjaśnienia. Aktualnie kończę driver RGBW i zastosowałem w nim właśnie rozwiązanie z bezpośrednim podłączeniem + zasilania do pinu mikrokontrolera. Kompletnie nie pomyślałem o spadku napięcia na diodzie. Niestety płytkę mam wytrawioną i wszystko polutowane więc nie chciałbym robić drastycznych zmian. Jedyne wyjście jakie widzę to zastosowanie diody schottkiego.
Witam
To powinno wystarczyć. Zawsze jednak możesz przeciąć ścieżkę, chyba, że masz tam niezły ścisk.
W związku z tym, że od greg'a przyszła dziś dioda, a wolne body już czekało, postanowiłem zatrudnić do sterowania wspomniany na wstępie driverek.
W związku jednak z tym, że konieczna jest kalibracja każdego egzemplarza procesora, ze względu na drobne różnice w działaniu ADC, tym razem postanowiłem działać teoretycznie a nie praktycznie, czyli myślenie zamiast wielu prób i poprawek.
Otóż napisałem krótki programik, który trzeba wgrać w procek jako pierwszy.
Potem podłączamy driverek do źródła napięcia, które chcemy ustawić jako granicę przełączania, może to być zarówno zasilacz laboratoryjny, jak i rozładowane ogniwo LiIon. Warto poczekać kilka sekund, i już mamy w eepromie zapisaną liczbę odpowiadającą napięciu minimalnemu.
Pierwsze dwie liczby po odczytaniu eepromu procka to nasza wartość.
Odczytujemy np. coś takiego: 01 F9 reszta komórek wypełnione jest liczbą FF FF...
Ze względu na to, że jest to liczba w kodzie szesnastkowym trzeba ją sobie przeliczyć:
01 F9 = (0*16 + 1)*256 + 15*16+9 = 505
Mamy więc gotową liczbę do wpisania w program, dla dokładnego przełączania trybów
mała ściąga z kodu szesnastkowego do przeliczeń.
1=1
2=2
3=3
4=4
5=5
6=6
7=7
8=8
9=9
A=10
B=11
C=12
D=13
E=14
F=15
Program wygląda tak:
Dim C As Byte 'zmienna pomocnicza
Dim T As Eram Word 'zmierzona wartość napięcia
Dim U1 As Word 'zmierzone napięcie ogniwa, napięcie średnie
Dim U As Word 'suma 8 pomiarów
Config Pinb.2 = Input 'we ADC
Config Adc = Single , Prescaler = 8 , Reference = Internal 'konfig przetwornika
U1 = Getadc(1) 'pierwszy pomiar = szmelc
U = 0
For C = 1 To 7 'ładowanie pomiarów do średniej
U1 = Getadc(1)
U = U + U1
Next C
Nap:
Waitms 100
U1 = Getadc(1) ' pomiar napięcia aku
U = U + U1 'uzupełnienie 8 pomiaru
U1 = U
Shift U1 , Right , 3 'wylicznie średniej wartości, dzielenie przez 8
U = U - U1 'odjęcie średniej wartości
T = U1
End
Pomysł
Kilka dni temu wpadłem na, wydawało mi się, fajny pomysł wskazywania napięcia baterii. Miało by to tak wyglądać: po 3 kliku program wyłącza na chwilę latarkę, mierzy napięcie na baterii, i w zależności od wyniku mruga 5, 4.... 1 raz i powrót do świecenia
No i tu pojawił się problem program który napisałem zajmuje 112% pamięci i to już po sporej optymalizacji.
Związywałem to na dwa sposoby:
1. Dzielenie różnicy U zmierzone - U dolne /5, wynik jest ilością mrugnięć
U = U - 310
u = u \ 20
for a = 1 to u
mrug
next a
2. kolejne porównania wartości i mrug po każdym niespełnionym warunku, czyli
if u < 310 then goto pocz
go sub mrug
if u < 330 then goto pocz
go sub mrug
.
.
.
Jakieś sugestie?
Pozdrawiam
To powinno wystarczyć. Zawsze jednak możesz przeciąć ścieżkę, chyba, że masz tam niezły ścisk.
W związku z tym, że od greg'a przyszła dziś dioda, a wolne body już czekało, postanowiłem zatrudnić do sterowania wspomniany na wstępie driverek.
W związku jednak z tym, że konieczna jest kalibracja każdego egzemplarza procesora, ze względu na drobne różnice w działaniu ADC, tym razem postanowiłem działać teoretycznie a nie praktycznie, czyli myślenie zamiast wielu prób i poprawek.
Otóż napisałem krótki programik, który trzeba wgrać w procek jako pierwszy.
Potem podłączamy driverek do źródła napięcia, które chcemy ustawić jako granicę przełączania, może to być zarówno zasilacz laboratoryjny, jak i rozładowane ogniwo LiIon. Warto poczekać kilka sekund, i już mamy w eepromie zapisaną liczbę odpowiadającą napięciu minimalnemu.
Pierwsze dwie liczby po odczytaniu eepromu procka to nasza wartość.
Odczytujemy np. coś takiego: 01 F9 reszta komórek wypełnione jest liczbą FF FF...
Ze względu na to, że jest to liczba w kodzie szesnastkowym trzeba ją sobie przeliczyć:
01 F9 = (0*16 + 1)*256 + 15*16+9 = 505
Mamy więc gotową liczbę do wpisania w program, dla dokładnego przełączania trybów
mała ściąga z kodu szesnastkowego do przeliczeń.
1=1
2=2
3=3
4=4
5=5
6=6
7=7
8=8
9=9
A=10
B=11
C=12
D=13
E=14
F=15
Program wygląda tak:
Dim C As Byte 'zmienna pomocnicza
Dim T As Eram Word 'zmierzona wartość napięcia
Dim U1 As Word 'zmierzone napięcie ogniwa, napięcie średnie
Dim U As Word 'suma 8 pomiarów
Config Pinb.2 = Input 'we ADC
Config Adc = Single , Prescaler = 8 , Reference = Internal 'konfig przetwornika
U1 = Getadc(1) 'pierwszy pomiar = szmelc
U = 0
For C = 1 To 7 'ładowanie pomiarów do średniej
U1 = Getadc(1)
U = U + U1
Next C
Nap:
Waitms 100
U1 = Getadc(1) ' pomiar napięcia aku
U = U + U1 'uzupełnienie 8 pomiaru
U1 = U
Shift U1 , Right , 3 'wylicznie średniej wartości, dzielenie przez 8
U = U - U1 'odjęcie średniej wartości
T = U1
End
Pomysł
Kilka dni temu wpadłem na, wydawało mi się, fajny pomysł wskazywania napięcia baterii. Miało by to tak wyglądać: po 3 kliku program wyłącza na chwilę latarkę, mierzy napięcie na baterii, i w zależności od wyniku mruga 5, 4.... 1 raz i powrót do świecenia
No i tu pojawił się problem program który napisałem zajmuje 112% pamięci i to już po sporej optymalizacji.
Związywałem to na dwa sposoby:
1. Dzielenie różnicy U zmierzone - U dolne /5, wynik jest ilością mrugnięć
U = U - 310
u = u \ 20
for a = 1 to u
mrug
next a
2. kolejne porównania wartości i mrug po każdym niespełnionym warunku, czyli
if u < 310 then goto pocz
go sub mrug
if u < 330 then goto pocz
go sub mrug
.
.
.
Jakieś sugestie?
Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.
Witam
Chyba macie rację, czas sobie assemblera przypomnieć......
DODANO
No cóż, żeby być w zgodzie ze starożytnym powiedzeniem "starego psa nie nauczysz nowych sztuczek" postanowiłem racjonalniej wykorzystać posiadane umiejętności, i tak, po dokonaniu optymalizacji struktury programu, zmianie kilku instrukcji na mniej pamięciożerne, ponownej optymalizacji... itd, zmieściłem cały program w 1018B czyli zostało całe 14B
Program aktualnie posiada następujące właściwości:
1. cztery tryby ciągłe (od 1mA do 1050mA) i jeden strobo (ostrzegawczy, 350mA)
2. zmianę trybów w górę 1-klik, w dół 2-klik
3. zabezpieczenie przed nadmiernym rozładowaniem akumulatora (nie dotyczy strobo) przy zejściu napięcia poniżej 3V (2,96 i 2,98V na dwu driverkach) tryby automatycznie przełączają się w dół, po dojściu do LOW, LED zaczyna mrugać.
4. pomiar napięcia na aku 3-klik, podzielony na 5, prawie równych pod względem pojemności, odcinków i odpowiadające im ilości mrugnięć:
5-powyżej 3,85V
4-pomiędzy 3,7V a 3,85V
3-pomiędzy 3,65V a 3,7V
2-pomiędzy 3,55V a 3,65V
1-poniżej 3,55V
w zależności od trybu możemy więc mieć inne wskazania
Zlikwidowano przepełnienie stosu przy automatycznej zmianie trybów
Wada, nie zawsze działa 3-klik w trybie max
Teraz listing programu:
'ATtiny 13V 9,6MHz divide 8
'ADC1 pomiar napięcia zasilania (Uz - 0,6)/4
'PB0 - OC0A drugi kanał PWM 2 x AMC
'PB1 - OC0B pierwszy kanał PWM 1 x AMC
'PB3 - we klik
Dim B As Byte 'licznik klików
Dim C As Byte 'zmienna pomocnicza
Dim L As Byte 'wskaźnik trybu
Dim T As Eram Byte 'pamięć trybu
Dim U1 As Word 'zmierzone napięcie ogniwa, napięcie średnie
Dim U As Word 'suma 8 pomiarów
Config Pinb.0 = Output 'wy PWMA 700mA
Config Pinb.1 = Output 'wy PWMB 350mA
Config Pinb.2 = Input 'we ADC
Config Pinb.3 = Input 'we sterujące
L = T 'odczyt trybu startowego
Wlacz: 'ustalenie wartości PWM
If L > 5 Then L = 1 'sprawdzanie zakresu trybów
If L < 1 Then L = 5
On L Goto Pwm , Tryb1 , Tryb2 , Tryb3 , Tryb4 , Migacz 'skok do ustawienia artości trybu
Pwm: 'konfig przetwornika
Config Adc = Single , Prescaler = 8 , Reference = Internal
Gosub Nap 'wyczyszczenie bufora ADC
U = 0
Gosub Zero
Do 'zapełnienie sumy pomiarów do średniej
Gosub Nap
Incr C
Loop Until C = 7
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 'konfig PWM
Pocz:
Do 'pętla główna
Gosub Zero 'Zerowanie licznika czasu
Do 'pętla odczekująca na zapis trybu po zmianie
If Pinb.3 = 0 Then Goto Zmiana 'sprawdzenie klika
Gosub 4ms
Gosub Nap
U = U - U1 'odjęcie średniej wartości od sumy pomiarów
If U1 < 505 Then Goto Dol 'sprawdzanie min napięcia aku (tu dzielnik 10k /2,7k)
Incr C
Loop Until C = 200
Powrot:
If T <> L Then Goto Pamiec 'zapis trybu do eprom jeśli się zmienił
Loop
Zmiana: 'rozpoznanie klików
B = 0 'zerowanie licznika klików
Stop Adc 'zatrzymanie przetwornika ADC
Zegar: 'pomiar czasu klika
Gosub Zero
Do
If Pinb.3 = 1 Then Goto Pomiar
Gosub 2ms
Incr C
Loop Until C = 150 'max czas klika
Kierunek:
On B Goto Pwm , Plus , Minus , Bat 'skok do procedur obsługi klików
Goto Pwm
Plus: 'tryb w górę
Incr L
Goto Wlacz
Minus: 'tryb w dół
Decr L
Goto Wlacz
Pamiec: ' zapamiętanie aktualnego trybu
T = L
Mryg: 'potwierdzenie zapamiętania
Config Timer0 = Timer
Reset Portb.0
Reset Portb.1
Waitms 10
Goto Pwm
Pomiar: 'sprawdzanie min czasu przerwy
If C < 5 Then Goto Pwm
B = B + 1
Gosub 4ms
Gosub Zero
Do
If Pinb.3 = 0 Then Goto Zegar 'oczekiwanie na kolejny klik
Gosub 2ms
Incr C
Loop Until C = 25
Goto Kierunek
Tryb1:
Pwm0a = 0
Pwm0b = 1
Goto Pwm
Tryb2:
Pwm0a = 0
Pwm0b = 40
Goto Pwm
Tryb3:
Pwm0a = 2
Pwm0b = 255
Goto Pwm
Tryb4:
Pwm0a = 255
Pwm0b = 254
Goto Pwm
Migacz:
Config Timer0 = Timer
Reset Portb.1
Do
Set Portb.0
Gosub 4ms 'czas załączenia
Reset Portb.0
Gosub Zero
Do 'czas przerwy
If Pinb.3 = 0 Then Goto Zmiana 'sprawdzenie stanu pinb3
Gosub 4ms
Incr C
Loop Until C = 15
Loop
Bat:
Gosub Nap
B = 773 - U1 'wyliczenie różnicy pomiędzy nap max a zmierzonym
Gosub Zero
If B > 73 Then C = 1 'sprawdzanie kolejnych progów napięcia
If B > 105 Then C = 2
If B > 115 Then C = 3
If B > 136 Then C = 4
Config Timer0 = Timer
Reset Portb.1
Reset Portb.0
Waitms 80
Do 'pętla odliczająca mignięcia
Set Portb.0
Gosub 4ms
Reset Portb.0
Waitms 40
Incr C
Loop Until C = 5
Waitms 50
Goto Pwm
Dol:
If L > 1 Then Goto Minus 'obniżenie trybu jeśli większy niż 1
Goto Mryg 'mruganie, jeśli tryb już jest 1
Nap:
U1 = Getadc(1) ' pomiar napięcia aku
U = U + U1
U1 = U
Shift U1 , Right , 3 'wylicznie średniej wartości, dzielenie przez 8
Return
2ms:
Waitms 2 'opóźnienie 2ms
Return
4ms: 'opóźnienie 4ms
Waitms 4
Return
Zero:
C = 0
Return
End 'KONIEC
Mam dzieję, że komuś się przyda
Pozdrawiam
PS: W załączeniu bin i hex
Chyba macie rację, czas sobie assemblera przypomnieć......
DODANO
No cóż, żeby być w zgodzie ze starożytnym powiedzeniem "starego psa nie nauczysz nowych sztuczek" postanowiłem racjonalniej wykorzystać posiadane umiejętności, i tak, po dokonaniu optymalizacji struktury programu, zmianie kilku instrukcji na mniej pamięciożerne, ponownej optymalizacji... itd, zmieściłem cały program w 1018B czyli zostało całe 14B
Program aktualnie posiada następujące właściwości:
1. cztery tryby ciągłe (od 1mA do 1050mA) i jeden strobo (ostrzegawczy, 350mA)
2. zmianę trybów w górę 1-klik, w dół 2-klik
3. zabezpieczenie przed nadmiernym rozładowaniem akumulatora (nie dotyczy strobo) przy zejściu napięcia poniżej 3V (2,96 i 2,98V na dwu driverkach) tryby automatycznie przełączają się w dół, po dojściu do LOW, LED zaczyna mrugać.
4. pomiar napięcia na aku 3-klik, podzielony na 5, prawie równych pod względem pojemności, odcinków i odpowiadające im ilości mrugnięć:
5-powyżej 3,85V
4-pomiędzy 3,7V a 3,85V
3-pomiędzy 3,65V a 3,7V
2-pomiędzy 3,55V a 3,65V
1-poniżej 3,55V
w zależności od trybu możemy więc mieć inne wskazania
Zlikwidowano przepełnienie stosu przy automatycznej zmianie trybów
Wada, nie zawsze działa 3-klik w trybie max
Teraz listing programu:
'ATtiny 13V 9,6MHz divide 8
'ADC1 pomiar napięcia zasilania (Uz - 0,6)/4
'PB0 - OC0A drugi kanał PWM 2 x AMC
'PB1 - OC0B pierwszy kanał PWM 1 x AMC
'PB3 - we klik
Dim B As Byte 'licznik klików
Dim C As Byte 'zmienna pomocnicza
Dim L As Byte 'wskaźnik trybu
Dim T As Eram Byte 'pamięć trybu
Dim U1 As Word 'zmierzone napięcie ogniwa, napięcie średnie
Dim U As Word 'suma 8 pomiarów
Config Pinb.0 = Output 'wy PWMA 700mA
Config Pinb.1 = Output 'wy PWMB 350mA
Config Pinb.2 = Input 'we ADC
Config Pinb.3 = Input 'we sterujące
L = T 'odczyt trybu startowego
Wlacz: 'ustalenie wartości PWM
If L > 5 Then L = 1 'sprawdzanie zakresu trybów
If L < 1 Then L = 5
On L Goto Pwm , Tryb1 , Tryb2 , Tryb3 , Tryb4 , Migacz 'skok do ustawienia artości trybu
Pwm: 'konfig przetwornika
Config Adc = Single , Prescaler = 8 , Reference = Internal
Gosub Nap 'wyczyszczenie bufora ADC
U = 0
Gosub Zero
Do 'zapełnienie sumy pomiarów do średniej
Gosub Nap
Incr C
Loop Until C = 7
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 1 'konfig PWM
Pocz:
Do 'pętla główna
Gosub Zero 'Zerowanie licznika czasu
Do 'pętla odczekująca na zapis trybu po zmianie
If Pinb.3 = 0 Then Goto Zmiana 'sprawdzenie klika
Gosub 4ms
Gosub Nap
U = U - U1 'odjęcie średniej wartości od sumy pomiarów
If U1 < 505 Then Goto Dol 'sprawdzanie min napięcia aku (tu dzielnik 10k /2,7k)
Incr C
Loop Until C = 200
Powrot:
If T <> L Then Goto Pamiec 'zapis trybu do eprom jeśli się zmienił
Loop
Zmiana: 'rozpoznanie klików
B = 0 'zerowanie licznika klików
Stop Adc 'zatrzymanie przetwornika ADC
Zegar: 'pomiar czasu klika
Gosub Zero
Do
If Pinb.3 = 1 Then Goto Pomiar
Gosub 2ms
Incr C
Loop Until C = 150 'max czas klika
Kierunek:
On B Goto Pwm , Plus , Minus , Bat 'skok do procedur obsługi klików
Goto Pwm
Plus: 'tryb w górę
Incr L
Goto Wlacz
Minus: 'tryb w dół
Decr L
Goto Wlacz
Pamiec: ' zapamiętanie aktualnego trybu
T = L
Mryg: 'potwierdzenie zapamiętania
Config Timer0 = Timer
Reset Portb.0
Reset Portb.1
Waitms 10
Goto Pwm
Pomiar: 'sprawdzanie min czasu przerwy
If C < 5 Then Goto Pwm
B = B + 1
Gosub 4ms
Gosub Zero
Do
If Pinb.3 = 0 Then Goto Zegar 'oczekiwanie na kolejny klik
Gosub 2ms
Incr C
Loop Until C = 25
Goto Kierunek
Tryb1:
Pwm0a = 0
Pwm0b = 1
Goto Pwm
Tryb2:
Pwm0a = 0
Pwm0b = 40
Goto Pwm
Tryb3:
Pwm0a = 2
Pwm0b = 255
Goto Pwm
Tryb4:
Pwm0a = 255
Pwm0b = 254
Goto Pwm
Migacz:
Config Timer0 = Timer
Reset Portb.1
Do
Set Portb.0
Gosub 4ms 'czas załączenia
Reset Portb.0
Gosub Zero
Do 'czas przerwy
If Pinb.3 = 0 Then Goto Zmiana 'sprawdzenie stanu pinb3
Gosub 4ms
Incr C
Loop Until C = 15
Loop
Bat:
Gosub Nap
B = 773 - U1 'wyliczenie różnicy pomiędzy nap max a zmierzonym
Gosub Zero
If B > 73 Then C = 1 'sprawdzanie kolejnych progów napięcia
If B > 105 Then C = 2
If B > 115 Then C = 3
If B > 136 Then C = 4
Config Timer0 = Timer
Reset Portb.1
Reset Portb.0
Waitms 80
Do 'pętla odliczająca mignięcia
Set Portb.0
Gosub 4ms
Reset Portb.0
Waitms 40
Incr C
Loop Until C = 5
Waitms 50
Goto Pwm
Dol:
If L > 1 Then Goto Minus 'obniżenie trybu jeśli większy niż 1
Goto Mryg 'mruganie, jeśli tryb już jest 1
Nap:
U1 = Getadc(1) ' pomiar napięcia aku
U = U + U1
U1 = U
Shift U1 , Right , 3 'wylicznie średniej wartości, dzielenie przez 8
Return
2ms:
Waitms 2 'opóźnienie 2ms
Return
4ms: 'opóźnienie 4ms
Waitms 4
Return
Zero:
C = 0
Return
End 'KONIEC
Mam dzieję, że komuś się przyda
Pozdrawiam
PS: W załączeniu bin i hex
- Załączniki
-
- AK47 V11.zip
- (2.08 KiB) Pobrany 102 razy
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Piszmy po polsku, wszak jesteśmy Polakami.