Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 06-08-2021
Franciscogc1988 Franciscogc1988 is offline
Registrado
 
Registrado: ago 2021
Posts: 6
Poder: 0
Franciscogc1988 Va por buen camino
Exclamation ComPort RxChar, Delphi vs Arduino (byte de lectura)

Buenas noches,
estoy programando un modulo MPU6050 para calcular los ángulos de giro en e pilotaje de una avión RC,

Ya tengo el código generado en Arduino y me devuelve correctamente en el monitor serie,
respecto a Delphi, estoy intentando leer los valores a través de las librerías comport y imprimir en un memo, el problema es que no recibo correctamente la cadena de texto, se come caracteres.

he estado indagando y debe tener alguna relacion con la velocidad de lectura de los bytes, al aumentar los BaudRate, parece que mejora, pero aun poniéndolos al máximo, sigue generando problemas.

he intentado también ponerle un sleep(70) después de la impresión en el memo, para darle tiempo a leer la cadena entera al buffer, pero sigue sin ser la solución definitiva., alguna sugerencia?

Codigo arduino:
Cita:
#include <I2Cdev.h>
#include <helper_3dmath.h>
#include <MPU6050.h>
#include <Wire.h>

const int mpuAddress = 0x68; // Puede ser 0x68 o 0x69
MPU6050 mpu(mpuAddress);
int ax, ay, az;
int gx, gy, gz;
void setup()
{
Serial.begin(9600);
Wire.begin();
mpu.initialize();
Serial.println(mpu.testConnection() ? F("IMU iniciado correctamente") : F("Error al iniciar IMU"));
}
void loop()
{
// Leer las aceleraciones
mpu.getAcceleration(&ax, &ay, &az);
//Calcular los angulos de inclinacion
float accel_ang_x = atan(ax / sqrt(pow(ay, 2) + pow(az, 2)))*(180.0 / 3.14);
float accel_ang_y = atan(ay / sqrt(pow(ax, 2) + pow(az, 2)))*(180.0 / 3.14);
//Mostrar resultados
Serial.print(("X:"));
Serial.print(accel_ang_x);
Serial.print(("/"));
Serial.print(("Y:"));
Serial.println(accel_ang_y);
delay(100);
}
ejemplo resultado monitor serie arduino:
X:32.60/Y:-6.03
X:32.75/Y:-6.18
X:32.63/Y:-6.15
X:32.81/Y:-5.93


Codigo Delphi:
Cita:
procedure TForm1.Button1Click(Sender: TObject);
begin
comport1.Port:='COM3';
comport1.BaudRate:=br9600;
try
comport1.Open;
if comport1.Connected then
begin
memo1.Text:=memo1.Text+'conexion serial establecida con exito('+comport1.Port+')';
memo1.Lines.Add('');
end
else
begin
memo1.Text:=memo1.Text+'ERROR en conexion serial';
end;
finally
end;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
comport1.Close;
memo1.Text:=memo1.Text+'conexion cerrada';
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
comport1.ShowSetupDialog;
end;

procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
Str: String;
begin
// Recibe mensajes desde Arduino.
ComPort1.ReadStr(Str, comport1.InputCount);
sleep(70);
// Muestra los mensaj,es en pantalla.
MEMO1.Lines.Add( Str );
end;
ejemplo resultado memo Delphi:

X:32
.88/Y:-6.01

X:3
2.76/Y:-5.85

X
:32.80/Y:-6.14

X:32
.69/Y:-6.28

X:
32.89/Y:-5.91




Agradecido x la ayuda!
Responder Con Cita
  #2  
Antiguo 06-08-2021
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is online now
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.286
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
En estos casos siempre recomiendo realizar la lectura primero con el HyperTerminal de windows.
De esta manera descartas problemas con librerías y te permite realizar diferentes configuraciones del puerto (velocidad,...).

Una vez que con el HyperTerminal leas los valores de forma correcta, puedes pasar a Delphi.
Si buscas en los foros encontrarás hilos que hablan de cómo trabajar con HT y cómo configurarlo, si no lo has hecho nunca.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.

Última edición por Neftali [Germán.Estévez] fecha: 06-08-2021 a las 10:00:36.
Responder Con Cita
  #3  
Antiguo 06-08-2021
Franciscogc1988 Franciscogc1988 is offline
Registrado
 
Registrado: ago 2021
Posts: 6
Poder: 0
Franciscogc1988 Va por buen camino
Cita:
Empezado por Neftali [Germán.Estévez] Ver Mensaje
En estos casos siempre recomiendo realizar la lectura primero con el HyperTerminal de windows.
De esta manera descartas problemas con librerías y te permite realizar diferentes configuraciones del puerto (velocidad,...).

Una vez que con el HyperTerminal leas los valores de forma correcta, puedes pasar a Delphi.
Si buscas en los foros encontrarás hilos que hablan de cómo trabajar con HT y cómo configurarlo, si no lo has hecho nunca.

Muchas Gracias por tu respuesta Neftali, he probado la lectura desde la HyperTerminal y lee y imprime correctamente los datos, igual que desde el terminal de arduino.
Definitivamente y por la forma de imprimir en el Memo de Delphi, deduzco que la lectura de delphi corre más rápida que el envío desde el comport, por eso imprime las string a trozos.

sinceramente me encuentro algo bloqueado, alguna sugerencia?
Responder Con Cita
  #4  
Antiguo 09-08-2021
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is online now
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.286
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Una vez que sabes que desde HyperTerminal la lectura es correcta y por lo tanto tienes los parámetros de confiiguración, ahora puedes probar con la misma configuración dede Delphi, e incluso hacer la prueba con varios componentes, no sea que el que estás probando tenga algun bug.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 09-08-2021
Franciscogc1988 Franciscogc1988 is offline
Registrado
 
Registrado: ago 2021
Posts: 6
Poder: 0
Franciscogc1988 Va por buen camino
Buenas, como me dijiste probé con la HyperTerminal y configure las mismas propiedades en delphi.
para comprobar que no fuera un defecto del componente he realizado una prueba simplemente haciendo un ping en bucle cada 1 seg a la arduino uno y a su vez escribiendo un texto en la terminal, en la hyperterminal funciona también correctamente, pero Delphi sigue comiéndose caracteres.

los parámetros que utilizo son:
*COM3
*9600 Bits x segundo
*8 bits de datos
*ninguna paridad
*1 bits de parada
*ningún control de flujo

crees que hay algún otro parámetro que no este teniendo en cuenta?
como explique en el primer post cuando aumento los bits x segundo (BaudRates), poniéndolos al valor máximo, parece que mejora, pero sigue sin leer del todo correctamente.

según parece, con la configuración que te he detallado, cuando el componente envía una string "hello world", Delphi imprime sin acabar de recibir la cadena completa y a su vez acumula el resto de caracteres en la memoria para la siguiente impresión, de esta forma imprime el texto así:

"hell
o wor
ld"

es decir, la función ComPort1RxChar se ejecuta nuevamente sin finalizar la lectura, alguna idea de como poder corregir este procedimiento?

también podría estar relacionado con el buffer, actualmente tengo 1024 inputsize y 1024 outputsize..
Responder Con Cita
  #6  
Antiguo 09-08-2021
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por Franciscogc1988 Ver Mensaje
....
es decir, la función ComPort1RxChar se ejecuta nuevamente sin finalizar la lectura, alguna idea de como poder corregir este procedimiento?

también podría estar relacionado con el buffer, actualmente tengo 1024 inputsize y 1024 outputsize..
Como en todo protocolo de comunicación, necesitas incluir el caracter de terminación de la cadena, en algunos protocolos requieren de un inicio de texto y termino de texto, aunque asumo que en tu caso es muy básico y debes leer hasta que te llegue el caracter "End of Text" o "Carrier Return" y no solo hasta finalizar una lectura ya que como te está pasando te gana el evento RxChar del comport.

Saludos
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #7  
Antiguo 10-08-2021
Franciscogc1988 Franciscogc1988 is offline
Registrado
 
Registrado: ago 2021
Posts: 6
Poder: 0
Franciscogc1988 Va por buen camino
Buenas egostar, gracias x tu aporte.

Ante todo comentar que tambien realice una prueba con la terminal de la librería COM y he observado que las terminales concatenan la información de la lectura por lo que la solución para obtener un memo como terminal es tan sencilla como concatenar el mismo memo: memo.text:=memo.text+STR,

actualmente en el proyecto tengo hecho un Blink a un led, cada segundo enciende/apaga un led y envía la string LED ON / LED OFF, el objetivo es poder recoger la string exacta "LED ON" y trasladarla a un label

según tu aporte estuve indagando y la libreria de Comport tine unas propiedades llamadas EofChar y EventChar he estado haciendo varias pruebas pero no he conseguido integrarlos.
también probé con el componente ComDataPacket, dispone de dos propiedades llamadas StartString y Sopstring tambien sin éxito..

alguno podría guiarme sobre como establecer el final de la cadena?
Responder Con Cita
  #8  
Antiguo 11-08-2021
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.557
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por Franciscogc1988 Ver Mensaje
Buenas egostar, gracias x tu aporte....

Hola, intenta con esto:

Código Delphi [-]
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
  Str: String;
begin
  ComPort1.ReadStr(Str, Count);  
  Memo1.Text := Memo1.Text + Str;
end;

Saludos
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #9  
Antiguo 11-08-2021
Franciscogc1988 Franciscogc1988 is offline
Registrado
 
Registrado: ago 2021
Posts: 6
Poder: 0
Franciscogc1988 Va por buen camino
La solución temporal que realizado ha sido agregar un condicional de escritura y gestionar la petición de los datos desde un timer en delphi,

de esta forma cuando delphi envia un "ok" al puerto COM arduino envia los angulos del giroscopio:

codigo arduino
Cita:
void loop(){

while (Serial.available() > 0){
caracter = Serial.read();
comando.concat(caracter);
delay(10);
}

// Si los carácteres es recibido y verdadero.
if (comando.equals("ok") == true) {
Serial.print (accel_ang_x);
Serial.print("/");
Serial.print(accel_ang_y);
}

// Limpiamos la cadena para volver a recibir el siguiente comando.
comando = "";
}
desde delphi, el timer envia un "ok" al puerto COM, y lee los datos con el RXChar para guardarlos en un Label, con Label1:=Label1+srt,

Codigo Delphi:
Cita:
procedure TForm1.Button1Click(Sender: TObject);
begin
comport1.Open;
if timer1.Enabled=false then
begin
timer1.Enabled:=true;
end
else
begin
timer1.Enabled:=false;
end;
end;

procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
Str: String;
begin
// Recibe mensajes desde Arduino.
ComPort1.ReadStr(Str, Count);
// Muestra los mensajes en pantalla.
label1.Text:=label1.Text+str;
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
comport1.Port:='COM3';
comport1.BaudRate:=br115200;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comport1.Close;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

label1.text:='';
ComPort1.WriteStr('ok'); // Envía el comando "ok" al puerto.

end;

Gracias a todos x los consejos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Delphi y Arduino REHome OOP 3 14-07-2017 14:14:42
Kit Arduino para Delphi K-ba ASM y Microcontroladores 9 25-03-2017 16:58:01
Cual es el equivalente de C# byte[] buffer = new byte[256]; para delphi? yatzenco Varios 1 20-01-2016 17:56:34
Leer byte a byte un fichero binario NPIdea C++ Builder 2 22-03-2012 16:36:34
ADO: Byte nulo (byte #0) en un string Pandre Conexión con bases de datos 0 02-04-2004 20:18:37


La franja horaria es GMT +2. Ahora son las 08:37:41.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi