Bascom-PWM


Witam. Zaczynam naukę programowania w bascomie przy okazji buduję linefollowera na tiny2313. Program udało mi się napisać bez większych problemów, jednak chciałbym go niedługo wzbogacić, m.in. o PWM. Tu się zaczyna problem-mimo że trochę poczytałem nie wiem jak to zrobić.
Powiedzmy, że chciałbym, aby na którymś porcie(obojętnie którym) był generowany sygnał o niezmiennej(niezależnie co się dzieje w programie) szerokości impulsu.
Na początku, w configu dopisuję:

Config Timer1 = Pwm , Pwm = 8 , Prescale = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down

Jednak nie wiem co dalej-jak ustawić port na którym ma być przebieg i jak ustawić jego wypełnienie?

Pozdrawiam




Portret użytkownika mirley

Re; PWM

Coś mi tutaj nie gra.... do PWM0a rozumiem że masz podłączony MOSFETN.... Jak chcesz podłączyć 2 tranzystory to wystarczy podłaczyć dwie bramki równolegle. Do bramek nie wpływają żadne prądy.

Co do MOSFETAP + NPN to sprawa też jest prosta. Bramka musi być podłączona jakimś rezystorem, np 10k do źródła (podłączonego do zasilania), czyli do + zasilania. Ta sama bramka podłączona jest do kolektora NPN a jego emiter do masy. Rezystor na bazie npn np 10k. Odbiornik jest między drenem mosfeta a masą. Podanie napięcie na bazę NPN powoduje jego otwarcie i ściągnięcie bramki mosfeta do masy co powoduje jego włączenie.

Tak czy inaczej lepiej dać dwa mosfety N jeśli nie ma to znaczenia dla innych układów współpracujących

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika maro

Czyli coś takiego.

Czyli coś takiego. Niepotrzebny jest rezystor między emiterem a bazą tranzystora NPN? i między bramką a źródłem MOSFETA?

Portret użytkownika mirley

RE: pwm

R5 jest niepotrzebny a zamiast tego obowiązkowy jest rezystor od bramki do żródła (do +12V) mosfeta bo inaczej nigdy się nie wyłączy

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika maro

Ok poprawiłem. Dałem rezystor

Ok poprawiłem. Dałem rezystor między bramką, a źródłem mosfeta, tylko jest jeszcze jeden problem, bo chciałem podłączyć jeszcze jeden mosfet tyle że nie wiem czy lepiej bedzie go podłączyć pod T5 czy porostu bać drugi tranzystor i mośfet na porcie PB.1?

Portret użytkownika mirley

Re: Tranzystor

Daj drugi mosfet i podłącz dwie bramki bezpośrednio do siebie.... to mosfety i można łączyć bramki bez kłopotu, w przypadku bipolarnych tranzystorów tak by się nie dało.

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika airman

Witam, potrzebuje podobny

Witam, potrzebuje podobny program do regulacji jasności ledów, chciałbym używając jednego przycisku włączać i zwiększać jasność co np 51 i tak klikając aż do 255 a jeśli przekroczy wartość 255 to wraca do 0 i tak w koło, jednak nie do końca wiem jak to rozwiązać gdyż program po przekroczeniu 255 nie gasi diody tylko zaczyna od kolejnej wartości 51. Dodatkowo chciałbym aby nie było powtarzania za każdym razem od 0 do 51 i później od 0 do 102 itd tylko aby wartości były płynnie dodawane bez zbędnego "rozświecania" od nowa przy każdej zmianie wartości Proszę o pomoc. Oto program:

$regfile = "attiny13.dat"
$crystal = 1000000
Ddrb = &B11110111 : Portb = &B00011001
 
$hwstack = 8
$swstack = 8
$framesize = 8
 
Klawisz Alias Pinb.3
Dim I As Byte
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim E As Byte
Dim F As Byte
 
A = 0
 
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
 
Enable Interrupts
 
Do
 
If Klawisz = 0 Then
Waitms 20
If Klawisz = 0 Then
Gosub Licz
End If
End If
Loop
 
 
Licz:
A = A + 51
If A > 255 Then
Portb.0 = 0
A = 0
Else
Pwm0a = 0
  Waitms 10
For I = 0 To A
     Pwm0a = I
     Waitms 20
  Next I
  End If
  Return

Portret użytkownika matrix

Re: Witam, potrzebuje podobny

Zobacz co napisałeś w programie.
Na początek dajesz deklarację zmiennej A jako byte.

Dim A as Byte

Więc ta przyjmie max wartość rzędu 255, a Ty dalej sprawdzasz warunek
If A > 255

Warunek nigdy nie zostanie spełniony. Tyle na początek.

Portret użytkownika airman

Dobrze, ale jeśli zadeklaruje

Dobrze, ale jeśli zadeklaruje

If A > 254

to również nic nie zmienia, tak samo jak do zmiennej A przypisze integer

i jak wygląda sprawa z płynnym dodawaniem określonej liczby do PWM aby od nowa nie rozświetlalo ?

Dziękuję za odpowiedzi :)

edit:
problemem iż za każdym razem program zaczyna od wartości minimalnej jest ten kawałek kodu

Licz:
A = A + 51

teraz rodzi się pytanie jak go zaimplikować tak aby po calym cylku zrobił 0 na wyjściu i dopiero później next click rodzi liczbę 51 na wyjściu itd...

Edit:
Oto aktualny kod, i nadal nie potrafię osiągnąć pełnego wygaszenia po 6 naciśnięciu przycisku. Proszę o sprawdzenie i naprowadzenie.

$regfile = "attiny13.dat"
$crystal = 1000000
Ddrb = &B11110111 : Portb = &B00011001
 
$hwstack = 8
$swstack = 8
$framesize = 8
 
Klawisz Alias Pinb.3
Dim I As Integer
Dim A As Byte
Dim B As Byte
Dim C As Byte
Dim D As Byte
Dim E As Byte
Dim F As Byte
 
A = 0
 
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
 
Enable Interrupts
 
Do
 
If Klawisz = 0 Then
Waitms 20
If Klawisz = 0 Then
Gosub Licz
End If
End If
Loop
 
 
Licz:
Incr B
If B > 5 Then
A = 0
B = 0
Pinb.0 = 0
Else
Gosub Licz1
End If
Return
 
 
Licz1:
A = A + 51
Pwm0a = 0
  Waitms 10
For I = 0 To A
     Pwm0a = I
     Waitms 20
  Next I
  Return

Portret użytkownika matrix

Re: Bascom-PWM

Problemem w tym przypadku jest to że dajesz obliczenie typu

A = A + 51

Z takiego działania przy zmiennej byte też nigdy nie uzyskasz liczby większej niż 255. Przeanalizuj sobie:
załóżmy że na początku mamy wartość 0, za pierwszym razem przy działaniu
A = A + 51

będziesz miał wartość 51, później kolejno 102, 153, 204 i 255.
Teoretycznie gdtbyś napisał warunek:
If A = 255 then

to według powyższych założeń powinno się udać. Do tego w warunku dokładasz zerowanie zmiennej A czyli
If A = 255 then A = 0

Sprawdź.

Portret użytkownika airman

Przepraszam, że tak długo nie

Przepraszam, że tak długo nie odpisywałem jednak miałem naprawde sporo pracy, teraz znalazlem chwile. Przetestowałem sugestie jednak w dalszym ciągu jest brak gaszenia po 6 kliknięciu tylko po 5, a to mnie nie urządza, gdyż nie osiągam pełnej mocy świecenia która następuje po 5 kliknięciu. może ktoś zasugerować jakieś rozwiązanie ? Bardzo dziękuję za pomoc

Portret użytkownika matrix

Re: Bascom-PWM

No to dodaj sobie jakąś tam zmienną i ją zwiększaj przypisując jej odpowiednie wartości PWM. Na przykład tak:

dim wartosc_pwm as byte   'to jest PWM
dim zmienna_pomocnicza as byte   'to jest zmienna do zwiększania
zmienna_pomocnicza - 0
 
if przycisk = 0 then incr zmienna_pomocnicza
If zmienna_pomocnicza  = 6 then zmienna_pomocnicza = 0
 
Select case zmienna_pomocnicza
       case 0:
       wartosc_pwm = 0   'załóżmy że zero to wygaszone czy jak wolisz
       case 1:
       wartosc_pwm = 51
       case 2:
       wartosc_pwm = 102
       case 3:
       wartosc_pwm = 153
       case 4:
       wartosc_pwm = 204
       case 5:
       wartosc_pwm = 255

Portret użytkownika airman

Oto kod: $regfile =

Oto kod:

$regfile = "attiny13.dat"
$crystal = 1000000
 
Config Pinb.0 = Output
Config Pinb.4 = Output
Config Pinb.3 = Input
 
Pinb.0 = 0
Pinb.4 = 0
Pinb.3 = 1
 
$hwstack = 8
$swstack = 8
$framesize = 8
 
Klawisz Alias Pinb.3
 
Dim I As Byte
Dim Wartosc_pwm As Byte
Dim Zmienna_pomocnicza As Byte
 
Wartosc_pwm = 0
Zmienna_pomocnicza = 0
 
Config Timer0 = Pwm , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down , Prescale = 8
 
Enable Interrupts
 
Do
 
If Klawisz = 0 Then
Waitms 20
If Klawisz = 0 Then
Gosub Licz
End If
End If
 
Loop
 
 
Licz:
Incr Zmienna_pomocnicza
 
If Zmienna_pomocnicza = 6 Then
Zmienna_pomocnicza = 0
End If
 
Select Case Zmienna_pomocnicza
 
       Case 0:
       wartosc_pwm = 0   'załóżmy że zero to wygaszone czy jak wolisz
       Case 1:
       wartosc_pwm = 51
       Case 2:
       wartosc_pwm = 102
       Case 3:
       wartosc_pwm = 153
       Case 4:
       wartosc_pwm = 204
       Case 5:
       Wartosc_pwm = 255
 
End Select
 
Pwm0a = 0
  Waitms 10
For I = 0 To Wartosc_pwm
     Pwm0a = I
     Waitms 20
  Next I
 
Return

taki zdążyłem spłodzić, przyznam ze uczyłem się select case, gdyż nigdy wcześniej tego nie używałem. Aktualnie sytuacja wygląda identycznie jak w poprzednim kodzie, czyli 5 kliknięć = 5 poziomów jasności, a 6 kliknięcie powoduje powrót do pozycji 1 czyli minimalnego wypełnienia PWM omijając pozycję 0, jakieś sugestie ? i przepraszam że tak męczę. Przyznam ze select case to całkiem ciekawa, dla mnie nowa opcja potrafiąca uprościć sporo :)

Portret użytkownika airman

drgania styków i wszystko

Drgania styków i wszystko jasne :), teraz działa. Gdybyś tylko jeszcze mógł sprawdzić czy powyższa składnia jest zgodna z sztuką programowania, czy if'y są dobrze zagnieżdżone itd.

Z całego serca ślę tobie matrix podziękowania za całą dotychczasową pomoc

Portret użytkownika kaktus

podpowiedź

Brakuje jednego End tego najważniejszego.
Ciekawostka

to:

If Klawisz = 0 Then
Waitms 20
If Klawisz = 0 Then
Gosub Licz
End If
End If

można zapisać tak:

 
If Klawisz = 0 Then
   Waitms 20
   If Klawisz = 0 Then Gosub Licz
End If

dla lepszej czytelności ;-)

-

"Cierpliwym być musisz, by wiedzę zgłębiać tajemną, gdyż ciemna strona mocy niszczącą i silną jest.".

Portret użytkownika matrix

Re: Bascom-PWM

Wiesz, każdy pisze jak mu pasuje. Kolega kaktus dobrze podpowiada, jest wtedy bardziej przejrzyście.
Za Loop daj End jak napisano wyżej, dodatkowo ten fragment:

If Zmienna_pomocnicza = 6 Then
   Zmienna_pomocnicza = 0
End if

Możesz zapisać tak:

If Zmienna_pomocnicza = 6 Then Zmienna_pomocnicza = 0

Jeśli warunek mieści się w jednej linii to nie musisz pisać end if.

Portret użytkownika airman

poprawione, i działa dalej

poprawione, i działa dalej bezbłędnie :) mam do was pytanie, czy trudno jest napisać program tak, aby dioda nie rozjaśniała się za każdym razem do wybranej wartości pwm od zera tylko aby płynnie dodawało wartość pwm bez zbędnego gaszenia ?

Portret użytkownika kaktus

8-)

Quote:
aby dioda nie rozjaśniała się za każdym razem do wybranej wartości pwm od zera tylko aby płynnie dodawało wartość pwm bez zbędnego gaszenia

Jakoś nie mogę odgadnąć co autor ma na myśli.

-

"Cierpliwym być musisz, by wiedzę zgłębiać tajemną, gdyż ciemna strona mocy niszczącą i silną jest.".

Portret użytkownika matrix

Re: Bascom-PWM

No ja też nie za bardzo jarzę więc jakby trochę jaśniej można było poprosić.

Portret użytkownika airman

Przepraszam :), może ciężko

Przepraszam :), może ciężko jest to sobie wyobrazić, to jest chyba "problem" którego słowa nie opiszą dlatego udostępniam krótki materiał video, oto on:

http://www.youtube.com/watch?v=lgs6XABVgmA

Portret użytkownika matrix

Re: Bascom-PWM

W tym miejscu masz wpisywanie do PWM'a wartości 0

Pwm0a = 0
  Waitms 10
For I = 0 To Wartosc_pwm

Dodaj zmienną stary_pwm i najpierw wpisz wartość aktualnego pwm'u do starego a dopiero obsługuj klawisze czyli inkrementację:

stary_pwm = wartosc_pwm

I zamiast tak:

For I = 0 To Wartosc_pwm

napisz tak:

For I = stary_pwm To Wartosc_pwm

Portret użytkownika gosc

Dziękuję, teraz program

Dziękuję, teraz program działa tak jak tego oczekiwałem :) po dodaniu wszystkiego co zasugerowałeś, miałem jeszcze problem z

Pwm0a = 0

gdyż mimo wszystko co prawda nie rozświetlał od zera kolejnej pozycji, ale szybko mignął i dodawał do poprzedniej wartości pwm. Rozwiązaniem było wpisać
Pwm0a = 0
do
Case 0:
i wszystko gra :)

Jeszcze raz bardzo dziękuję wszystkim, i podziwiam za chęć pomocy, sam na pewno będę odwiedzał forum i starał się pomagać potrzebującym gdy tylko będę w stanie.

Portret użytkownika gosc

PWM wentylatora

Witam
Nie będę zakładał nowego tematu bo mój problem też jest związany z funkcją PWM.
Chce zbudować trzy stopniowy regulator wentylatora ale regulacja będzie się odbywała za pomocą przełącznika trzystopniowego.
Napisałem mały programik ale nie działa od dobrze w 100%

Zasada jest prosta:
- Pozycja przełącznika 1 = 50% mocy
- Pozycja przełącznika 2 = 75% mocy
- Pozycja Przełącznika 3 = 100% mocy

Gdzie ja w programie robię błąd?
Oto mój kod:

$regfile = "m8def.dat"
$crystal = 8000000
 
Config Timer1 = Pwm , Pwm = 8 , Prescale = 8 , Compare A Pwm = Clear Down , Compare B Pwm = Clear Down
Enable Interrupts
 
$hwstack = 8
$swstack = 8
$framesize = 8
 
Config Pinb.1 = Output
Config Pind.5 = Input
Config Pind.6 = Input
Config Pind.7 = Input
 
Set Pind.5
Set Pind.6
Set Pind.7
 
Do
 
Debounce Pind.5 , 0 , 1 , Sub
Debounce Pind.6 , 0 , 2 , Sub
Debounce Pind.7 , 0 , 3 , Sub
 
Loop
End
 
1:
Pwm1a = 80
Return
 
2:
Pwm1a = 120
Return
 
3:
Pwm1a = 255
Return

Pozdrawiam

Portret użytkownika EDC

Odp. Pwm wentylatora

Przepraszam, nie doczytałem że masz ustawione Pwm = 8. Masz chyba Pinb.1 = Output ..nie powinno być Port?

-

BARTek
Moja strona

Portret użytkownika gosc

Problem jest w tym że jak

Problem jest w tym że jak przełączam między portami nie zawsze zmienia się wartość zachowanie jest takie jak by się atmega zawiesiła.
Zmieniłem na timer0 i teraz to w ogóle nie reaguje.

Config Timer0 = Pwm , Prescale = 1 , Compare Pwm = Clear Down , Pwm = On 


Portret użytkownika gosc

Nie ma to znaczenia czy pin

Nie ma to znaczenia czy pin czy port zachowanie programu jest takie same.

Portret użytkownika gosc

Nie ma to znaczenia czy PIN

Nie ma to znaczenia czy PIN czy PORT. Zachowanie programu jest takie same.

Portret użytkownika matrix

Re: PWM wentylatora

Zamiast

Config Pinb.1 = Output

powinno być
Config Portb.1 = Output

Chociaż w smumie może tego nie być bo bascom po deklaracji PWMA sam ustawia dany pin jako wyjście.

Spróbuj dopisać

Enable Timer1

A tak poza tym to ja wolałbym korzystać z PWM'a programowego. Mi programowy zawsze działa bezbłędnie.
No chyba że odmierzasz kilka innych rzeczy to programowy PWM odpada.

Portret użytkownika EDC

Odp. PWM

Często szybciej coś napiszę a potem dopiero myślę ;)
Jeśli tylko o to chodzi to te Sub`y sa chyba niepotrzebne.

Napisz w pętli

If Pind.5 = 0 Then Pwm1a = 80
If Pind.6 = 0 Then Pwm1a = 120
If Pind.7 = 0 Then Pwm1a = 255

Drgania styków nie będą tu miały znaczenia.

-

BARTek
Moja strona

Portret użytkownika gosc

Teraz to w ogóle nie reaguje.

Teraz to w ogóle nie reaguje. Czasami dioda zgaśnie :(

$regfile = "m8def.dat"
$crystal = 8000000
 
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
$hwstack = 8
$swstack = 8
$framesize = 8
 
Enable Timer1
 
Config Portb.1 = Output
Config Pind.5 = Input
Config Pind.6 = Input
Config Pind.7 = Input
 
Set Pind.5
Set Pind.6
Set Pind.7
 
Do
If Pind.5 = 0 Then Pwm1a = 80
If Pind.6 = 0 Then Pwm1a = 120
If Pind.7 = 0 Then Pwm1a = 255
 
Loop
 
End

Na próbę zrobiłem regulację z potencjometria i ona działa. Czyli timerek działa.

Config Adc = Single , Prescaler = Auto , Reference = Avcc
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
 
Config Portc.0 = Input
Config Portb.1 = Output
 
Dim W As Word
 
Do
 
W = Getadc(0)
W = W / 4
 
Pwm1a = W
 
Waitms 20
Loop
 
End

Portret użytkownika EDC

Przełącznik - oszczędzanie pinów procesora

Dokładając dwie diody do przełacznika i przepisując lekko warunki możesz oszczędzić wyprowadzenia procesora.

W tej konfiguracji w pozycji "3" obydwa piny maja stan niski.
Obsługa przerwań jest w tych trybach niepotrzebna (Enable Interrupts i Enable Timer1).
Nie należy też chyba mylić Clear Up z Set .. tam w Clear Up po prostu licznik liczy albo w dół albo w górę.
Zmieniając kilka rzeczy naraz w programie nie dojdziesz do jego funkcjonalnej postaci :D

-

BARTek
Moja strona

Portret użytkownika gosc

Co mi po tych diodach jak

Co mi po tych diodach jak program nie reaguje, a timer działa jak pisałem wyżej.

Portret użytkownika EDC

Odp. Pwm

W Helpie pisza żeby używać zmiennych do odczytu i zapisu danych w rejestrach Compare. Spróbuj napisać tak:

If Pinb.5 = 0 Then W = 80
...
Pwm1a = W

-

BARTek
Moja strona

Portret użytkownika gosc

Teraz w ogóle sygnału na

Teraz w ogóle sygnału na wyjściu nie ma. Chyba sobie daruję.

Portret użytkownika EDC

Wentylator PWM 100% working ;)

Miałem tyle chęci by zbudować to Twoje cudo. Podłączyłem nawet wentylator z komputera poprzez IRFZ44 ;)
Działa sto procentowo bo mi wartość PWM wyświetla na LCD. Każdorazowe dotknięcie któregoś z pinów PORTC ustawia żądaną wartość PWM i tak się zachowuje wentylator. Enkoder sobie dołączyłem dla zabawy. Też ładnie działa.
Co ciekawe Kompilator nie pozwala już ustawiac żadnych stanów na PORTB.1 jeśli skonfiguruje się PWM...on go zajmuje.

$regfile = "m328pdef.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 64
 
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portc.0
Config Lcd = 20 * 4
Cursor Off Noblink
Cls
 
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Disconnect
 
Config Portc.5 = Input : Set Pinc.5
Config Portc.4 = Input : Set Pinc.4
Config Portc.3 = Input : Set Pinc.3
 
$include "encoder_config.bas"
 
Dim W As Word
 
Lcd "PWM = "
 
Do
 
Stan_enc = Sprawdz_encoder()
 
If Stan_enc = Enc_next Then
If W > 0 Then Decr W
End If
 
If Stan_enc = Enc_prev Then
If W < 255 Then Incr W
End If
 
Stan_enc = 0
 
If Pinc.5 = 0 Then W = 255
If Pinc.4 = 0 Then W = 120
If Pinc.3 = 0 Then W = 80
 
Locate 1 , 7 : Lcd W ; "  "
 
Pwm1a = W
 
 
Loop
 
End
 
$include "encoder.bas"

Dodam co doczytałem wczoraj. Wiki Bascoma pisze, że użycie Compare A/B lub Compare A/B PWM automatycznie ustawia korespondujący z nim Pin jako wyjście, chyba że wpisze się NO_OUTPUT lub, jak ja, Disconnect.
Drugą sprawą jest to, że fabryczne ustawienia ATmega8 to 1MHz. Na 8MHz trzeba ją sobie przestawić.

-

BARTek
Moja strona

Portret użytkownika gosc

Pwm

Napisałem programik tak:

$regfile = "m16def.dat"
$crystal = 8000000
 
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
Start Timer1
 
Config Portb.0 = Input
Config Portb.1 = Input
Config Portb.2 = Input
 
Set Portb.0
Set Portb.1
Set Portb.2
 
Do
 
If Pinb.0 = 0 Then
Pwm1a = 100
End If
 
If Pinb.1 = 0 Then
Pwm1a = 160
End If
 
If Pinb.2 = 0 Then
Pwm1a = 255
End If
 
Waitms 20
Loop
End

Zmieniłem na atmegę16, program reaguje poprawnie między wartościami 160 i 255. Natomiast gdy przełączę na 100 czyli najmniejszą dioda gaśnie. Miernik pokazuje 0V.
Jak możesz to wrzuć mój programik u siebie i zobacz czy tak samo reaguje.

Portret użytkownika EDC

Odp. Pwm + USB control

Widzisz Kolego problem jest w tym, że pytasz, a nie czytasz odpowiedzi. Napisałem Ci wyraźnie, że w instrukcji, którą najwyraźniej przeczytałem za Ciebie, jest napisane by do odczytu i zapisu rejestrów Compare używać zmiennych. Zrobiłem jak napisali i mi wszystko działa. Poszedłem w międzyczasie dalej. Wentylator rusza się dopiero od wartości PWM = 50 więc na wszelki wypadek, żeby silnik czasem nie stał w miejscu, zrobiłem mu "rozruch", po czym śmiga na najniższej prędkości 50.
Sprawdziłem tez pomysł z diodami do wyboru prędkości i spisuje się znakomicie. Prędkością wentylatora można też sterować poprzez Terminal na porcie Com wpisując wartość PWM. Pokręcając enkoderem widzimy wartość PWM w oknie Terminala.
Może zerknij na działające rozwiązanie i porównaj ze swoim.

$regfile = "m328pdef.dat"
$crystal = 8000000
$baud = 38400
$hwstack = 64
$swstack = 64
$framesize = 64
 
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.0 , Rs = Portc.0
Config Lcd = 20 * 4
Cursor Off Noblink
Cls
 
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Disconnect
 
Config Serialin = Buffered , Size = 10
 
Config Portc.5 = Input : Set Pinc.5
Config Portc.4 = Input : Set Pinc.4
Config Portc.3 = Input : Set Pinc.3
 
Enable Interrupts
 
$include "encoder_config.bas"
Dim W As Word , X As Byte
 
For X = 100 To 51 Step -1                                   ' rozruch wentylatorka
Waitms 50                                                   '  gdyby miał opory
Pwm1a = X                                                   'można to wrzucić przed wolnymi prędkościami
Next X
 
Lcd "nowe PWM = "                                           'wyswietlane tylko raz
 
Do
'--------------------------- zmiana PWM enkoderem ---------
Stan_enc = Sprawdz_encoder()
If Stan_enc <> 0 Then
 
If Stan_enc = Enc_next Then
If X > 50 Then Decr X
End If
 
If Stan_enc = Enc_prev Then
If X < 255 Then Incr X
End If
 
End If
Stan_enc = 0
'--------------------------- zmiana PWM poprzez piny ------
If Pinc.5 = 0 Then X = 80
If Pinc.4 = 0 Then X = 120
If Pinc.4 = 0 And Pinc.5 = 0 Then X = 255
'--------------------------- zmiana PWM przez port com ----
If Ischarwaiting() = 1 Then
     X = Waitkey()
End If
If X < 50 Or X > 255 Then X = W                             'jesli wartość z poza zakresu to jest ignorowana
'---------------------------
If X <> W Then                                              'tylko jesli jest zmiana wartości...
 
Print X                                                     'wyslij na Com
Locate 1 , 12 : Lcd X ; "  "                                ' wyswietl na LCD
W = X                                                       'wyrównaj wartości i zmień na Word
Pwm1a = W
End If
 
Loop
 
End
 
$include "encoder.bas"

Miłego dnia

-

BARTek
Moja strona

Portret użytkownika gosc

Owszem czytam kolego :) Czy

Owszem czytam kolego :)
Czy zrobię to tak:

$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 64
$swstack = 64
$framesize = 64
 
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Disconnect
 
Config Portb.0 = Input : Set Portb.0
Config Portb.1 = Input : Set Portb.1
Config Portb.2 = Input : Set Portb.2
 
Dim W As Word
 
Do
 
If Pinb.2 = 0 Then W = 255
If Pinb.1 = 0 Then W = 192
If Pinb.0 = 0 Then W = 128
 
Pwm1a = W
 
Loop
End

Czy tak:

$regfile = "m16def.dat"
$crystal = 8000000
 
Config Timer1 = Pwm , Prescale = 1 , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Down
Start Timer1
 
Config Portb.0 = Input
Config Portb.1 = Input
Config Portb.2 = Input
 
Set Portb.0
Set Portb.1
Set Portb.2
 
Do
 
If Pinb.0 = 0 Then
Pwm1a = 100
End If
 
If Pinb.1 = 0 Then
Pwm1a = 160
End If
 
If Pinb.2 = 0 Then
Pwm1a = 255
End If
 
Waitms 20
Loop
End

Efekt jest ten sam. Sam sprawdź.

Portret użytkownika EDC

Dioda pod Pwm

Napiszę Ci tak :D
Z ciekawości, zamiast wentylatorka podłączyłem diodę LED.
U mnie podłączona jest do +5V i procesor przez 200R i MosFeta zwiera ją do masy.
W tej konfiguracji i ustawieniu "Clear Up" Dioda świeci pełnym blaskiem od 255 do około 100. Rozjaśnianie się diody najbardziej widać od 2 do 50 ..potem dla oka jakby wszystko jedno. Zapewniam Cię że nie wszystko jedno było wentylatorkowi. Natomiast wpisanie "Clear Down" odwraca logikę i dioda przy 255 gaśnie a świeci pełnym blaskiem przy Pwm = 0. PwmB jest od drugiego pinu (u Ciebie PD4). Ja na OC1B mam już LCD więc mam je odłączone od Timera.
Podsumowując podłącz może element którym chcesz końcowo sterowac bo diody rozświetlają sie nieliniowo.

Przed chwilą sprawdziłem. Między 255 a 128 różnica w świeceniu jest prawie żadna...a wentylatorek napewno zauważył by zmianę ;) Przy 50 wentylatorek dopiero rusza, a dioda już normalnie świeci...

-

BARTek
Moja strona