PicBasic 4 PWM Kanalen

Ik heb voor een project 4 pwm kanalen uit een pic 16F84A of 628 nodig. Nu is het probleem als ik onderstaande code gebruik krijg ik een "looplichtje" van de 4 uitgangen die na elkaar aan gaan(wel gedimt op de pwm frequentie die moet gebruikt worden). Hoe kan ik dit oplossen zodat de 4 uitgangen tegelijk werken?

code:


PWM PortB.1 , 110 , 255
PWM PortB.2 , 50  , 255 
PWM PortB.3 , 190 , 255 
PWM PortB.4 , 210 , 255 

Alvast bedankt,
Stynus

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--
elmowww

Golden Member

Dat kan je niet hardwarematig oplossen, ook niet softwarematig achter-elkaar zoals jij doet.

code:



symbol PWM_cycles

dim x as byte
dim y as word
dim pwma as byte
dim pwmb as byte
dim pwmc as byte
dim pwmd as byte

symbol pen_a = portb.1
symbol pen_b = portb.2
symbol pen_c = portb.3
symbol pen_d = portb.4

pwma = 128       '50%
pwmb = 0         '0%
pwmc = 64        '64%
pwmd = 255       '100% 

output pen_a
output pen_b
output pen_c
output pen_d

PWM:
   for y = 0 to pwm_cycles
      pen_a = 1
      pen_b = 1
      pen_c = 1
      pen_d = 1
      For x = 0 to 255
         if x => pwma then
            pen_a = 0
         endif
         if x => pwmb then
            pen_b = 0
         endif
         if x => pwmc then
            pen_c = 0
         endif
         if x => pwmd then
            pen_d = 0
         endif
         delayus 5
      Next
   Next
   return
PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling

Bedankt.
Ik heb je code wel wat moeten aanpassen want daar zaten een 10-tal fouten in:

code:




Dim x As Byte
Dim y As Word
Dim pwma As Byte
Dim pwmb As Byte
Dim pwmc As Byte
Dim pwmd As Byte
Dim PWM_cycles As Byte

Symbol pen_a = PORTB.1
Symbol pen_b = PORTB.2
Symbol pen_c = PORTB.3
Symbol pen_d = PORTB.4    
PWM_cycles =255

pwma = 4       
pwmb = 64         
pwmc = 128        
pwmd = 255        
x = 0
Output pen_a
Output pen_b
Output pen_c
Output pen_d

PBM:
   For y = 0 To PWM_cycles
      High  pen_a
      High pen_b
      High pen_c
      High pen_d
      For x = 0 To 255
         If x >= pwma Then  
             Low pen_a
         EndIf
         If x >= pwmb Then 
             Low pen_b
         EndIf
         If x >= pwmc Then
            Low pen_c
         EndIf
         If x >= pwmd Then
            Low pen_d
         EndIf
         DelayUS 5
      Next
   Next
   Return
End

Maar nu zit ik met een ander probleem: na +-2sec stopt de pic ermee en zet zijn uitgangen terug laag

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--

Waarom die Y-lus?

Ik ben niet zo bekend met PicBasic (Lees: helemaal niet) dus ik weet zo niet wat die Return doet (lijkt me het einde van een sub ofzo? Je roept hem alleen nergens aan dus zal wel onzin zijn :P ), maar ik neem aan dat je PWM: oneindig wilt loopen of zo? Dan kun je Y er net zo goed uitlaten.
Ook kun je PWM_cycles eruit slopen (als je y dan toch laat zitten), scheelt je weer een byte geheugen :P Bij X staat 255 er ten slotte ook hardcoded in.

1x PWM: uitvoeren kost aan delay's 0,325125 seconde, hij lijkt dus maar 5 of 6x uitgevoerd te worden?

Eerst stond in de instellingen het kristal op 20mhz terwijl er een 4mhz kristal aanhangt.
Nu ik dit verandert heb doet hij het wel.

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--
elmowww

Golden Member

Code is bedoeld om als sub aan te roepen, met als y de tijd dat ie actief moet zijn.

Zo ongeveer :P

Enja, die gereserveerde commando`s, => en >= en dergelijke... Het ging om de werking :P had geen zin om proton te booten.

PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling

Als het net als hardware-pwm gewoon moet lopen en verder niet naar omkijken (al zal dat misschien eerder opgaan voor een fan of zo, en niet voor 3 ledjes) kun je beter de X-loop in een timer-interupt zetten (mits je nog een timer vrij hebt natuurlijk :P )

Op 28 december 2005 17:41:40 schreef Paul Nieuwkamp:
Als het net als hardware-pwm gewoon moet lopen en verder niet naar omkijken (al zal dat misschien eerder opgaan voor een fan of zo, en niet voor 3 ledjes) kun je beter de X-loop in een timer-interupt zetten (mits je nog een timer vrij hebt natuurlijk :P )

Het moet gaan dienen voor bij een versterker het volume en de bas enzo te regelen.
Ik heb namelijk een versterker printplaat uit een k40 (tv) liggen en daar kan je het geluid op regelen met een signaal van 0-5V.
Nu nog is goed uitzoeken hoe ik de waarde van de pwm kan regelen met drukknoppen maar dat zal wel lukken.

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--
elmowww

Golden Member

Op 29 december 2005 13:04:21 schreef Stynus:
[...]
Het moet gaan dienen voor bij een versterker het volume en de bas enzo te regelen.
Ik heb namelijk een versterker printplaat uit een k40 (tv) liggen en daar kan je het geluid op regelen met een signaal van 0-5V.
Nu nog is goed uitzoeken hoe ik de waarde van de pwm kan regelen met drukknoppen maar dat zal wel lukken.

Kan je daar niet beter van die digitale potmeters voor gebruiken? of een paar DA convertortjes?

PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling

Op 29 december 2005 13:06:58 schreef elmowww:
[...]

Kan je daar niet beter van die digitale potmeters voor gebruiken? of een paar DA convertortjes?

Nee want die hebben geen geheugen van hoe het volume etc stond toen het werd afgezet en een pic heeft toch een eeprom (ofniet) waar ik dit kan in wegschrijven.

[Bericht gewijzigd door Stynus op donderdag 29 december 2005 13:16:15

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--
elmowww

Golden Member

Op 29 december 2005 13:15:15 schreef Stynus:
[...]
Nee want die hebben geen geheugen van hoe het volume etc stond toen het werd afgezet en een pic heeft toch een eeprom (ofniet) waar ik dit kan in wegschrijven.

Daar heb je toch een initialisatie voor :P
je PIC start op, schrijft de oudste waardes naar EEPROM en DAC`s en je gaat weer vrolijk verder.

Ook de standalone digipots hebben memory functies.

Ik ben gewoon bang dat je probs krijgt met storingen...

PA0EJE - www.eje-electronics.nl - e.jongerius[aapje]eje-electronics.nl - EJE Electronics - Elektronica/firmware ontwikkeling

Op 29 december 2005 13:19:38 schreef elmowww:
[...]

Daar heb je toch een initialisatie voor :P
je PIC start op, schrijft de oudste waardes naar EEPROM en DAC`s en je gaat weer vrolijk verder.

Ook de standalone digipots hebben memory functies.

Ik ben gewoon bang dat je probs krijgt met storingen...

Die digipots en Dac's vind ik nogal overkill omdat het volume geregeld word door een TDA1524. En die gewoon aangestuurd moet worden door de pic.

edit:
en voor het geval ik toch storingen krijg heb ik juist 2x DS1868 gevonden in mijn schuif :-D.

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--

Ik zit weeral vast met men code :-(|:(|:(|:(
Hier is een deel van men code. (in plaats van langzaam aangaan gaat het ledje van men test-bord na 3 keer drukken op volle sterkte branden.

Waar zou mijn fout nu kunnen zitten? |:(|:(|:(

code:


Symbol volumup = PORTA.0
Symbol Volumdown = PORTA.1
Symbol Bassup = PORTA.2
Symbol Bassdown = PORTA.3
Symbol Trembleup = PORTA.4
Symbol Trembledown = PORTA.5
Symbol MiddleR = PORTA.6
Symbol MiddleL = PORTA.7
     
PWM_cycles =24

pwma = 4       
pwmb = 4         
pwmc = 8        
pwmd = 12        
x = 0
Output pen_a
Output pen_b
Output pen_c
Output pen_d

PBM:
   For y = 0 To PWM_cycles
      High  pen_a
      High pen_b
      High pen_c
      High pen_d
      For x = 0 To 24
         If x >= pwma Then  
             Low pen_a
         EndIf
         If x >= pwmb Then 
             Low pen_b
         EndIf
         If x >= pwmc Then
            Low pen_c
         EndIf
         If x >= pwmd Then
            Low pen_d
         EndIf
         DelayUS 5
      Next
   Next
   If volumup       = 1 Then Inc pwma
   If Volumdown     = 1 Then Dec pwma
   If Bassup        = 1 Then Inc pwmb
   If Bassdown      = 1 Then Dec pwmb
   If Trembleup     = 1 Then Inc pwmc
   If Trembledown   = 1 Then Dec pwmc
   If MiddleR       = 1 Then Inc pwmd
   If MiddleL       = 1 Then Dec pwmd
GoTo PBM
End
Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--

Je hebt nu je PWM dutycycle onderverdeeld in 24 stapjes ipv de 255 die het eerst waren, je kunt nu dus nog maar 24 verschillende standen kiezen voor vol/bass/treble/bal, de hardcoded 255 in de lus moet je laten zoals hij was (tenzij je dit uiteraard expres hebt gedaan, maar die 24 komt verdacht veel overeen met je PWM_cycles instelling). PWM_cycles kun je wel naar hartelust aanpassen, die geeft aan hoe veel complete golven je wilt sturen.

Nu duurt je hele PBM-procedure (inclusief 'typfout' in de header http://gathering.tweakers.net/global/smileys/confused.gif ) 5x24x24 = 0,003 seconde aan wachten en nog wat voor de code. Als je HEEEEEL snel bent met je knopje zou je pulsjes zo kort als 50ms kunnen genereren (ontdenderen doe je in hardware?). In 50ms is (als PBM: in een oneindige loop wordt aangesproken) de functie dus 16x aangeroepen en wordt pwm* dus 16x verhoogd. Dan is het niet vreemd dat je na 2 of 3 keer drukken aan je 24 zit.

Ik zou overigens (de opbouw van) je overige code wel eens willen zien, want knopjesafhandeling in de functie die je (software-)PWM-signaal verzorgd klinkt me als een fout in je ontwerp :)

Op 30 december 2005 19:20:06 schreef Paul Nieuwkamp:
Je hebt nu je PWM dutycycle onderverdeeld in 24 stapjes ipv de 255 die het eerst waren, je kunt nu dus nog maar 24 verschillende standen kiezen voor vol/bass/treble/bal, de hardcoded 255 in de lus moet je laten zoals hij was (tenzij je dit uiteraard expres hebt gedaan, maar die 24 komt verdacht veel overeen met je PWM_cycles instelling). PWM_cycles kun je wel naar hartelust aanpassen, die geeft aan hoe veel complete golven je wilt sturen.

Dat is bewust gedaan aangezien het volume in 255 stappen wat veel is heb ik voor 24 stappen gekozen (ook omdat men pioneer er ook 24 heeft)

Nu duurt je hele PBM-procedure (inclusief 'typfout' in de header [afbeelding] ) 5x24x24 = 0,003 seconde aan wachten en nog wat voor de code. Als je HEEEEEL snel bent met je knopje zou je pulsjes zo kort als 50ms kunnen genereren (ontdenderen doe je in hardware?). In 50ms is (als PBM: in een oneindige loop wordt aangesproken) de functie dus 16x aangeroepen en wordt pwm* dus 16x verhoogd. Dan is het niet vreemd dat je na 2 of 3 keer drukken aan je 24 zit.

Zal is zoeken dan om het te maken dat als er in de cyclus na een bediende knop de knoppen niet meer gechect worden.

Ik zou overigens (de opbouw van) je overige code wel eens willen zien, want knopjesafhandeling in de functie die je (software-)PWM-signaal verzorgd klinkt me als een fout in je ontwerp :)

Zal men code is op mijn ftp zetten want dit topic begint te lang te worden zo.
edit: http://home.versateladsl.be/henricoenen/co/Versterker%20volume%20contr…

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--

Op 30 december 2005 19:29:23 schreef Stynus:
Zal men code is op mijn ftp zetten want dit topic begint te lang te worden zo.

Zal is zoeken dan om het te maken dat als er in de cyclus na een bediende knop de knoppen niet meer gechect worden.

ah ok, dit is dus de hele code...

Ik zou zeggen, verhoog PWM_cycles (of je DelayUS) tot een dusdanige waarde dat het aanpassen van de duty-cycles maar een paar keer per seconde gebeurd :)

Ik weet niet hoe je tv intern je PWM-signaal afhandeld, maar je hebt momenteel (als we even aannemen dat de code zelf 0 tijd kost, in onrealistisch maar ik kan niet echt inschatten hoeveel het wel kost, en ik ken je kloksnelheid niet), dus bij een delay van 5 miljoenste seconde een PWM frequentie van 200 kilohertz. Als je de delay verhoogd wordt je frequentie lager en worden dus je kabels / routing wat minder kritisch, maar ik heb dus geen idee wat je TV verwacht...

Let wel dat je PWM redelijk onnauwkeurig is nu, omdat je zo'n korte delay hebt. Met een 4 MHz klok en (bij PIC) dus 1 MIPS, kost iedere itteratie door je X-loop tussen de 4 (alle if-jes false) en de 8 (alle ifjes true) instructies (denk dat dit redelijk 1-op-1 naar ASM te zetten is), dat wil dus zeggen bijna net zo lang als je wait tot bijna 2x je wait.
Je random instructie-tijd is dus buitenproportioneel ten opzichte van je wachttijd -> je denkt een pwm van 50% te sturen maar stiekum is het de helft van de tijd maar 25% zeg maar.

Ik zou dus of een krankzinnig hoge klok voor zoiets uber-simpels nemen (denk aan 16 of 20 MHz) als je TV zo'n hoge PWM-frequentie nodig heeft, of een delay van 50 ipv 5. Dan kosten je instructies nog 10 versus 20% van je wachttijd, maar iig geen 90% tot 180% meer

Je PWM-frequentie wordt dan als we 1 MIPS als uitgangspunt nemen (4 MHz, 1us per instructie), middelen op 6 instructies per itteratie, 2 voor de loop, 4 voor het high-zetten, 50us wachten, 24 stapjes in de duty-cycle, 24 * 50 + 24 * 6 + 24 * 2 + 4 = 24 * 58 + 2 = 1394 instructies per cycle = 717 Hz PWM-frequentie, waardoor je dus (even zonder de ds-aanpassing) 717x Y doorloopt per seconde.
Als je nu 5 seconden wilt doen over het van 0 naar 100 gaan in je aanpassingen moet je dus 5/24 * 171 = PWM_cycles op 149,4 zetten. Die berekening klopt wel niet helemaal want ik vergeet nu de tijd die het loopen van Y kost, maar je snapt het idee :)

Let wel, voorbeeldjes met 4MHz klok (ik meen dat een PIC 4 cycles nodig heeft per instructie), 50 us delay en wat flinke aannames mbt de assembler die eruit komt rollen :)

Op 30 december 2005 22:11:48 schreef Paul Nieuwkamp:
[...]
ah ok, dit is dus de hele code...

Ik zou zeggen, verhoog PWM_cycles (of je DelayUS) tot een dusdanige waarde dat het aanpassen van de duty-cycles maar een paar keer per seconde gebeurd :)

Zal ik is proberen.

Ik weet niet hoe je tv intern je PWM-signaal afhandeld,

Het is geen complete tv maar alleen de versterker printplaat. Schema: Links Rechts

maar je hebt momenteel (als we even aannemen dat de code zelf 0 tijd kost, in onrealistisch maar ik kan niet echt inschatten hoeveel het wel kost, en ik ken je kloksnelheid niet), dus bij een delay van 5 miljoenste seconde een PWM frequentie van 200 kilohertz. Als je de delay verhoogd wordt je frequentie lager en worden dus je kabels / routing wat minder kritisch, maar ik heb dus geen idee wat je TV verwacht...

Ik gebruik een kristal van 4Mhz

Let wel dat je PWM redelijk onnauwkeurig is nu, omdat je zo'n korte delay hebt. Met een 4 MHz klok en (bij PIC) dus 1 MIPS, kost iedere itteratie door je X-loop tussen de 4 (alle if-jes false) en de 8 (alle ifjes true) instructies (denk dat dit redelijk 1-op-1 naar ASM te zetten is), dat wil dus zeggen bijna net zo lang als je wait tot bijna 2x je wait.
Je random instructie-tijd is dus buitenproportioneel ten opzichte van je wachttijd -> je denkt een pwm van 50% te sturen maar stiekum is het de helft van de tijd maar 25% zeg maar.

Ik zou dus of een krankzinnig hoge klok voor zoiets uber-simpels nemen (denk aan 16 of 20 MHz) als je TV zo'n hoge PWM-frequentie nodig heeft, of een delay van 50 ipv 5. Dan kosten je instructies nog 10 versus 20% van je wachttijd, maar iig geen 90% tot 180% meer

Je PWM-frequentie wordt dan als we 1 MIPS als uitgangspunt nemen (4 MHz, 1us per instructie), middelen op 6 instructies per itteratie, 2 voor de loop, 4 voor het high-zetten, 50us wachten, 24 stapjes in de duty-cycle, 24 * 50 + 24 * 6 + 24 * 2 + 4 = 24 * 58 + 2 = 1394 instructies per cycle = 717 Hz PWM-frequentie, waardoor je dus (even zonder de ds-aanpassing) 717x Y doorloopt per seconde.
Als je nu 5 seconden wilt doen over het van 0 naar 100 gaan in je aanpassingen moet je dus 5/24 * 171 = PWM_cycles op 149,4 zetten. Die berekening klopt wel niet helemaal want ik vergeet nu de tijd die het loopen van Y kost, maar je snapt het idee :)

Let wel, voorbeeldjes met 4MHz klok (ik meen dat een PIC 4 cycles nodig heeft per instructie), 50 us delay en wat flinke aannames mbt de assembler die eruit komt rollen :)

Hier snap ik niet veel van :-( Maar wat ik wel uit begrepen heb is dat ik die 5µS delay naar 50µS delay moet omzetten.

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--

Ik heb de voorbije dagen vanalles geprobeert in de code maar ik krijg het niet werkend :-(.
Kan iemand soms voor mij een "werkende" code posten of heel duidelijke tips geven?

Bedankt,
Stynus

Met vriendelijke groet, Stynus ||| http://www.elektronicastynus.be ||| http://e-stynus.com ||| --> Automatische trapverlichting <--