# Control de un servomotor con Visual Basic



## yeaaa (Feb 21, 2011)

Saludos.
El proyecto que tengo es el siguiente, es una interfaz hecha en Visual Basic 2008, que envía datos por el puerto serial y se conecta con un max232  a un PIC16F876, y posteriormente se realiza el control para un servomotor, pero hay ciertos detalles que me gustaría que me ayudaran.

Aquí les anexo todos los archivos.

Bueno, en sí son 2 problemas:
1.- Me gustaría poder cambiar de puerto COM, a la interfaz le puse unos RadioButtons, según el RadioButton que se presione es el COM que se usará, pero el problema es que una vez iniciada la aplicación, se inicializa el puerto y no sé cómo cambiarlo.

Soy nuevo en esto de interfaces de Visual Basic, y bajé un tutorial donde venía como mandar datos por el puerto serial, pero no viene como poder cambiar el COM que utilizamos.
Así que requiero de su ayuda para resolver este problema.
Aquí anexo todos los archivos y el código fuente.

2.- El otro problema que tengo, es que cada vez que se presiona un botón para mover el servo se ejecuta lo siguiente:


```
Private Sub ButtonS1arriba_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonS1arriba.Click
        Dim mBuffer As Byte() = New Byte(0) {}
        mBuffer(0) = &H61   'Envia una a
        SerialPort1.Write(mBuffer, 0, mBuffer.Length)
    End Sub
```
Con esto me enviá un carácter, en este caso una 'a' pero me gustaría si me pueden ayudar en un código que me envié muchas 'a' mientras esta presionado el botón, porque de esta manera el servo se mueve pero le tengo que estar aplastando al botón.
Quisiera saber si hay la forma de sensar cuando el botón se queda presionado, y enviar muchas 'a'

Aquí anexo el código completo de Visual Basic.


```
Imports System.IO.Ports
Public Class Form1
    Public Sub New()
        InitializeComponent()
        'Abrir puerto mientras se ejecuta la aplicacion
        If Not SerialPort1.IsOpen Then
            Try
                SerialPort1.Open()
            Catch ex As System.Exception
                MessageBox.Show(ex.ToString())
            End Try
        End If
    End Sub
    Sub ConfiguracionPuerto()
        If RadioButton3.Checked Then       'Configura el tipo de puerto
            SerialPort1.PortName = "COM1"
        End If
        If RadioButton4.Checked Then
            SerialPort1.PortName = "COM2"
        End If
        If RadioButton5.Checked Then
            SerialPort1.PortName = "COM3"
        End If
        If RadioButton6.Checked Then
            SerialPort1.PortName = "COM4"
        End If
        If RadioButton7.Checked Then
            SerialPort1.PortName = "COM5"
        End If
        If RadioButton8.Checked Then
            SerialPort1.PortName = "COM6"
        End If
        If RadioButton9.Checked Then
            SerialPort1.PortName = "COM7"
        End If
        If RadioButton10.Checked Then
            SerialPort1.PortName = "COM8"
        End If
        If RadioButton11.Checked Then
            SerialPort1.PortName = "COM9"
        End If
        If RadioButton12.Checked Then
            SerialPort1.PortName = "COM10"
        End If
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        ConfiguracionPuerto()
    End Sub

    Private Sub ButtonS1arriba_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonS1arriba.Click
        Dim mBuffer As Byte() = New Byte(0) {}
        mBuffer(0) = &H61   'Envia una a
        SerialPort1.Write(mBuffer, 0, mBuffer.Length)
    End Sub

    Private Sub ButtonS1abajo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonS1abajo.Click
        Dim mBuffer As Byte() = New Byte(0) {}
        mBuffer(0) = &H62   'Envia una b
        SerialPort1.Write(mBuffer, 0, mBuffer.Length)
    End Sub
End Class
```
Para el caso del PIC, éste es el código fuente, está hecho con PICC de CCS:


```
#include<16f876a.h>
#fuses XT,NOPROTECT,NOWDT,PUT
#use delay (clock=4000000)
#use fast_io(b)
#byte portb=0x06
#bit rb0=6.0
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

void iniciar(void);

void main()
{
    set_tris_a(0xff);
    set_tris_b(0b11111110);
    portb=0;
    disable_interrupts(GLOBAL); 
    iniciar();
}
void iniciar(void)
{
   char caracter_recibido;
   long int tiempo_alto,tiempo_bajo;
   tiempo_alto=900; //damos el valor inicial para establecer el servo a 0 grados
   while(TRUE)
   {
      if(kbhit())  //prueba si a llegado un caracter
      {
        caracter_recibido=getc();   //Guarda el caracter
        if(caracter_recibido=='a')  //si es una a
        { 
           if(tiempo_alto<2100)
           {  tiempo_alto+=10; }       //incrementa el tiempo en alto
        }
        if(tiempo_alto>900)
        {
           if(caracter_recibido=='b')  //si es una b
           {  tiempo_alto-=10; }       //decrementa el tiempo en alto
        }
      }
      tiempo_bajo=20000-tiempo_alto; //establece el tiempo en bajo, como
                                     //el servo hitec maneja f=50hz en tiempo son
                                     //20000 microsegundos
      rb0=1;                   //empieza el PWM
      delay_us(tiempo_alto);
      rb0=0;
      delay_us(tiempo_bajo);
   }
}
```


----------



## Unikfriend (Feb 21, 2011)

Hi, que version de VB utilizas?
1) para poder cambiar de COM, necesitas primero cerrar la conexion,
2) puedes utilizar un Timer para estar enviando un caracter, sin tener que presionar otra vez el boton.


----------



## yeaaa (Feb 21, 2011)

Saludos unikfriend agradesco tu respuesta tan rapida

Bueno estoy utilizando Visual Basic Express 2008,
Nose si me puedas ayudar un poco con el codigo para cerrar y volver a abrir el puerto para poderlo cambiar,
En cuanto a lo del timer no se como implementarlo en Visual Basic, si me puedes echar la mano te lo agradeceria, ya que soy novato en esto de Visual Basic


----------



## Unikfriend (Feb 21, 2011)

Hi, lo malo es que yo solo use hasta el VB6,  ahora us VC++ para todos estos casos
pues intenta agrengando la intruccion close al inicio de configuracion y cada vez
que modifiques un valor de configuracion.

Sub ConfiguracionPuerto()

SerialPort1.Close ()

If RadioButton3.Checked Then 'Configura el tipo de puerto
SerialPort1.PortName = "COM1"
End If
If RadioButton4.Checked Then
SerialPort1.PortName = "COM2"
End If


----------



## arturouc (Mar 14, 2011)

hay diferentes eventos en VB
puedes utilizar el evento mousedown para que envies miestras estas presionado el boton izquierdo del raton envias "a" y cuando se de el evento mouseup dejas de enviar....


----------



## yeaaa (Mar 15, 2011)

Saludos arturouc

Agradesco tu respuesta, pero la verdad nunca he manejado esos eventos mi pregunta es la siguiente,
por ejemplo en el codigo como le podria acer para detectar lo siguiete (pseudocodigo):

Si se preciona el boton entonces
-
    Si se deja precionado el click del mouse
           enviar
    Si no
           no enviar
-

Como quedaria en codigo:

Private Sub ButtonS1abajo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonS1abajo.Click
     Dim mBuffer As Byte() = New Byte(0) {}
     mBuffer(0) = &H62 'Envia una b
     SerialPort1.Write(mBuffer, 0, mBuffer.Length)
End Sub

No se si tendras alguna sugerencia, agradeceria tu ayuda 

                              ¿?


----------



## Unikfriend (Mar 15, 2011)

Hi yeaa, es que para eso ocupas el evento MouseDown no el Click
como te comentaba para eso yo utilizaria un timer con el
MouseDown lo habilitas y con el MouseUp lo deshabilitas


----------



## arturouc (Mar 15, 2011)

yeaaa dijo:


> Private Sub ButtonS1abajo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonS1abajo.Click
> Dim mBuffer As Byte() = New Byte(0) {}
> mBuffer(0) = &H62 'Envia una b
> SerialPort1.Write(mBuffer, 0, mBuffer.Length)
> ...



Lo que esta en rojo es el evento CLICK, necesitas usar el evento mousedown
como te dice Unikfriend habilitas un temporizador timmer1.enable=true y dentro del codigo
envias el caracter al microcontrolador.
cuando sueltes el boton izquierdo del raton, se produce otro evento el mouseup, en este
evento desabilitas el temporizador timmer1.enable=false y se deja de enviar el caracter

este es un ejemplo en VB6 que es lo que tengo...

Private Sub cmdHbilitaTimmer_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
tmrEnviaA.Enabled = True
End Sub

Private Sub cmdHbilitaTimmer_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
tmrEnviaA.Enabled = False
End Sub

Private Sub tmrEnviaA_Timer()
' muy importante el intervalo del temporizador
' ojo el puerto ya debe estar habierto

MSComm1.Output = "a"          '' & Chr(13) & Chr(10)

' aqui va tu codigo para enviar los caracteres
' los estara enviando dependiendo de el intervalo del temporizador
End Sub


----------



## yeaaa (Mar 15, 2011)

Gracias por tu ayuda arturouc provare los cambios y posteare los resultados


----------



## arturouc (Mar 16, 2011)

yeaaa dijo:


> Gracias por tu ayuda arturouc provare los cambios y posteare los resultados



PREGUNTA: ya tienes la programacion del microcontrolador para el control del servomotor?
con que frecuencia envia pulsos el encoder que estas utilizando? ya integraste la ecuacion
de PID para el control de la posicion, velocidad y aceleracion?
te lo pregunto por que yo estoy haciendo lo mismo con vb6 pero estoy en la lectura del encoder
por que me envia 100 000 pulsos por seg  (100 KHz) ya que resuelva este problema voy con lo 
del PID. 
este es el codigo de ejemplo que tengo en PIC BASIC PRO solo para 2 posiciones

```
'****************************************************************
'*  Name    : servodriver.BAS                                   *
'*  Date    : 21/11/2010                                        *
'****************************************************************
define osc 8   'declaracion del oscilador
Trisd = 255     'puerto D como entradas
Trisb = 0       'puerto B como salidas

Posicion var word  'Posicion a la que tiene que ir el servo
PosMenos var word  'Histeresis abajo
PosMas var word    'Histeresis arriba
Contador var word  ' Contador de pulsos del encoder
A var bit          'canal A del encoder 500 pulsos/r
B var bit          'canal B del encoder 500 pulsos/r
C var Bit          'canal C del encoder 500 pulsos/r
uA var bit         'variable para saber si cambio canal A
uB var bit         'variable para saber si cambio canal B
uC var bit         'variable para saber si cambio canal C
Giro var bit       'sentido de giro del servo

contador = 0
posicion=5000    'una posicion arbitraria
ua=0
ub=0
Cambio:          'cambiar sentido de giro
posmenos=posicion-15
posmas=posicion+15
portb=0

Inicio:
        ; si se presiona un pulsador se cambia la
        ;posicion a la que se debe de mover el servomotor
        if portd.1 =1 then  goto soltar
        if portd.0=1 then  ' LEE CANAL A  del encoder
            A=1     'activado
        else
            A=0     'desactivado
        endif 
        if portd.2=1 then ' LEE CANAL B   del encoder
            B=1     'activado
        else
            B=0     'desactivado
        endif               
        ;si el canal A mando un flanco de subida
        ;y el canal B esta activo giro=1
        IF UA=0 and A=1 and B=1 then giro=1
        ;si el canal A mando un flanco de subida
        ;y el canal B esta desactivado giro=0
        IF UA=0 and A=1 and B=0 then giro=0
        ;si cambia alguno de los canales del encoder
        ;es una posicion diferente y por lo tanto
        ;el contador se debe de incrementar
        ;dos canales de 500 pulsos con dos estados posibles
        ;me dan 2000 pulsos por revolucion (4 combinaciones)
        if A<>uA or B<>uB then
            if giro=1 then  contador =contador+1   'incremento
            if giro=0 then  contador =contador-1   'decremento
        endif
        
        uA=A   'ultimo estado del canal A
        uB=B   'ultimo estado del canal B
        
        if contador =posicion then  ' si llego a la posicion apago el motor
            portb.1 =0
            portb.2=0
        endif 
        
        if contador<posmenos then  ' giro en sentido =1
            portb.1=1 'se activa la salida para que gire el motor giro=1
        endif
       ;despues cambiare esto por PWM
       if Contador>posmas then     'giro en sentido =0
            portb.2=1 'se activa la salida para que gire el motor giro=0
         endif        
        goto inicio
Soltar:
        if portd.1=1 then goto Soltar
        ;cambio la posicion para que gire en sentido contrario
        if posicion=1000 then
            posicion=5000
        else
            posicion=1000
        endif        
        goto Cambio
end
```

este codigo lo publique en el post #835 del hilo curso programacion pic basic pro de este mismo foro



Unikfriend dijo:


> Hi yeaa, es que para eso ocupas el evento MouseDown no el Click
> como te comentaba para eso yo utilizaria un timer con el
> MouseDown lo habilitas y con el MouseUp lo deshabilitas


Unikfriend
estabas haciendo algo muy parecido, como va tu proyecto para controlar el servo de 2800 rpm?


----------



## Unikfriend (Mar 16, 2011)

Hi Arturo, 
No en realidad mi proyecto es algo muy distinto, 
pero me interesa aprender acerca de los servos, 
con que servo estas trabajando ?


----------



## arturouc (Mar 16, 2011)

Unikfriend dijo:


> Hi Arturo,
> No en realidad mi proyecto es algo muy distinto,
> pero me interesa aprender acerca de los servos,
> con que servo estas trabajando ?




 un servomotor SANYODENKI
de 24V 2.7A 3000 rpm. se trata de controlar la posicion del servomotor
el encoder
manda 2000 pulsos por revolucion a 3000 rpm = 100000 pulsos/seg
son dos canales del encoder de 500 pulsos/rev


----------



## Unikfriend (Mar 16, 2011)

Gracias Arturouc,
y donde lo conseguistes? son muy caros?


----------



## arturouc (Mar 16, 2011)

Unikfriend dijo:


> Gracias Arturouc,
> y donde lo conseguistes? son muy caros?



fui al parque industrial de la ciudad y tienen un lugar donde tiran todas las maquinas que ya no utilizan, me encontre una zavatech (maquina de SMT, montaje superficial de componentes electronicos) y de ahi los tome y me los regalaron por que para ellos es basura....
en todas las ciudades donde estan concentradas las empresas (parque industrial) puedes encontrar o incluso en alguna empresa especifica....

P.D. si son caros...


----------



## yeaaa (Mar 16, 2011)

Saludos aqui les traigo el codigo completo de Visual Basic.NEt gracias a ustedes pude corregir el error

Imports System.IO.Ports
Imports System.Timers

Public Class Form1

Dim CaracterEnviado As Char = ""         'Caracter enviado
Dim mBuffer As Byte() = New Byte(0) {} 'Bufer para envio

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Interval = 100    'Establecemos el periodo del timer
        AddHandler Timer1.Elapsed, AddressOf Enviar  'Configura desbordamiento el timer va a Enviar() 
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
        SerialPort1.Close()
    End Sub

Private Sub ConfiguracionPuerto()
        Dim NombrePuerto As String
        NombrePuerto = ""
        SerialPort1.Close()
        If RadioButton3.Checked Then       'Configura el tipo de puerto
            NombrePuerto = "COM1"
        End If
        If RadioButton4.Checked Then
            NombrePuerto = "COM2"
        End If
        If RadioButton5.Checked Then
            NombrePuerto = "COM3"
        End If
        If RadioButton6.Checked Then
            NombrePuerto = "COM4"
        End If
        If RadioButton7.Checked Then
            NombrePuerto = "COM5"
        End If
        If RadioButton8.Checked Then
            NombrePuerto = "COM6"
        End If
        If RadioButton9.Checked Then
            NombrePuerto = "COM7"
        End If
        If RadioButton10.Checked Then
            NombrePuerto = "COM8"
        End If
        If RadioButton11.Checked Then
            NombrePuerto = "COM9"
        End If
        If RadioButton12.Checked Then
            NombrePuerto = "COM10"
        End If
        If NombrePuerto = "" Then
            MsgBox("Selecciona un puerto", vbInformation, "Error")
        Else
            SerialPort1.PortName = NombrePuerto   'Configura el COM a utilizar
            If Not SerialPort1.IsOpen Then        'Si no se abre
                Try                               'Intenta abrirlo
                    SerialPort1.Open()
                Catch ex As System.Exception
                    MessageBox.Show(ex.ToString()) 'Si no me muestra un mensaje de error
                End Try
            End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ConfiguracionPuerto()
End Sub

Private Sub ButtonS1arriba_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseDown
CaracterEnviado="a"
Enviar()
End Sub

Private Sub ButtonS1abajo_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseDown
CaracterEnviado="b"
Enviar()
End Sub

    Private Sub ButtonS1arriba_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseUp
        Timer1.Enabled = False
        CaracterEnviado = “”
    End Sub

    Private Sub ButtonS1abajo_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseUp
        Timer1.Enabled = False
        CaracterEnviado = “”
    End Sub

Private Sub Enviar()
Select Case CaracterEnviado
Case "a"
mBuffer(0) = &H61   'Envia una a
Case "b"
mBuffer(0) = &H62 'Envia una b
End Select
SerialPort1.Write(mBuffer, 0, mBuffer.Length)    'Envia el dato por el puerto
End Sub
End Class

Bueno gracias a ustedes pude completar el proyecto, espero les sirva, cualquier duda aganmela saber

Una disculpa pero faltaron algunas cosas en el post anterior aqui mando las correcciones:

Imports System.IO.Ports
Imports System.Timers

Public Class Form1

Dim CaracterEnviado As Char = "" 'Caracter enviado
Dim mBuffer As Byte() = New Byte(0) {} 'Bufer para envio
*Dim Timer1 As New System.Timers.Timer()  'Declaramos un Timer
*
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Timer1.Interval = 100 'Establecemos el periodo del timer
AddHandler Timer1.Elapsed, AddressOf Enviar 'Configura desbordamiento el timer va a Enviar() 
End Sub

Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
SerialPort1.Close()
End Sub

Private Sub ConfiguracionPuerto()
Dim NombrePuerto As String
NombrePuerto = ""
SerialPort1.Close()
If RadioButton3.Checked Then 'Configura el tipo de puerto
NombrePuerto = "COM1"
End If
If RadioButton4.Checked Then
NombrePuerto = "COM2"
End If
If RadioButton5.Checked Then
NombrePuerto = "COM3"
End If
If RadioButton6.Checked Then
NombrePuerto = "COM4"
End If
If RadioButton7.Checked Then
NombrePuerto = "COM5"
End If
If RadioButton8.Checked Then
NombrePuerto = "COM6"
End If
If RadioButton9.Checked Then
NombrePuerto = "COM7"
End If
If RadioButton10.Checked Then
NombrePuerto = "COM8"
End If
If RadioButton11.Checked Then
NombrePuerto = "COM9"
End If
If RadioButton12.Checked Then
NombrePuerto = "COM10"
End If
If NombrePuerto = "" Then
MsgBox("Selecciona un puerto", vbInformation, "Error")
Else
SerialPort1.PortName = NombrePuerto 'Configura el COM a utilizar
If Not SerialPort1.IsOpen Then 'Si no se abre
Try 'Intenta abrirlo
SerialPort1.Open()
Catch ex As System.Exception
MessageBox.Show(ex.ToString()) 'Si no me muestra un mensaje de error
End Try
End If
End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ConfiguracionPuerto()
End Sub

Private Sub ButtonS1arriba_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseDown
*Timer1.Enabled = True*
CaracterEnviado="a"
Enviar()
End Sub

Private Sub ButtonS1abajo_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseDown
*Timer1.Enabled = True*
CaracterEnviado="b"
Enviar()
End Sub

Private Sub ButtonS1arriba_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseUp
Timer1.Enabled = False
CaracterEnviado = “”
End Sub

Private Sub ButtonS1abajo_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Buttonarriba.MouseUp
Timer1.Enabled = False
CaracterEnviado = “”
End Sub

Private Sub Enviar()
Select Case CaracterEnviado
Case "a"
mBuffer(0) = &H61 'Envia una a
Case "b"
mBuffer(0) = &H62 'Envia una b
End Select
SerialPort1.Write(mBuffer, 0, mBuffer.Length) 'Envia el dato por el puerto
End Sub
End Class

Las sentencias que estan en negritas me faltaron en el post pasado


----------



## Unikfriend (Mar 16, 2011)

Ok, gracias por el dato.


Que servo motor estas utilizando Yeaaa?


----------



## arturouc (Mar 16, 2011)

les propongo hacer un driver para controlar servomotores de CD con ciertas características:
rango determinado de corriente, rango de frecuencia de encoder, etc.
en verdad es lo que estoy haciendo para un robotde 5 GDL, ya lo tengo con motores paso a paso
les paso un link para que lo vean. 
http://www.uts.edu.mx/archivoselectronicos/Video/ArchivosElectronicos\3VideoRobot_UTS\RP5E_UTS1.rar
voy a postear un hilo en el grupo de automatización y robótica cuando tenga 25 mensajes...jajaja...


----------



## Unikfriend (Mar 16, 2011)

arturouc dijo:


> les propongo hacer un driver para controlar servomotores de CD con ciertas características:
> rango determinado de corriente, rango de frecuencia de encoder, etc.
> en verdad es lo que estoy haciendo para un robotde 5 GDL, ya lo tengo con motores paso a paso
> les paso un link para que lo vean.
> ...


 
ok, me interesa aprender acerca de los servomotores, yo si me apunto, 
lo que necesitaba saber era donde conseguir un servo, entonces los CD lo usan,
tu dices como empezamos.


----------



## arturouc (Mar 17, 2011)

Unikfriend
ya viste el video?
.
.
.
en el Grupo de  Automatizacion y Robotica 
acabo de crear un hilo para este proyecto
espero que participen...


----------



## Unikfriend (Mar 18, 2011)

ok, ya vi el video les quedo muy bien el robot,


----------



## arturouc (Mar 18, 2011)

Unikfriend dijo:


> ok, ya vi el video les quedo muy bien el robot,


a este robot le das un punto en el espacio y el modelo matematico calcula los angulos y se los envia por el puerto paralelo a los driver de los motores paso a paso y el robot se posiciona en ese punto... y no es nada complicado hacerlo... ahora lo quiero hacer con servomotores y estoy invitando al grupo de utomatizacion y robotica


----------



## Unikfriend (Mar 18, 2011)

Ok, pues continuemos en ese grupo, haber quien mas se anima.


----------



## yeaaa (Mar 18, 2011)

Los servomotores que yo he manejado son los HITEC, y los FUTABA, que yo creo ke son los mas comerciales, el modo de control de estos es simplemente enviar un tiempo en alto y un tiempo en bajo sin alterar la frecuencia, es decir como son servos de 50Hz el periodo es de 20000us (T=1/f) por tanto el tiempo en alto + el tiempo en bajo deben de ser igual a 20000us, y para el tiempo en alto ay una restriccion deve de estar en un rango de 900us-2100us para manejar un rangon de 0-180 grados, lo unico que ay ke sacar es la resolucion de movimiento es decir (2100-900)/180, de esta manera optenemos los us/grado que queremos para establecer las ecuaciones para su movimiento quedarian mas o menos asi:

talto=((2100-900)/180)*(Grado en el que queremos pocisionar) + 900
tbajo= 20000-talto

Bueno esta es una manera sencilla para controlar la posicion del servomotor, estos calculos noo me han fallado para posicionar este tipo de motores (HITEC y FUTABA).
El chiste es realizar un PWM con estos valores y listo. 
Bueno aqui anexo un pequeño manual de servomotores dond esta programado en C, espero y les sirva


----------



## arturouc (Mar 19, 2011)

en la hoja 3 es el t402-011 estan las especificaciones del motor, salida del encoder es colector abierto de 500 pulsos por canal 
ya vi el datasheet del 16f877a y podemos utilizar el modulo del timmer1 para contar los pulsos del encoder y el modulo del pwm timmer2 para controlar el motor 

pag. 57 de datasheet 16f877a  http://ww1.microchip.com/downloads/en/devicedoc/39582b.pdf
T1CON 
bit 1 TMR1CS: Timer1 Clock Source Select bit
1 = External clock from pin RC0/T1OSO/T1CKI (on the rising edge) esto es lo que necesitamos
0 = Internal clock (FOSC/4)
configurando este registro podemos hacer que el microcontrolador lea los pulsos del encoder a una frecuencia diferente a la del oscilador...y de manera independiente a la programacion del micro
esta hoja esta mejor
http://ww1.microchip.com/downloads/en/DeviceDoc/33023a.pdf 
aqui hay ejemplos en ensamblador

P.D. Unikfriend los subi aqui por el archivo adjunto de los datos del motor


----------



## Unikfriend (Mar 22, 2011)

Hi arturouc,
Tienes alguna idea que aparatos de uso domestico utilizan los servomotores????
Saludos.


----------



## arturouc (Mar 23, 2011)

Hola Unikfriend
en las copiadoras podras encontrar motores de CD con un encoder acoplado a un eje, ese te puede servir.
Nosotros los conseguimos en las chatarreras muy muy economicos.
has programado los modulos ccp de un microcontrolador?
necesitamos que el micro este capturando los pulsos del encoder y al mismo tiempo enviando pwm y al mismo tiempo este realizando otras tareas...


----------



## Unikfriend (Mar 23, 2011)

Gracias arturouc,
Corrigeme si me equivoco,
Con el PWM lo van a utilizar para generar un pulso de control y
con el CCP van a recibir la retroalimentacion de la posicion del servo.


----------



## arturouc (Mar 23, 2011)

Unikfriend dijo:


> Gracias arturouc,
> Corrigeme si me equivoco,
> Con el PWM lo van a utilizar para generar un pulso de control y
> con el CCP van a recibir la retroalimentacion de la posicion del servo.



esa es la idea, conoces de programacion de pic basic pro
en el curso de pic basic pro estoy programando eso...
https://www.forosdeelectronica.com/f24/curso-programacion-pic-bsic-pro-20658-new/

has programado los modulos ccp o timmer1 y 2 del pic 16f877a?


----------



## Unikfriend (Mar 23, 2011)

Hi Arturouc,
no he utilizado esos módulos del Pic, 
de hecho prefiero usar otro microcontrolador,
la funcion pwm es común en los microcontroladore
la ccp no tanto pero hay varias que similares,  

lo que me preocupa es que esos motores no 
son fáciles de conseguir y no quiero quedarme en la teoría,
ya sabes que en teoría todo funciona jijii.


----------



## arturouc (Mar 24, 2011)

Unikfriend
aqui te dejo la simulacion en proteus de un servomotor con encoder....es un principio de lo que estamos buscando....solo tengo 2 dias utilizando el proteus hay cosas que se pueden mejorar
Ver el archivo adjunto 50472
por que prefieres utilizar otro micro?


----------



## Unikfriend (Mar 25, 2011)

Gracias arturouc,
pues no hay ningun razon en particular para usar otro micro,
simplemente tengo un kit de Texas con display disponible.


----------



## eduardo20093881 (Dic 17, 2011)

Hola soy nuevo en el foro y les traigo un aporte que talvez les pueda servir. Hice un programa en visual basic 6.0 para controlar un servomotor pero logre ver que no se pueden manejar intervlos con decimales por lo que no serviria para manejar el servomotor les dejo por si les interesa la señal se saca por el pin 2 del puerto paralelo si tienes alguna duda no dudes en comentamerla. 



*Este es otro que encontre en la web en el cual me base, esta mega recomendado.*

http://wiki.webdearde.com/index.php?title=Testeador_de_servo_a_trav%C3%A9s_del_pc


----------

