Arizona Chris
Joined: 20 Dec 2014 Posts: 69 Location: Arizona
|
About Sending Serial data from PIC to PC |
Posted: Mon Apr 13, 2015 10:06 pm |
|
|
Greetings all,
I would like to go over the procedure to allow your PC running a data acquisition or terminal program to receive data directly from your micro controller. You would not believe just how fun this can be! I have done this at work for decades for sending data back and forth between the operator control station and a remote teleoperated and autonomous robotic system. But when I started using CCS-C, it was easier than ever - and I will show you what I have learned in the past few months with this wonderful compiler so you can try this too.
Now first of all, before I get into the technical details, why would you want to do this in the first place? Of what use is it? Just think about the possibilities for a moment - I know you've used a 2 x 16 LCD display for showing status data, numbers and a few words of text. But what if you want to do something really interesting, like record temperature data each minute for weeks on end and plot this on a gorgeous full color graph? Or perhaps you are recording analog data from an experiment in process, such as monitoring the resistance of the soil around your garden for several days or the output from a sonar to record the passing of cars or people for 24 hours. Now you'll need something a bit more than that miniscule 2 x 16 display. Imaging a display with about 80 characters wide (depending on text size) and yes - infinitely long. You have such a device, your PC and by running a terminal program you have essentially a gigantic LCD display to not only record your data, but then you can save it in text format, import it into excel, and using the killer chart wizard - plot out some stunning charts and graphics. Sound interesting? Lets go over what you will need to do this.
Components required for PIC to PC:
1. A PIC with a serial data line available connected to your experiment or monitoring sensor.
2. CCS-C (ok you already have this)
3. A TTL to RS232 converter board
4. A windows PC with a serial port - DB9 or DB25 type (see discussion)
5. A terminal program such as Hyperterminal on win xp.
Now lets look at a few items here. For a TTL to RS232 converter, you can use the Maxim 232 chip. I have posted complete schematics, and photos of the board I built ready to connect to your pc on my web site here:
http://www.schursastrophotography.com/PICprojects/TTL232.html
This is an EASY part to work with and does its own voltage generation to be able to create the +/- 10v used to send to the serial port. Inside your computers serial port, is the same basic chip used to receive the data and re convert it back to TTL levels (0-5v) for use in the computers main processor.
Now about that windows PC with Hyperterminal. Up to windows XP, you got this for free in the accessories folder. for later versions, you get nothing. So you can buy the program for around $70 from the company that took it over or find a free one online. either way you set it up for say 9600 baud, 8N1 the correct com port and your ready to receive. You can jumper pins 2 and 3 and hit the key board to see the data echoing back to test it.
Serial port? Yeah, remember the days when all PCs came with one? You as an engineer all ready probably have one or two XP machines around with one, as this is the industry standard operation system for development. Alternately, you can easily buy for $20 a serial card to install one in your full size PC. OR buy one of those USB to DB9 serial adapters. I have not had much luck with those, your better off buying a used $150 laptop with XP and a mess of ports. ;)
Now your ready to send data TO your PC. A later write up will cover the reverse direction, PC to PIC which is a bit more complicated since the data from the PC is all in ASCII.
No matter what chip you use, somewhere near the top of the program, you set up your serial output stream to match what the PC is going to receive. For non inverted 8N1 no parity at 9600 it will look something like this:
#use rs232(baud=9600, xmit=Pin_B1, bits=8, parity=N,stream=TERMINAL)
Then in your C program, you can use the fprintf statement to send the data format you wish. This includes pure text, int8, int16, and floating point. By also indicating the format on the float you can set the digits and numbers after the decimal to match your application. Just remember that CCS puts out 7 significant digits, the rest if any will be zeros or not significant.
Before I show you the code I used with my 16F877a processor in my robot to send data to the terminal, just remember to read up carefully on the printf statements various options to be used with the "%" sign to properly get the right data on the screen! Its laid out pretty good in the manual.
Here is the demo code. It sends various types of characters and numbers to the PC and repeats over and over. Pretty cool to see floating point data so clearly on the screen, we are going to have a lot of fun with this! ~Chris
Code: | //****************************************************************************
//Chris Schur
//( 16F877A Terminal display tests.)
//Date: 3/29/15
//****************************************************************************
/*Description of this Program: Send commands to the terminal program "hyper
terminal" set up for 9600kb data one way. We use the lcd output jack on the
board, connected to our brand new TTL to 232 converter board.*/
//I/O Designations ---------------------------------------------------
// RB0: Status LED output
// RB1: Serial output to Terminal or LCD
// RB2: Piezzo Speaker
// RB3:
// RB4:
// RB5:
// RB6:
// RB7:
//--------------------------------------------------------------------
//Include Files:
#include <16F877A.h> //Normally chip, math, etc. used is here.
//Directives and Defines:
#device ADC=10 //Set ADC when used to 10 bit = 0 - 1023
#fuses NOPROTECT,HS,NOWDT //xtal is used
#use delay(crystal=10MHz) //xtal speed
#use fast_io(ALL) //must define tris below in main when using this
//for LCD / Terminal:
#use rs232(baud=9600, xmit=Pin_B1, bits=8, parity=N,stream=TERMINAL)
//****************************************************************************
//-- Main Program
//****************************************************************************
void main(void) {
// Set TRIS I/O directions, define analog inputs, compartors:
set_tris_A(0b11111);
set_tris_B(0b11111000);
set_tris_C(0b11111111);
set_tris_D(0b11111111);
set_tris_E(111);
//(analog inputs digital by default)
//Initialize variables and Outputs: --------------------------------------
output_low(Pin_B0); //status off
delay_ms(1000); //LCD warmup time
int8 n = 255;
int16 x = 50000;
float y = 65000.123; //only 7 digit precision will truncate last digit
float z = 3.14159;
//----------------------------------------------------------------
//MAIN PROGRAM:
while (true) {
//First flash lamp
output_high(Pin_B0);
delay_ms(250);
output_low(Pin_B0);
delay_ms(250);
//Now send messages to Terminal:
delay_ms(1000);
fprintf(TERMINAL,"Hello World"); //text plus integer8 (Byte)
fprintf(TERMINAL,"\n\r"); //New line, Carrige Return
delay_ms(250);
//Displays: ROBOT BOARD= 255
fprintf(TERMINAL,"ROBOT BOARD= %u"n); //text plus integer8 (Byte)
fprintf(TERMINAL,"\n\r"); //New line, Carrige Return
delay_ms(250);
//Displays: Value= 50000
fprintf(TERMINAL,"Value= %Lu"x); //text plus Integer 16 (word)
fprintf(TERMINAL,"\n\r"); //New line, Carrige Return
delay_ms(250);
//Displays: floating= 65000.120
fprintf(TERMINAL,"floating= %8.3f"y); //text plus floating point
fprintf(TERMINAL,"\n\r"); //New line, Carrige Return
delay_ms(250);
//Displays: floating= 65000.12
fprintf(TERMINAL,"floating= %f"y); //text plus floating point DEFAULT float
fprintf(TERMINAL,"\n\r"); //New line, Carrige Return
delay_ms(250);
//Displays: floating= 3.14159
fprintf(TERMINAL,"floating= %6.5f"z); //text plus floating point
fprintf(TERMINAL,"\n\r"); //New line, Carrige Return
delay_ms(250);
} //elihw
} //niam
|
|
|