|
|
View previous topic :: View next topic |
Author |
Message |
yr Guest
|
reading two strings simultaneously!!! |
Posted: Wed Jan 18, 2006 12:53 pm |
|
|
Hi guyz
i am having trouble reading some data in the format:
data1<CR>
data2<CR>
the gets() command is able to pick up data1 string but due to high baudrate (which cant be changed) it is unable to get data2 string. is there any way to avoid the first <CR> after the data1 so that both data1 and data2 are read together hence avoiding the loss of data |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 18, 2006 1:05 pm |
|
|
Use an interrupt-driven receive fifo and get the strings from the
fifo buffer, instead of directly from the UART. This method will
provide more time for your code to do other things, besides
"camping on" the UART. See the CCS example file, EX_SISR.C.
It's in this folder: c:\Program Files\Picc\Examples |
|
|
Guest
|
|
Posted: Tue Feb 07, 2006 1:23 am |
|
|
Well, PCMprogrammer would i need to buffer up the string if im using the hardware port, initialized as:
#use rs232(baud=4800,xmit=PIN_C6,stream=MICRO2, ERRORS)
In my case im receiving data on the hardware port, in the format
string<CR> by using the gets function |
|
|
Guestuser Guest
|
Strings |
Posted: Tue Feb 07, 2006 1:24 am |
|
|
Well, PCMprogrammer would i need to buffer up the string if im using the hardware port, initialized as:
#use rs232(baud=4800,xmit=PIN_C6,stream=MICRO2, ERRORS)
In my case im receiving data on the hardware port, in the format
string<CR> by using the gets function |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 07, 2006 1:36 am |
|
|
Quote: |
would i need to buffer up the string if im using the hardware port, initialized as:
#use rs232(baud=4800,xmit=PIN_C6,stream=MICRO2, ERRORS)
|
Your statement above does not create a hardware UART. It creates
a software UART. That might be part of your problem.
To create a hardware UART, you must specifiy both hardware pins
for transmit and receive in the #use rs232() statement. Example:
Code: | #use rs232(baud=4800,xmit=PIN_C6, rcv=PIN_C7, stream=MICRO2, ERRORS) |
|
|
|
Guest
|
|
Posted: Tue Feb 07, 2006 4:09 am |
|
|
Thanks for this solution; problem only half resolved. THe uC on the other half sends ABC<CR> where ABC are digits. This string is sent once per second. The problem is that even after trying ur suggestion i receive only receive the first two digits and miss the third. now this one is not a bitbanging driver, but a hardware UART so shouldnt it print all the three characters correctly. Plz post suggestion |
|
|
Guest
|
|
Posted: Tue Feb 07, 2006 4:15 am |
|
|
forgot to mention, this happens after i made it a hardware UART like u suggested. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 07, 2006 10:00 am |
|
|
It sounds like you may be letting your code fall off the end of main().
If you're using a hardware UART, you will lose two characters at the end,
if you do this. Put a while(1) statement at the end of main() to prevent
this. Example:
Quote: |
void main()
{
printf("Hello World");
while(1);
} |
|
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Tue Feb 07, 2006 1:29 pm |
|
|
Anonymous wrote: | Thanks for this solution; problem only half resolved. THe uC on the other half sends ABC<CR> where ABC are digits. This string is sent once per second. The problem is that even after trying ur suggestion i receive only receive the first two digits and miss the third. now this one is not a bitbanging driver, but a hardware UART so shouldnt it print all the three characters correctly. Plz post suggestion |
4800bps is NOT fast. Post a simple but complete example that demonstrates the problem. It sounds like you aren't properly taking advantage of the RDA interrupt to create a multi-byte receive buffer. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
Guest
|
|
Posted: Thu Feb 09, 2006 5:24 am |
|
|
It sounds like you may be letting your code fall off the end of main().
Well PCM programmer, the following is a small application i had written, and the above query is with reference to it. I would try to solve the problem without having to alter my physical PCB.
Code: |
#include <16f877a.h>
#device *=16
#include<stdlib.h>
#fuses XT,NOWDT,NOLVP,NOPROTECT,BROWNOUT
#use delay (clock=4000000,restart_wdt)
#use rs232(baud=4800,xmit=PIN_C4,rcv=PIN_C5,stream=PC,parity=N)
#use rs232(baud=4800,xmit=PIN_C6,rcv=PIN_C7,stream=SONARIN_REMOUT,ERRORS)
#include<nju6355.c>
#include<math.h>
#include<24256.c>
#include<lcd.c>
#include<input.c>
long VALTMRAVG= 229;
long DATUM= 600 ;
char sensorin[4];
char nullsensorin[4]={0};
char endptr[4];
long range;
long average=0;
long samplenum=0;
int1 sample1=1; // initializing it to sample no. 1
long INTcountavg=0;
BYTE day, mth, year, dow, hour, min,sec;
#define length 4
int rodlength=0;
// storage variables related to EEPROM
char avgstring[length]={};
char packet[16]={};
BYTE value;
EEPROM_ADDRESS address=0; // EEPROM_ADDRESS= long
char choice; // used in config menu
void set_datetime();
//************************************
#INT_TIMER0
void timer0isr()
{
INTcountavg++;
}
//************************************
BYTE get_bcd() {
char first,second;
do {
first=fgetc(PC);
} while ((first<'0') || (first>'9'));
putc(first);
first-='0';
do {
second=getc(PC);
} while (((second<'0') || (second>'9')) && (second!='\r'));
fputc(second);
if(second=='\r')
return(first);
else
return((first<<4)|(second-'0'));
}
//************************************
void set_datetime()
{
BYTE day, mth, year, dow, hour, min;
// #use rs232(baud=4800, xmit=PIN_C4, rcv=PIN_C5, parity=N)
fprintf(PC,"\r\nPress ENTER after 1 digit answers.");
fprintf(PC,"\r\nYear 20: ");
year=get_bcd();
fprintf(PC,"\r\nMonth: ");
mth=get_bcd();
fprintf(PC,"\r\nDay: ");
day=get_bcd();
fprintf(PC,"\r\nWeekday 1-7: ");
dow=get_bcd();
fprintf(PC,"\r\nHour: ");
hour=get_bcd();
fprintf(PC,"\r\nMin: ");
min=get_bcd();
rtc_set_datetime(day,mth,year,dow,hour,min);
fprintf(PC,"\r\n\n");
}
//*************************************
void display_bcd(BYTE n)
{
fprintf(PC,"%c",(n/16)+'0');
fprintf(PC,"%c",(n%16)+'0');
}
//*************************************
void display_3_bcd( char separator, BYTE a, BYTE b, BYTE c )
{
fprintf(PC," ");
display_bcd(a);
fprintf(PC,"%c",separator);
display_bcd(b);
fprintf(PC,"%c",separator);
display_bcd(c);
}
//*************************************
void stamp_eeprom(BYTE rx)
{
value=(rx/16)+'0';
value-=0x30;
WRITE_EXT_EEPROM(address,value);
WRITE_EXT_EEPROM(address,value);
fprintf(PC,"\r\nEEPROM Value %lu: %X",address,READ_EXT_EEPROM(address) );
address++;
value=(rx%16)+'0';
value-=0x30;
WRITE_EXT_EEPROM(address,value);
WRITE_EXT_EEPROM(address,value);
fprintf(PC,"\r\nEEPROM Value %lu: %X",address,READ_EXT_EEPROM(address) );
address++;
}
//*************************************
int a=0,sub=0;
EEPROM_time_storage()
{
for(a=0;a<length-1;a++)
{
packet[a]=avgstring[a]; // do so before the 0x30 subtraction
value= avgstring[a]- 0x30 ;
WRITE_EXT_EEPROM(address,value);
fprintf(PC,"\r\nEEPROM Value %lu: %X",address,READ_EXT_EEPROM(address) );
address++;
sub= a;
}
sub++;
stamp_eeprom(hour);
stamp_eeprom(min);
stamp_eeprom(sec);
stamp_eeprom(day);
stamp_eeprom(mth);
stamp_eeprom(year);
value = 0xff; // Last byte being padded with 0xFF,to make it 16 byte
WRITE_EXT_EEPROM(address,value);
fprintf(PC,"\r\nEEPROM Value %lu: %X",address,READ_EXT_EEPROM(address) );
address++;
}
//*************************************
void memorydump()
{
fprintf(PC,"\r\n**** EEPROM STORED DATA ****" );
for(address=0;address<1300;address++)
fprintf(PC," %X",READ_EXT_EEPROM(address));
address=0; // 'address' being reset to store from beginning
}
//*************************************
void set_averaging()
{
fprintf(PC,"\r\n**** SET AVERAGING INTERVAL ****");
fprintf(PC,"\r\n (1) 60sec (2) 10min (3) 5sec ");
choice=fgetc(PC);
if(choice=='1')
VALTMRAVG = 917;
else if(choice=='2')
VALTMRAVG = 9170;
else if(choice=='3')
VALTMRAVG = 76 ;
}
//*************************************
void initial_menu()
{
do
{
fprintf(PC,"\r\n**** ECOM SONOLOGGER7000 CONFIG MENU ****");
fprintf(PC,"\r\n Press the relevant digit only !");
fprintf(PC,"\r\n 1. Set Date/Time");
fprintf(PC,"\r\n 2. Take Memory dump");
fprintf(PC,"\r\n 3. Set Configuration parameters");
fprintf(PC,"\r\n 4. Set Averaging interval");
fprintf(PC,"\r\n 5. Exit");
choice= fgetc(PC);
switch(choice)
{
case '1':
set_datetime();
break;
case '2':
memorydump();
break;
case '3':
set_datum();
break;
case '4':
set_averaging();
break;
case '5':
break;
}
}
while(choice!='5');
}
//*************************************
int dig1,dig2;
void main()
{
lcd_init();
rtc_init();
init_ext_eeprom();
setup_timer_0(RTCC_INTERNAL| RTCC_DIV_256);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
printf(lcd_putc,"Sample=%lu",range);
lcd_gotoxy(1,2);
printf(lcd_putc,"Av=");
initial_menu();
while(1)
{
fgets(sensorin,SONARIN_REMOUT);
fprintf(PC,"%s",sensorin);
range=strtod(sensorin,endptr); //stored in long
if(INTcountavg< VALTMRAVG)
{
if(sample1) // cutting down the error-prone sample here !
{
sample1=0;
}
else
{
average = average + range ;
lcd_gotoxy(8,1);
printf(lcd_putc,"%lu",range);
samplenum++;
}
}
else
{
lcd_gotoxy(4,2);
printf(lcd_putc,"%lu",average/samplenum); // being averaged,printed on LCD !
fprintf(PC,"%lu",average/samplenum); // being printed on PC
average = average /samplenum;
if(average < 100)
{
dig1= average/10;
dig2=average%10;
avgstring[0]='0';
avgstring[1]=dig1 + '0';
avgstring[2]=dig2 + '0';
avgstring[3]=0x00 ; //NULL
}
else
sprintf(avgstring,"%lu",average); // stored in string called avgstring
fprintf(SONARIN_REMOUT,"%s\r",avgstring);
rtc_get_date(day, mth, year, dow);
rtc_get_time(hour, min, sec);
display_3_bcd(':',hour,min,sec);
display_3_bcd('/', day, mth, year);
EEPROM_time_storage();
average=0;
samplenum=0;
INTcountavg=0;
set_timer0(0);
sample1=1;
}
}
}
|
Comments ?? |
|
|
Guest
|
|
Posted: Thu Feb 09, 2006 7:42 am |
|
|
The fprintf() after the fgets() in the main while loop checks for the correct reception and it, at times receives all three digits(ABC<CR>) and mostly first two digits..
Plz suggest solution,
Regards |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Feb 09, 2006 12:06 pm |
|
|
My first suggestion is to clean up your code. In your "get_bcd()"
function, there are many places where you use either getc() or fgetc()
and putc() or fputc(), and sometimes you specify the stream and other
times you don't.
You have two streams, PC and SONARIN_REMOUT. You need to go
completely through your program and change it so that you always
use fputc() and fgetc() and you always specify the stream. |
|
|
Guest
|
|
Posted: Fri Feb 10, 2006 1:49 am |
|
|
Ive cleaned up the code and the only change was probably the get_bcd function, changed as
Code: |
BYTE get_bcd() {
char first,second;
do {
first=fgetc(PC);
} while ((first<'0') || (first>'9'));
fputc(first,PC);
first-='0';
do {
second=fgetc(PC);
} while (((second<'0') || (second>'9')) && (second!='\r'));
fputc(second,PC);
if(second=='\r')
return(first);
else
return((first<<4)|(second-'0'));
}
|
BUT.. the problem remains... In the fgets() in main while loop it receives 2 out of 3 characters. I dont think changing baud rate is a solution, is it? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Feb 10, 2006 2:44 am |
|
|
Quote: | BUT.. the problem remains... In the fgets() in main while loop it receives 2 out of 3 characters. |
Is it receiving only 2 out of 3, or is the transmission to the PC
only sending 2 out 3 properly ?
First let's test and see if it's an interrupt problem.
Add the lines shown in bold below.
Quote: | while(1)
{
disable_interrupts(GLOBAL);
fgets(sensorin,SONARIN_REMOUT);
fprintf(PC,"%s",sensorin);
enable_interrupts(GLOBAL);
range=strtod(sensorin,endptr); //stored in long
if(INTcountavg< VALTMRAVG) |
If that makes it work, then change the interrupt enable-disable lines
so they are only around the "fprintf(PC,"%s",sensorin);" line. |
|
|
Guest
|
|
Posted: Fri Feb 10, 2006 4:07 am |
|
|
Well, ive tried the following two changes, but the result is the same. i.e two digits received only. Only once it receives the total chunk of 3,mostly in the beginning.
Code: |
fgets(sensorin,SONARIN_REMOUT);
disable_interrupts(GLOBAL);
fprintf(PC,"%s",sensorin);
enable_interrupts(GLOBAL);
|
and Code: |
disable_interrupts(GLOBAL);
fgets(sensorin,SONARIN_REMOUT);
fprintf(PC,"%s",sensorin);
enable_interrupts(GLOBAL);
|
I dont have a hardware debugger, otherwise it wdve bn easier to figure out the problem |
|
|
|
|
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
|