16f628a servo control

proton 1.1.2.8
ide compiler 1.0.0.1
oud dus, maar werkt nog goed

paaltje73

Golden Member

De oorzaak van o.a. het xtal probleem.

Lambiek

Special Member

Op 3 augustus 2016 20:51:49 schreef jank:
ik moet de ontvangerpuls inlezen en sturen naar 2 servo's , waarvan 1 in reverse.
Ook moet er bij de uiterste uitslag geen puls meer op de servo staan.

Als je dit daad werkelijk moet doen, dus wat hier boven staat. Dat gaat niet met de code die je nu hebt. Dan zal je eerst je ontvanger uit moeten lezen met je PIC, en dat kan met de PULSIN instructie. En als je dat gedaan hebt kun je de servo's aan sturen.

Of je hebt de vraag niet goed geformuleerd, dat kan ook natuurlijk.

Als je haar maar goed zit, GROETEN LAMBIEK.

Lambiek,
het was een testje om een servo te bewegen.
De code die ik nu heb is als volgt:
nu alleen nog zorgen dat hij langzamer gaat en de puls afvalt bij de eidpunten

pic basic code:

DEVICE 16F628A                ;Gebruik een 16F628A type
CONFIG WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF, HS_OSC ;INTRC_OSC_NOCLKOUT verwijderd 
ALL_DIGITAL TRUE              ;Alle ingangen digitaal
XTAL 20                       ;Kristal van 20MHz


;Alle uitgangen op de chip declareren.
Symbol  zwaardL     = PORTb.2
Symbol  zwaardR     = PORTA.0
SYMBOL Speed        = 30      ;Snelheid waarmee de motor verdraaid
 
DIM     Positie                              AS WORD    ;variabele bevat de positie van de motor-as 
dim     ontv                                 as word
dim     snelheid                             as word  
;Alle ingangen declareren        

;De min en max servowaarde's van het intrekbare landingsgestel
Symbol zwaardout                = 1975
Symbol zwaardin                 = 1021
symbol failsave                 = 1500
Symbol  InputCH7                = PORTB.1

;        76543210
PORTA = %00000000             ;Maak alle 8 bits van poortregister PORTA laag
PORTb = %00000000             ;Maak alle 8 bits van poortregister PORTB laag
TRISA = %00000000             ;Alles uitgangen op poort A
TRISB = %00000010             ;Alles uitgangen op poort B

CLEAR                         ;Wis alle RAM geheugen
   
;Hoofdprogramma
WHILE 1 = 1                                  ;Oneindige lus
  ontv = PulsIn InputCH7, 1                      ;meet zenderpuls
   Select Case ontv
   Case <600                              ;puls 1200 msec
    positie =zwaardout
   Case >900                 ;Overige waarden de servomotor in de neutraalstand zetten
    positie = zwaardin
    Case >650 ,< 850                         ;puls 1500 msec 
    positie = failsave
endselect
    
  
    SERVO zwaardL, Positie             ;Stuur 'Positie' pulsjes naar PORTB.2
    SERVO zwaardR, Positie             ;Stuur 'Positie' pulsjes naar PORTA.0   
    DELAYMS 20                         ;20mSec = 50Hz, eventueel wijzigen bij ander type motor 
  
 
wend                                     ;naar WHILE
Lambiek

Special Member

Heb je een voorbeeld gestuurd.

Als je haar maar goed zit, GROETEN LAMBIEK.

let niet op het commentaar achter de code, die klopt niet

Op 4 augustus 2016 10:14:56 schreef jank:
proton 1.1.2.8
ide compiler 1.0.0.1
oud dus, maar werkt nog goed

Fijn dattie nog goed werkt. Maar als je hier vragen gaat stellen moet je er wel rekening mee houden dat veel PicBasic kenners met een ietwat modernere versie werken (ikzelf zit op 3.5.8.6) waar dus wel het één en ander is veranderd.
Het verklaart overigens meteen dat het zonder XTAL wel werkt, de default XTAL in die tijd is 4.

Just find out what you like and let it kill you
Lambiek

Special Member

Hier het voorbeeld dat ik naar jank gestuurd heb, misschien heeft een ander er ook nog iets aan.

pic basic code:


Device 16F887                     ; Processor type

Xtal 10                           ; Cristal 10Mhz

Asm                               ; Config settings
CONFIG_REQ            
__CONFIG _CONFIG1, HS_OSC & WDT_OFF & DEBUG_OFF & FCMEN_OFF & LVP_OFF & IESO_OFF & BOR_OFF & CPD_OFF & CP_OFF & MCLRE_OFF & PWRTE_ON 
__CONFIG _CONFIG2, WRT_OFF & BOR40V 
EndAsm
   
All_Digital true                  ; Alle poorten digitaal

Declare LCD_RSPin PORTD.2         ; Reset display poort D.2
Declare LCD_ENPin PORTD.3         ; Enable display poort D.3
Declare LCD_DTPin PORTD.4         ; Data display poort D.4 t/m D.7

Symbol MOTOR = PORTA.0            ; Servo op poort A.0
Symbol SNELHEID = 20              ; Frequentie servo 50Hz

Dim POSITIE As Word               ; Variabele positie servo
Dim ONTVANGER As Word             ; Variabele signaal ontvanger
Dim WAARDE As Word                ; Variabele waarde ontvanger

Cls                               ; Wis display

DelayMS 500                       ; Pauze 0.5 sec 

Clear                             ; Wis geheugen

         ;543210                  ; Hulpregel poort A
PORTA  = %000000                  ; Maak poort A laag
TRISA  = %000000                  ; Poort_A I/O

         ;543210                  ; Hulpregel poort B
PORTB  = %000000                  ; Maak poort B laag
TRISB  = %111111                  ; Poort_B I/O

         ;76543210                ; Hulpregel poort C
PORTC  = %00000000                ; Maak poort C laag
TRISC  = %00000000                ; Poort_C I/O

         ;76543210                ; Hulpregel poort D
PORTD  = %00000000                ; Maak poort D laag
TRISD  = %00000000                ; Poort_D I/O

         ;210                     ; Hulpregel poort E 
PORTE  = %000                     ; Maak poort E laag
TRISE  = %000                     ; Poort_E I/O

         ;76543210                ; Hulpregel analoog
ADCON0 = %00000001                ; ADCON0 register analoog

         ;543210                  ; Hulpregel analoog poort_B
ANSELH = %000000                  ; ANSEL register analoog poort_B

;-----------------------------
; VOORBEELD ZWAARD BESTURING.
;-----------------------------

;-----------------------------------------------------
; BIJ AAN ZETTEN WORDT HET ZWAARD ALTIJD INGETROKKEN.
;-----------------------------------------------------

POSITIONEREN:

    For POSITIE = 2600 To 1000 Step - 5  
     Servo MOTOR,POSITIE                  
      DelayMS SNELHEID                      
    Next
    
    If POSITIE < 1000 Then
     GoTo RUN
    EndIf
GoTo POSITIONEREN

;--------------------------------------------------------
; UITLEZEN ONTVANGER, ALS WAARDE WAAR IS VOER ACTIE UIT.
;--------------------------------------------------------

RUN:

    ONTVANGER = PulsIn PORTB.0 , 1
    WAARDE = ONTVANGER
    
    Print At 1,1,Dec WAARDE,"   "
    Print At 2,1,Dec POSITIE,"  "
    
    If WAARDE > 400 Then
     GoSub ZWAARD_UIT
    EndIf
    
    If WAARDE < 250 Then
     GoSub ZWAARD_IN
    EndIf
      
GoTo RUN

;------------------------------------------------------
; EERST WORDT DE POSITIE VAN HET ZWAARD GECONTROLEERD.
; ALS HET ZWAARD IN POSITIE IS GA DAN NAAR RUN.
; ANDERS STUUR ZWAARD NAAR POSITIE.
;------------------------------------------------------

ZWAARD_UIT:

    If POSITIE > 2500 Then
     GoTo RUN
    EndIf
    
    For POSITIE = 1000 To 2600 Step 5    
     Servo MOTOR,POSITIE                  
      DelayMS SNELHEID                      
    Next 
    
    Return
    
GoTo ZWAARD_UIT

;-----------------------------------------------------
; EERST WORDT DE POSITIE VAN HET ZWAARD GECONTROLEERD.
; ALS HET ZWAARD IN POSITIE IS GA DAN NAAR RUN.
; ANDERS STUUR ZWAARD NAAR POSITIE.
;-----------------------------------------------------

ZWAARD_IN:

    If POSITIE < 1100 Then
     GoTo RUN
    EndIf
                                    
    For POSITIE = 2600 To 1000 Step - 5  
     Servo MOTOR,POSITIE                  
      DelayMS SNELHEID                      
    Next
    
    Return
    
GoTo ZWAARD_IN

End                                                                     

De waardes zijn wel gebaseerd op mijn zend ontvanger, dus die kunnen afwijken met andere types of merken.

Het merk en type is: Graupner-JR - C4-X - SSM 40

De print instructie had ik erbij gezet om wat te experimenteren met de waardes van de ontvanger.

Als je haar maar goed zit, GROETEN LAMBIEK.

De file is nu compleet en geïmplementeerd.
De servo gaat nu langzaam positioneren en dan aan de hand van de stand van de schakelaar op de zender linksom of rechtsom tot het einde.
Daar wordt de puls onderbroken zodat er geen spanning maar op de servomotor staat.
Hierdoor staat hij niet te jitteren.
Hier een paar filmjes .
http://kraakmodelbouw.com/NH1816-model/00002%20%282%29.wmv
http://kraakmodelbouw.com/NH1816-model/00003%20%282%29.wmv

http://kraakmodelbouw.com/NH1816-model/P1040661%20%282%29.JPG

pic basic code:

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : jan Kraak                                         *
'*  Notice  : Copyright (c) 2016 Kraakmodelbouw                 *
'*          : All Rights Reserved                               *
'*  Date    : 10-8-2016                                         *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Device 16F628A                     ;Gebruik een 16F628A type
Config WDT_OFF, PWRTE_ON, LVP_OFF, MCLRE_OFF, HS_OSC ;INTRC_OSC_NOCLKOUT verwijderd 
All_Digital TRUE                   ;Alle ingangen digitaal
Xtal 20                            ;Kristal van 20MHz

Symbol zwaardL = PORTb.2           ; Servo op poort B.2
Symbol zwaardR = PORTA.0           ; Servo op poort A.0
Symbol SNELHEID = 20               ; Frequentie servo 50Hz

Dim POSITIE     As Word            ; Variabele positie servo
Dim ONTVANGER   As Word            ; Variabele signaal ontvanger
Dim WAARDE      As Word            ; Variabele waarde ontvanger
symbol zwaardout     = 1940        ; zwaard uit
Symbol zwaardin      = 1250        ; zwaard in 
Symbol  InputCH7     = PORTB.1     ;waarde uit ontvangerClear                            

         ;543210                   ; Hulpregel poort A
PORTA  = %000000                   ; Maak poort A laag
TRISA  = %000000                   ; Poort_A I/O

         ;543210                   ; Hulpregel poort B
PORTB  = %000000                   ; Maak poort B laag
TRISB  = %000010                   ; Poort_B I/O
 
;-----------------------------------------------------
; BIJ AANZETTEN WORDT HET ZWAARD ALTIJD INGETROKKEN.
;-----------------------------------------------------

POSITIONEREN:

delayms 2000
    oNTVANGER = PulsIn InputCH7 , 1
    WAARDE = ONTVANGER
     If WAARDE  < 690 Then
    GoSub ZWAARD_in
     EndIf
    GoTo RUN
GoTo POSITIONEREN

;--------------------------------------------------------
; UITLEZEN ONTVANGER, ALS WAARDE WAAR IS VOER ACTIE UIT.
;--------------------------------------------------------

RUN:

    ONTVANGER = PulsIn InputCH7 , 1
    WAARDE = ONTVANGER
    If WAARDE > 900 Then
     GoSub ZWAARD_UIT
    EndIf
    If WAARDE < 690 Then
     GoSub ZWAARD_IN
    EndIf
GoTo RUN

;----------------------------------------
; EERST WORDT DE POSITIE VAN HET ZWAARD GECONTROLEERD.
; ALS HET ZWAARD IN POSITIE IS GA DAN NAAR RUN.
; ANDERS STUUR ZWAARD NAAR POSITIE.
;---------------------------------------

ZWAARD_UIT:

    If POSITIE > zwaardout Then
     GoTo RUN
    EndIf
    For POSITIE = zwaardin To zwaardout Step 10    
     Servo zwaardL,POSITIE
     Servo zwaardR,POSITIE                  
     DelayMS SNELHEID                      
    Next 
    Return
GoTo ZWAARD_UIT

;----------------------------------------
; EERST WORDT DE POSITIE VAN HET ZWAARD GECONTROLEERD.
; ALS HET ZWAARD IN POSITIE IS GA DAN NAAR RUN.
; ANDERS STUUR ZWAARD NAAR POSITIE.
;---------------------------------------

ZWAARD_IN:

    If POSITIE < zwaardin Then
     GoTo RUN
    EndIf
    For POSITIE = zwaardout To zwaardin Step - 10  
     Servo zwaardL,POSITIE
     Servo zwaardR,POSITIE               
     DelayMS SNELHEID                      
    Next
    Return
GoTo ZWAARD_IN

End

Natuurlijk met dank aan Lambiek.
Voor iedere modelbouwer.

Vraag aan Lambiek, of iemand anders.
Ik heb deze servo controller gemaakt en werkt mooi en nauwkeurig.
Echter nu wil ik 12 stuks van deze maken op 1 print met 1 kristal.
is het mogelijk om dit te doen zonder extra onderdelen te moeten plaatsen
Dit ivm. ruimte gebrek.

bedank alvast

Lambiek

Special Member

Op 24 februari 2021 14:05:54 schreef jank:
Echter nu wil ik 12 stuks van deze maken op 1 print met 1 kristal.
is het mogelijk om dit te doen zonder extra onderdelen te moeten plaatsen
Dit ivm. ruimte gebrek.

Wil je die alle 12 afzonderlijk gaan bedienen?

Of is het voor de test en mogen ze alle 12 tegelijk?

Als je haar maar goed zit, GROETEN LAMBIEK.

neen, ik wil ze afzonderlijk bedienen, net als in de vorige schakeling.
Maar ik wil geen 12 printen plaatsen, voor elke servo 1.
Nu zie ik ook dat het eenvoudiger kan via een arduino 12 servo's sturen.
dus de twijvel is er nu.

Lambiek

Special Member

Dus je hebt een ontvanger met 12 kanalen?

Als je haar maar goed zit, GROETEN LAMBIEK.

zo bedoel ik het niet.
ik heb een multiswitch met met 12 uitgangen waar 5volt uit komt als hij aan is.
Dus schakellaar 1 aan op de zender, uitgang 1van de multiswitch aan, uitgang 5v ( hoog)
Die wil ik uitlezen en dan de servo1 naar een bepaalde waarde sturen.
Als hij daar dan is valt staat er geen puls meer op de servo en is hij niet meerbekrachtigd en onderhevig aan jitter.
Dit moet dus 12 keer gebeuren voor 12 servo's
onafhankelijk van elkaar.
Ik zou dus 12 keer de schakeling kunnen maken zoals in deze topic.
Deze schakeling werkt goed voor 1 servo.

in het vorige prog. las ik de waarde van de ontvanger uit. Dat moet ik even veranderen naar het uitlezen van de multiswitch of de ingang hoog of laag is.

Lambiek

Special Member

Aha op die manier, dat kan maar niet met een 16F628. Daar heb je een andere pic voor nodig, bijvoorbeeld een 16F887. Je hebt 12 in en uitgangen nodig.

Als je haar maar goed zit, GROETEN LAMBIEK.

oke, ook geen probleem, die heb ik ook wel eens gebruikt.
maar ik zie nog niet hoe ik onafhankelijk van elkaar de kanalen kan uitlezen en de diverse servo's aansturen.
Zo als ik het altijd deed ( pic basic) meerder ingangen testen op een hoog of laag en dan de desbetrefende servo laten lopn naar het punt wat ik had ingesteld.
tijdens dit lopen doet de pic geen afvragingen naar ingangen.
ik hoop dat ik het een beetje uitleg op deze manier.

Lambiek

Special Member

Het zal wat tijd kosten, maar ze hoeven toch niet allemaal tegelijk zeker.

Wat wil je er mee doen of waar dient het voor als ik vragen mag?

Zelf doe ik zoiets anders, stuur anders even een Mail.

Als je haar maar goed zit, GROETEN LAMBIEK.
Arco

Special Member

Ik gebruik in dat soort situaties nooit de pwm modules (er zijn er toch niet genoeg), maar een timerinterrupt om de duty cycle in te stellen.
Dat gaat zelfs met 24 pwm outputs prima op een 32MHz pic24... (bij pwm samplefreq 100Hz, en 100 duty-cycle steps)

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