|
|
View previous topic :: View next topic |
Author |
Message |
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
communication issue |
Posted: Fri Apr 01, 2011 4:57 pm |
|
|
Hi There,
Friday afternoon and I'm having another issue that I have no clue about yet - checking if anyone here can think of why I'm seeing a problem.
However, I have two mcus a 18f87k22 and a 16f883 and they're supposed to communicate over rs232 with each other. The 18f is the "client" and the 16f the "server" so 18f is requesting data from the 16f, I put it all together into an array (9 Bytes)and send it off like this:
Code: | fprintf (MCU1, " %s", snd) ; |
and on the serverside, I see things coming in nicely but the data only seem to be right until the 6th Byte and that's weird, it's always the 6th Byte thus I don't think it's a capacitive issue with my little wires that are like 6 inches long. Any clues? Should I be using putc() in a for loop instead of fprintf()?
The receiving ISR looks like this:
Code: | #int_rda
void RDA_isr()
{
static int8 incnt=0;
static char recv_dat[9]={0};
char cin=0;
cin=fgetc(MCU2);
if (cin==0x86 || incnt!=0) {
recv_dat[incnt++]=cin;
if (incnt>=9) {
if (recv_dat[6]==0x01 || recv_dat[6]==0x00) {
strncpy(datagram,recv_dat,9);
memset(recv_dat,0x00,sizeof(recv_dat));
incnt=0;
}
}
}
} |
of course it never gets to do the strncpy as I verify byte no6 which is always coming in wrongly...
Thanks for hints,suggestions or ideas!
Ron
Enjoy the weekend!
Oh, by the way what I should mention! I'm not using any rs232 drivers, the communication is only on TTL levels on either side. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Apr 01, 2011 5:02 pm |
|
|
probably 'dies' due to too much time in the ISR..
ISRs MUST be short and fast, set a flag or two, exit asap !!!
also have you got 'errors' in the use rs232(....)..statement ?
best to look at sisr.c example to see how to use circular buffers. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Fri Apr 01, 2011 5:09 pm |
|
|
temtronic wrote: | probably 'dies' due to too much time in the ISR..
ISRs MUST be short and fast, set a flag or two, exit asap !!!
also have you got 'errors' in the use rs232(....)..statement ?
best to look at sisr.c example to see how to use circular buffers. |
Thanks, I'll try that out but I think it shouldn't really die as the isr isn't THAT long, my baud rate is only 9600 and the MCU is running with 20MHz... |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Fri Apr 01, 2011 5:37 pm |
|
|
Okay, I was wrong, you were right! Seems like that was the problem!
Thanks buddy! Now it's time for weeekend!
Talk next week! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Apr 01, 2011 7:10 pm |
|
|
us crazy canuks have to help each other ! |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Fri Apr 01, 2011 9:35 pm |
|
|
temtronic wrote: | us crazy canuks have to help each other ! |
Hehe well, that works or better will (hopefully) work - next week. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Mon Apr 04, 2011 12:43 pm |
|
|
Okay, while i was able to resolve above issue (replaced fprintf() with a loop and fputc() in the sending algorithm), I'm now fighting with something else:
On the 18f87k22 I seem to be able to only receive 2 characters from USART2 even though I'm sending 9 to it. I'm wondering what might be wrong there.
My isr looks like this, I'm using the circular buffer code from the example sisr.c
Code: | #int_rda2
void RDA2_isr()
{
int8 ch=0;
int8 t=0;
// if interrupt USART1 enabled, we're in pass through mode
buffer[next_in]=fgetc(MCU1);
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
} |
and then i use following algorithm to retrieve the data:
Code: | while(bkbhit){
cin=bgetc();
if (cin == 0x86 || (*byte_cnt)!=0) {
recv_data[(*byte_cnt)++]=cin;
}
} |
and bgetc() looks like this:
Code: | BYTE bgetc() {
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
} |
I'm puzzled, after my retrieve algorithm, (*byte_cnt) only shows two. it's like it's receiving two Bytes and just filling the buffer up with these two Bytes... any clues, hints or ideas!
Thanks, replies are appreciated!!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 04, 2011 1:08 pm |
|
|
You have renamed 'incnt' as 'byte_cnt' and somehow it gets magically
turned into a pointer, which you now de-reference (*byte_cnt).
You didn't show the declaration of byte_cnt or show it being updated.
How are we supposed to understand this ? |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Mon Apr 04, 2011 1:19 pm |
|
|
Yah, Sorry.
I got have following function that I use to receive a reply that gets called after i send a request:
It is supposed to be able to receive a whole packet (9 Bytes) without hanging, so it checks if there's anything available and it also features a timeout which will signal the request function to re-request the data after time X as nothing as arrived...I used it before without interrupt/the sisr.c example thus the kbhit() in comments.
Code: |
int32 RecReply(UNSIGNED int16 *time_cnt, unsigned int16 *timeout, int8 *byte_cnt, int1 *present)
{
STATIC char recv_data[9] ={0};
int32 value = 0;
int8 cin=0;
/* receive reply */
if (/*!kbhit (MCU1)*/!bkbhit) // check if there's no Byte waiting for us
{
( * time_cnt) ++;
( * byte_cnt) = 1; //just set the value so it doesn't get requiested again before timeout
if (( * time_cnt) > (*timeout))
{
if (Dbg_Flg)
fprintf (PC, "Timeout: no data received from MCU1, request again... ( * timeout) 0x%x\r\n", timeout);
( * present) = 0;
( * byte_cnt) = 0; //reset bytes received to force another request
( * time_cnt) = 0; //also reset count variable for timeout
}
}else{
while(bkbhit){
cin=bgetc();
if (cin == 0x86 || (*byte_cnt)!=0) {
recv_data[(*byte_cnt)++]=cin;
}
}
(*time_cnt) = 0; // reset timeout
}
if ( (*byte_cnt) >= 9)
{
//when whole packet received,
value = MCU1Parse (recv_data); //parse !
if (value != - 1)
{
if (Dbg_Flg||opmode == TEST)
fprintf (PC, "Received Data:0x%Lx\r\n", value) ;
( * present) = 1; //set present flag
}
( * byte_cnt) = 0; //reset count variable to receive next packet
RETURN value;
} else {
RETURN - 1;
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 04, 2011 1:31 pm |
|
|
Quote: | int32 RecReply(UNSIGNED int16 *time_cnt, unsigned int16 *timeout, int8 *byte_cnt, int1 *present) |
Why are all these parameters pointers ? And regarding the parameter
in bold, the compiler doesn't allow pointers to bits. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Mon Apr 04, 2011 1:35 pm |
|
|
PCM programmer wrote: | Quote: | int32 RecReply(UNSIGNED int16 *time_cnt, unsigned int16 *timeout, int8 *byte_cnt, int1 *present) |
Why are all these parameters pointers ? And regarding the parameter
in bold, the compiler doesn't allow pointers to bits. |
They're pointers because I'm working with them outside of the function too and instead of passing by value or a structure, I just pass them by address. and the int1* is an int8 outside the function (still only 1 or 0) so it compiles well. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Mon Apr 04, 2011 1:58 pm |
|
|
I just figured out that I might have some kind of timing issue. I may wanna do too much together...
I changed following:
This is where i send the request to mcu1
Code: | fprintf (PC, "cmd sent to MCU1:");
for (i=0;i<9;i++){
fputc(snd[i],MCU1);
fprintf(PC," 0x%x",snd[i]);
}
fprintf(PC,"\r\n"); |
before I had just an fprintf() under this loop:
Code: | fprintf (PC, "cmd sent to MCU1: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\r\n", snd[0], snd[1], snd[2], snd[3], snd[4], snd[5], snd[6], snd[7], snd[8]) ; |
after i changed this, I now get to read 3 Bytes from MCU1 - I have a debugging printf statement in the int_RDA2 routine so i can monitor what's coming in.... so before 2 Bytes, now 3 Bytes... which is still not 9 Bytes ( that I see on my oscilloscope being sent!). Any other clues? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Apr 04, 2011 3:16 pm |
|
|
Still a lot of code to handle inside the ISR, try getting rid of all of it, except for the 9 'raw data' bytes. Let your PC program figure out and display the debug data. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Mon Apr 04, 2011 3:20 pm |
|
|
temtronic wrote: | Still a lot of code to handle inside the ISR, try getting rid of all of it, except for the 9 'raw data' bytes. Let your PC program figure out and display the debug data. |
The RecReply isn't in the isr but in the main loop.
The INT_RDA2 isr looks like this (as shown in the example):
Code: | void RDA2_isr()
{
int8 t=0;
buffer[next_in]=fgetc(MCU1);
fprintf(PC,"\r\n0x%x\r\n",buffer[next_in]);
t=next_in;
next_in=(next_in+1) % BUFFER_SIZE;
if(next_in==next_out)
next_in=t; // Buffer full !!
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Mon Apr 04, 2011 6:46 pm |
|
|
Might like to see your listing to see how much code the 'streamed formatted print' function takes, I count 7 characters going to the 'PC'.At 9600 baud, that's about 7-8 ms not including any other overhead of the other 4 or 5 lines in the ISR. |
|
|
|
|
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
|