Het wordt eigenlijk te ingewikkeld en gekunsteld om zelf de pulsen / lengte te maken en die te laten op-of aflopen.
Misschien toch maar terug naar de PWM library, waarbij je de pulsbreedte kan variëren...
Golden Member
Het wordt eigenlijk te ingewikkeld en gekunsteld om zelf de pulsen / lengte te maken en die te laten op-of aflopen.
Misschien toch maar terug naar de PWM library, waarbij je de pulsbreedte kan variëren...
Special Member
Als je een wat nieuwere pic met 16 bits PWM gebruikt, gaat 't allemaal een stuk simpeler...
(die kan lagere frequenties aan en heeft veel meer mogelijkheden qua PWM)
Dit geeft een op 50Hz PWM dimmende led op RA1 pin: (processor 12F1571/72)
pic basic code:
'=====================================================
' Processor: 12F1571/72
'=====================================================
Program Servo
Dim Duty As LongInt
Cnt As LongInt
main:
TRISA = %00000000
ANSELA = 0
LATA = 0
OSCCON = %11110000
Pwm1_init(50,64)
Pwm1_Start()
While True
For Cnt = 0 To 65535 Step 50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(1)
Next Cnt
Delay_ms(250)
For Cnt = 65535 To 0 Step -50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(1)
Next Cnt
Delay_ms(250)
Wend
End.
Special Member
Op 29 juli 2020 23:29:35 schreef Bavelt:
Het is een for - next loop.
Sorry, zie het nu ook in je laatste voorbeeld. Maar daarvoor kon ik dat er niet uithalen.
Special Member
Dit beweegt de servo heen en weer (stopt 1000mS in neutrale positie)
pic basic code:
'=====================================================
' Processor: 12F1571/72 - 32MHz (8MHz int * 4xPLL)
'=====================================================
Program Servo
Dim Duty As LongInt
Cnt As LongInt
Const MINPWM = 3300 'Min value puls (65536/20000) * uS min
MAXPWM = 10500 'Max value puls (65536/20000) * uS max
MEDPWM = (MAXPWM - MINPWM) / 2 + MINPWM 'Neutral position
main:
TRISA = %00000000
ANSELA = 0
LATA = 0
OSCCON = %11110000
OSCTUNE = 0
Pwm1_init(50,64)
Pwm1_Start()
While True
For Cnt = MEDPWM To MAXPWM Step 50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(50)
Next Cnt
For Cnt = MAXPWM to MINPWM Step -50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(50)
Next Cnt
For Cnt = MINPWM to MEDPWM Step 50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(50)
Next Cnt
Delay_ms(1000)
Wend
End.
Golden Member
Als je een wat nieuwere pic met 16 bits PWM gebruikt, gaat 't allemaal een stuk simpeler...
Nou, daar heb ik er maar een paar van besteld bij Farnell.
Zo te zien is dit veel makkelijker dan gedoe om die 50Hz te krijgen met andere PIC's.
Special Member
De helpfile van de compiler is nog niet aangepast voor 16 bits PWM.
Daar staat nog dat PWMx_Set_Duty() een waarde van 0...255 moet krijgen, maar bij 16 bits is dat 0...65535.
Golden Member
Inderfaad, de parameter van deze procedure (duty_ratio) is als een byte gedefenieerd.
pic basic code:
sub procedure PWMx_Set_Duty(dim duty_ratio as byte)
Dat zal dan wel een longint zijn voor deze PIC12F1572.
Golden Member
Is trouwens een erg goedkope processor die PIC12F1572:
€ 0,63 bij Farnell...
Special Member
Is inderdaad erg goedkoop... (dat men soms nog de 12f629 gebruikt begrijp ik niet: veel langzamer, kan veel minder, minder geheugen, en is 2x zo duur... )
In principe is een Word goed voor PWMx_Set_Duty(), maar in het voorbeeld heb ik een longint gebruikt.
Dat komt doordat deze (en vele andere) compilers alleen 'downcount' loops (step -xx) willen doen als de variabele 'signed' is.
(ook al wordt het getal nooit negatief)
Golden Member
De PIC12F1572 is binnen. De 72 heeft 2K aan flash, dus deze maar genomen ipv de 71 (=1K).
Probleem is alleen dat PicKit3 deze uc niet kent. Hij komt nergens voor (base-midrange, etc).
Ik lees op diverse sites dat dit probleem vaker voorkomt, maar ik zie overal dat je MPLAB moet installeren.
En daar was ik nu net van af...
Wellicht kan dat ook anders?
Special Member
Gelukkig kun je nieuwe pics meestal toevoegen aan de devicelist met Device list editor...
Hierbij eentje waar de 1571/72 in zitten. (bestaande file vervangen)
Golden Member
Dank Arco! Het werkt meteen.
Inderdaad gelukkig dat dit kan.
Nu als een speer dat MPLABX er maar weer afhalen. Wat een enorme puist is dat als je dat vergelijkt met het veel simpelere maar doeltreffende combinatie MikroBasic en Pickit V3.10 stand alone;)
Is die devicelist te downloaden op de site van MicroChip of komt het ergens anders vandaan? Ik heb een tijdje lopen zoeken maar kwam dat niet tegen om de Pickit3 bij te werken.
Het zelfde geldt eigenlijk voor het OS dat je in Pickit V3.10 moet laden.
Ik heb nu een bestand PK3OSV020005.hex dat is van dec 2012...
Special Member
De devicefile editor is door een pic gebruiker geschreven: https://sites.google.com/site/pk2devicefileeditor/
Wat je doet is een pic in de bestaande lijst opzoeken die er het meest op lijkt, en die kopieeren.
Daarna naam en parameters aanpassen (aantal config words, geheugengrootte, enz...)
Enige wat niet klopt is de device (silicon) revision, omdat device id en revision veranderd zijn enkele jaren terug, en dat begrijpt 't programma uiteraard niet...
(vroeger zaten device id en revision in 1 register, nu in 2 registers)
Sommige pics (zoals bijv. de 16F1709) moet je daarom op 'manual device select' zetten, kan niet automatisch gedetecteerd worden.
Nieuw OS is er niet en zal ook wel niet meer komen, is voor meeste pics ook niet nodig.
Gelukkig is alle sourcecode voor het pickit2 en 3 programma gewoon beschikbaar (ook uitgebreide beschrijving van de devicefile) dus wijzigen kan altijd...
Golden Member
Dit beweegt de servo heen en weer (stopt 1000mS in neutrale positie)
pic basic code:
pic basic code:
'=====================================================
' Processor: 12F1571/72 - 32MHz (8MHz int * 4xPLL)
'=====================================================
Program Servo
Dim Duty As LongInt
Cnt As LongInt
Const MINPWM = 3300 'Min value puls (65536/20000) * uS min
MAXPWM = 10500 'Max value puls (65536/20000) * uS max
MEDPWM = (MAXPWM - MINPWM) / 2 'Neutral position
main:
TRISA = %00000000
ANSELA = 0
LATA = 0
OSCCON = %11110000
OSCTUNE = 0
Pwm1_init(50,64)
Pwm1_Start()
While True
For Cnt = MEDPWM To MAXPWM Step 50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(50)
Next Cnt
For Cnt = MAXPWM to MINPWM Step -50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(50)
Next Cnt
For Cnt = MINPWM to MEDPWM Step 50
Duty = Cnt
Pwm1_Set_Duty(Duty)
Delay_ms(50)
Next Cnt
Delay_ms(1000)
Wend
End.
Het motortje beweegt (maakt een kleine slag heen en weer (ca 40gr) en lijkt soms te 'haperen'. Geen vloeiende beweging, tussenpauzes.
Dat zal vast te maken hebben met de waardes MINPWM,etc.
Waar zit nu relatie tussen deze waarden en de pulsduur?
als ik 10500 - 3300 / 2 = 3600, dat zou 1000ms moeten zijn?
of bedoel je 1000 us?
Maar waar zit nu het verband?
Special Member
Foutje...
Moet zijn: MEDPWM = (MAXPWM - MINPWM) / 2 + MINPWM (da's het gemiddelde tussen MIN (~ 1007uS) en MAX (~ 3204uS)
Puls ziet er hier op de scoop goed uit...
Golden Member
Maar waar komt dan die eenheid 65536/20000 vandaan?
De motor gaat nu inderdaad naar midden-verder en weer hele slag terug.
Zij het dat de totale draai nu ca 75 Graden is. Ik zal dus wat moeten spelen met de waarden om het ding 180 Gr te laten draaien.
Special Member
65536 is 16 bits, dat is de max pwm waarde, Bij een 20000uS (20mS) pwm period duurt iedere uS is dus 65536/20000 = 3.2768 pwm stapjes.
(1000uS is dus 3.2768 * 1000 = 3276 stapjes, voor het gemak afgerond op 3300)
De MINPWM en MAXPWM zul je op de juiste waarde voor die servo in moeten stellen. (Clock moet op 32MHz staan, anders gebeuren er ook vreemde dingen...)
[Bericht gewijzigd door Arco op woensdag 5 augustus 2020 23:48:44 (27%)
Golden Member
(Clock moet op 32MHz staan, anders gebeuren er ook vreemde dingen...)
Er gebeurt idd iets raars. Ik heb de scoop er ook maar eens bij gepakt.
Ik kreeg een signaal van 200Hz.
Bleek de clock op 8.000 Mhz te staan. En dus in de Project setting snaar 32 Mhz gebracht.
Komt nu keurig 50Hz uit. Zoals ook zou moeten. Pulsduur is ook goed van 1- 3,2ms
Maar dan doet het motortje helemaal niks...
Terug naar 200 Hz dan wil-ie wel weer draaien (maar dus niet goed).
Rectificatie: hij doet het nu wel (spanning er helemaal af gehaald),
Het is alleen jammer dat de PWM1 pin ook op de Clock van ICS zit.
Daardoor moet ik steeds het motortje eruit doen anders wil PicKit hem niet programmeren..
[Bericht gewijzigd door Bavelt op donderdag 6 augustus 2020 00:18:07 (19%)
Special Member
Weerstand tussen servo en pwm pin van 1k of zo?
(of PWM3 gebruiken, die zit op een vrije pin zo te zien)
[Bericht gewijzigd door Arco op donderdag 6 augustus 2020 00:30:08 (38%)
Golden Member
PWM3 is inderdaad RA2. Die is 'vrij'. Ga ik morgen proberen!
Golden Member
Ja, het werkt nu allemaal...
Grappig, en toch knap om zo'n microprocessr met maar 8 pins en deze functionaliteit voor een paar dubbeltjes te produceren...
Golden Member
Leuk spelen met die PIC12F1752. Ding werkt geweldig.
Nu maar eens een gewoon motortje aansluiten. Ik heb een 3V DC-motortje.
Ik zie op het forum al diverse varianten voorbijkomen om zo'n ding aan te sturen vanuit de uC. Je ziet wel eens de L293D, of een Power FET IRL1004.
Maar waarom niet gewoon bijvoorbeeld een BD137? Veelzijdig en dubbeltjeswerk (of nog minder)...
Update: Ik nu dat de L293D de mogelijkheid biedt de draairichting om te draaien..
Special Member
Kijk hier eens naar.
https://www.circuitsonline.net/artikelen/view/54
Golden Member
Op 8 augustus 2020 22:26:17 schreef Lambiek:
Kijk hier eens naar.
https://www.circuitsonline.net/artikelen/view/54
Is inderdaad een leuk voorbeeld. Ook hier wordt overigens een L293D gebruikt voor aansturing / richting van de motor. Blijkbaar een populair ding.
Ik zag op het forum al oude topics met een zelfgemaakte omkeerschakeling met transitoren. Wel meestal voor 12V zo te zien.
Zou er ook zoiets (H-brug) zijn te maken voor een lage spanning, 3-5V?
Special Member
Met transistoren niet handig (je verliest 2x Vce van de transistoren op een toch al lage spanning)
Beter dan mosfets nemen. En dan zijn logische exemplaren ook weer niet zo makkelijk te vinden.
Een H-bridge is meestal makkelijker en goedkoper...
https://www.reichelt.nl/zetex-h-bridge-mosfet-2xn-2xp-zxmhc-6a07-t8ta-…