Geek Electrónica

Explicaciones, tutoriales y noticias sobre electrónica y tecnología en general

ArduinoElectrónica DigitalMATLABMicrocontroladores

RECEPCIÓN DE DATOS SERIAL Y GRAFICACIÓN EN MATLAB

La comunicación entre un circuito electrónico y un equipo de computo es una practica muy común para recopilar o graficar datos.  Esta practica generalmente se realiza por una recepción de datos mediante un protocolo serial. En la practica que les presentamos en esta entrada se realiza una comunicación serial entre un arduino (Puede ser cualquier otra tarjeta con comunicación serial) y un computador para recibir los datos en MATLAB y realizar una grafica de estos datos capturados.

Lo primero que se necesita para realizar esta práctica es escribir el programa (Sketch) de arduino, en este programa se debe:

  • Configurar la comunicación serial.
  • Tomar un dato por uno de los canales análogos de arduino.
  • Enviar el dato por protocolo serial.
  • Dependiendo de la velocidad de muestreo que se requiera es necesario hacer un retardo en el programa.
Las líneas de programación del sketch para este proyecto se pueden ver a continuación.
 
Como se puede apreciar el programa que se realizo en arduino contiene muy pocas líneas, esto se hizo con el único fin de reducir la cantidad de procesos que debe realizar el arduino y con esto tener un poco mas de confianza al tener que determinar la velocidad de muestreo utilizada, aunque no va a ser exacta por la cantidad de procesos internos que lleva a cabo el microcontrolador si se puede aproximar la velocidad de muestreo al tiempo de retardo que se da entre cada muestra tomada.
 
El programa en MATLAB consta de una función que recibe el numero de muestras que el programa va a tomar para hacer la gráfica en el mismo instante que va recibiendo los datos desde la tarjeta de arduino. A continuación se van a mostrar y explicar partes de la función escrita en MATLAB:
 


Se declara la función con el nombre ADC_Serial y entre los paréntesis el nombre de la variable que va a recibir el número de muestras que el usuario requiere tomar. Esta función luego será llamada desde el Command Window de MATLAB con el nombre de la función y el número de muestras a tomar, por ejemplo para tomar 500 muestras se debería escribir lo siguiente:

 
 
En las siguientes líneas lo que se hace es borrar cualquier rastro anterior que quede en el puerto COM que se vaya a utilizar, esto se hace borrando por completo el puerto, luego se vuelve a crear un nuevo puerto COM, se declara la velocidad en baudios a la que se va a realizar la comunicación y por último se abre ese puerto que se acaba de crear.
Es importante tener en cuenta que el nombre del puerto depende de cómo lo haya nombrado su computador al momento de conectar la tarjeta arduino, si quieren revisar lo pueden hacer desde el administrador de dispositivos de su computador y luego buscar puertos COM y LPT.
En las siguientes líneas lo que se hace es configurar la ventana en la cual se va a mostrar la grafica resultado, por lo tanto se le da un nombre a la ventana, títulos tanto de la gráfica como de los ejes, entre otros parámetros.
Lo siguiente es crear un ciclo con el cual se van a ir tomando una a una las muestras enviadas por el arduino, además de eso se hace la conversión del valor entregado por el ADC de arduino a un valor de voltaje y por último se realiza la grafica del voltaje.
 
El método utilizado para graficar y que se acaba de mostrar en las líneas anteriores puede llegar a ser nocivo cuando se requieren tomar un número demasiado elevado de muestras, esto es debido a que al estar tomando datos y graficando cada una de esas muestras en cada ingreso al ciclo, se puede crear una sobrecarga del equipo y puede empezar a mostrar fallos. Por lo tanto si no desean mostrar la grafica “En tiempo real” si no que prefieren primero tomar todos los datos y luego de terminar este proceso si graficar, pueden eliminar del ciclo la línea que grafica la señal y la pueden colocar fuera del ciclo justo al terminar este.
 

Lo último que se hace dentro de esta función creada en MATLAB es cerrar y borrar el puerto mediante los comandos fclose y delete tal como se puede ver a continuación.

Al final de la publicación pueden encontrar el enlace para la descarga de todos los archivos correspondientes a esta explicación.
 
El resultado de esta práctica lo pueden observar a continuación.

Graficar dos  señales


Hasta el momento solo se ha mostrado y explicado como graficar una sola señal enviada desde un dispositivo electrónico (Arduino, Pic, Psoc, etc) hacia el computador, ¿Pero qué pasa cuando se requiere graficar más de una señal?, ¿Qué hay que cambiar en el código para graficar mas señales?
 
A continuación se va a mostrar el procedimiento para poder graficar dos señales, procedimiento que en realidad es muy sencillo y que bastará solamente con modificar una de las líneas del código que ya se ha explicado anteriormente y agregar un par de ciclos.
 
El comando que se encarga de tomar los datos enviados desde el dispositivo externo es el fscanf, con este comando se puede tomar más de un dato a la vez, por lo tanto la línea de código en la que se encuentra este comando es la que se va a tener que modificar para poder recibir datos de mas señales y posteriormente poder graficar más de una señal.

Hasta ahora la línea de código se encuentra como se observa en la siguiente imagen:
 
 
El comando fscanf recibe como parámetros el puerto por el que se van a recibir los datos y el tipo de datos que va a recibir, para este caso el ‘%d’ significa que va a recibir un dato de tipo entero, entonces lo que habría que hacer es indicarle a MATLAB que se va a recibir otro dato y su respectivo tipo, por lo tanto si se quieren recibir dos datos enteros la línea de código quedaría como a se muestra a continuación.
 
 
Al escribir ‘%d%d’ se indica que se van a recibir dos datos de tipo entero que corresponderían a dos valores de dos señales diferentes, con este simple cambio ya se tendrían los datos requeridos para poder graficar las dos señales.
 
Sin embargo hay que tener en cuenta que esos datos estarían quedando guardados de forma intercalada dentro del mismo vector, por lo tanto es recomendable antes de realizar la gráfica separar los datos en un vector diferente para cada señal, eso se puede lograr haciendo dos ciclos for uno para que guarde los valores de las casillas impares (Señal1) y otro para que guarde los valores de las casilla pares (Señal 2). 
 
 
 
Luego de haber realizado estos ciclos para separar los valores de las dos señales en dos vectores diferentes si se puede proceder a graficar por medio del comando plot.
 
Donde vectorM es una variable que contiene los números desde el 1 hasta el números de muestras que se van a mostrar en el eje X, voltaje1 y voltaje2 son las dos señales que se quieren graficar.
 
Luego de realizar este proceso ya se pueden observar los resultados de la gráfica de las dos señales adquiridas.
 
 
 
IMPORTANTE TENER EN CUENTA
  • Como en cada muestra se van a tomar dos valores (uno de cada señal), el numero de muestras que se va a tomar por cada señal va a disminuir a la mitad respecto a las que se indican cuando se llama a la función en MATLAB, por lo tanto si se requiere tomar 1000 muestras de cada señal, cuando se vaya a hacer el llamado a la función se tiene que especificar que se van a tomar 2000 muestras.
  • No se recomienda realizar el proceso de “Grafica en tiempo real” ya que al estar tomando más datos, requiere un mayor esfuerzo de la maquina y pueden llegar a presentarse retardos en la adquisición y graficación y posteriores fallos en los resultados, por lo tanto se recomienda primero tomar todos los datos que se requieran y luego de esto si graficar al final en un solo proceso.
  • El archivo de programación de Arduino, Pic o el dispositivo que vayan a utilizar para enviar los datos hacia el computador, también varia pero lo único que tienen que cambiar es que envíe un dato más por el puerto serial.
Si quieren descargar los archivos de MATLAB y Arduino utilizados en los ejemplos de esta publicación (completamente comentados), pueden hacerlo en el siguiente link:


Otra opción que pueden tomar si quieren capturar y graficar los datos con MATLAB es utilizar la herramienta Simulink, este proceso es mucho mas sencillo que el descrito en esta publicación, así que si les interesa este método con simulink, pueden seguir el siguiente link donde les explicamos como hacerlo.

TOMAR DATOS POR PUERTO SERIAL COM Y GRAFICAR CON SIMULINK DE MATLAB

 
 

Iván Cuadros Acosta

Licenciado en Electrónica y Master en desarrollo de aplicaciones móviles con experiencia en docencia universitaria. Apasionado por la electrónica y la programación.

37 comentarios en «RECEPCIÓN DE DATOS SERIAL Y GRAFICACIÓN EN MATLAB»

  • excelente practica. se podría enviar dos señales por el puerto serie para ser graficadas al mismo tiempo??

  • Buenos dias, me sale el siguiente error Error using ADC_Serial (line 35)
    Not enough input arguments.

  • Hola buen día.
    si esta colocando la cantidad de muestras que quiere tomar cuando invoca la función ADC_Serial?
    Por ejemplo
    ADC_Serial(500) %seria pedirle a la función tomar 500 muestras.

  • Buenas, podria enviar los datos de mas de un sensor a la vez?

  • Buenas tardes.

    me fue de mucha utilidad tu publicación.
    Pero como le podría hacer para hacer la gráfica de dos datos.
    ejemplo: por el puerto serial me arroja los datos de temperatura y humedad.
    y no se como separarlos para que me los grafique por separados o que haga una comparación de ambos.

    temperatura, humedad
    25 , 50
    27 , 48
    23 , 35
    .
    .
    .
    ¿Como puedo gráficar estos datos?

  • Buenas tardes.

    me fue de mucha utilidad tu publicación.
    Pero como le podría hacer para hacer la gráfica de dos datos.
    ejemplo: por el puerto serial me arroja los datos de temperatura y humedad.
    y no se como separarlos para que me los grafique por separados o que haga una comparación de ambos.

    temperatura, humedad
    25 , 50
    27 , 48
    23 , 35
    .
    .
    .
    ¿Como puedo gráficar estos datos?

  • Hola buen día.

    Podría intentar en la linea donde se leen los datos del puerto, agregar el formato de la otra variable del sensor que quiere leer.

    Por ejemplo

    valorADC=fscanf(pueto,'%d%d');

    Con esto ya se le esta indicando a MATLAB que le van a ingresar datos de dos variables enteras.

    Sin embargo los datos de las dos variables estarían quedando guardadas en el mismo vector de forma intercalada, ya después de esto todo seria cuestión de separarlas en vectores diferentes.

    Ademas recomendaría (a menos que sea indispensable para su proyecto) que eliminara la impresión del símbolo " , " ya que el valor de este símbolo también le quedaría guardado en el mismo vector cuando realice la lectura en MATLAB.

    Espero que esto le haya sido de ayuda y espero pronto poder hacer una nueva publicación solucionando completamente esta inquietud.

    Muchas gracias por visitar el blog Geek Electronica.

  • Hola buen día.

    Podría intentar en la linea donde se leen los datos del puerto, agregar el formato de la otra variable del sensor que quiere leer.

    Por ejemplo

    valorADC=fscanf(pueto,'%d%d');

    Con esto ya se le esta indicando a MATLAB que le van a ingresar datos de dos variables enteras.

    Sin embargo los datos de las dos variables estarían quedando guardadas en el mismo vector de forma intercalada, ya después de esto todo seria cuestión de separarlas en vectores diferentes.

    Ademas recomendaría (a menos que sea indispensable para su proyecto) que eliminara la impresión del símbolo " , " ya que el valor de este símbolo también le quedaría guardado en el mismo vector cuando realice la lectura en MATLAB.

    Espero que esto le haya sido de ayuda y espero pronto poder hacer una nueva publicación solucionando completamente esta inquietud.

    Muchas gracias por visitar el blog Geek Electronica.

  • Hola Iván ,
    muy buena la publicacion.
    Queria preguntarte si es posible enviarle mediante matlab al arduino que encienda un led, por el puerto serie?, es decir por ejemplo cuando el valor de voltaje alcance 2 Volt, encender el led? y si baja apagarlo?
    gracias

  • Hola buen día.

    Me agrada saber que le gusto la publicación y espero que le haya sido de ayuda.
    En cuanto a su pregunta, si es posible controlar entradas y salidas del arduino desde MATLAB, esto se puede hacer mediante la utilización de algunas herramientas como librerias o toolbox de MATLAB que permiten la comunicación de Software con la tarjeta de Arduino (Por el momento personalmente recomiendo esta http://www.mathworks.com/matlabcentral/fileexchange/32374-legacy-matlab-and-simulink-support-for-arduino aunque es un poco antigua, funciona bastante bien, es sencilla y es soportada por MATLAB 2010 en adelante, hay herramientas mas recientes pero así mismo requieren versiones de MATLAB mas recientes). Espero muy pronto tener tiempo para hacer una publicación respecto a este tema.

    Muchas gracias por visitar el blog y espero que siga pendiente de las publicaciones de Geek Electrónica.

  • que tal como podria modificar el programa de matlab para que me reciba los datos de un PIc??

  • Hola buen día.
    Para estos casos digamos que mas importante que el tipo de elemento que se utiliza (Arduino, PIC, PSoC, PLC), lo que importa es el protocolo de comunicación o el tipo de puerto que va a utilizar para comunicarse con el computador.
    Entonces lo que habría que mirar es que tipo de comunicación o que tipo de puerto utiliza el PLC para conectarse con el computador. En este ejemplo en MATLAB se esta creando un puerto serial tipo COM, que es el mismo que emula el PC cuando se le conecta el arduino, si el PLC también utiliza puertos COM para comunicarse con el PC, los cambios que habría que hacer no son significativos, lo máximo seria cambiar el numero de puerto dependiendo de a cual se conecte, pero no seria mas, pero si el PLC se utiliza otro tipo de puerto si tocaría hacerle mas modificaciones al código, empezando por la creación de puertos diferentes.

    Espero que haya aclarado un poco su duda.

    Muchas gracias por visitar el blog y espero que siga visitándolo.

  • Excelete Publicacion Ivan felicitaciones muy buen aporte, solo tengo una consulta requiero para mi aplicacion que se vaya graficando las dos senales en tiempo real asi como la haces de una sola senal,.. e posible hacer esto y como se lograria gracias por su respuesta amigo…

  • Hola Luis buen día, primero que todo gracias por visitar el blog y me agrada saber que la publicación le ha gustado.
    En cuanto su pregunta, si es posible hacer la gráfica de las dos señales en tiempo real como se hizo con una sola señal, sin embargo no lo mostré ni lo explique de esta forma, porque con el método que se esta implementando no es conveniente ya que puede generar algunos retardos y posteriores fallos en la adquisición de datos.
    Si requiere tomar los datos de dos señales y gráficarlas en tiempo real, le recomiendo que mejor utilice el simulink de MATLAB, si le interesa hacerlo de esta forma puede consultar la entrada del blog donde se explica como hacerlo, el link lo puede encontrar al final de la publicación.

    Espero que le sea de ayuda y que siga visitando el blog, recuerde que puede seguirnos en nuestras redes sociales (facebook o twitter) o suscribirse en el canal de YouTube para estar pendiente de las nuevas publicaciones.

  • Hola, muy bueno el codigo , una mejora para la funcion de matlab:

    Usar voltaje = zeros(1,1000000); en vez de voltaje = 0;

    Muchas gracias

  • Hola buen día, me agrada saber que le ha gustado la publicación, muchas gracias por la recomendación, la voy a probar.

  • Muy buena Información Ivan.
    Se podria hacer el envio de las dos variables por un modulo bluetooth hc-05?
    Solo seria cambiar el puerto serial en el COMX del Bluetooth?
    y en el archivo .ino de arduino cambiar por Bluetooth.Serial(9600);

  • Hola Willman, buen día y gracias por visitar el blog.
    primero tocaría revisar la forma en la que se esta haciendo la conexión al computador y mirar si en el computador se esta creando un puerto COM.

    * Si el módulo Bluetooth esta recibiendo datos por este tipo de comunicación desde otro módulo y es el Arduino el que esta conectado al computador transmitiendo vía serial, si se podría hacer con este método.

    *Pero si el módulo Bluetooth se esta conectado y sincronizando directamente con el PC, es necesario revisar en el administrador de dispositivos si se esta creando un puerto virtual COM, si es así entonces también se podría utilizar este método, de lo contrario no seria posible.

    Espero que esta respuesta le sea de ayuda.

  • Buena tarde.
    Muy util tu demostracion, gracias.
    Ahora quiero preguntarte como hago para generarle un desplazamiento a esa señal, una inversion….Gracias…

  • Buen día, muchas gracias por visitar el blog y me alegra que la información le haya sido de utilidad.

    recuerde que si quiere puede seguirnos en facebook, twitter o YouTube para que pueda estar mas enterado de las publicaciones del blog.

  • MUY ÚTIL EJEMPLO DE ADC GRACIAS, TENDRAS ALGUN EJEMPLO DE UN DAC.

  • Hola buen día y gracias por visitar el blog.

    En el momento no tengo disponible ningún ejemplo con DAC, pero si quieres darme alguna sugerencia sobre con que dispositivos te interesaría utilizar el DAC o de alguna practica especifica, la tendré en cuenta para futuras publicaciones del blog.

  • Hola buen día y gracias por visitar el blog.
    El potencionetro se encuentra conectado al pin A0 del arduino, pero igual se puede conectar a cualquiera de las entradas análogas, todo depende de como lo configures en el programa de arduino.
    Lo importante es que el potenciometro este conectado como divisor de voltaje, los pines de los extremos uno a Vcc y el otro a Gnd y por ultimo el pin del centro si a la entrada análoga del arduino.

  • Me ha gustado este artículo, muchas gracias por compartirlo y sigue así.

    • Muchas gracias por visitar el blog.
      Me alegra que el articulo haya sido de tu agrado.

  • Hola! Primero que nada, excelente aportación, me ha gustado mucho!
    Solo tengo una duda en la que espero me puedas ayudar, se podría aplicar el programa para 3 señales? y si es asi, que cambios necesito realizar en el código?
    Muchas gracias!

    • Hola buen día y gracias por visitar la pagina.

      Primero que todo disculpa la demora en la respuesta. Si seria posible hacerlo con tres señales, pero no lo recomiendo ya que con este método se alcanza a saturar un poco el PC y entre mas señales el problema va a ser mas notorio, por lo tanto si requieres mas señales puedes hacerlo por medio de Simulink de MATLAB, que es mas eficiente para tomar una mayor cantidad de señales. Si te interesa hacerlo con simulink puedes ver la publicación que hice sobre este tema en el siguiente link: https://geekelectronica.com/tomar-datos-por-puerto-serial-com-y-graficar-con-simulink-de-matlab/

      Por último si quieres estar al tanto de las publicaciones del sitio puedes seguirnos en nuestras cuentas de Facebook, Twitter y YouTube.

  • Hola, como puedo separar los datos si es que quiero utilizar otro sensor? o cual seria el proceso para añadir más sensores, es esto posible?

    • Hola buen día y gracias por visitar la página.

      Para agregar otra señal basta con colocar el tipo del otro dato que quieres graficar en el comando fscanf(puerto,’%d%d’), donde cada %d significa que va a recibir un dato entero, para este caso especifico dice que va a recibir dos datos enteros. si colocas ‘%d%f’ significa que vas a recibir un dato entero y un dato con coma flotante. Espero que a pesar de la respuesta esta te sea de ayuda.

      Recuerda que si quieres estar al día con las publicaciones de Geek Electrónica puedes seguirnos en nuestras cuentas de Twitter, Facebook y canal de YouTube.

  • Buenas, primero que nada muchas felicidades por tu excelente aporte.
    Tengo un problema que me ha estado intrigando mucho y no he podido resolver.
    cuando declaras valorADC en el sketch de arduino, lo declaras como tipo int, luego lo envías por el puerto serial y en matlab lo recibes tal cual como tipo entero usando %d.
    mi pregunta es:
    ¿se pueden enviar valores de tipo float de arduino a matlab y como se haria en este caso?.
    he intentado cambiando %d por %f de la función fread pero no funcionó.
    ¿y como se lograria esto para otro tipo de datos(double,String,char)?.
    GRACIAS.

    • Hola buen día, gracias por visitar la página y me alegra que te haya gustado la publicación.

      En cuanto a tu pregunta, en lugar de utilizar la función fread utiliza la función fscanf y entregale como parametros el puerto y tipo de datos que vas a recibir, por ejemplo fscanf(puerto,’%d%f’) con eso estarías diciendo que vas a recibir un entero y un flotante.

      para otro tipos de datos:

      caracter -> %c
      string -> %s
      double -> %e
      entero sin signo -> %u

      Espero que esta respuesta te haya sido de ayuda. Recuerda que si quieres estar al día con las publicaciones de Geek Electrónica puedes seguirnos en nuestras cuentas de Twitter, Facebook y canal de YouTube.

  • hola, que gran aporte!!!!

    tengo un proyecto donde debo recibir mas de 2 señales, me podrías dar un ejemplo de como programar para recibir 3 o mas señales?

    muchas gracias.

    • Hola buen día y gracias por visitar la pagina.

      Para graficar tres o mas señales el proceso es básicamente el mismo que para graficar dos señales, en la linea del fscanf agregar el tipo de dato extra que vas a recibir por ejemplo fscanf(puerto, ‘%d%d%d’) y luego mediante ciclos separar los datos de cada señal. Sin embargo no recomiendo utilizar este método para graficar tantas señales ya que por la forma en la que se está haciendo el proceso puede que el computador se cuelgue en algún momento y se empiecen a ver retardos entre el dato tomado y el graficado.

      Para tu caso te recomendaría mejor utilizar el método que explico en otra publicación del blog donde se toman los datos por puerto serial y se grafican directamente en un scope de simulink. Si te interesa a continuación te dejo el enlace de esa publicación.

      https://geekelectronica.com/tomar-datos-por-puerto-serial-com-y-graficar-con-simulink-de-matlab/

      Si quieres estar al día en las publicaciones de Geek Electrónica, te recomiendo seguirnos en nuestras redes sociales, estamos en Facebook, Twitter y YouTube.

Los comentarios están cerrados.