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

Problem reading data from an RFID module
Goto page Previous  1, 2
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PrinceNai



Joined: 31 Oct 2016
Posts: 325
Location: Montenegro

View user's profile Send private message

PostPosted: Wed Feb 02, 2022 5:08 pm     Reply with quote

For parsing anything serial I always use the same approach: find something distinct in incoming message in ISR_RDA that indicates that useful data will come next. Disregard that part of the message (in your case OK and whatever special character comes next) and fill the working buffer only with the data I'll work with. From address 0 of the buffer, to make it really easy to display or compare later. Unlike the old hands out there, I do use a debugger, otherwise my first LED would never blink till now. That is why I have a second, much bigger circular buffer where I store everything I get from a serial, not stopping when it's full, just overwriting old stuff. To see in a debug window everything I've received. And if it doesn't work as expected, why my breakpoint wasn't reached.
vas57



Joined: 31 Jan 2022
Posts: 13

View user's profile Send private message

PostPosted: Wed Feb 02, 2022 9:37 pm     Reply with quote

Quote:
You need each time to be using:

putc(bgetc());

Then the next time you use this code it'll access the next message,
not the first one.

Thanks Ttelmah,
Unfortunately, I don't know how to use putc(bgetc ()) to work correctly.
Can you send an example? How do I clear the circular buffer to enter new data?
If I use bkbhit() :

Code:
while(bkbhit())
putc(bgetc());


my software locks in this loop.
PrinceNai



Joined: 31 Oct 2016
Posts: 325
Location: Montenegro

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 4:25 am     Reply with quote

To clear a buffer:

Code:

// clear UART buffer
void Clear_UART_Buffer() {          //
   next_in=0;
   while (next_in < BUFFER_SIZE){
     buffer[next_in] = '\0';
      next_in++;
      }
   next_in=0;
}
vas57



Joined: 31 Jan 2022
Posts: 13

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 8:48 am     Reply with quote

PrinceNai wrote:
To clear a buffer:

Code:

// clear UART buffer
void Clear_UART_Buffer() {          //
   next_in=0;
   while (next_in < BUFFER_SIZE){
     buffer[next_in] = '\0';
      next_in++;
      }
   next_in=0;
}


@PrinceNai,
Yes, that was it. If the buffer is reset, the new data is retrieved without any problems.
Thank you so much for insisting on giving me this idea.
Thanks also to Ttelmah, PCM programmer, Temtronic.
Ttelmah



Joined: 11 Mar 2010
Posts: 18060

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 8:51 am     Reply with quote

You should never have to clear a circular buffer. When you read a character,
using the bgetc, the space this used immediately becomes available for a
new character.
The way to clear the buffer if you need to, is simply to set next_out=next_in.
This says the buffer is empty.
PrinceNai's routine would not work, he needs to set next_out to zero as well.
vas57



Joined: 31 Jan 2022
Posts: 13

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 9:50 am     Reply with quote

Ttelmah wrote:
You should never have to clear a circular buffer. When you read a character,
using the bgetc, the space this used immediately becomes available for a
new character.
The way to clear the buffer if you need to, is simply to set next_out=next_in.
This says the buffer is empty.
PrinceNai's routine would not work, he needs to set next_out to zero as well.

Sorry, I can send a video with my project.
I don't use bgetc, to read UART, I delete it from my code.
PrinceNai's help me with this routine.
Thank you all.


Last edited by vas57 on Thu Feb 03, 2022 10:43 pm; edited 1 time in total
Ttelmah



Joined: 11 Mar 2010
Posts: 18060

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 12:17 pm     Reply with quote

Your approach is fundamentally flawed.
Using a linear buffer, and clearing like this risks losing data if you receive
a character before you finish processing the received message.
You are missing the 'point' about using the circular buffer. This is not
used instead of your linear store for the assembled string, but as well as.
You use this to handle the interrupt, and then have as many character
times as you give space for in this to do the message handling.
You then assemble your message into a linear buffer from this. Ideally
parsing the message, so you know it is complete when you see the 'OK'.
At this point you output or parse the assembled message, and then
start again.
temtronic



Joined: 01 Jul 2010
Posts: 8525
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 2:54 pm     Reply with quote

I got into the habit of clearing all buffers back in the Assembler dayze, to be 100% SURE the 'new' data really, really was NEW data...
kinda like wiping chalkboards clean, before writing on them....
vas57



Joined: 31 Jan 2022
Posts: 13

View user's profile Send private message

PostPosted: Thu Feb 03, 2022 10:59 pm     Reply with quote

@PrinceNai's
You didn't have to delete the last post, I'll use your idea in a reader for an access system.
Ever since I corrected the software with this idea, my reader, with a tag on it, has never made a mistake reading UID. I am 100% satisfied, even if the theory says otherwise. Thank you all.
Ttelmah



Joined: 11 Mar 2010
Posts: 18060

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 11:30 am     Reply with quote

You have to understand that while a design works perfectly on the bench,
when it goes out into the real world, you will at some point have an
occasion where a character gets corrupted. To be really reliable, your
code needs to be able to handle and recover this sort of event. It may
only happen once every few years, but at some point it will happen.
Designing code to actually be 'rugged' is much harder than simply
writing something that works......
PrinceNai



Joined: 31 Oct 2016
Posts: 325
Location: Montenegro

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 12:48 pm     Reply with quote

I agree that bench and real world are two completely different beasts. Only the end users and working environment can test your system beyond anything you ever imagined could happen when it was designed. I also agree that a code should be able to recover from the unexpected, not just sucking a thumb when (not if) it happens. Regarding reading RFID cards. They are used for what? Opening doors, registering presence, confirming something (opening doors and confirming money transactions is what we use them for where I work). Nothing life threatening, so elaborate escape sequences in code are not really needed. From my perspective the procedure is simple: read a card, compare ID that was read with stored ID's and do something if they match. If not, remove the card and try again or use another, registered card. With some delays between readings it works 100%, with a linear buffer. I made this one because my then 6 year old kid was stating he must use a card just like me. OK, order readers from China, solder something, add a beeper and bring home some cards. Write some code. He tested it like 10.000 times on the first day. I seldom heard a short beep indicating something went wrong and always a long one shortly after. But I did hear from my wife that she'll bash my head in if I ever again construct something with a beeper.
vas57



Joined: 31 Jan 2022
Posts: 13

View user's profile Send private message

PostPosted: Fri Feb 04, 2022 3:26 pm     Reply with quote

Here I agree with PrinceNai, because the software is for access systems in residential buildings. If a code is read incorrectly, nothing happens, the next one comes correct and the reader will open the door.
temtronic



Joined: 01 Jul 2010
Posts: 8525
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sat Feb 05, 2022 7:45 am     Reply with quote

One thing to add to the 'reader' section is a 'timed out escape'. In EVERY serial communication it's possible to 'stall', get 'hung up'(can happen when cat pulls out the com cable...sigh). CCS saw this and in the FAQ section show how to 'escape'.
Ttelmah



Joined: 11 Mar 2010
Posts: 18060

View user's profile Send private message

PostPosted: Sat Feb 05, 2022 8:16 am     Reply with quote

Yes. This also handles the 'part message' situation for you. Smile
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 Previous  1, 2
Page 2 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