MikroBasic en Servomotor

Bavelt

Golden Member

Ik ben wat aan het oefenen geslagen met een Servomotor, type SG-90.

Met een MikroBasic Proramma wil ik het ding in twee standen heen en weer zetten.

Volgens de data aheet moet je dan een puls kiezen van 1,5 ms (=666 Hz) voor de middenstand en 1 ms (= 1000 Hz) voor de meest linkse stand.

Maar bij de 2e PWM_INT reboot de processor.
Wat doe ik fout?

pic basic code:

program PWM_Test

Main:


  OSCCON =   %01110000                            '8 Mhz internal

  ANSEL  = 0                         ' Configure AN pins as digital I/O
  ANSELH = 0
  PORTA = 255
  PORTB = 255
  TRISA = 255                        ' configure PORTA pins as input
  PORTB = 0                          ' set PORTB to 0
  TRISB = 0                          ' designate PORTB pins as output

  PORTB.6 = 1                        'Test LED On
  Delay_ms(1000)

  while True
  
  PORTB.6 = 0                        'Test LED Off
  Delay_ms(1000)

    PWM1_Init(1000)
    PWM1_Set_Duty(67)
    PWM1_Start()
    Delay_ms(1000)
    PWM1_Stop()

    PWM1_Init(666)
    PWM1_Set_Duty(67)
    PWM1_Start()
    Delay_ms(1000)
    PWM1_Stop()

  wend
end.
Fouten zijn het bewijs dat je het probeert..

Je hebt wat vergeten, een servo werkt met een puls van 1 tot 2ms en een interval van 20mS, dus heb je een pwm nodig van 50Hz.

Beter van te starten zonder pwm en werken met delay's

[Bericht gewijzigd door MGP op vrijdag 24 juli 2020 23:57:00 (18%)

LDmicro user.
Arco

Special Member

Pics zijn niet echt goed in zulke lage pwm frequenties van 50Hz...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Lambiek

Special Member

Op 24 juli 2020 23:43:23 schreef Bavelt:
Ik ben wat aan het oefenen geslagen met een Servomotor, type SG-90.

Misschien kun je hier iets mee.

https://www.circuitsonline.net/artikelen/view/48

Als je haar maar goed zit, GROETEN LAMBIEK.
Bavelt

Golden Member

Ik heb het veranderd. Ik had inderdaad over het hoofd gezien dat de frequentie steeds 50Hz moet zijn.
Daarom zelf maar een 'PWM' geregeld zoals MGP al opperde.
De bedoeling is midden-links-midden-rechts en dat in een loop.

Puls hoog gedurende de nodige ms en dan weer laag en wachten tot je de 20 ms vol hebt.

Het resutaat is dat na de eerste beweging de controller (PIC16F887) aan het rebooten slaat.
(Blijkt uit de Testled)

Er gebeurt dus iets wat de PIC niet leuk vindt...

pic basic code:

program PWM_Test

Dim i1 As byte


Sub Procedure Left_Pos()
  Portb.3 = 1
  Delay_us(1000)
  Portb.3 = 0
  Delay_us(19000)
End Sub

Sub Procedure Middle_Pos()
  Portb.3 = 1
  Delay_us(1500)
  Portb.3 = 0
  Delay_us(18500)
End Sub

Sub Procedure Right_Pos()
  Portb.3 = 1
  Delay_us(2000)
  Portb.3 = 0
  Delay_us(18000)
End Sub

Main:


  OSCCON =   %01110000                            '8 Mhz internal

  ANSEL  = 0
  ANSELH = 0
  TRISA = 0
  TRISB = 0
  PORTA = 0
  PORTB = 0

  PORTB.6 = 1                        'Test LED On
  Delay_ms(2000)
  PORTB.6 = 0                        'Test LED Off

  while True

  For i1 = 0 to 255
   Middle_Pos()
  Next i1
  Delay_ms(500)
  
  For i1 = 0 to 255
   Left_Pos()
  Next i1
  Delay_ms(500)
  
  For i1 = 0 to 255
   Middle_Pos()
  Next i1
  Delay_ms(500)

  For i1 = 0 to 255
   Right_Pos()
  Next i1
  Delay_ms(500)

  wend
end.
Fouten zijn het bewijs dat je het probeert..

Je hebt email met een artikel dat in Elektuur heeft gestaan, daar kun je zien hoe je dat moet doen in Picbasic.

LDmicro user.
Arco

Special Member

MCLRE of watchdog staat misschien aan?...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Ik zie dat je de delay steeds aanpast aan de pulslengte. Dat hoeft niet. Die 50Hz hoeft niet precies te zijn, ongeveer is goed genoeg.

Bavelt

Golden Member

Op 25 juli 2020 13:21:07 schreef Arco:
MCLRE of watchdog staat misschien aan?...

Nee, staat op disabled.

Ik heb het even over een andere boeg gegooid: het gebruik van een timer interrupt. Hierdoor krijg je een keurig 50 Hz signaal.
3 schakelaartjes (A0 t/m A2) die de noodzakelijke delay toepassen om op 1000, 1500 of 2000 ms te komen.

Ook hier weer: het motortje reageert, maar na de beweging reboot de processor onmiddelijk.

pic basic code:

Program PWM_Test

'-------------------------------------------------------------------------------
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'-------------------------------------------------------------------------------
  If TMR2IF_bit Then                                    'See if timer2 irq
     PORTB.3 = 1
     if PORTA.0 = 1 then
       Delay_ms(1000)
     End if
     if PORTA.1 = 1 then
       Delay_ms(1500)
     End if
     if PORTA.2 = 1 then
       Delay_ms(2000)
     End if
     PORTB.3 = 0
     TMR2IF_bit = 0
  End If
End sub

Main:

  OSCCON     = %01000000                                '1 Mhz internal
  T2CON      = %00100101                                'Post:5 - Pre:16
  PR2        = 249                                      'Timer load value
  GIE_bit    = 1                                        'Enable timer2 irq
  PEIE_bit   = 1
  TMR2IE_bit = 1

  ANSEL  = 0
  ANSELH = 0
  TRISA = 0
  TRISB = 0
  PORTA = 0
  PORTB = 0

  PORTB.6 = 1                        'Test LED On
  Delay_ms(2000)
  PORTB.6 = 0                        'Test LED Off

  while True
  wend
end.
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Brrr, wat eng... (delays in een interrupt... :+ )
Zo werkt de 50Hz ook niet meer natuurlijk... (met 2000mS delay wordt 't 0.5Hz)

[Bericht gewijzigd door Arco op zaterdag 25 juli 2020 14:18:49 (15%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Op 25 juli 2020 14:17:35 schreef Arco:
Brrr, wat eng... (delays in een interrupt... :+ )
Zo werkt de 50Hz ook niet meer natuurlijk... (met 2000mS delay wordt 't 0.5Hz)

Ik heb de 'engigheid' er uit gehaald.. :)

De benodigde vertraging om de poort weer laag te krijgen zit nu in de main

Maar ook nu is het rebooten na de eerste beweging van de servo.

pic basic code:

'-------------------------------------------------------------------------------
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'-------------------------------------------------------------------------------
  If TMR2IF_bit Then                                    'See if timer2 irq
     PORTB.3 = 1
     TMR2IF_bit = 0
  End If
End sub

Main:

  OSCCON     = %01000000                                '1 Mhz internal
  T2CON      = %00100101                                'Post:5 - Pre:16
  PR2        = 249                                      'Timer load value
  GIE_bit    = 1                                        'Enable timer2 irq
  PEIE_bit   = 1
  TMR2IE_bit = 1

  ANSEL  = 0
  ANSELH = 0
  TRISA = 0
  TRISB = 0
  PORTA = 0
  PORTB = 0

  PORTB.6 = 1                        'Test LED On
  Delay_ms(2000)
  PORTB.6 = 0                        'Test LED Off

  Direction = 2

  While True
  
   If PORTA.0 = 1 then
      Direction = 1
   End if
   If PORTA.1 = 1 then
      Direction = 2
   End if
   If PORTA.2 = 1 then
      Direction = 3
   End if
   
   Select Case Direction
   Case 1
     Delay_ms(1)
   Case 2
    Delay_us(1500)
   Case 3
    Delay_ms(2)
   End Select
   PORTB.3 = 0

 Wend
 
end.
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dat 't met een delay van 2sec in de interrupt niet werkte lijkt me logisch: de interrupt 'hangt' dan gedurende die tijd.

De 'If PORTA.x = 1 Then' wordt nooit uitgevoerd; alle pinnen staan als outputs...
In het RCON register kun je de oorzaak van de reset uitlezen...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
eSe

Honourable Member

Doet de servo de volledige beweging of maar een stuk?

Misschien zakt je spanning in elkaar en reset daardoor je processor.

Groetjes,
eSe

CChheecckk yyoouurr dduupplleexx sswwiittcchh..

Volgens mij heeft Picbasic een servo comando zie picbasic deel 8

De syntaxis:
SERVO Pin, Rotatie waarde

[Bericht gewijzigd door Kees.s op zaterdag 25 juli 2020 16:52:01 (26%)

Bavelt

Golden Member

De 'If PORTA.x = 1 Then' wordt nooit uitgevoerd; alle pinnen staan als outputs...

PORTA stons idd als output. Maar het 'grappige' is wel dat bij indrukken van de Schakelaar de poort wel netjes naar +5V gaat. Ook reageert het motortje op de schakelaar. De 'if' wordt dus dan blijkbaar toch wel uitgevoerd.

Maar het hoort natuurlijk niet, daarom heb ik het als input gezet.

pic basic code:

PORTA  = %11111111 

Met overigens hetzelfde resultaat: na 1 beweging reboot.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

In het RCON register kun je de oorzaak van de reset uitlezen...

Dat is voor mij een nieuwe....

Fouten zijn het bewijs dat je het probeert..
Lambiek

Special Member

Op 25 juli 2020 16:50:03 schreef Kees.s:
SERVO Pin, Rotatie waarde

Dat zit inderdaad in picbasic, maar niet in micro basic. :)

Als je haar maar goed zit, GROETEN LAMBIEK.
Arco

Special Member

Als je ze als output zet, sluit de schakelaar de uitgang kort, niet bevorderlijk voor de mosfets... ;)
Wat veroorzaakt de reset? (als het een oudere pic is heb je weinig info in RCON)

Kan ook een stoorpuls op de voeding zijn. Zet BOR in ieder geval uit zolang.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Misschien zakt je spanning in elkaar en reset daardoor je processor.

Daar zit misschien idd iets in. Als ik nl een externe voeding van 5V aansluit (ipv dat hij de spanning van de PicKit3 krijgt) dan reageert het anders: het motortje gaat dan staan te trillen en weet niet waar heen te gaan (zonder een ingedrukte schakelaar.

Wat ik daarbij zelf nog niet begrijp van dergelijke servo-motortjes: blijft hij op een eenmaal ingestelde positie staan of wordt dat anders als je de pulsen weghaalt?
Hoeveel pulsen moet hij dan gehad hebben om naar de positie te gaan?

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Zet BOR in ieder geval uit zolang.

Dat heeft inderdaad invloed. Bij BOR disabled krijg ik nu hetzelfde effect als met een externe voeding: de motor staat wat wild te trillen...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Dit is het programma tot nu toe:

Poort B.3 is voor de Servo. B6 een testled en met B7 meet ik de frequentie met een f-metertje. Geeft keurig 50Hz aan.

pic basic code:

Program PWM_Test

Dim Direction as byte
 
'-------------------------------------------------------------------------------
Sub procedure Interrupt() iv 0x0004 ics ICS_AUTO
'-------------------------------------------------------------------------------
  If TMR2IF_bit Then                                    'See if timer2 irq
     PORTB.3 = 1
     PORTB.7 = 1
     TMR2IF_bit = 0
  End If
End sub

Main:

  OSCCON     = %01000000                                '1 Mhz internal
  T2CON      = %00100101                                'Post:5 - Pre:16
  PR2        = 249                                      'Timer load value
  GIE_bit    = 1                                        'Enable timer2 irq
  PEIE_bit   = 1
  TMR2IE_bit = 1

  ANSEL  = 0
  ANSELH = 0
  TRISA = %11111111
  TRISB = %00000000
  PORTA = %00000000
  PORTB = %00000000
  
  PORTB.7 = 1                        'Measure Frequency
  PORTB.6 = 1                        'Test LED On
  Delay_ms(2000)                     'Wait befors start
  
  PORTB.6 = 0                        'Test LED Off
  Direction = 2                      'Default Mid Position
 
  While True

   If PORTA.0 = 1 then
      Direction = 1
   End if
   If PORTA.1 = 1 then
      Direction = 2
   End if
   If PORTA.2 = 1 then
      Direction = 3
   End if
   
   Select Case Direction
   Case 1
     Delay_ms(1)
   Case 2
    Delay_us(1500)
   Case 3
    Delay_ms(2)
   End Select
   
   PORTB.3 = 0
   PORTB.7 = 0

 Wend
 
end.
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 25 juli 2020 16:50:03 schreef Kees.s:
Volgens mij heeft Picbasic een servo comando zie picbasic deel 8

De syntaxis:
SERVO Pin, Rotatie waarde

MikroBasic kent dit niet.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Normaal gesproken stuur je een servo altijd aan, ook in rust. ('t ding moet tenslotte weten wat te doen)
Als je ze niet aanstuurt, is er ook bijna geen holding torque, dus zijn de simpel te verdraaien.

Als het met BOR uit wel werkt, dan resette de controller omdat de spanning te laag werd...

[Bericht gewijzigd door Arco op zaterdag 25 juli 2020 18:59:23 (18%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
eSe

Honourable Member

Voeding en stuursignaal toch niet gewisseld?

Ik had hier een hele tijd geleden ook een paar servo's waarvan 1 een micro servo, aansluitingen op de connector waren andersom (draden hadden ook andere kleuren + kleinere connector).

Groetjes,
eSe

CChheecckk yyoouurr dduupplleexx sswwiittcchh..
Bavelt

Golden Member

Voeding en stuursignaal toch niet gewisseld?

Nee, die zijn wel goed. Ipv Oranje is de draad geel.

Ik heb het even met de Arduino sketch geprobeerd en die deed het direct goed. Een simpele sketch die de motor langzaam 180 graden laat draaien en weer terug.
Op dezelfde laptop met dezelfde USB aansluiting.

Nu ik weet dat het motortje goed werkt en bedrading goed is, maar eens zien of ik dit ook kan nabootsen met de PIC en MikroBasic.

Fouten zijn het bewijs dat je het probeert..