MikroBasic en Servomotor

Bavelt

Golden Member

Volgens de datasheet zou de sprong van 0 - 90 - 180 graden moeten verlopen via 1Ms - 1,5ms - 2 Ms.

In mijn geval verloopt dat via 1Ms - 2,2Ms - 3,1 Ms.
Wellicht zijn er inderdaad meerdere uitvoeringen van deze SG-90. Zo kan dit exemplaar dus ook gewoon 360 graden draaien.

Bijvoorbeeld met :

pic basic code:

PORTB.3 = 1
  Delay_us(8000)
  PORTB.3 = 0
  Delay_us(12000)

Draait hij keurig continu zijn rondjes..

Fouten zijn het bewijs dat je het probeert..
Lambiek

Special Member

Als je het via een potmeter wil bedienen krijg je dit.

pic basic code:


RUN:


    POTMETER = ADIn 0

    SERVO_PULS = 1
      DelayUS 850 + (POTMETER * 6)
    SERVO_PULS = 0
      DelayMS 20
      
GoTo RUN

Het is met 8 bit getest, dus van 0 tot 255. Potmeter even in een variabele zetten. En jij zal de waarde misschien iets aan moeten passen voor jou servo.

Als je haar maar goed zit, GROETEN LAMBIEK.
Bavelt

Golden Member

Het lastige met MikroBasic is dat je in het delay-commando geen variabelen mag zetten (alleen literals of rekenkundige uitkomsten. Maar dus geen gedefiniëerde variabelen).

Fouten zijn het bewijs dat je het probeert..
Lambiek

Special Member

Dan moet je het omrekenen denk, ik ken microbasic verder niet. Misschien dat Arco weet hoe dat moet. :)

Als je haar maar goed zit, GROETEN LAMBIEK.
Arco

Special Member

Met een instructieclock van 2MHz (8MHz oscillator) kun je zoiets inline assembly gebruiken:
(vooraf Timerval laden met gewenste delay in 5uS stapjes, voorbeeld geeft 250uS vertraging)

pic basic code:


Dim Timerval As Byte
...
...
Timerval = 50

Asm
    loop:  decfsz  _Timerval, f
           goto    loop2
           goto    loop5
    loop2: goto    loop3
    loop3: goto    loop4
    loop4: nop
           goto    loop
    loop5: goto    loop6
    loop6: goto    loop7
    loop7: goto    loop8
    loop8:  
End Asm

Of korter:

pic basic code:


Dim Timerval As Byte
...
...
Timerval = 50

Asm                               'decr loop    last loop
    loop:  goto    loop2          ' 2            2 
    loop2: goto    loop3          ' 2            2 
    loop3: goto    loop4          ' 2            2
    loop4: nop                    ' 1            1
           decfsz  _Timerval, f   ' 1            2  
           goto    loop           ' 2            
           nop                    '              1  
End Asm                           '----         ----
                                  '10           10 cycles

[Bericht gewijzigd door Arco op dinsdag 28 juli 2020 10:28:05 (18%)

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

Op 27 juli 2020 12:00:46 schreef Bavelt:
Volgens de datasheet zou de sprong van 0 - 90 - 180 graden moeten verlopen via 1Ms - 1,5ms - 2 Ms.

Megasecondes? Dat is wel erg lang. ;)

Bavelt

Golden Member

Fouten zijn het bewijs dat je het probeert..
Lambiek

Special Member

@ Hieronder,

Lekker duidelijk die code. :) Maar niet heus.

Als je haar maar goed zit, GROETEN LAMBIEK.
Bavelt

Golden Member

Dim Timerval As Byte
...
...
Timerval = 50

Asm
loop: goto loop2
loop2: goto loop3
loop3: goto loop4
loop4: nop
decfsz _Timerval, f
goto loop
nop
End Asm

4 keer deze code aanroepen (in een Sub gestopt) zou dan hetzelfde moeten opleveren als Delay_ms(1)
Toch?

Maar dat doet-ie niet...De delay lijkt meer dan 250us op te leveren met Timerinterval = 50

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Of Timerval = 200 (geeft ook 1 mS / 1000uS)
Staat de interne oscillator wel op 8MHz?
Als je een sub gebruikt klopt de timing niet meer precies. (er komen cycles bij voor de aanroep/return en parameter passing)

Het kan zijn dat je Timerval vast specificeert (om zeker te weten dat die in het shared memory van 0x70 tot 0x7F zit):

code:


Dim Timerval As Byte Absolute 0x70

[Bericht gewijzigd door Arco op maandag 27 juli 2020 17:36:03 (29%)

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

Golden Member

Inderdaad.
Ik heb de ASM code in de code geplaatst, dus niet in een sub die wordt aangeroepen. Timerval = 200 levert inderdaad hetzelfde effect op als delay_ms(1).

Dus de aanroeperij met parameters kost ook weer de nodige tijd.

Maar ik wilde graag de delay variabel maken (en bv langzaam laten oplopen en teruglopen).

Ik dacht aan dit maar volgens mij klopt dat niet:

[code="picbasic"

For Timerval = 0 to 200
Asm
loop: goto loop2
loop2: goto loop3
loop3: goto loop4
loop4: nop
decfsz _Timerval, f
goto loop
nop
End Asm

Next Timerval
PORTB.3 = 0[/code]

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Zou moeten kunnen, maar wel vanaf 1 (lengte '0' bestaat niet)

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

Golden Member

Timerval is een byte, hierdoor is de maximale delay 255 * 5 = 1275 us.

Ik kan Timerval wel als word definiëren, maar vermoedelijk zal ASM dat niet zien als byte neem ik aan.
Ik zou er natuurlijk een of meerdere 'loops' in de ASM code kunnen stoppen.
Dan wordt de stap wel groter.

[Bericht gewijzigd door Bavelt op maandag 27 juli 2020 18:55:01 (24%)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

't Is nu eenmaal een 8 bit CPU, die kent geen words... ;)
Words betekent veel overhead (en dus afwijking) omdat je steeds 2 bytes aan elkaar moet plakken en shiften.
1275 uS is toch genoeg? Verschil tussen laagste en hoogste waarde is tenslotte maar 1mS...

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

Golden Member

Verschil tussen laagste en hoogste waarde is tenslotte maar 1mS...

Bij mij dus niet.

Het kost 2,1 milliseconde om de servo 180 Graden te laten draaien (volgens de sheet van 1 naar 2, maar dat is hier niet zo).

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Je kunt ook 10uS/stap nemen (250 geeft 2500uS):

pic basic code:


Dim Timerval As Byte Absolute 0x70
...
...
Timerval = 250

Asm                                 'decr loop    last loop
    loop:   goto    loop2           ' 2            2
    loop2:  goto    loop3           ' 2            2
    loop3:  goto    loop4           ' 2            2
    loop4:  goto    loop5           ' 2            2
    loop5:  goto    loop6           ' 2            2
    loop6:  goto    loop7           ' 2            2
    loop7:  goto    loop8           ' 2            2
    loop8:  goto    loop9           ' 2            2
    loop9:  nop                     ' 1            1
            decfsz  _Timerval, f    ' 1            2
            goto    loop            ' 2            
            nop                     '              1
End Asm                             '----         ----
                                    '20           20 cycles       

[Bericht gewijzigd door Arco op dinsdag 28 juli 2020 10:24:40 (35%)

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

Golden Member

Dim Timerval As Byte
...
...
Timerval = 50

Asm
loop: goto loop2
loop2: goto loop3
loop3: goto loop4
loop4: nop
decfsz _Timerval, f
goto loop
nop
End Asm

Ik probeer even te bekijken waarom bij Timerval = 50 een delay van 250us oplevert.
De instuctiecyclus os 8 Mhz / 4 = 2 Mhz. Dus 0,5 us per instructie.

dat zou dan betekenen dat in deze code 500 instructies zijn.
Die zie ik niet zo snel...

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Het is 10 instructiecycles lang, en dat wordt 50 keer uitgevoerd...
(een GOTO is 2 cycles lang, een NOP 1 cycle, en een DECFSZ 1 of 2 cycles, heb de cycles erbij gezet...)

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

Golden Member

Je kunt ook 10uS/stap nemen (250 geeft 2500uS):

pic basic code:

Dim Timerval As Byte Absolute 0x70
...
...
Timerval = 250

Asm 'decr loop last loop
loop: goto loop2 ' 2 2
loop2: goto loop3 ' 2 2
loop3: goto loop4 ' 2 2
loop4: goto loop5 ' 2 2
loop5: goto loop6 ' 2 2
loop6: goto loop7 ' 2 2
loop7: goto loop8 ' 2 2
loop8: goto loop9 ' 2 2
loop9: nop ' 1 1
decfsz _Timerval, f ' 1 2
goto loop ' 2
nop ' 1
End Asm '---- ----
'20 20 cycles

Toch is het hem nog niet: ik moet van bv een delay van 1000 naar 3500.

Instructies maar uitbreiden met loops net zolang je een bereik van 1000-3500 hebt?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

De eerste 1000mS (tot de minimumwaarde) kun je toch 'vast' maken? (die is toch altijd gelijk)
Dan heb je alleen van 1000-3500 nodig, en dat is 2500uS...

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

Golden Member

Het blijkt toch wat lastiger. Ik wilde het motortje in stappen 180 graden laten draaien.
(en in een later stdium weer terug).

Ik heb al getest dat 1000 us = 0Gr, 2000us = 90Gr en 3000us = 180Gr.

Maar doe ik het in een loop met de ASM statements:
(800 ms vaste delay, dan 200 tot 2200 erbij zou dus 1000 - 3000 worden).

Het motortje slaat echter op hol en blijft ronddraaien.

(Omdat je geen variabele in de delay mag stoppen, gaat de laatste delay van 19000 us, die je eigenlijk steeds wilt aanpassen aan de andere delay om in totaal op 20ms te komen sowieso niet helemaal correct. Ik blijf het lastig vinden dat je geen variabele in de delay mag opgeven)

Maar wat gaat hier nu niet goed?

pic basic code:

For Timerval = 20 to 220 step 10
   For z1 = 0 to 99
      PORTB.6 = 1
      PORTB.3 = 1
      Delay_us(800)
      Asm
      loop1:   goto    loop21
      loop21:  goto    loop31
      loop31:  goto    loop41
      loop41:  goto    loop51
      loop51:  goto    loop61
      loop61:  goto    loop71
      loop71:  goto    loop81
      loop81:  goto    loop91
      loop91:  nop
            decfsz  _Timerval, f
            goto    loop1
            nop
      End Asm

      PORTB.3 = 0
      Delay_us(19000)
   Next z1
  Next Timerval
Fouten zijn het bewijs dat je het probeert..
Lambiek

Special Member

Ik vind het een vreemde manier van doen. Dat moet toch simpeler kunnen. En via een for next lus gaat dat ook niet?

Als je haar maar goed zit, GROETEN LAMBIEK.
Arco

Special Member

Wat je nu doet mag zeker niet. Een loopcount variabele (timerval) veranderen in de loop kan niet.
Je krijgt geen foutmelding, omdat de compiler geen error-checking op assembly doet, alleen of 't grammaticaal juist is.

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

Golden Member

Op 29 juli 2020 22:25:18 schreef Arco:
Wat je nu doet mag zeker niet. Een loopcount variabele (timerval) veranderen in de loop kan niet.
Je krijgt geen foutmelding, omdat de compiler geen error-checking op assembly doet, alleen of 't grammaticaal juist is.

Klopt.. :D In MikroBasic krijg je dan een foutmelding.

Dan maar zoeken naar andere oplossing...

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Op 29 juli 2020 22:19:40 schreef Lambiek:
Ik vind het een vreemde manier van doen. Dat moet toch simpeler kunnen. En via een for next lus gaat dat ook niet?

Het is een for - next loop.
Maar wat ik in het programma doe doe mag niet. (timerval is een variabele, die mag je in de loop niet wijzigen)

Fouten zijn het bewijs dat je het probeert..