TODOPIC
Lenguajes de programación para PC => Visual Basic => Mensaje iniciado por: loverman24 en 27 de Septiembre de 2005, 05:34:00
-
Hola a todos, os explico:
Tengo que monitorizar los datos q me envia mi pic por pc, y pensaba hacerlo por VB, que es, dentro de lo q cabe, lo mas sencillo. Mi problema es q no tengo ni idea de VB.
Tengo un pic q me envia los datos obtenidos a traves del ADC, el envio lo hago (uso CCS), lo he probado usando el Hyperterminal de windows y va bien, pero lo que quiero poder hacer es decirle al pic cuando quiero q envie y decirle q canal del ADC tiene q activar para obtener los datos. He mirado en el primer post de este foro (el de rs-232 q es lo q voy a utilizar), pero no lo entiendo demasiado bien.
Bueno, si alguien hizo alguna vez algo parecido o sabe de algun sitio donde pueda encontrar mas informacion sobre el control de pic´s mediante VB se lo agradeceria.
Muchas gracias
Un saludo
-
Hola:
Recientemente Artifox coloco un ejemplo de envio y recepcion de datos en VB para el puerto serie:
http://miarroba.com/foros/ver.php?foroid=348538&temaid=3607620&do=prevtopic
Suerte......!!!
-
Muchas gracias, lo he probado y va bien, recibe perfectamente, ya me pondre con el envio. Me surge una duda, en el textbox para la recepcion, los datos q me envia el pic me van apareciendo uno debajo del otro, con retorno de carro. Para que los datos se vayan escribiendo uno encima del otro, es decir, q me aparezca una sola cifra constante, ¿como lo hago? modificando el envio desde el pic (uso el ccs)? o puedo hacerlo desde el visual basic?
De momento esta es mi duda, mas adelante seguramente preguntare mas, siento ser pesado.
Un saludo
-
En vez de:
TxtRecibir.Text = TxtRecibir.Text & StrConv(MSComm1.Input, vbUnicode) & vbCrLf
probá con:
TxtRecibir.Text = TxtRecibir.Text & StrConv(MSComm1.Input, vbUnicode)
o tal vez quieras esto:
TxtRecibir.Text = StrConv(MSComm1.Input, vbUnicode)
-
Hola:
Si no te llegara a funcionar cambia el codigo del pic y envia los datos sin retorno de carro...!
-
Bueno, he usado la segunda opción que me daba Colores2, y al ppio parpadeaba, he aumentado la velocidad de conexion a 19200 baudios (trabaja a 9600) y perfecto. Muchisimas gracias por vuestra ayuda. Me temo que mas tarde os molestare con cosas relacionadas con el envio
Gracias
Un saludo
-
Aqui estoy de nuevo otra vez y con una nueva duda, os la comento:
¿como puedo hacer q visual basic me reconozca q le envio una variable en concreto? me explico:
yo le envio a visual basic una serie de datos q salen del convertidor adc del pic, esto no es problema, soy capaz de enviarlos y q vb me los muestre por pantalla; pero resulta q tengo q cambiar de canal adc y enviar otros datos a otra textbox de vb, no a la misma de antes, por lo q tengo q decirle a vb q he cambiado de canal adc y por tanto de textbox, es decir, vb me tiene q ser capaz de segun el canal de adc q tengo activado mostrarme los datos en una determinada textbox, por lo tanto me tiene q distinguir entre unos datos (lo q quiero enviar) y otros (los canales adc).
os pego el codigo en c de lo q tengo:
//Programa que realiza una conversion de un potenciometro
#include <16f877A.h>
#device adc=10
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
//wrt
#use delay (clock= 4000000)
#use rs232(BAUD=19200, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
void main() {
float const resoluc= 4.90/1024.00; //Resolución del convertidor (4.90 es la tension de alimentacion
//q se usa como referencia
float corriente= (2*4.90)/11400.00;
float tension; //Valor tension sacada
float valor; //Numero de pasos de la medida
float v_ohmico, v_ohmicom, v_ohmicot; //Valor ohmico del potenciometro
int i,j; //Indices que vamos a utilizar
setup_adc_ports (ALL_ANALOG); //Todas las entradas del covertidor son analogicas
setup_adc (ADC_CLOCK_INTERNAL); //Selecciono reloj interno del pic
for (;
{ //Bucle infinito
for (i= 0; i<4; i++) { //Hace las medidas alternando entre pot
v_ohmicom= 0;
v_ohmicot= 0;
putchar(i); //Envia el numero del canal q vamos a usar
set_adc_channel (i); //Elige el canal segun valor de i
for (j= 1; j<101; j++) { //Bucle que va obteniendo 100 valores de tension
delay_us(20); //Retardo para que de tiempo de cargarse el condensador del adc
valor= read_adc(); //Obtiene el valor del adc
tension= valor*resoluc; //Calcula la tension
v_ohmico= (2*tension)/corriente; //Calculo valor ohmico de los potenciometros
v_ohmicot= (v_ohmicot+v_ohmico); //Va sumando los valores ohmicos de los 100 datos
}
v_ohmicom= v_ohmicot/100; //Media del valor ohmico
printf ("%1.2f", v_ohmicom); //Saca a hyperterminal valor ohmico
delay_ms(20); //Retraso de 20ms y vuelta a empezar
}
}
}
Haber si podeis aclarme esa duda por favor.
Gracias
Un saludo
-
Hola:
Pues yo creo que debes avisar a Visual cuando has cambiado de canal, porque a visual lo que le llega es datos enviados del pic... por ejemplo si le envias algun caracter en especifico para indicar que canal estas utilizando Visual entenderia y mostraria los datos en el Text que corresponda....
-
Leete esto:
http://miarroba.com/foros/ver.php?foroid=64652&temaid=172512&pag=3
el usuario hhpp tenía un problema similar al tuyo, fijate las respuestas que le doy y seguí el hilo de el thread que te vas a dar cuenta como funciona el sistema que propuse. Cualquier cosa fijate en las páginas anteriores y posteriores del thread donde también hay otras explicaciones.
Espero que te sirve, probalo y seguimos conversando.
Salu2.
-
Bueno, ya lei todo el post y entiendo lo que tengo que hacer, el envio lo hago con una letra q me indica de que canal esta sacada esa lectura y lo termino con un retorno de carro, en hyperterminal obtengo:
A7.4521
B.4.2565
C.3.5478
D.10.1254
y otra vez a empezar. Pero aunq comprendo lo q tengo q hacer en vb, no se muy bien como hacerlo.
Se que tengo q hacer la comunicacion por eventos, cada vez q aparezca el retorno de carro, y luego de ese trozo de informacion quedarme con los datos y deshechar la letra. Como dije, he mirado el codigo q hay en ese post, lo entiendo, pero no se muy bien como aplicarlo luego para que en diferentes textbox o label´s salgan los datos.
Lo tengo ahi delante pero no doy con la tecla. Si me podeis ayudar un poco mas os lo agradeceria.
Gracias
Un saludo
-
Bueno pues ya esta, ya lo tengo. He hechos pruebas y con el siguiente codigo parece q funciona:
Option Explicit
Private buffer As String
Private canal As String
Private lectura As String
Private Sub Form_Load()
"Dim CommPort As String, Handshaking As String, Settings As String
"Dim buferentrada As String
MSComm1.CommPort = 1 "puerto com1
MSComm1.Settings = "19200,N,8,1"
MSComm1.InputLen = 0
MSComm1.RThreshold = 1
MSComm1.PortOpen = True
End Sub
Private Sub MSComm1_OnComm()
If MSComm1.InputLen > 8 Then
MSComm1.PortOpen = False
MSComm1.PortOpen = True
Exit Sub
End If
buffer = MSComm1.Input
If buffer = " " Then Exit Sub
canal = Left$(buffer, 1)
lectura = Mid$(buffer, 2, 7)
Select Case canal
Case "A"
LblPot1.Caption = lectura
Case "B"
LblPot2.Caption = lectura
Case "C"
LblPot3.Caption = lectura
Case "D"
LblPot4.Caption = lectura
End Select
End Sub
Private Sub cmdFinalizar_Click()
Hide
End Sub
Me he basado en lo q habia puesto en el otro post. Cogi un pokito de alli y otro de alla y parece q funciona.
Lo q si tengo q pedir es q alguien me confirme q este bien, o mejor, q me lo "depure" un poco. Sigo con problema de fluctuacion, tendre q poner un condensador de mas capacidad, pq ya hago la media de 100 valores.
Tengo q agradecer a Lordlafebre y a Colores2 su ayuda. Gracias
Un saludo
-
La fluctuacion en la lectura molesta bastante porque te hace llamar al evento OnComm constantemente. Esto puede ser por ruidos electromagneticos, fluctuaciones en la fuente de alimentación, etc.
Pero de cualquier manera no es deseable.
Solución 1:
Ponele un capacitor cerámico al potenciometro que querés medir, creo que 100nf te va a funcionar bien.
Solución 2:
Hacé en el pic una rutina que sólo envíe datos si el nuevo valor es diferente y sólo mayor al anterior en 1 o 2 unidades.
Ejemplo con un algoritmo:
Leer valor ADC y guardarlo en ADCvalor
Si ADCvalor <> ADCvalorAnterior y ADCvalor <> ADCvalorAnterior + 1 entonces
***Enviar ADCvalor
***ADCvalorAnterior = ADCvalor
Entonces esto es igual a decir que solo va a transmitir el dato si el valor es diferente en al menos una unidad. Por ejemplo si tenemos la secuencia:
232 - 233 - 236 - 236 - 237 - 236 - 250 solo va a transmitir:
232 - 236 - 250.
Con esto se solucionan la mayoría de los problemas de este tipo, si a esto le agregamos que vos usas una escala de 0 a 100 y para esto tenés que dividir por 2,54 se desprende que no perdés exactitud al ignorar una unidad de cambio en la escala de 255 del ADC (2,5 unidades del ADC corresponden a 1 en la escala 0-100)
La aplicación de las 2 soluciones me funcionaron perfectamente a mi.
Salu2.
-
Siento no haber podido contestar antes, pero ultimamente he tenido bastante trabajo. Bueno, el algoritmo lo entiendo, pero tengo problemas a la hora de implementarlo en C, y no se por que. Lo he probado con el Proteus, y el problema esta en q no envia nada por hyperterminal, te pego el codigo completo:
//Programa que realiza una conversion de un potenciometro
#include <16f877A.h>
#device adc=10
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
#use delay (clock= 4000000)
#use rs232(BAUD=19200, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
void main() {
float const resoluc= 5.00/1024.00; //Resoluci�n del convertidor (4.90 es la tension de alimentacion
//q se usa como referencia
float corriente= (2*5.00)/11400.00; //Cuidado aqui para medir la resistencia REAL, esto conlleva fallos
float tension, tensionm, tensiont; //Valor tension sacada
float valor[]; //Numero de pasos de la medida
float v_ohmico, v_ohmicom, v_ohmicot; //Valor ohmico del potenciometro
int m, j, k;
char canal, modo;
setup_adc_ports (ALL_ANALOG); //Todas las entradas del covertidor son analogicas
setup_adc (ADC_CLOCK_INTERNAL); //Selecciono reloj interno del pic
for (;
{
j= 0;
k= 0;
for (k= 0; k<2; k++) {
switch (k) {
case 0: modo= "a"; break;
case 1: modo= "b"; break;
}
for (j= 0; j<4; j++) {
valor[0]= 0;
tensionm= 0;
tensiont= 0;
v_ohmicom= 0;
v_ohmicot= 0;
set_adc_channel (j);
switch (j) {
case 0: canal= "A"; break;
case 1: canal= "B"; break;
case 2: canal= "C"; break;
case 3: canal= "D"; break;
}
for (m= 1; m<101; m++) { //Bucle que va obteniendo 100 valores de tension
delay_us(20); //Retardo para que de tiempo de cargarse el condensador del adc
valor[m]= read_adc(); //Obtiene el valor del adc
if ((valor[m]!=valor[m-1])&&(valor[m]!=valor[m-1]+1))
tension= valor[m]*resoluc; //Calcula la tension
v_ohmico= (2*tension)/corriente; //Calculo valor ohmico de los potenciometros
v_ohmicot= (v_ohmicot+v_ohmico); //Va sumando los valores ohmicos de los 100 datos
tensiont= (tensiont+tension);
}
v_ohmicom= v_ohmicot/100; //Media del valor ohmico
tensionm= tensiont/100;
if (modo="a")
printf ("%c%c%1.2f
",modo, canal, tensionm);
if (modo= "b")
printf ("%c%c%1.2f
", modo, canal, v_ohmicom);
delay_ms(20); //Retraso de 20ms y vuelta a empezar
}
}
}
}
Creo q esta bien implementado en c tu algoritmo, creo q deberia funcionar. Espero vuestra ayuda.
Muchas gracias
Un saludo
-
Me parece que te olvidas de mandar el valor de la variable tensión por el RS232 (transmirtir) puede ser?
-
Hola,
No creo q sea por eso, pq envia perfectamente sin el "if" q me dijiste. Ademas envia a al puerto serie por el "printf" asi q eso no creo q sea. Tiene q haber algun problema con la variable valor[], q este mal definido el array o algo asi, no lo se. La verdad es q creo q esta bien declarada, y en teoria de beria funcionar, no lo se. Haber si alguien sabe q puede ser, pq yo la verdad no se q pasa.
Muchas gracias colores2 por tu ayuda, gracias.
Un saludo