"Aquí nadie está loco, solo vive un realidad distinta"
Jim Morrison.

" ¿De qué serviría hablar de aquello? Nadie me creería"
Napoleón Bonaparte.

jueves, 1 de agosto de 2019

Comunicación serial utilizando Advanced Serial Port Terminal (ASPT)

   Ha pasado un tiempo desde la publicación de la última entrada en este blog, una disculpa a todos(as) los seguidores(as), ya que por diversas situaciones, me mantuve distanciado de este blog. Agradezco a todos(as) aquellos(as) que han estado pendientes de mi persona y a los suscriptores(as) del canal de youtube que administro. 

En la institución donde trabajo, se desarrollan algunos prototipos con microcontroladores en donde la comunicación es mediane el puerto serie, como éste puerto ya ha sido descontinuado en el hardware de una computadora, la conexión se realiza utilizando un convertidor de USB a serie o mediante los módulos bluetooth HC-05 y HC-06.

Para realizar pruebas de transmisión/recepción entre los dispositivos conectados, he utilizado software como el Hyperterminal que en su momento fue incluido con el sistema operativo Windows de Microsoft, el Monitor Serie de la interfáz de Arduino, el Monitor Serie de Energia y el Advanced Serial Port Terminal (ASPT) de la empresa Eltima Software, éste último me ha parecido muy interesante y completo, ya que posee la mayor parte de las características de los programas ya mencionados, además de que permite múltiples sesiones de comunicación serie en la misma ventana haciendo uso de pestañas.

El software Advanced Serial Port Terminal (ASPT) lo pueden descargar del siguiente enlace, tiene una versión de prueba de 14 días y la licencia está en $39.95 USD:


Al abrir el software aparece la siguiente interfáz grafica de inicio:  

ASPT - microsysoftware.blogspot.com
Figura 1. Aspecto de la pantalla de bienvenida de ASPT.
(clic en la imagen para ampliar)


Figura 2. Datos de contacto para adquirir el ASPT.
(clic en la imagen para ampliar)
 
A continuación, se muestran tres ejemplos de circuitos que utilizan comunicación serie, y al final, se incluye un video del uso simultáneo de comunicación serie mediante ASPT en donde se envían o reciben datos de los tres circuitos:

1. Encendido/apagado del LED del pin 24 del microcontrolador ATMEGA328 ahora propiedad de Microchip, o el pin digital 13 de la tarjeta Arduino UNO R3.

En la siguiente figura, se muestra la ubicación del LED de prueba de la tarjeta Arduino UNO R3: 


Figura 3. PCB de Arduino UNO R3.
(clic en la imagen para ampliar)

El código que se muestra a continuación se compila con la IDE de Arduino, permite encender/apagar el LED de prueba de la tarjeta Arduino UNO R3, enviando un "1" desde la PC mediante comunicación serial: 


////////////////////////////////////////////
//  Blog: microsysoftware.blogspot.com    //
//  País: México                          //
//  Fecha: 01/12/2018                     //
////////////////////////////////////////////

//  Programa que controla el encendido/apagado
//  del LED de prueba de la tarjeta Arduino UNO R3 (pin 13),
//  el control se hace mediante comunicación serial a 9600 baudios,
//  se envía el número "1" desde la PC.

//  Material Requerido:
//  * Tarjeta Arduino UNO R3 o similar
//  * Cable USB de la tarjeta Arduino
//  * Computadora con puerto USB

byte LED = 13;         // Variable de 8 bits para declarar el LED
                       // de prueba incluido en el PCB de Arduino (Pin 13).
byte indicador = 0;    // Variable de 8 bits que indica si el LED 
                       // está apagado(0) o encendido(1).
char dato;             // Variable de tipo caracter para almacenar
                       // el dato procedente de la computadora.

void setup() 
{
Serial.begin(9600);   // Habilita la comunicación serial a 9600 bauds del uC.
pinMode(LED,OUTPUT);  // Se declara el pin del LED de prueba, como salida.
}

void loop() 
{
while(Serial.available() > 0) // Revisa si existe un dato en el puerto serie.
  {
    dato = Serial.read();     // Lee el dato presente en el puerto serie.
    if (dato == '1' && indicador == 0)
    { 
    digitalWrite(LED,HIGH);  // Enciende el LED.
    Serial.println("LED encendido");  // Envía esta frase y un salto de línea
                                      // por el puerto serie del uC.
    indicador = 1; // El LED está encendido.
    }
    else if (dato == '1' && indicador == 1)
    { 
    digitalWrite(LED,LOW);  // Apaga el LED.
    Serial.println("LED apagado");// Envía la frase y un salto de línea 
                                  // por el puerto serie del uC.
    indicador = 0; // El LED está apagado.
    }
    else
    { 
    Serial.println("Dato no valido");// Envía la frase y un salto de línea
                                     // por el puerto serie del uC.
    }
  }
}

2. Lectura de datos de una entrada analógica del micrcontrolador MSP430G2553 de la tarjeta MSP430 Launchpad de Texas Instruments.
  
La tarjeta MSP430 Launchpad, tiene la capacidad de muestrear una señal analógica que varíe en un rango máximo de 0 V a 3.3 V de CD, en este ejemplo, se utilizan los pines de alimentación que incluye el PCB, y un potenciómetro de 10 k.


Figura 4. Diagrama de conexión para la MSP430 Launchpad.
(clic en la imagen para ampliar)

El siguiente código elaborado para Energia, habilita la comunicación serial del MSP430G2553 con una velocidad de 9600 baudios, y configura el pin P1.4 como entrada analógica para voltaje de CD, cuyo muestreo se realiza cada 200 ms.
 

////////////////////////////////////////////
//  Blog: microsysoftware.blogspot.com    //
//  País: México                          //
//  Fecha: 30/11/2018                     //
////////////////////////////////////////////

//  Programa que lee la entrada analógica pin A4 (P1.4),
//  y envía al valor a una computadora usando 
//  comunicación serial.

//  Hardware Requerido:
//  * MSP-EXP430G2 LaunchPad
//  * Potenciómetro de 10 kilo-Ohms
//  * Cables de conexión

int ADC = 0;          // Variable de tipo entero de 16 bits,
                      // utilizada para almacenar el valor obtenido por el ADC.

void setup() 
{
Serial.begin(9600);   // Habilita la comunicación serial a 9600 bauds del uC.
}

void loop() 
{
ADC = analogRead(A4); // Realiza la lectura del pin analógico A4 (P1.4).
Serial.println(ADC);  // Envía el valor del ADC por el puerto serie del uC.
                      // se incluye el salto de línea y retorno.
delay(200);           // Retardo de 200 ms (5 muestras de la señal en 1 s).
}

3. Recepción de caracteres ASCII mediante un módulo bluetooth HC-05, y despliegue de los mismos utilizando un PIC16F877A y una pantalla LCD 16 x 2.

El siguiente diagrama muestra la conexión básica entre el PIC16F877A y el módulo bluetooth HC-05:

Figura 5. Diagrama de conexión para el PIC16F877A y el módulo bluetooth HC-05.
(clic en la imagen para ampliar)
Aspecto físico del diagrama anterior:

Figura 6. Aspecto físico del circuito de prueba.
(clic en la imagen para ampliar)

El siguiente código para el circuito anterior, escrito para el compilador C CCS, permite recibir caracteres ASCII por el puerto serie del PIC16F887A a través de un módulo bluetooth, y mostrarlos en una pantalla LCD; así también, permite enviar una secuencia de prueba al terminal de la computadora:


////////////////////////////////////////////
//  Blog: microsysoftware.blogspot.com    //
//  País: México                          //
//  Fecha: 01/12/2018                     //
////////////////////////////////////////////

/* CÓDIGO PARA EL PIC16F877A, QUE UTILIZA EL
PUERTO SERIE DEL MICROCONTROLADOR PARA 
ENVIAR/RECIBIR DATOS HACIA UNA PC CON PUERTO SERIE.

PARA INICIAR LA COMUNICACIÓN, SE DEBE CONECTAR
EL PUERTO SERIAL DEL PIC AL PUERTO DE LA PC, 
UTILIZANDO UN CONVERTIDOR USB A SERIE O UN MÓDULO
BLUETOOTH, POSTERIORMENTE ENVIAR EL COMANDO "AT" 
Y UN SALTO DE LÍNEA, DESPUÉS ENVIAR LOS CARACTERES
DESEADOS SIEMPRE QUE NO EXCEDA DE 29, INCLUYENDO ESPACIOS.

UTILIZA UN CRISTAL DE CUARZO DE 4 MHz Y UNA LCD DE 16x2.

------ CARACTERES ESPECIALES --------
\n -> 0x0A -> CAMBIO/SALTO A LA SIGUIENTE LÍNEA/FILA.
\f -> BORRA PANTALLA/DATOS DEL TERMINAL.
\r -> RETORNA EL CURSOR AL INICIO DE UN RENGLÓN.

*/
#INCLUDE <16F877A.H>       // MICROCONTROLADOR UTILIZADO.
#USE DELAY(CLOCK=4000000)  // 4 MHz
////////////////////// FUSIBLES ////////////////////////////
#FUSES XT,NOWDT,PUT,NOBROWNOUT,NOLVP,NOCPD,NODEBUG,NOPROTECT
//////// CONFIGURACIÓN DEL PUERTO SERIE DEL PIC ////////////
#USE RS232(BAUD=9600,XMIT=PIN_C6,RCV=PIN_C7,PARITY=N,BITS=8)
////////////// CONEXIÓN DE LOS PINES DEL LCD ///////////////
#DEFINE  LCD_DB4  PIN_D2
#DEFINE  LCD_DB5  PIN_D3
#DEFINE  LCD_DB6  PIN_D4
#DEFINE  LCD_DB7  PIN_D5
#DEFINE  LCD_RS   PIN_D0
#DEFINE  LCD_RW   1        // PIN R/w CONECTADO A GND.
#DEFINE  LCD_E    PIN_D1
#INCLUDE <FLEX_LCD.C>      // LIBRERÍA PARA LA LCD.
#DEFINE  BOTON    PIN_A0   // PUSH-BUTTON.

INT A=1;    // VARIABLE DE 8 BITS.
CHAR DATO;  // VARIABLE QUE ALMACENA EL DATO RECIBIDO
            // EN EL PUERTO SERIE DEL PIC.
/////// ARREGLO PARA ALMACENAR HASTA 29 CARACTERES ////////
CHAR DATO1[29]={' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
                ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
                ' ',' ',' ',' ',' ',' ',' ',' ',' ',};

#INT_RDA          // INTERRUPCIÓN DE RX DEL PUERTO SERIE.
VOID RECIBE (VOID)// NOMBRE DE LA SUBRUTINA DE LA #INT_RDA.
{
DATO = GETCH();   // LEE DATO EN EL BUFFER Y LO GUARDA EN DATO.
   IF (DATO != 0x0A)// SI NO SE RECIBE UN SALTO DE LÍNEA...
   {
   DATO1[A]=DATO; // ALMACENA EL DATO EN EL ARREGLO DATO[A].
   A=A+1;         // INCREMENTA "A" EN UNA UNIDAD.
   }
   
   ELSE           // SI SE RECIBE UN SALTO DE LÍNEA...
   {
  //// VERIFICA SI SE RECIBE EL COMANDO "AT" ////
     IF(DATO1[1]=='A' && DATO1[2]=='T' && DATO==0x0A)
      {
  //// BORRA LA LCD Y MUESTRA EL MENSAJE RX: ////
       PRINTF(LCD_PUTC,"\fRX:");
  //// ENVÍA EL SIGUIENTE MENSAJE POR EL PUERTO SERIE ////     
       PRINTF("\n\rOK\n\rLISTO PARA RECIBIR DATOS...\n\r");
  //// BORRA LOS DATOS UTILIZANDO EL CARACTER ASCII, ESPACIO ////
       DATO1[1]=' ';
       DATO1[2]=' ';
      }
      ELSE
  //// EN CASO SE NO RECIBIR EL COMANDO "AT"
      {
  //// POSICIONA EL CURSOR EN LA FILA 1 COLUMNA 4 DEL LCD ////
       LCD_GOTOXY(4,1);
  //// BUCLE QUE IMPRIME EN EL LCD LOS CARACTERES RECIBIDOS ////
       FOR (A=1;A<14;A=A+1)
       {
        PRINTF(LCD_PUTC,"%c",DATO1[A]);
  //// BORRA EL CARACTER DESPUÉS DE IMPRIMIRLO EN EL LCD ////
        DATO1[A]=' ';
       }
  //// ENVÍA UN SALTO DE LÍNEA AL CURSOR DEL LCD ////
       PRINTF(LCD_PUTC,"\n");
  //// CONTINÚA LA IMPRESIÓN DE CARACTERES EN LA 2a LÍNEA ////
       FOR (A=A;A<30;A=A+1)
       {
        PRINTF(LCD_PUTC,"%c",DATO1[A]);
  //// BORRA EL CARACTER DESPUÉS DE IMPRIMIRLO EN EL LCD ////
        DATO1[A]=' ';
       }
      }
     A=1; // NUEVAMENTE INICIA LA VARIABLE A EN 1.
   }
}

VOID MAIN (VOID) // SUBRUTINA PRINCIPAL.
{
LCD_INIT(); // COMANDO PARA INICIALIZAR EL LCD.
PRINTF(LCD_PUTC,"INICIANDO...\n"); // IMPRIME FRASE EN EL LCD.
SET_TRIS_A(0B000001);   // RA0 (IN), RA1 -> RA5 (OUT).
//// HABILITA LA INTERRUPCIÓN DE RX EN EL PUERTO SERIE DEL PIC ////
ENABLE_INTERRUPTS(INT_RDA);
ENABLE_INTERRUPTS(GLOBAL);
DELAY_MS(1000); // RETARDO DE 1 s.
PRINTF(LCD_PUTC,"LISTO!"); // IMPRIME FRASE EN EL LCD.
DELAY_MS(1000); // RETARDO DE 1s.
//// BORRA LOS CARACTERES EN LCD E IMPRIME FRASE ////
PRINTF(LCD_PUTC,"\fENVIE COMANDO AT\nDESDE TERMINAL..");
   WHILE(TRUE) // BUCLE INFINITO.
   {
      //// MIENTRAS NO SE PULSE EL BOTÓN ////
      WHILE(INPUT(BOTON)==1)
      {
      // ELPROGRAMA SE QUEDA ESPERANDO AQUÍ.
      }
      //// SE PULSA EL BOTÓN ////
      WHILE(INPUT(BOTON)==0)
      {
      //// EL PROGRAMA ESPERA QUE SE LIBERE NUEVAMENTE ////
      }
      //// DESHABILITA LA INTERRUPCIÓN RX DEL PIC ////
      DISABLE_INTERRUPTS(INT_RDA);
      //// BORRA LOS CARACTERES DEL LCD E IMPRIME FRASE //// 
      PRINTF(LCD_PUTC,"\fTX DATOS\nPRUEBA...");
      DELAY_MS(1000); // RETARDO DE 1 s.
      PRINTF("HEX:"); // ENVÍA FRASE HACIA EL PC.
      PUTC(0x31); // ENVÍA EL "0" EN HEXADECIMAL HACIA EL PC.
      PRINTF(" DEC:"); // ENVÍA FRASE HACIA EL PC.
      PUTC(50); // ENVÍA EL "1" EN DECIMAL HACIA EL PC.
      PRINTF(" BIN:"); // ENVÍA FRASE HACIA EL PC.
      PUTC(0B00110011); // ENVÍA EL "2" EN BINARIO HACIA EL PC.
      DELAY_MS(1000); // RETARDO DE 1 s.
      PRINTF(LCD_PUTC,"LISTO!"); // ENVÍA FRASE AL LCD.
      DELAY_MS(1000); // RETARDO DE 1 s.
      //// HABILITA LA INTERRUPCIÓM RX DEL PIC ////.
      ENABLE_INTERRUPTS(INT_RDA);
      //// BORRA CARACTERES EN LCD Y ENVÍA FRASE ////.
      PRINTF(LCD_PUTC,"\fENVIE COMANDO AT\nDESDE TERMINAL..");
   }
}
Por último, se muestra un video de aplicación en donde se realiza la comunicación simultánea de los tres ejemplos mencionados arriba:


Video de Youtube


¡Muchas gracias por visitar el blog y leer esta entrada!

Alfredo Alcázar