View previous topic :: View next topic |
Author |
Message |
PrinceNai
Joined: 31 Oct 2016 Posts: 507 Location: Montenegro
|
|
Posted: Wed Feb 02, 2022 5:08 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
vas57
Joined: 31 Jan 2022 Posts: 29
|
|
Posted: Wed Feb 02, 2022 9:37 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
PrinceNai
Joined: 31 Oct 2016 Posts: 507 Location: Montenegro
|
|
Posted: Thu Feb 03, 2022 4:25 am |
|
|
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;
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
vas57
Joined: 31 Jan 2022 Posts: 29
|
|
Posted: Thu Feb 03, 2022 8:48 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19658
|
|
Posted: Thu Feb 03, 2022 8:51 am |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
vas57
Joined: 31 Jan 2022 Posts: 29
|
|
Posted: Thu Feb 03, 2022 9:50 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19658
|
|
Posted: Thu Feb 03, 2022 12:17 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9377 Location: Greensville,Ontario
|
|
Posted: Thu Feb 03, 2022 2:54 pm |
|
|
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.... |
|
![](templates/subSilver/images/spacer.gif) |
vas57
Joined: 31 Jan 2022 Posts: 29
|
|
Posted: Thu Feb 03, 2022 10:59 pm |
|
|
@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. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19658
|
|
Posted: Fri Feb 04, 2022 11:30 am |
|
|
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...... |
|
![](templates/subSilver/images/spacer.gif) |
PrinceNai
Joined: 31 Oct 2016 Posts: 507 Location: Montenegro
|
|
Posted: Fri Feb 04, 2022 12:48 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
vas57
Joined: 31 Jan 2022 Posts: 29
|
|
Posted: Fri Feb 04, 2022 3:26 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9377 Location: Greensville,Ontario
|
|
Posted: Sat Feb 05, 2022 7:45 am |
|
|
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'. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19658
|
|
Posted: Sat Feb 05, 2022 8:16 am |
|
|
Yes. This also handles the 'part message' situation for you. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|