CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

HELP ! - Using PIC to acquire RS232 data from PC

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ernest



Joined: 11 Feb 2004
Posts: 51

View user's profile Send private message

HELP ! - Using PIC to acquire RS232 data from PC
PostPosted: Tue Mar 30, 2004 6:16 pm     Reply with quote

Hello,

I am having some problem trying to acquire a stream of serial data from a software in PC. Looking at the results using Hyperterminal, the software will output the readings of the sensors (termistor & humidity sensor) every 100 ms.
eg.:

"Temperature: 23.7 C Humidity: 61.3 %"

So, how can I actually acquire the values of the temperature and humidity using PIC 16F877A? How do we segregate the values and the text?

I know we need to use the getch() command and #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) pre-processor but how do we implement the buffering for the serial data and adding a timeout? How can we be sure that we are getting the correct data we want, in this case the NUMERIC values of the temperature and humidity from a PC software?



Thanks a lot in advance.
Ernest
agrj



Joined: 26 Sep 2003
Posts: 48

View user's profile Send private message

PostPosted: Wed Mar 31, 2004 7:24 am     Reply with quote

Hi you could do something like:

start getting the caracters (use the RDA interupt to do this);
when you get the fist number (you have to compare the caracter to some structure that contain olny ASCII numbers like valid = {0,1,2,3,4,5,6,7,8,9} I don;t remember well how to define it);
then you can use a CASE to do:

buffer = getc();

switch (buffer)
{
CASE valid:
store[i] = buffer - 0x30 (with this you will store the integer )
i++;
BREAK;
CASE 'C':
temp = sotre;
BREAK;
CASE '%'
hum = store;
BREAK;
}

you have to correct the code, because I just write it as an example.

Thanks

Dinho
ernest



Joined: 11 Feb 2004
Posts: 51

View user's profile Send private message

Tried some codes but STILL UNABLE to receive proper data
PostPosted: Thu Apr 01, 2004 2:47 am     Reply with quote

I have written the following codes to check the data received by the PIC16F877A from COM 1. Basically, it echoes the data signal that it received back to the PC for us to view and verify.

However, this program does not work most of the time. On a few occasion, it echoes some irrelevant data.

Please help...


#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include <input.c> //found in the CCS drivers example//

#define KEYHIT_DELAY 500 // in milliseconds ie 500 ms


char timed_getc() {
long timeout;
char retval;

timeout=0;
while(!kbhit() && (++timeout< (KEYHIT_DELAY*100)))
delay_us(10);
if(kbhit())
retval = getc();
else
retval = 0;
return(retval);
}



//================================
void main()
{
int status, i;
char value;
//char valid[11] = {'1','2','3','4','5','6','7','8','9','0'}; tried this but can't work
char valid;


long int temp, hum;
long int store[3];


while(TRUE)
{
status=1;
printf("\r\nStart typing:\r\n");
while(!kbhit());

while(status==1)
{
value=timed_getc();
if(value==0)
status=0;
else
{
status=1;
putc(value);


switch (value)
{
//Tried the following but can't work
// CASE valid:
// store[i] = buffer - 0x30 (with this you will store the integer )
// i++;
// BREAK;

CASE '0':
store[i] = value - 0x30; //Value(ASCII format) - 0x30 = Value(decimal)
i++;
BREAK;

CASE '1':
store[i] = value - 0x30;
i++;
BREAK;

CASE '2':
store[i] = value - 0x30;
i++;
BREAK;

CASE '3':
store[i] = value - 0x30;
i++;
BREAK;

CASE '4':
store[i] = value - 0x30;
i++;
BREAK;


CASE '5':
store[i] = value - 0x30;
i++;
BREAK;


CASE '6':
store[i] = value - 0x30;
i++;
BREAK;

CASE '7':
store[i] = value - 0x30;
i++;
BREAK;

CASE '8':
store[i] = value - 0x30;
i++;
BREAK;


CASE '9':
store[i] = value - 0x30;
i++;
BREAK;

CASE 'C':
temp = 100*store[0] + 10*store[1] + store[2];
i = 0;
printf("%04ld Celcius",temp);
BREAK;

CASE '%':
hum = 100*store[0] + 10*store[1] + store[2];
i = 0;
printf("%04d percent",hum);
BREAK;
}
}


}
printf("\r\nToo slow!\r\n");
}
}
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Thu Apr 01, 2004 11:31 am     Reply with quote

This comes up often.
Part of the problem can be hyperterm.....Hyperterm is full of hidden features which I would never call bugs...teraterm has so few features it actually works.
Part of the problem is a simple one char transfer test program needs to be written to prove out the electrical connection and baud rate etc.
Part of the problem is lack of buffering. The communications is asynchronous and the PC has extremely long path lengths to and from the IO port. Buffering is needed on the PIC USart side
ernest



Joined: 11 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Thu Apr 01, 2004 6:57 pm     Reply with quote

How do we do buffering then...
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Fri Apr 02, 2004 7:47 am     Reply with quote

Ernest
There are many posts on this forum about circular buffering. You'll learn if you roll it yourself. The PIC hardware usart is one char deep buffer. The concept is to retreive the last char before the PC completes putting the next one in the hard ware buffer. Your intterrupt routine gets the last received char and places it in a buffer ( an array of chars say 16 deep) at the location of a receive pointer and increments the pointer. The pointer is made to roll around at the end of the buffer creating a circular buffer. In the main code chars are extracted from the buffer at the address of the next char to read pointer. The next char to read pointer is incremented and also wraps around.
Now as long as your main routine loop can extract chars at a throughput faster than the average incoming chars your expanded circular bufer will not overflow. The PC gan surge a few chars into the buffer and because of its
depth it will not overflow. The bufferring will allow long path length things such as printf to be run on the PIC providing on average they don't exceed the average time available between PC transmitted chars. The PC buffers its input so the buffer on the PIC transmit is not critical. and often is ommitted. The circular buffer is a nice way to introduce flow control by setting a high water mark and with holding a hardware CTS signal or Xmitting a software Xoff
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group