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

reading two strings simultaneously!!!
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
yr
Guest







reading two strings simultaneously!!!
PostPosted: Wed Jan 18, 2006 12:53 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Jan 18, 2006 1:05 pm     Reply with quote

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








PostPosted: Tue Feb 07, 2006 1:23 am     Reply with quote

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
PostPosted: Tue Feb 07, 2006 1:24 am     Reply with quote

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

View user's profile Send private message

PostPosted: Tue Feb 07, 2006 1:36 am     Reply with quote

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








PostPosted: Tue Feb 07, 2006 4:09 am     Reply with quote

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








PostPosted: Tue Feb 07, 2006 4:15 am     Reply with quote

forgot to mention, this happens after i made it a hardware UART like u suggested.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Feb 07, 2006 10:00 am     Reply with quote

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

View user's profile Send private message Send e-mail

PostPosted: Tue Feb 07, 2006 1:29 pm     Reply with quote

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








PostPosted: Thu Feb 09, 2006 5:24 am     Reply with quote

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;
        }

    }
}
Quote:


Comments ??
Guest








PostPosted: Thu Feb 09, 2006 7:42 am     Reply with quote

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

View user's profile Send private message

PostPosted: Thu Feb 09, 2006 12:06 pm     Reply with quote

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








PostPosted: Fri Feb 10, 2006 1:49 am     Reply with quote

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

View user's profile Send private message

PostPosted: Fri Feb 10, 2006 2:44 am     Reply with quote

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








PostPosted: Fri Feb 10, 2006 4:07 am     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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