Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

21/02/2011 #1


Control de un servomotor con visual basic express 2008
Saludos
El proyecto que tengo es el siguiente es una interfaz echa en Visual Basic 2008, que envia 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 gustaria que me ayudaran, aqui les anexo todos los archivos.

Bueno en si son 2 problemas:
1.- Me gustaria poder cambiar de puerto COM, a la interfaz le puse unos radiobotones, segun el radio boton que se presione es el COM que se usara, pero el problema es que una vez iniciada la aplicacion se inicializa el puerto y no se como cambiarlo, soy nuevo en esto de interfaces de Visual Basic, y baje un tutorial donde venia como mandar datos por el puerto serial, pero no viene como poder cambiar el COM que utilizamos, asi que requiero de su ayuda para resolver este problema, aqui anexo todos los archivos y el codigo fuente.
2.- el otro problema que tengo, es que cada vez que se presiona un boton 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 envia un caracter en este caso una 'a' pero me gustaria si me pueden ayudar en un codigo que me envie muchas 'a' mientras esta presionado el boton, por que de esta manera el servo se mueve pero le tengo que estar aplastando al boton, quisiera saber si hay la forma de sensar cuando el boton se queda presionado, y enviar muchas 'a'

Aqui anexo el codigo 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 este es el codigo fuente esta echo 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=PI N_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);
}
}
21/02/2011 #2

Avatar de Unikfriend

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.

21/02/2011 #3


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
21/02/2011 #4

Avatar de Unikfriend

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
14/03/2011 #5

Avatar de arturouc

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....
15/03/2011 #6


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

¿?
15/03/2011 #7

Avatar de Unikfriend

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


15/03/2011 #8

Avatar de arturouc

yeaaa dijo: Ver Mensaje

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

¿?
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
15/03/2011 #9


Gracias por tu ayuda arturouc provare los cambios y posteare los resultados
16/03/2011 #10

Avatar de arturouc

yeaaa dijo: Ver Mensaje
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
Código:
'****************************************************************
'*  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: Ver Mensaje
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?
16/03/2011 #11

Avatar de Unikfriend

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

Avatar de arturouc

Unikfriend dijo: Ver Mensaje
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
16/03/2011 #13

Avatar de Unikfriend

Gracias Arturouc,
y donde lo conseguistes? son muy caros?
16/03/2011 #14

Avatar de arturouc

Unikfriend dijo: Ver Mensaje
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...
16/03/2011 #15


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
16/03/2011 #16

Avatar de Unikfriend

Ok, gracias por el dato.


Que servo motor estas utilizando Yeaaa?
16/03/2011 #17

Avatar de arturouc

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/archivoselectr...CRP5E_UTS1.rar
voy a postear un hilo en el grupo de automatización y robótica cuando tenga 25 mensajes...jajaja...
16/03/2011 #18

Avatar de Unikfriend

arturouc dijo: Ver Mensaje
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/archivoselectr...CRP5E_UTS1.rar
voy a postear un hilo en el grupo de automatización y robótica cuando tenga 25 mensajes...jajaja...
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.
17/03/2011 #19

Avatar de arturouc

Unikfriend
ya viste el video?
.
.
.
en el Grupo de Automatizacion y Robotica
acabo de crear un hilo para este proyecto
espero que participen...
18/03/2011 #20

Avatar de Unikfriend

ok, ya vi el video les quedo muy bien el robot,
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.