View previous topic :: View next topic |
Author |
Message |
Nick Guest
|
simple kbhit problem. |
Posted: Fri Aug 05, 2005 1:39 am |
|
|
what i'm trying to do is check the rs232 port for messages, this check_msg function is called in an infinate loop with a 1 second delay. what happens with my code is that it will work for the first or second time the function is called, but after that it doesnt work again. its probably a simple error i made, but i cant seem to find it. any help would be great.
Thanks,
Nick
Code: |
int check_msg()
{
char temp;
int returns=0;
long timeout;
timeout=0;
while(!kbhit()&&(++timeout<50000)) // 1/2 second
delay_us(10);
if (kbhit())
if (getc() == '1')
{printf("first");
if (kbhit())
if (getc() == '2')
{printf("second");
if (kbhit())
if (getc() == '3')
{printf("third");
if (kbhit())
if (getc() == '4')
returns=1;
}//end of third
}//end of second
}//end of first
|
|
|
|
Koko Guest
|
|
Posted: Fri Aug 05, 2005 4:07 am |
|
|
There is something wrong in logic, incorrect calling getc() may be (more than once). Try to do something like this:
while(!kbhit()&&(++timeout<50000)) // 1/2 second
delay_us(10);
if (kbhit()) {
temp=getc();
if (temp=='1') { do something here }
if (temp=='2') { ........................... }
...........
} |
|
|
Nick Guest
|
|
Posted: Fri Aug 05, 2005 4:50 am |
|
|
the string i'm trying to catch is "1234" sent over the serial port
Nick |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Aug 05, 2005 4:52 am |
|
|
What do you mean when you say the function works? Do you ever get to the '4' state?
Depending on how you send the data to the PIC the chance of reaching '4' is very small. If you are typing the text manually the processor will already check for '2' to be received before you even had time to press the key on the keyboard. With a proper state machine this can easily be solved.
Or are you sending the data from the PC as a complete string? In that case the error is a receive buffer overflow in the UART. You are printing texts to the UART at the same speed of data arriving. Problem is that you are sending larger texts than receiving. The UART is capable of buffering up to three characters, after that it will stall until the error state is cleared. Add ERRORS to the #use RS232 line for the compiler to take care of clearing the error flags (you will still loose data in case of receive errors).
Code: | int check_msg()
{
char temp;
long timeout;
int8 state = 0;
timeout=0;
while ((state<4)
&& (++timeout<50000)) // 1/2 second
{
if (kbhit())
{
if (getc() == state + '1')
{
state++;
printf("%d", state); // Tricky, only for debug. Do not print more than 1 character.
}
}
else
delay_us(10);
}
if (state == 4)
return 1;
else
return 0;
|
|
|
|
Ttelmah Guest
|
|
Posted: Fri Aug 05, 2005 6:42 am |
|
|
You do not reset the 'timeout' counter, so this may contain anything.
Code it more tidily with something like:
Code: |
#define TOUT (1)
#define FAIL (2)
#define OK (0)
int check_msg(void) {
char temp;
long timeout=0;
int state=0;
//Note is important to zero timeout when the function is called...
while (true) {
//Include the timout in the wait for the whole of the message
while (!kbhit()&&(++timeout<50000))
delay_us(10);
//Here the next character has arrived or there is a timeout
if (!kbhit) return(TOUT);
temp=getc();
switch (state) {
case 0:
if (temp=='1') state=1;
else return(FAIL);
break;
case 1:
if (temp=='2') state=2;
else return(FAIL);
break;
case 2:
if (temp=='3' state=3;
else return(FAIL);
break;
case 4:
if (temp=='4') return(OK);
else return(FAIL);
}
}
}
|
This has no diagnostic printout, and will exit after either seeing the characters '1234', returning the 'OK' value, while if a string of characters that differ arrive, it'll return with 'fail', or if the code times out (it applies a total 0.5 second timeout on the whole string, rather than on each character - this can be changed by resetting the counter), it'll return the 'TOUT' value.
Best Wishes |
|
|
Nick Guest
|
|
Posted: Fri Aug 05, 2005 2:30 pm |
|
|
the code slightly modifed, works for PC 2 pic, but from device 2 pic i think its not working because there is no buffering. i guess i should write some buffer code then scan the buffer string for '1234'. so if i get the input aasdf1234asdf , I can find the 1234.
Thanks for the help all!
Code: |
case 0:
if (temp=='1')
{state=1;
printf("1");
}
// else return(FAIL);
break;
|
|
|
|
|