Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola:
Mi idea es construir un hexapodo con 18 servos.
Me gustaria seber si puedo manejar el controlador de servos SD21 desde una placa de desarrollo BasicX, es decir, en vez de colocar el BasicX-24 en el SD21, lo colocaria en la placa de desarrollo BasicX y a traves de un bus I2C mandar informacion al SD21.
Si no es mucho pedir, me podriais poner un ejemplo para controlar al menos 2 servos a traves del bus I2C con la controladora SD21.
S2.
Hola, es el siguiente codigo el que empleare para mover los servos de mi hexapodo. Aqui hago un movimiento simple para una pata.
¿Alguien sabe, utilizando este ejemplo, como controlar la velocidad de cada servo? La conexiones estan escritas mas arriba.
Otra cosa, al conectar la corriente al SD21 los servos estan haciento un constante esfuerzo para mantener la posicion, incluso en el centrado, cosa que no me hacen con un baasic stamp, para ahorrar bateria necesitaria saber si existe la forma de de ordenar al SD21 que permanezca temporalmente en un estado de bajo consumo. Incluso los sevos estan trabajando para mantener la posicion de centrado sin ejecutar ninguna orden sobre el SD21.
Option Explicit
Const SCL As Byte = 6 ' I2C clock - SCL
Const SDA As Byte = 5 ' I2C data - SDA
Const SD21 As Byte = &HC2 'SD21 I2CAddress
Const SV1Base As Byte = 63 ' Servo 1 Base Register
Const SV1PO As Byte = 84 ' Servo 1 Positive Offset
Const SV1NO As Byte = 105 ' Servo 1 Negative Offset
Const SV1Centre As Byte = 128 ' Servo 1 Centre Position
Const SV2Base As Byte = 64 ' Servo 1 Base Register
Const SV2PO As Byte = 85 ' Servo 1 Positive Offset
Const SV2NO As Byte = 106 ' Servo 1 Negative Offset
Const SV2Centre As Byte = 128 ' Servo 1 Centre Position
Const SV3Base As Byte = 65 ' Servo 1 Base Register
Const SV3PO As Byte = 86 ' Servo 1 Positive Offset
Const SV3NO As Byte = 107 ' Servo 1 Negative Offset
Const SV3Centre As Byte = 128 ' Servo 1 Centre Position
Sub Main()
Call PutPin(SCL, bxOutputHigh)
Call PutPin(SDA, bxOutputHigh)
Call I2cByteWrite(SD21, SV1Base, SV1Centre)
Call I2cByteWrite(SD21, SV2Base, SV2Centre)
Call I2cByteWrite(SD21, SV3Base, SV3Centre)
call delay(1.0)
Paso1:
call Posicion(SV1PO, 00, SV2NO, 30, SV3NO, 30)
Paso2:
call Posicion(SV1PO, 00, SV2NO, 60, SV3NO, 60)
Paso3:
call Posicion(SV1NO, 77, SV2NO, 60, SV3NO, 60)
Paso4:
call Posicion(SV1NO, 77, SV2NO, 30, SV3NO, 30)
Paso5:
call Posicion(SV1PO, 77, SV2NO, 30, SV3NO, 30)
Paso6:
call Posicion(SV1PO, 77, SV2NO, 60, SV3NO, 60)
goto Paso3
end sub
Sub Posicion(ByVal SV1 As Byte, ByVal a As Byte, _
ByVal SV2 As Byte, ByVal b As byte, _
ByVal SV3 As Byte, ByVal c As Byte)
Call I2cByteWrite(SD21, SV1, a)
Call I2cByteWrite(SD21, SV2, b)
Call I2cByteWrite(SD21, SV3, c)
call delay(1.0)
End Sub
'--------------------------------
'I2C Sub Routines by Gerald Coe
'--------------------------------
' writes I2cData to I2cReg at I2cAddr
Sub I2cByteWrite(ByVal I2cAddr As Byte, ByVal I2cReg As Byte, ByVal I2cData As Byte)
Call I2cStart()
Call I2cOutByte(I2cAddr) ' send device address
Call I2cOutByte(I2cReg) ' send register address
Call I2cOutByte(I2cData) ' send the data
Call I2cStop()
End Sub
Sub I2cOutByte(I2cData As Byte)
Call ShiftOut(SDA, SCL, 8, I2cData) ' shift data out
Call PutPin(SDA, bxInputTristate) ' turn SDA around
Call PutPin(SCL, bxOutputHigh) ' and clock in the ack' bit
Call PutPin(SCL, bxOutputLow)
End Sub
Sub I2cStart() ' I2C start bit sequence
Call PutPin(SDA, bxOutputHigh)
Call PutPin(SCL, bxOutputHigh)
Call PutPin(SDA, bxOutputLow)
Call PutPin(SCL, bxOutputLow)
End Sub
Sub I2cStop() ' I2C stop bit sequence
Call PutPin(SDA, bxOutputLow)
Call PutPin(SCL, bxOutputHigh)
Call PutPin(SDA, bxOutputHigh)
End Sub
Si echas un vistazo a la página de producto que posteastes. Veras las diferentes tablas y registros que puedes utilizar para cada servo y su control. Por ejemplo: con los registros 0,1y2 tienes acceso a la velocidad y byte de nivel lógico bajo/alto del servo 1. Además tienes los registros 63,84,105 con los que también puedes controlar la posición del servo 1 o establecer una compensación positiva/negativa.
ya me he dado cuenta de los registros. Lo que pasa es que no tengo ni idea de como usarlos.
Para lo siguiente:
Call I2cByteWrite (SD21, 84, 50)
Aqui el servo se movera a la posicion 50 en sentido de la agujas del reloj.
Si cambiamos 84 por 105 se movera a la posicion 50 en sentido inverso.
Para el servo dos seria:
Call I2cByteWrite (SD21, 85, 50) 'posicion 50 en sentido horiario
Call I2cByteWrite (SD21, 106, 50) 'posicion 50 en sentido antihorario
Y asi con todos los servos.
Pero para introducir los registros de la velocidad y el byte de nivel lógico bajo/alto de la posición no se ni los comandos ni como tengo que estructurar el codigo.
Este es un ejemplo para el BS2p:
I2COUT SDA, SD21, Servo1, [Speed, Servo.LOWBYTE, Servo.HIGHBYTE]
Me hace falta un ejemplo para el BasicX-24.
Aquí tienes un programa completo de Lynxmotion para el robot EH2. No he encontrado el link de donde lo conseguí hace ya tiempo.
'***********************************************************
'** **
'** Simple Program for Lynxmotion **
'** EH2 Hexapod using a BX24 Microcontroller **
'** and a SD21 Devantech Servo Controller **
'** the SD21 is connected to a 3 channel **
'** R/C receiver **
'** **
'** TESTED **
'** **
'** Copyright 2004 - Luigi Carnevale **
'** Commercial use of this software is prohibited **
'** Private and educational use only is permitted **
'** **
'** **
'********************************************************
Option Explicit
Const SCL As Byte = 6 ' I2C clock - SCL
Const SDA As Byte = 5 ' I2C data - SDA
Const SD21 As Byte = &HC2 'SD21 I2C Address
Dim Speed As Byte
Dim Height As Byte
Const FwdCh As Byte = 12 'Forward/Backward Stick (CH2)
Const LRCh As Byte = 7 'Left/Right Stick (CH4)
Const HeightCh As Byte = 8 'Height Linear Pot (CH5)
Dim FwdPulse As Integer 'Forward/Backward Pulse (CH2)
Dim LRPulse As Integer 'Left/Right Pulse (CH4)
Dim HeightPulse As Integer 'Height Pulse (CH5)
'--------------------------------
'Tune the servo max range here - important for robot safety -
'--------------------------------
Const MaxSpeed As Byte = 35
Const MaxHeight As Byte = 40
'--------------------------------
'Servo Configuration
'--------------------------------
'Left Front Propulsion -> Servo 17 //////////////
Const LFPcentre As Byte = 62 'Left Front Propulsion Centre value
Const LFPbck As Byte = 83 'Left Front Propulsion Back value
Const LFPfwd As Byte = 104 'Left Front Propulsion Forward value
'Left Front Lift -> Servo 18
Const LFLcentre As Byte = 80 'Left Front Lift Centre value
Const LFLdwn As Byte = 101 'Left Front Lift Down value
Const LFLup As Byte = 122 'Left Front Lift Up value
'Right Front Propulsion -> Servo 15 ///////////////
Const RFPcentre As Byte = 63
Const RFPfwd As Byte = 84
Const RFPbck As Byte = 105
'Right Front Lift -> Servo 16
Const RFLcentre As Byte = 78
Const RFLup As Byte = 99
Const RFLdwn As Byte = 120
'Left Middle Propulsion -> Servo 7 //////////
Const LMPcentre As Byte = 64
Const LMPfwd As Byte = 85
Const LMPbck As Byte = 106
'Left Middle Lift -> Servo 8
Const LMLcentre As Byte = 70
Const LMLdwn As Byte = 91
Const LMLup As Byte = 112
'Right Middle Propulsion -> Servo 9 ///////////
Const RMPcentre As Byte = 65
Const RMPbck As Byte = 86
Const RMPfwd As Byte = 107
'Right Middle Lift -> Servo 10
Const RMLcentre As Byte = 72
Const RMLup As Byte = 93
Const RMLdwn As Byte = 114
'Left Rear Propulsion -> Servo 11 //////////
Const LRPcentre As Byte = 66
Const LRPbck As Byte = 87
Const LRPfwd As Byte = 108
'Left Rear Lift -> Servo 12
Const LRLcentre As Byte = 74
Const LRLdwn As Byte = 95
Const LRLup As Byte = 116
'Right Rear Propulsion -> Servo 13 /////////
Const RRPcentre As Byte = 67
Const RRPfwd As Byte = 88
Const RRPbck As Byte = 109
'Right Rear Lift -> Servo 14
Const RRLcentre As Byte = 76
Const RRLup As Byte = 97
Const RRLdwn As Byte = 118
'--------------------------------
'Servo Configuration End
'--------------------------------
Sub Main()
Call PutPin(SCL, bxOutputHigh)
Call PutPin(SDA, bxOutputHigh)
Speed = 10
'Centering Servo
Call I2cByteWrite(SD21, LFLcentre, 128)
Call I2cByteWrite(SD21, LFPcentre, 128)
Call I2cByteWrite(SD21, RFLcentre, 128)
Call I2cByteWrite(SD21, RFPcentre, 128)
Call I2cByteWrite(SD21, LMLcentre, 128)
Call I2cByteWrite(SD21, LMPcentre, 128)
Call I2cByteWrite(SD21, RMLcentre, 128)
Call I2cByteWrite(SD21, RMPcentre, 128)
Call I2cByteWrite(SD21, LRLcentre, 128)
Call I2cByteWrite(SD21, LRPcentre, 128)
Call I2cByteWrite(SD21, RRLcentre, 128)
Call I2cByteWrite(SD21, RRPcentre, 128)
Delay(0.3)
'----------Program Start---------------------
Do
'Channel scanning----------------------------
FwdPulse = PulseIn(FwdCh, 1)
'Debug.Print "FwdCh = " ; Cstr(FwdPulse) 'Useful for checking incoming
'Delay(0.2) 'signal from receiver
LRPulse = PulseIn(LRCh, 1)
'Debug.Print "LRCh = " ; Cstr(LRPulse)
'Delay(0.2)
HeightPulse = PulseIn(HeightCh, 1)
'Debug.Print "HeightCh = " ; Cstr(HeightPulse)
'Delay(0.2)
'Channel scanning End------------------------
'Decoding Commands---------------------------
Dim NoCmd As Boolean 'This is a Flag useful for auto-centering function
Dim BotStopped As Boolean 'This Flag tells StopBot Sub the Robot is already stopped
FwdPulse = (FwdPulse - 650) 6
LRPulse = (LRPulse -650) 6
HeightPulse = (HeightPulse - 650) 6
NoCmd = True
If FwdPulse <120> MaxSpeed then
Speed = MaxSpeed
End if
Call WalkFwd
NoCmd = False
BotStopped = False
End if
If FwdPulse > 130 then
Speed = CByte(FwdPulse - 130)
if Speed > MaxSpeed then
Speed = MaxSpeed
End if
Call WalkBack
NoCmd = False
BotStopped = False
End if
If LRPulse <120> MaxSpeed then
Speed = MaxSpeed
End if
Call TurnLeft
NoCmd = False
BotStopped = False
End if
If LRPulse >130 then
Speed = CByte(LRPulse - 130)
if Speed > MaxSpeed then
Speed = MaxSpeed
End if
Call TurnRight
NoCmd = False
BotStopped = False
End if
Height = MaxHeight
If HeightPulse <120> MaxHeight then
Height = MaxHeight
End if
Elseif HeightPulse >130 then
Height = CByte(HeightPulse - 130)
If Height > MaxHeight then
Height = MaxHeight
End if
End if
If (NoCmd = True) and (BotStopped = False) then
Call StopBot
BotStopped = True
End if
'Decoding Commands End-----------------------
Loop
'----------Program End-----------------------
End Sub
'--------------------------------
'Sub Routines
'--------------------------------
Sub WalkFwd()
Call LiftLeft
Delay(0.1)
Call BackRight
Delay(0.1)
Call FwdLeft
Delay(0.1)
Call LowLeft
Delay(0.1)
Call LiftRight
Delay(0.1)
Call BackLeft
Delay(0.1)
Call FwdRight
Delay(0.1)
Call LowRight
Delay(0.1)
End Sub
Sub WalkBack()
Call LiftLeft
Delay(0.1)
Call FwdRight
Delay(0.1)
Call BackLeft
Delay(0.1)
Call LowLeft
Delay(0.1)
Call LiftRight
Delay(0.1)
Call FwdLeft
Delay(0.1)
Call BackRight
Delay(0.1)
Call LowRight
Delay(0.1)
End Sub
Sub TurnLeft()
Call LiftLeft
Delay(0.1)
Call BackRightRev
Delay(0.1)
Call BackLeftRev
Delay(0.1)
Call LowLeft
Delay(0.1)
Call LiftRight
Delay(0.1)
Call FwdLeftRev
Delay(0.1)
Call FwdRightRev
Delay(0.1)
Call LowRight
Delay(0.1)
End Sub
Sub TurnRight()
Call LiftRight
Delay(0.1)
Call BackLeftRev
Delay(0.1)
Call BackRightRev
Delay(0.1)
Call LowRight
Delay(0.1)
Call LiftLeft
Delay(0.1)
Call FwdRightRev
Delay(0.1)
Call FwdLeftRev
Delay(0.1)
Call LowLeft
Delay(0.1)
End Sub
'This sub reset the starting position
Sub StopBot()
Call LowLeft
Call LowRight
Delay(0.1)
Call LiftLeft
Delay(0.1)
Call CentreLeft
Delay(0.1)
Call LowLeft
Delay(0.1)
Call LiftRight
Delay(0.1)
Call CentreRight
Delay(0.1)
Call LowRight
Delay(0.1)
End Sub
Sub LiftLeft()
Call I2cByteWrite(SD21, LFLup, Height)
Call I2cByteWrite(SD21, RMLup, Height)
Call I2cByteWrite(SD21, LRLup, Height)
End Sub
Sub LiftRight()
Call I2cByteWrite(SD21, RFLup, Height)
Call I2cByteWrite(SD21, LMLup, Height)
Call I2cByteWrite(SD21, RRLup, Height)
End Sub
Sub LowLeft()
Call I2cByteWrite(SD21, LFLdwn, Height)
Call I2cByteWrite(SD21, RMLdwn, Height)
Call I2cByteWrite(SD21, LRLdwn, Height)
End Sub
Sub LowRight()
Call I2cByteWrite(SD21, RFLdwn, Height)
Call I2cByteWrite(SD21, LMLdwn, Height)
Call I2cByteWrite(SD21, RRLdwn, Height)
End Sub
Sub FwdLeft()
Call I2cByteWrite(SD21, LFPfwd, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, RMPbck, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, LRPfwd, Speed)
End Sub
Sub FwdRight()
Call I2cByteWrite(SD21, RFPfwd, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, LMPbck, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, RRPfwd, Speed)
End Sub
Sub BackLeft()
Call I2cByteWrite(SD21, LFPbck, Speed)
Call I2cByteWrite(SD21, RMPfwd, Speed)
Call I2cByteWrite(SD21, LRPbck, Speed)
End Sub
Sub BackRight()
Call I2cByteWrite(SD21, RFPbck, Speed)
Call I2cByteWrite(SD21, LMPfwd, Speed)
Call I2cByteWrite(SD21, RRPbck, Speed)
End Sub
Sub CentreLeft()
Call I2cByteWrite(SD21, LFPcentre, 128)
Call I2cByteWrite(SD21, RMPcentre, 128)
Call I2cByteWrite(SD21, LRPcentre, 128)
End Sub
Sub CentreRight()
Call I2cByteWrite(SD21, RFPcentre, 128)
Call I2cByteWrite(SD21, LMPcentre, 128)
Call I2cByteWrite(SD21, RRPcentre, 128)
End Sub
Sub FwdLeftRev()
Call I2cByteWrite(SD21, LFPfwd, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, RMPfwd, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, LRPfwd, Speed)
End Sub
Sub FwdRightRev()
Call I2cByteWrite(SD21, RFPfwd, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, LMPfwd, Speed)
Delay(0.1)
Call I2cByteWrite(SD21, RRPfwd, Speed)
End Sub
Sub BackLeftRev()
Call I2cByteWrite(SD21, LFPbck, Speed)
Call I2cByteWrite(SD21, RMPbck, Speed)
Call I2cByteWrite(SD21, LRPbck, Speed)
End Sub
Sub BackRightRev()
Call I2cByteWrite(SD21, RFPbck, Speed)
Call I2cByteWrite(SD21, LMPbck, Speed)
Call I2cByteWrite(SD21, RRPbck, Speed)
End Sub
'--------------------------------
'I2C Sub Routines by Gerald Coe
'--------------------------------
' writes I2cData to I2cReg at I2cAddr
Sub I2cByteWrite(ByVal I2cAddr As Byte, ByVal I2cReg As Byte, ByVal I2cData As Byte)
Call I2cStart()
Call I2cOutByte(I2cAddr) ' send device address
Call I2cOutByte(I2cReg) ' send register address
Call I2cOutByte(I2cData) ' send the data
Call I2cStop()
End Sub
Sub I2cOutByte(I2cData As Byte)
Call ShiftOut(SDA, SCL, 8, I2cData) ' shift data out
Call PutPin(SDA, bxInputTristate) ' turn SDA around
Call PutPin(SCL, bxOutputHigh) ' and clock in the ack' bit
Call PutPin(SCL, bxOutputLow)
End Sub
Sub I2cStart() ' I2C start bit sequence
Call PutPin(SDA, bxOutputHigh)
Call PutPin(SCL, bxOutputHigh)
Call PutPin(SDA, bxOutputLow)
Call PutPin(SCL, bxOutputLow)
End Sub
Sub I2cStop() ' I2C stop bit sequence
Call PutPin(SDA, bxOutputLow)
Call PutPin(SCL, bxOutputHigh)
Call PutPin(SDA, bxOutputHigh)
End Sub
'*******************************************
Suerte!