TODOPIC
Lenguajes de programación para PC => Visual Basic => Mensaje iniciado por: migsantiago en 09 de Julio de 2007, 18:38:08
-
Hola
He programado poco en VB y voy a iniciarme en RS232... pero antes de empezar con pruebas quisiera saber lo siguiente:
- Si uso WinXP y VB6, ¿puedo usar normalmente el puerto serial o necesito la librería IO.DLL?
- ¿El control MSCOMM acepta puertos com más allá del 4? Por ejemplo el COM9.
Hasta ahora esas son las dudas que tengo. Encontré una página que lo lleva a uno de la mano para iniciarse con la MSCOMM...
http://www.thaiio.com/prog-cgi/0002_serial.htm
Gracias
-
Hola:
La librería IO.DLL yo la he usado para el puerto paralelo, para el puerto serie, basta con el mscomm, y respecto a lo otro, del com9, si lo tienes habil, pues te debe funcionar.
-
OK!
Ya comencé a hacer pruebas y he tenido éxito, tienes razón MSCOMM es suficiente...
(http://img180.imageshack.us/img180/4783/screenshot003xu4.th.jpg) (http://img180.imageshack.us/my.php?image=screenshot003xu4.jpg)
Posteriormente haré pruebas con un puerto virtual COM9. :mrgreen:
-
el mscomm viene como anillo al dedo, trae lo justo y necesario para hacer una comunicación.
la desventaja es que al crear el .exe, y portarlo a otra máquina puede que no corra, porque hace falta instalar y/o registrar el control ocx, entonces hay que crear un instalable. cosa que no ocurre si te vas por el camino de las apis (aunque sería complicarse la vida) :)
-
Interesante, luego les preguntaré como generar el instalador. Gracias Pali :mrgreen:
-
Hola de nuevo
Ya regresé a mis pruebas con MSCOMM y me encuentro con varias dudas. Aquí lo que "creo" que hacen las sig. propiedades:
- mscomm1.inputlen = 0 'sirve para capturar todo lo que tiene el buffer de entrada en una variable, por ejemplo:
text1.text=mscomm1.input
así capturaría todos los caracteres del buffer de entrada en text1.
- El evento MSComm1_OnComm se detona cuando cualquier cosa ocurre en el puerto serial, pero no sé como diferenciar entre recepción y envío, creo que es con banderas como:
MSComm1.CommEvent = comEvReceive And MSComm1.InBufferCount > 0
pero no estoy seguro.
¿Existe alguna guía fácil para esos eventos en donde se detallen esas banderas? Si no tendré que instalar la ayuda MSDN :mrgreen:
Otra cosa que quiero hacer es lo siguiente...
- El pic va a estar enviando una trama de caracteres así:
a346a245a876a...
-La pc debe sincronizarse con la "a" e interpretar el dato 346, 245 y 876.
¿Qué instrucciones me recomiendan estudiar para lograrlo?
Gracias por su ayuda :mrgreen:
-
Hola Migsantiago, eso lo manejas como un string, tienes como dato el LEN (largo de todo el string) y puedes ir buscando con MID$ caracter por caracter hasta que encuentras una "a", luego de alli, tomas 3 caracteres...
Hay una instruccion que directamente te busca un caracter de una cadena... pero no recuerdo como se llama... :?
Ya algun colega me pegara un palazo :D :-)
Un abrazo
Norberto
-
Gracias Norberto, buscaré más info sobre la instrucción MID$, soy muy nuevo en vb todavía.
Todavía no encuentro alguna guía sobre la MSCOMM, espero que alguien cuente con una en el foro. :D
-
Ahhh, perdon Mig!,
por ejemplo defines
PALABRA AS STRING
supongamos que lo que llega se llama DATO$ -> que podria ser "MIGSANTIAGO"
PALABRA=MID$(dato$,4,3)
entonces mid tomara Desde el cuarto caracter, tres caracteres
PALABRA=SAN
Logicamente, los numeritos podrian ser contadores, valores fijos etc
-
Buennass:
La función de la que habla Norberto es InStr,
Devuelve un tipo Variant (Long) que especifica la posición de la primera aparición de una cadena en otra.
te pongo un ejemplo que viene en la ayuda msdn del visual basic,
Dim SearchString, SearchChar, MyPos
SearchString ="XXpXXpXXPXXP" ' Cadena en la que se busca.
SearchChar = "P" ' Se busca "P".
' Una comparación textual que comienza en la posición 4. Devuelve 6.
MyPos = Instr(4, SearchString, SearchChar, 1)
' Una comparación binaria que comienza en la posición 1. Devuelve 9.
MyPos = Instr(1, SearchString, SearchChar, 0)
' La comparación es binaria por configuración predeterminada (si se omite el último argumento).
MyPos = Instr(SearchString, SearchChar) ' Devuelve 9.
MyPos = Instr(1, SearchString, "W") ' Devuelve 0.
Yo no he utilizado nunca esta función pero estoy teniendo problemas con la sincronización de datos del pic al pc, yo utilizo la propiedad RThreshold la pongo a 5, para que me salte el evento cada vez que reciba 5 bytes, el problema que tengo es que cuando mando mucha cantidad de datos 800 bloques de 5 bytes el algún momento coge uno de mas o uno de menos y ya me trastoca todos los siguientes datos. Me toca hacerlo de otra manera pero aún no tengo muy claro como.
Espero que te valga de algo la información, el la ayuda mdsn viene explicado la instrucción mejor.
Saludos y suerte
-
Ah, ahora entiendo :mrgreen:
Pero antes de hacer uso de MID$ y de INSTR, quisiera preguntar algo más. Cuando uno hace uso de la instrucción...
mistring=mscomm1.input
y el buffer de entrada tenía 300bytes almacenados... ¿se depositan automáticamente 300 bytes en mistring y el buffer... se borra?
(ohh y feliz cumple Milo :D )
-
Efectivamente, se borran al leer el buffer.
Saludos.
-
...
Todavía no encuentro alguna guía sobre la MSCOMM, espero que alguien cuente con una en el foro. :D
busqué unas guias viejas que tenía en un cd, y resulta que son sacadas de la MSDN :(, Mig esa es la fuente principal, el resto es revisar codigos hechos en VB
-
jeje sí! pero se me sigue olvidando traerme los cd's de la msdn para instalarlos en mi trabajooooo :8} :8}
-
Ya regresé a mis pruebas...
Quise compilar la siguiente instrucción pero VB me regaña...
Public volt(1 To 40) As String 'lleva el voltaje de cada medidor
y me dice que...
(http://img410.imageshack.us/img410/1001/errorgd5.jpg)
ya le di varias revisadas y no entiendo porqué está mal.
Ah y lo de mid e instr todavía no lo pruebo. Apenas compile les aviso. :mrgreen:
-
Ya regresé a mis pruebas...
Quise compilar la siguiente instrucción pero VB me regaña...
Public volt(1 To 40) As String 'lleva el voltaje de cada medidor
y me dice que...
(http://img410.imageshack.us/img410/1001/errorgd5.jpg)
ya le di varias revisadas y no entiendo porqué está mal.
Ah y lo de mid e instr todavía no lo pruebo. Apenas compile les aviso. :mrgreen:
Estas intentando declarar un array publico en un formulario. O creas un modulo(.bas) y lo declaras como publico ahi y accedes desde el formulario, o bien cambias el "Public" a "Private" en la declaracion dentro del form, pero solamente vas a poder acceder al array desde codigo dentro del form.
Saludos.
-
Bruno, gracias, funcionó con private :mrgreen:
Ya probé la instrucción Mid e Instr y funciona bien, gracias!!! :mrgreen:
El pic manda una cadena cuando vb la pide, la cadena es más o menos así...
B01 12.5V(enter)B02 12.5(enter) B03..... B40 12.5(enter)
Aquí mi código...
Public cadena As String 'cadena a recibir desde pic
Public poscad As Integer 'posición de texto en cadena
Public i As Integer 'lleva el conteo del arreglo
Private volt(1 To 40) As Double 'lleva el voltaje de cada medidor
Public buscadena As String 'cadena a buscar
Private Sub Close_Click()
MSComm1.PortOpen = False 'Cierra puerto
End 'termina programa
End Sub
Private Sub Command1_Click()
Text1.Text = ""
End Sub
Private Sub Command2_Click()
MSComm1.Output = Chr$(115) 'envía petición de envío, letra s
Command2.Enabled = False 'evita que puede reclickear botón
End Sub
Private Sub Form_Load()
MSComm1.Settings = "19200,N,8,1"
MSComm1.CommPort = 1 'usa el com1
MSComm1.InputLen = 0 'tamaño de buffer de entrada
MSComm1.PortOpen = True 'abre puerto
MSComm1.RThreshold = 1 'habilita el evento ante recepción
'en buffer después de recibir 1 byte
'inicializa el contenido de las labels que muestran
'el voltaje en tiempo real
Label01.Caption = "n/d"
Label02.Caption = "n/d"
.........
Label34.Caption = "n/d"
Label35.Caption = "n/d"
Label36.Caption = "n/d"
Label37.Caption = "n/d"
Label38.Caption = "n/d"
Label39.Caption = "n/d"
Label40.Caption = "n/d"
End Sub
Private Sub MSComm1_OnComm()
'aquí llega si el com1 tuvo cambios en rx o tx
If MSComm1.InBufferCount >= 419 Then 'el pic envía 419bytes
cadena = MSComm1.Input
For i = 1 To 40
If (i < 10) Then
buscadena = "B0" & i
Else
buscadena = "B" & i
End If
poscad = InStr(cadena, buscadena) 'busca B?? en cadena
volt(i) = Mid(cadena, (poscad + 4), 4) 'deposita voltaje
Next
Label01.Caption = volt(1)
Label02.Caption = volt(2)
Label03.Caption = volt(3)
Label04.Caption = volt(4)
Label05.Caption = volt(5)
Label06.Caption = volt(6)
Label07.Caption = volt(7)
Label08.Caption = volt(8)
Label09.Caption = volt(9)
Label10.Caption = volt(10)
Label11.Caption = volt(11)
.......
Label35.Caption = volt(35)
Label36.Caption = volt(36)
Label37.Caption = volt(37)
Label38.Caption = volt(38)
Label39.Caption = volt(39)
Label40.Caption = volt(40)
vstring.Caption = 0 'borra contenido
For i = 1 To 40
vstring.Caption = vstring.Caption + volt(i) 'suma los voltajes
Next
Command2.Enabled = True 'evita que pueda reclickear botón
End If
End Sub
Private Sub Timer1_Timer()
'cada 25ms entrega el tamaño del buffer de entrada
Text2.Text = MSComm1.InBufferCount
End Sub
Y la pantalla queda así...
http://img131.imageshack.us/img131/5717/dibujotp7.jpg
Seguiré trabajando, gracias de nuevo.
Aprovechando el tema, ¿cómo hago para que el estilo visual de las ventanas de vb sea como winxp? En vc++ lo hago de esta forma...
http://www.migsantiago.com/index.php?option=com_content&view=article&id=5&Itemid=6
-
Pali me hizo favor de enviarme una guía de MSCOMM muy buena, sacada de los discos de MSDN. La pueden encontrar aquí...
http://todopicsan.4shared.com
Gracias
-
Hola de nuevo
Ya he estado trabajando más con el componente MSCOMM. Quisiera saber como generar un ejecutable que incluya ese componente, para instalarlo en una PC que no tenga Visual Basic instalado.
¿Necesito descargar algún generador de instalador o Visual Basic lo puede generar?
Gracias ;-)
-
En el mismo visual hay una herramienta boton inicio->programas-> microsoft visual basic (si la tienes instalada) se llama asistente para empaquetador o algo así, solo sigue los pasos y listo.
-
OK lo voy a buscar, también tengo otra pregunta... estoy usando una imágenes GIF que cambian dentro de la ventana según la ejecución del programa... ¿esas también las empaca esta herramienta?
-
umm :roll: no recuerdo... creo que sip. todo lo que use el proyecto vbp quedará empacado (incluso si usas un control activeX)
-
OK Pali, les cuento mis resultados luego :mrgreen:
Gracias
-
Dentro de las opciones de empaquetado se pueden agregar los archivos que uno quiera, incluso en donde se instalarán.
(http://img516.imageshack.us/img516/1083/dibujost6.jpg)
Gracias Pedro
-
exacto migsantiago. sino mal recuerdo el empacador mira que es lo que tienes enlazado al .vbp y lo encapsula.
-
Otra duda...
Hablando en lenguaje C cuando quiero imprimir un flotante con 1 decimal y 2 cifras enteras le pongo
flota=12;
printf("%2.1f",flota); //y entrega 12.0
Ahora que estoy en VB... no sé ni como hacerlo.
Me interesa que esta línea muestre los decimales...
Private volt(1 To 40) As Double 'lleva el voltaje de cada medidor
lblVpantalla(i).Caption = volt(i + 1)
¿Qué me sugieren? :mrgreen:
-
No se si entendi bien:
A ver...
If Len(volt(i + 1)) < 3 Then
lblvpantalla(i).Caption = volt(i + 1) & ".0)"
Else
lblvpantalla(i).Caption = Left(volt(i + 1), 4)
End If
-
con double puedes mostrar decimales sin necesidad de arrays, si lo que quieres es mostrar n digitos después de la coma, entonces habría que convertirlo a string y seleccionar cuantos caracteres quieres mostrar.
-
No me expliqué bien :oops:
Si mi variable double (flotante en c) tiene el valor 12 quiero que cuando la imprima en una label entregue 12.0.
----------------------
public volt as double
volt=12
lblLabel.caption =volt 'esto normalmente entrega 12 en vez de 12.0
------------------------
Bruno, por ahí va la cosa, pero ¿no hay forma de hacerlo automáticamente como en c?
Además... no sé qué hace Len y Left :oops:
Pedro, ¿cómo hago esa conversión que mencionas?
-
Bruno, por ahí va la cosa, pero ¿no hay forma de hacerlo automáticamente como en c?
Hasta donde yo se de VB6, no.
Me equivoque. la instruccion LEN devuelve la longitud de la variable en bytes.
La Left es solo para cadenas de texto, y lo que hace es tomar cierta porcion del lado izquierdo de un string:
Su estructura es:
Left(cadena,cantidadcaracteres)
Entonces si por ejemplo:
MiCadena = "Hola Mundo"
y pongo
Msgbox left(MiCadena,6)
deberia salir "Hola M"
El algoritmo anterior sería:
If Len(cstr(volt(i + 1))) < 3 Then
lblvpantalla(i).Caption = volt(i + 1) & ".0)"
Else
lblvpantalla(i).Caption = Left(volt(i + 1), 4)
End If
Me había olvidado de hacer una conversión explícita :D para pasar de double a string
Saludos.
-
Hola Bruno
Es mucho código para corregir un detalle estético, mejor me quedo con las ganas :D aunque ya aprendí algo más, como CStr, e investigué sobre CDbl y Cint, ¡a qué buenas funciones! :mrgreen:
Gracias
-
Mig, no es nada de otro mundo, lo que hay que hacer es convertirlo a string y lo demás es jugar con las funciones para string ($MID, $left, Right, etc).
-
Lo malo es que soy nuevo con VBasic... hago todo con bolitas y palitos :D me tardo mucho y pues como es solo un detalle estético mejor sigo programando lo demás.
Ahora otra pregunta, ¿cómo obtengo el residuo de una división?
En lenguaje C se pone
residuo= 9%7; //residuo valdrá 2
:?:
-
con la función MOD
Acá (http://www.todopic.com.ar/foros/index.php?topic=14851.msg92667#msg92667) el maestro Bruno dá una aplicación a dicha función, y la explica en gran detalle.
-
Perfecto... lo puse a prueba con un programa simple...
Text3.Text = Text1.Text Mod Text2.Text 'saca residuo
Gracias Pedro
Edito:
Haciendo más pruebas intenté dividir 40 entre 3.5 y pasa algo raro, me entrega 0 como residuo. Parece ser que siempre hay que entregarle enteros a esta función para que trabaje bien.
-
Hola!
Efectivamente. Sólo sirve para enteros NO negativos.
Podriamos recurrir a la matemática para hacer lo que querés con punto flotante:
Si querés el resto con decimales:
Resto = Dividendo - fix(Dividendo/Divisor)*Divisor
Si lo querés pero sin decimales:
Resto = fix(Dividendo - fix(Dividendo/Divisor)*Divisor)
Probalo.
Saludos!
P.D: Fix() se queda sólo con la parte entera de la expresión entre paréntesis.
-
Hola
Lo corregí de forma más directa usando Int(). Es bueno porque no redondea el número como la instrucción CInt().
residuo = dividendo Mod Int(divisor)
Gracias Bruno
-
Otra pregunta...
¿Cómo se usa una listbox?
Solo me gustaría saber qué opción es la que selecciona el usuario. Estuve leyendo por internet que es con la propiedad .text y .listindex, pero no encontré qué tipo de variable entregan y vb me marca errores.
Sé agregarle un elemento a la lista, es con .additem pero es lo único que sé.
-
añadiendo a lo de Bruno, en la ayuda msdn dice:
"El operador de módulo, o resto, divide número1 por número2 (redondeando a enteros los números de signo flotante) y devuelve sólo el resto como resultado"
es decir, que si tienes 3.5 él lo reconoce como 4, dando por ello 0 el resto.
respecto a lo del listbox, tendré quie repasar ese control jeje, ya que las veces que lo he usado ha sido guiandome por la ayuda 8)
-
Hola!
Está bien tu solución. El int() es una conversión explicita de variable a entero y hace lo mismo que un fix().
Con respecto al ListView:
Hay 4 modos de visualizar los datos si mal no recuerdo, yo uso el ultimo casi siempre(el "report").(podes configurarlo facilmente desde tiempo de diseño, haciendo click derecho sobre el control listview y seleccionando "propiedades".
"Objeto.SelectedItem" hace referencia al elemento seleccionado actualmente.
Ejemplo:
Private Sub Form_Load()
ListView1.ListItems.Add , , "Foro"
ListView1.ListItems.Add , , "Todopic"
ListView1.ListItems.Add , , "2007"
End Sub
Private Sub ListView1_Click()
MsgBox "El item seleccionado es el: " & ListView1.SelectedItem.Index & ". Y tiene por texto: " & ListView1.ListItems.Item(ListView1.SelectedItem.Index)
End Sub
El Listview es un control MUY completo. Si necesitas algo mas, decime.
Salu2!!!
-
Hola Bruno
¿Esas son instrucciones para una listbox de visual basic 6? Es que cuando corro el programa me marca...
(http://img239.imageshack.us/img239/9260/dibujoan1.jpg)
-
Sisi.
¿En que linea te tira eso?
¿Agregaste un objeto Listview al formulario?
Saludos.
-
Hola :)
El error aparece en:
ListView1.ListItems.Item(ListView1.SelectedItem.Index)
pero en vez de ponerle listview, yo le pongo el nombre de mi list box.
Va a sonar tonto, ¿pero que un listbox no es diferente a un listview? Además no encuentro ese control en la barra de controles...
(http://img209.imageshack.us/img209/3529/dibujowf2.jpg)
-
jaja ok!
Bueno, era lo que me temía.
Vete a Proyecto->Componentes y tilda en la lista "Microsoft Windows Common Controls 6.0".
Se te agregarán varios controles. Inserta uno de tipo "ListView".
Saludos.
-
Gracias Bruno :mrgreen:
-
Ya veo que el maestro Bruno lo hace a puro código, (que es mejor). Yo lo hago es al estílo novato, buscando el control:
...
Vete a Proyecto->Componentes y tilda en la lista "Microsoft Windows Common Controls 6.0".
...
cuyo atajo es Ctrl+T, es útil esa ventana porque así conocemos cuantos ocx tenemos instalados en nuestro sistema y cuál podemos utilizar (dependiendo si es gratuito o no), también sirve de medida para conocer cuanta "basura" tenemos en instalado en el windows , ej: un programa que no desintaló por completo sus partes.
-
Gracias por la recomendación Pedro. :)
-
Hola Amigos!, una forma muy simple de expresar valores, con decimales, es FORMAT$
ejemplo, ingresamos un valor por text2 y lo presentamos en text1, con 2 decimales..
Text1 = Format$(Val(Text2), "00.00") :mrgreen:
Un abrazo!
-
Muy útil el tip.
Gracias Jefe. :mrgreen: