Ready to make our first data transmission between an electronic system and a computer?
Here begins our way to design and create electronic systems combined with the power of a computer for data handling which will expand significantly all the possibilities that we previously handled and that in itself were not few.
In this article we will learn how to send information from our microcontroller to a computer using the USART (Universal Synchronous Asynchronous Receiver Transmitter) communication mode by which we will send a message in the form of text and the data of an analog variable. We will use Proteus to simulate the circuit and a virtual port emulator to create a port on the PC that will allow us to communicate with Proteus, we will be handling the input data on the port with the Hercules software as announced in the previous article.
¿Listos para hacer nuestra primera transmisión de datos entre un sistema electrónico y un ordenador?
Aquí inicia nuestro camino a diseñar y crear sistemas electrónicos combinados con la potencia de un ordenador para el manejo de datos lo cual expandirá de forma notable todas las posibilidades que antes manejabamos y que de por si no eran pocas.
En este artículo aprenderemos a enviar información desde nuestro microcontrolador hasta un ordenador usando el modo de comunicación USART (Universal Synchronous Asynchronous Receiver Transmitter) mediante el cual enviaremos un mensaje en forma de texto y el dato de una variable analogica. Usaremos Proteus para simular el circuito y un emulador de puerto virtual para crear un puerto en el PC que nos permita comunicarnos con Proteus, estaremos manejando los datos de entrada en el puerto con el software Hercules tal como fue anunciado en el artículo anterior.
The USART module |
|---|
USART is a communication mode that operates under the RS232 standard which facilitates communication between devices that handle this mode and computers because computers handle the RS232 standard by default and although the most modern ones do not have this port in physical form it is always possible to adapt it.
The RS232 protocol is a serial communication mode, which means that the information is sent as a "bit stream" through a wire, the USART mode follows the same principle. We are going to simplify a lot of information by focusing only on explaining the mode that we are going to be using to communicate, which will be the asynchronous mode.
In the asynchronous mode, one line is used to send data and another to receive, that is, the data goes in one direction on each line but in opposite directions between one line and another.
USART es un modo de comunicación que opera bajo el estándar RS232 lo que facilita la comunicación entre dispositivos que manejen este modo y ordenadores pues los ordenadores manejan el estándar RS232 por defecto y aunque los más modernos no disponen de este puerto en forma física siempre es posible adaptarlo.
El protocolo RS232 es un modo de comunicación serial, lo que significa que la información es enviada en forma de "tren de bits" mediante un hilo, el modo USART sigue este mismo principio. Vamos a simplificar mucha información centrándonos solo en explicar el modo que vamos a estar usando nosotros para comunicarnos que será el modo asíncrono
En el modo asíncrono se usa una lineal para enviar datos y otra para recibir, es decir, los datos van en un solo sentido en cada línea pero en sentidos opuestos entre una línea y otra.
Features |
|---|
La primera característica que considero importante resaltar son los niveles de voltaje, nuestro microcontrolador maneja voltajes entre 0 y 5VDC siendo el 0 una representación lógica de un valor bajo (0 lógico) y 5V una representación lógica de un valor alto (un 1 lógico), de esta forma cumple con la lógica TTL en su modo de funcionamiento.
En el caso de RS232 aplica una lógica totalmente distinta y de paso dañina si se conecta directamente a un dispositivo TTL ya que el 0 es interpretado para voltajes +3 y +15V usándose comúnmente +12V y un 1 lógico es interpretado para valores de voltaje de entre -3 y -15V siendo -12 el más usado.
The first thing to take into account is that connecting a TTL device directly to a RS232 device will end up destroying the TTL, to avoid this you need a Driver that controls the voltage levels of both parts without altering the transmitted information, in this case the MAX232 chip fulfills the purpose.
In our simulation circuit we will not be using MAX232 only because we are emulating the RS232 port and we are not using physical connections or physical devices but simulated ones, but when this is implemented physically ALWAYS a driver such as MAX232 must be included.
La primera característica que considero importante resaltar son los niveles de voltaje, nuestro microcontrolador maneja voltajes entre 0 y 5VDC siendo el 0 una representación lógica de un valor bajo (0 lógico) y 5V una representación lógica de un valor alto (un 1 lógico), de esta forma cumple con la lógica TTL en su modo de funcionamiento.
En el caso de RS232 aplica una lógica totalmente distinta y de paso dañina si se conecta directamente a un dispositivo TTL ya que el 0 es interpretado para voltajes +3 y +15V usándose comúnmente +12V y un 1 lógico es interpretado para valores de voltaje de entre -3 y -15V siendo -12 el más usado.
Lo primero a tener en cuenta es que conectar un dispositivo TTL directamente a uno RS232 acabará por destruir el TTL, para evitarlo se necesita un Driver que controle los niveles de tensiones de ambas partes sin alterar la información transmitida, para este caso el chip MAX232 cumple con el propósito.
En nuestro circuito de simulación no estaremos usando el MAX232 únicamente porque estamos emulando el puerto RS232 y no estamos usando conexiones físicas ni dispositivos físicos sino simulados, pero cuando se implementa esto de forma física SIEMPRE debe incluirse un driver como el MAX232.
Another characteristic is the speed at which data is sent, this determines the time it takes to reach a number of pulses that can be interpreted as a single data, the unit to measure this speed is the Baud where a baud is equal to the number of bits that are sent in 1 second (bps). This parameter can have values of: 75, 150, 300, 600, 600, 1200, 2400, 4800, 9600 and higher but we will always use 9600 for USART. So that there are no errors in the communication all the devices must be configured in the same baud value.
Otra característica es la velocidad a la que se envían los datos, esto determina el tiempo que tarda en llegar una cantidad de pulsos que pueden ser interpretados como un solo dato, la unidad para medir esta velocidad es el Baudio donde un baudio es igual a la cantidad de bits que son enviados en 1 segundo (bps). Este parámetro puede tener valores de: 75, 150, 300, 600, 1200, 2400, 4800, 9600 y mayores pero nosotros usaremos siempre 9600 para USART. Para que no existan errores en la comunicación todos los dispositivos deben ser configurados en el mismo valor de baudios.
Connections in the PIC16F877A |
|---|
The PIC16F877A has two pins dedicated to USART communication, which are pins 25 for transmit (TX) and 26 for receive (RX), since USART only needs 2 lines to communicate no more than the MAX232 is required to make the conversions in voltage levels.
El PIC16F877A tiene dos pines dedicados a la comunicación USART, que son los pines 25 para transmitir (TX) y 26 para recibir (RX), dado que USART solo necesita 2 líneas para comunicarse no se requiere más que el MAX232 para hacer las conversiones en los niveles de voltaje.
To make the communication between Proteus and the virtual port that we create we will use a component that only exists for simulation purposes and that internally makes the voltage conversions as the MAX232 would do, this component is found in Proteus as COMPIM and we can double click on it to configure the communication parameters.
Para hacer la comunicación entre Proteus y el puerto virtual que creamos usaremos un componente que solo existe para efectos de simulación y que internamente hace las conversiones de voltajes tal como lo haría el MAX232, este componente se encuentra en Proteus como COMPIM y podemos darle doble click para configurar los parámetros de comunicación.
Now we are going to test the data transmission by USART and we will do it in two ways, the first will be to transmit any message and the second will be to transmit the value of a variable in real time.
The second case is the one that most interests us for the purposes of automated electronic systems because when receiving the value of a variable in the computer we can use different software to handle this value, convert it into the form we want and even establish computer control and monitoring systems (which is the highest level we may reach in this blog).
Ahora vamos a comprobar la transmisión de datos mediante USART y lo haremos de dos formas, la primera será transmitir un mensaje cualquiera y la segunda será transmitir el valor de una variable en tiempo real.
El segundo caso es el que más nos interesa para efectos de sistemas electrónicos automatizados porque al recibir el valor de una variable en el ordenador podemos usar diferentes softwares para manejar este valor, convertirlo en la forma que queramos e incluso establecer sistemas de control y monitoreo por ordenador (que es el nivel más alto al que tal vez lleguemos en este blog).
Programming |
|---|
Until now we have been using C language oriented to microcontrollers through functions contained in the libraries that we always include with the name of the microcontroller used (16f877a.h) and it is likely that many of these functions were not familiar to readers who only handled knowledge in a C language oriented to computer programs.
As we will now establish communications with computers we will need to add the computer-oriented C language functions and that makes it necessary that we also start using the stdio.h library that is never missing in a program that will be used by computers 😉. We will also use an ADC to transmit the analog variable through a potentiometer, so we must configure it and add the variables that we will use to handle this data.
The communication parameters are configured with the code line:
#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7).
Hasta ahora hemos estado usando lenguaje C orientado a microcontroladores mediante funciones contenidas en las librerías que siempre incluimos con el nombre del microcontrolador usado (16f877a.h) y es probable que muchas de estas funciones no eran familiares a lectores que solo manejaban conocimientos en un lenguaje C orientado a programas de ordenador.
Como ahora estableceremos comunicaciones con ordenadores necesitaremos añadir las funciones de lenguaje C orientadas a ordenadores y eso hace necesario que comencemos a usar además la librería stdio.h que nunca falta en un programa que será usado por ordenadores 😉. Tambien es usaremos un ADC para transmitir la variable analogica mediante un potenciometro, asi que debemos configurarlo y añadir las variables que usaremos para el manejo de estos datos.
Los parametros de comunicacion los configuraremos con la linea de codigo:
#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
#include <16f877a.h>
#device ADC = 10
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP,BROWNOUT
#use delay(clock=20M)
#use RS232(BAUD=9600, BITS=8, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7)
#include <stdio.h
long adc_value;
float volts;
In our main program we are going to configure the ADC, we will also send the first transmission which will be a welcome message and we will do it before the while loop so that it is only sent once.
Then we will read the value of the ADC and send the raw value (from 0 to 1023) and the converted value equivalent to voltage. This value if we will be sending it repeatedly through the while loop because it is a variable that you want to monitor at all times.
En nuestro programa principal vamos a configurar el ADC, además enviaremos la primera transmisión que será un mensaje de bienvenida y lo haremos antes del bucle while para que solo se envie una vez.
Posteriormente vamos a leer el valor del ADC y enviaremos el valor crudo (de 0 a 1023) y el valor convertido equivalente a voltaje. Este valor si lo estaremos enviando de forma repetida mediante el bucle while porque supone una variable que se desea monitorear en todo momento.
void main()
{
setup_adc_ports(AN0);
setup_adc(adc_clock_internal);
delay_ms(600);
printf("Welcome to my blog\r\n");
delay_ms(600);
printf("USART transmission\r\n");
delay_ms(600);
printf("@electronico - HIVE\r\n");
delay_ms(600);
printf("original content\r\n");
delay_ms(600);
while(true)
{
set_adc_channel(0);
delay_us(2);
adc_value = read_adc();
volts = (adc_value * 5.0) / 1023.0;
printf("ADC: %Lu , Volts: %0.2f\r\n", adc_value, volts);
delay_ms(150);
}
}
Simulation |
|---|
If you notice before sending the first message I put a delay_ms(600), this is because I want to have a delay when starting the program to give me time to place the Hercules window and we can see there the result from the beginning.
When starting the program should transmit the welcome message and then it will keep repeating constantly the value that has the ADC both in raw value and in the equivalent to voltages. If it is fulfilled we could say that we are already able to transmit any data from the microcontroller to the computer.
Si lo notas antes de enviar el primer mensaje coloque un delay_ms(600), esto es porque quiero tener un retardo al iniciar el programa para que me de tiempo de colocar la ventana de Hércules y que podamos ver ahí el resultado desde el inicio.
Al iniciar el programa deberá transmitir el mensaje de bienvenida y luego se quedará repitiendo constantemente el valor que tenga el ADC tanto en valor sin procesar como en el equivalente a Voltajes. Si se cumple podríamos decir que ya estamos en capacidad de transmitir cualquier dato desde el microcontrolador al ordenador.