TODOPIC

Misceláneas - Interés General => Off Topic => Mensaje iniciado por: gera en 18 de Mayo de 2009, 23:49:35

Título: programa para graficar señales [pedido]
Publicado por: gera en 18 de Mayo de 2009, 23:49:35
Buenas amigos!!!
Alguien conoce algun programa simple para graficar señales en tiempo real q entren por el puerto serie (o usb cdc)?? preferentemente en linux, pero si no no importa.
Se que podria usar matlab o labview, pero son programas pesadisimos y q requieren algo de conocimiento, el cual no tengo :(
Lo necesito para ver la señal de un acelerometro.
Muchas gracias!!!
Título: Re: programa para graficar señales [pedido]
Publicado por: alexysar en 19 de Mayo de 2009, 11:39:33
En linux lo más facil ( aunque trabajoso), es hacerte la aplicación vos. Lo podes hacer en los lenguajes tipicos de linux como C ó Perl

En c una idea que se me ocurre, es algo asi:

Código: C
  1. main()
  2. {
  3. fd=open("\dev\tty",RD_ONLY);
  4.  
  5. do{
  6.         n=read(fd,bufer_serie,1);
  7.        
  8.         graficar(bufer_serie);
  9.  
  10.         }while(*bufer_serie!=EOF);
  11.  
  12.  
  13. }

fijate que es sencillo leer el puerto serie, ahora lo más dificil viene a la hora de graficar. Una función sencilla que se me ocurre, aunque no gráfica, imprime en la consola el valor del puerto seria asi:

Código: C
  1. void graficar(char *bufer_serie)
  2. {
  3. printf("%x ",bufer_serie[0]);
  4. }

Si vos lo queres graficar en tiempo real, si o si, podes usar x-cursore para graficar en una consola. Este tema lo explican en la guia GULP de linux para C que se consigue en internet.
Otra opción aunque no es en tiempo real seria mandar todo el bufer a un archivo y luego graficarlo con openoffice planilla de calculos, con el diagrama de barras por ej.

Algo mucho más facil e inmediato es bajarte el free-serial-port-monitor que se consigue en internet pero no es para linux (que yo sepa). Esta aplicación no grafica pero te muestra los datos que ingresan por el puerto serie en hexa ( algo parecido a la idea de la función que te pase de linux). Si no es en tiempo real, podes graficarlas con Excel.

Lo más profesional, como vos decis, es  Matlab. Seguramente hay otras aplicaciones comerciales que hagan lo mismo pero es mejor aprender Matlab ( no es tan dificil como parece) y tine aplicaciones muy diversas en ingenieria.

Nota: El programa que te pase es solo una idea, ni siquiera probe si compila( de hecho no compila porque no puse ni los includes, ni la iniciación de variables), pero te sirve para seguir la idea.
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 19 de Mayo de 2009, 12:44:53
Gracias alexysar!!!
Tendria q ver si puedo hacer una llamada a gnuplot para q me grafique los datos q voy recolectando... pero dudo q pueda hacerlo en tiempo real ya q le tengo q pasar como parametro una funcion o un archivo entero.
Me parece q lo mas facil por ahora es entrarle al matlab. Pasa q el profe q nos dio eso el año pasado no se lucio mucho y bueh... pero no es nada q un buen tutorial o guia no pueda resolver jaja.
saludos!!
Título: Re: programa para graficar señales [pedido]
Publicado por: cerebro en 19 de Mayo de 2009, 13:27:27
 :?....
Esta bueno utilizar Matlab si vas a procesar los datos en la pc si vos querés visualizarlo a pesar de ser muy fácil de utilizar yo optaría por hacer mi propia aplicación.
yo lo he realizado con builder (borland c++) para eso utilice
http://www.activexperts.com/activcomport/
pegale una hojeada  ;-)
Título: Re: programa para graficar señales [pedido]
Publicado por: IAO en 24 de Mayo de 2009, 08:44:54
Hola....

Mira yo conseguí uno que se llama DynaPlot3, te digo que funciona bien
pero hay que saber como llamar sus funciones que me enredó un poco.

Es un .ocx, trae ejemplos VB6, .Net, C#, Delphi, VC6 y otros.....

Espero te sirva....
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 31 de Mayo de 2012, 21:04:08
Hola Gera! Conseguiste programa para graficar las señales del puerto serie?

Yo consegui un programita de parallax que grafica en una planillla de excel, pero no logro que me funcione en windows 7.

Necesitaría usar un programita para ajustar las mediciones que estoy haciendo con un giróscopo y un acelerómetro.

Título: Re: programa para graficar señales [pedido]
Publicado por: rivale en 31 de Mayo de 2012, 22:26:56
marito, porque no usas la terminal "octopus" del amigo LAbmouse

http://www.todopic.com.ar/foros/index.php?topic=38196.0 (http://www.todopic.com.ar/foros/index.php?topic=38196.0)
http://www.todopic.com.ar/foros/index.php?topic=35482.0 (http://www.todopic.com.ar/foros/index.php?topic=35482.0)
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 31 de Mayo de 2012, 23:25:21
Marito, al final me hice yo mismo un programita en processing. Tengo dos, uno que grafica la curva en funcion del tiempo, y otro que grafica la inclinacion mostrando unos rectangulos.
Si sabes usar processing, puedo mandarte los sketchs.
Saludos!!
Título: Re: programa para graficar señales [pedido]
Publicado por: rivale en 31 de Mayo de 2012, 23:29:48
Con permiso de Gera, te pongo el programa que hizo ;-)
http://www.todopic.com.ar/foros/index.php?topic=35513.msg295919#msg295919 (http://www.todopic.com.ar/foros/index.php?topic=35513.msg295919#msg295919).

creo que te serviria para probar tu filtrado del angulo
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 01 de Junio de 2012, 09:15:01
Rivale, Gera muchas gracias por sus respuestas!

Rivale, en el octoplus se pueden graficar flotantes? porque estaba leyendo que recibe datos de 8 bits.

Gera, estoy buscando información a ver si me pongo a aprender processing. De igual manera tengo que focalizar en la medición con el giro y el acelerómetro, pero voy a ir viendo algo
Título: Re: programa para graficar señales [pedido]
Publicado por: rivale en 01 de Junio de 2012, 11:40:49
solo acepta variables de 8 bits, pero quizas podrias escalar tu angulo para que 0 sea el angulo menor y 255 sea el angulo mayor
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 01 de Junio de 2012, 11:57:27
creo que perdería resolución.

Estoy viendo el otro link con el terminal echo en labview, creo que ese permite flotantes y voy a poder hacer un ajuste más fino. Usaste ese programita?
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 01 de Junio de 2012, 12:21:27
Labview es una muy buena opcion. Yo opte por processing porque soy usuario de linux.
Processing es muy facil de usar, si sabes Java (o C en su defecto) te va a resultar muy familiar el lenguaje. Te podes bajar el IDE/compilador de processing.org. No hace falta instalacion ni nada. Esta es una version vieja del programa que uso para calibrar los sensores:

Recibe tres numeros (flotantes o enteros) separados por coma con un salto de linea al final. Tambien tengo un programa que grafica las 3 curvas en el tiempo.
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 01 de Junio de 2012, 12:41:04
Buenísimo esa aplicación! Voy a descargar el processing.

Me podrías enviar la aplicación? Así empiezo con esa a modo de ejemplo

P.D. que señal usaste para el robot??? La azul!!!???
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 02 de Junio de 2012, 13:02:23
Hola Gera!

Ya estoy usando el processing. Lo que quiero hacer es recibir señales del puerto serie. El tipo de datos es flotante, pero para comenzar estoy mandando un entero. Leyendo el dato desde un terminal, el dato llega de manera correcta, pero en el processing no puedo leer el dato. El código de mi sketch es el que sigue:

Código: [Seleccionar]
import processing.serial.*;
Serial puerto;
int dato;

void setup() {
   puerto = new Serial(this, Serial.list()[0], 56000);
   
}

void serialEvent(Serial puerto)
{
 dato = puerto.read();
 }



void draw(){
 
println(dato);

}

En el terminal recibo el dato 171, pero en el processing leo el dato 32. Cual puede ser mi problema?
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 02 de Junio de 2012, 14:16:28
Marito, lo que pasa es q por el puerto serie tenes q enviar el dato codificado en ascii como una cadena, luego en processing lo lees y lo convertis al tipo de dato q quieras (entero, flotante..).
Te paso mi programa en processing:
Código: [Seleccionar]
import processing.serial.*;
Serial myPort;  // The serial port

float acc_angle=0;
float gyro_angle=0;
float angle=0;

void setup()
{
  size(650,300);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  myPort.write("m\r");
}


void draw ()
{
  while (myPort.available() > 0)
  {
    String recibido = myPort.readStringUntil('\n');
    if (recibido != null)
    {
      float[] val = float(split(recibido,","));
      drawGraph(val);
    }
  }
}

void drawGraph(float[] val)
{
  float x_acc = (val[0]-513)/97;
  float y_acc = (val[1]-500)/105;
  float z_acc = -(val[2]-511)/103;
  float gyro = -(val[3]-455)/67; //*0.015;
  float dt=0.1;
 
  acc_angle = atan(z_acc/y_acc);
  gyro_angle += gyro * dt;
 
  angle = (0.95)*(angle + gyro * dt) + (0.05)*(acc_angle);

 
  stroke(0);
  background(255);
  rectMode(CENTER);
  textSize(14);
 
  pushMatrix();
    fill(255,100,100);
    translate(100, 200);
    text("acc angle = " + degrees(acc_angle) + "º" ,-90,-100);
    rotate(acc_angle);
    rect(0, 0, 100, 30);
  popMatrix();

  pushMatrix();
    fill(100,255,100);
    translate(300, 200);
    text("gyro angle = " + degrees(gyro_angle) + "º" ,-90,-100);
    rotate(gyro_angle);
    rect(0, 0, 100, 30);
  popMatrix();

  pushMatrix();
    fill(100,100,255);
    translate(500, 200);
    text("filtered angle = " + degrees(angle) + "º" ,-90,-100);
    rotate(angle);
    rect(0, 0, 100, 30);
  popMatrix();
 

  /*strokeWeight(10);
  line(width/2 , height/2 +100, width/2 + v.x , height/2 + v.y +100);*/
}

En el pic tengo un programa que envia las lecturas del acelerometro y gyro sin procesar en este formato:
Código: [Seleccionar]
printf("%li,%li,%li,%li,%li,\n",val[0],val[1],val[2],val[3],val[4]);
Estoy mandando 5 enteros porq el ADC convierte a valores enteros, pero podes enviar flotantes tranquilamente, fijate en el codigo de processing que convierte todo a flotante en esta linea:
Código: [Seleccionar]
float[] val = float(split(recibido,","));
Aca va otro programa similar, pero que grafica en funcion del tiempo:
Código: [Seleccionar]
import processing.serial.*;
Serial myPort;  // The serial port
int i = 0;      // counter


void setup()
{
  size(800, 600);       
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600); // Serial.list()[0] modify that number if don't works
  background(255,255,255);
 
  //myPort.write(83);
}


void draw ()
{
  while (myPort.available() > 0)
  {
    String a0 = myPort.readStringUntil('\n');
   
    if (a0!=null)
    {
      float[] val = float(split (a0, ","));
      //println (val[0] + "," + val[1] + "," + val[2]);
      drawGraph_accel(val[0]*100,val[1]*100,val[2]*100);  //100 is a scale factor
    }
  }
}

void drawGraph_accel (float d_ax, float d_vx, float d_px)
{
  stroke(255,0,0,70);
  line(i, height/4, i, height/4 - d_ax);
  stroke(0,0,255,70);
  line(i, height/4*2, i, height/4*2 - d_vx);
  stroke(0,255,0,70);
  line(i, height/4*3, i, height/4*3 - d_px);
 
  if (i >= width-2)
  {
    i = 0;
    background(255,255,255);
  }
  else
  {
    i++;
  }
}

Podes modificar el programa a tu gusto para q se adapte a tus necesidades. cualquier duda avisame.
Saludos!
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 02 de Junio de 2012, 19:34:06
Gera muchas gracias por tu excelente explicación!

El %Li es para transmitir valores enteros en acsii?

Como haces la conversión de entero o flotante a acsii?

Como se definen variables acsii?
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 02 de Junio de 2012, 20:17:56
Marito, el printf se encarga de convertir los valores. %li es para imprimir enteros largos (long int). Si la variable que queres imprimir es un flotante, tenes que usar %f.
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 03 de Junio de 2012, 11:10:18
Ah! Para enteros largos yo tengo que usar %lu, enteros %u y flotantes %f.

Para la prueba que estoy haciendo, estoy enviando un entero (%u) ya que por lo que leí en la ayuda de processing, se reciben enteros (16bits - 0..255) desde el puerto serie. Pero enviando el entero 171 desde mi pic con la instrucción:

Código: [Seleccionar]
printf(" %u ", datoentero);
Recibo un 32 en el processing con el comando

 
Código: [Seleccionar]
dato = puerto.read();

Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 03 de Junio de 2012, 13:19:39
Es que lo estas leyendo mal.  Lo que hace read() es leer un solo caracter, cuando tu dato tiene 3 caracteres. Ademas lee ese dato como un entero, y tendrias q leerlo como cadena. La funcion que tenes q usar es readStringUntil().
Aca te dejo la referencia de ambas:
http://processing.org/reference/libraries/serial/Serial_read_.html
http://processing.org/reference/libraries/serial/Serial_readStringUntil_.html

En tu cadena tenes q poner un salto de linea al final (un punto o algo), entonces a readStringUntil() le pasa como parametro ese caracter para que sepa que ahi termina el dato. En el pic haces:
Código: [Seleccionar]
printf("%u\n",datoentero);
Y en processing
Código: [Seleccionar]
String myString = null;
...
myString = myPort.readStringUntil(lf);

Saludos!
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 04 de Junio de 2012, 21:10:03
Buenísimo Gera! Ya estoy recibiendo un entero!

Tenía que usar, tal como me dijiste, la sentencia ReadUntilString.

Muchas gracias! Ahora voy a trabajar para recibir flotantes para enviar los ángulos medidos por el giro y el acelerómetro.
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 05 de Junio de 2012, 08:48:00
Gera para enviar un número flotante tengo que hacer la conversión a doble entero (long Int) en el PIC antes de enviarlo?
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 05 de Junio de 2012, 13:00:32
Para enviar un flotante tenes que cambiar el printf nomas. Por ej:

Código: [Seleccionar]
float var1=3.14, var2=5.2, var3=6.4;
printf("%f,%f,%f,\n",var1,var2,var3);

Acordate que vos estas enviando una cadena (texto) por el puerto serie, no el numero. Por lo tanto podes enviar cualquier tipo de dato, que luego processing lo transforma a flotante.
Saludos!
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 05 de Junio de 2012, 13:07:35
Hola Gera;

He intentado enviar flotantes con el %f en el printf, pero me genera un error cuando intento cargarlo en una variable en el processing con el comando:

Código: [Seleccionar]
float[] val = float(split (a0, "\n"));

No tengo el proyecto ahora, pero en un rato lo conecto y te digo cual es el error
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 06 de Junio de 2012, 09:14:08
Hola Gera!

El problema estaba en processing. Use el sketch que me pasaste con algunas modificaciones y comenzó a trabajar muy bien!

Una de las modificaciones que hice fue la velocidad de comunicación, uso 56000 mbps. Lo que me pasa ahora es que se pone lenta el refresco de las señales que me manda el PIC. Puede ser que se "atore" a esta velocidad de transmisión?
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 06 de Junio de 2012, 12:50:36
Yo estoy utilizando 115200 baudios en la comunicacion y me funciona bastante bien. No creo que haya un cuello de botella ahi, es una velocidad bastante alta como para que la puedas percibir visualmente. Tal vez tenes tu pc muy cargada y lo que se esta demorando es el refresco de la imagen.
Si te queres sacar la duda, podes poner en el micro un timer que mida el tiempo entre una trasmision y la otra, y asi vas a ver que tan rapida es la trasmision.
Saludos!
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 06 de Junio de 2012, 12:58:46
Lo que estoy midiendo actualmente es el tiempo de ciclo de ejecución de programa, dentro de cual tengo la transmisión de datos, que es de 5mseg aproximadamente.


Voy a probar cerrar todos los programas y ejecutar solo el processing. Lo que me resulta raro es que un terminal común recibe los datos a gran velocidad, pero puede ser que al estar graficando necesite mayor cantidad de recursos
Título: Re: programa para graficar señales [pedido]
Publicado por: marito en 07 de Junio de 2012, 23:21:15
Gera probe con comunicación a 56000 y 9600 baudios y me da el siguiente error luego de unos segundos:

Código: [Seleccionar]
Exception in thread "Animation Thread" java.lang.ArrayIndexOutOfBoundsException: 1
at Medicion_angulo.drawGraph(Medicion_angulo.java:53)
at Medicion_angulo.draw(Medicion_angulo.java:46)
at processing.core.PApplet.handleDraw(Unknown Source)
at processing.core.PApplet.run(Unknown Source)
at java.lang.Thread.run(Thread.java:662)

 Desde el PIC mando las mediciones del acelerómetro y giróscopo en flotante, expresado en grados.

Código: [Seleccionar]
printf("%f, %f, \r",anggrad,angacelgrad); //imprimo datos por puerto serie
El sketch lo modifique y quedo como lo pongo a continuación:

Código: [Seleccionar]
import processing.serial.*;
Serial myPort;  // The serial port

float acc_angle=0;
float gyro_angle=0;
float angle=0;

void setup()
{
  size(650,300);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 56000);
  myPort.write("m\r");
}


void draw ()
{
  while (myPort.available() > 0)
  {
    String recibido = myPort.readStringUntil('\n');
    if (recibido != null)
    {
      float[] val = float(split(recibido,","));
      drawGraph(val);
    }
  }
}

void drawGraph(float[] val)
{
 acc_angle = ((val[1])*PI/180.0);
 gyro_angle = ((val[0])*PI/180.0);
 
 
  stroke(0);
  background(255);
  rectMode(CENTER);
  textSize(14);
 
  pushMatrix();
    fill(255,100,100);
    translate(100, 200);
    text("acc angle = " + degrees(acc_angle) + "º" ,-90,-100);
    rotate(acc_angle);
    rect(0, 0, 100, 30);
  popMatrix();

  pushMatrix();
    fill(100,255,100);
    translate(300, 200);
    text("gyro angle = " + degrees(gyro_angle) + "º" ,-90,-100);
    rotate(gyro_angle);
    rect(0, 0, 100, 30);
  popMatrix();

  pushMatrix();
    fill(100,100,255);
    translate(500, 200);
    text("filtered angle = " + degrees(angle) + "º" ,-90,-100);
    rotate(angle);
    rect(0, 0, 100, 30);
  popMatrix();


Se te ocurre alguna idea de cual puede ser el problema?

Saludos!!!
Título: Re: programa para graficar señales [pedido]
Publicado por: gera en 07 de Junio de 2012, 23:46:00
Código: [Seleccionar]
printf("%f, %f, \r",anggrad,angacelgrad); //imprimo datos por puerto serie

Ese printf deberia ser:
Código: [Seleccionar]
printf("%f,%f,\n",anggrad,angacelgrad);
Sin los espacios y con un salto de linea (\n) al final. Tambien fijate que antes de empezar a graficar, processing envia una letra 'm' por el puerto serie. Eso sirve para sincronizar el pic con processing. Dejas al pic esperando a q reciba esa 'm' antes de empezar a mandar los datos. Por ej:

Código: [Seleccionar]
while(getc() != 'm');
...resto del codigo