|
|
View previous topic :: View next topic |
Author |
Message |
nuclear__
Joined: 24 Jan 2015 Posts: 63
|
Text buffer |
Posted: Sat Oct 28, 2017 3:30 am |
|
|
Hi. I'm experimenting on how to use a text buffer in the correct way.
For example i want to write text and variables for debug purposes in a large buffer and then call a routine every second that will print the buffer to lcd and or to usb (could be uart too).
I have nothing to show up. I achieve that in some ways but i don't make use of functions like rcv_buffer_bytes, or others that i don't know exactly how they work.
Can someone give me a versatile example on the optimum way to send text in a buffer within the code ?
I have made a board with 18f45j right now and play with that. I have working usb and lcd. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sat Oct 28, 2017 4:59 am |
|
|
There is no 'correct' way. How you display the data really is up to you.
You say 'large' buffer but LCD modules tend to be 16x2 or 20x4 in size, not really 'large' so typically maybe 5-8 variables get displayed on a fixed format screen.
If sending data to a PC you could see more data on the PC screen, say 1000 characters, however that is a LOT of data to look at especially if updated every second.
For large data transfers a transmit ISR would be the best method, CCS has supplied a working example of this in the 'examples' folder.
However you mention 'rcv_buffer_bytes' which implies the PIC getting data NOT sending it so we need more information of what you really want to do.
Jay |
|
|
nuclear__
Joined: 24 Jan 2015 Posts: 63
|
|
Posted: Sat Oct 28, 2017 8:19 am |
|
|
Ok, lets forget rcv_buffer.
I'm using lcd flex driver, so i use this command to print:
Code: | printf(LCD_PUTC,"\f\1%s\2%s","LCD BackLight"," ON "); //Clear display, print again on Line 2 |
and usb_cdc driver so i use
Code: | printf(usb_cdc_putc,"\n\rLCD BackLight ON"); | too.
Instead of these 2 lines i prefer to send my string "LCD..." +variables if any, to a buffer (actually add the string to previous buffer string, if any) and then print buffer to lcd and usb, and of course clear the buffer after that. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Oct 29, 2017 1:58 am |
|
|
If you look in the compiler examples, at ex_sisr.c, this is a serial receive buffer (now I know you want to transmit...). However the basic principles of a 'circular buffer' can be used for anything....
What you have is two 'counters', that chase each other round a 'ring' of storage locations. Now the actual ring is physically linear in memory, but each buffer 'wraps' when it gets to the end of the buffer, so it behaves as if it is a ring.
To add a character, you just write it to the 'next_in' location, and increment this counter (with wrap if necessary). If it has 'caught up' with the 'out' counter, than you have a potential 'overflow', and have to decide what to do (wait, throw something away etc..).
You can at any time tell if something is in the buffer by just testing if next_in==next_out. If so, then the buffer is empty. You never have to actually 'clear' anything, just set next_in to equal next_out, and the buffer will be 'empty'.
To read, you just test if there is a character (next_in!=next_out), and if there is read the character from 'next_in', and then increment this (with wrap).
It's a very good way of handling lots of I/O tasks on any processor.
Now as posted, there is a problem with the way it wraps the buffer unless you use 'binary' buffer sizes (2,4,8,16 etc.), but how to fix this has been posted here many times. The nice thing is you can just call your buffer write something like 'bputc, and then use:
Code: |
printf(bputc,"\n\rLCD BackLight ON");
|
To send the data to the buffer.
Then if you have a corresponding 'bgetc' to read the characters
Code: |
if (next_in!=next_out)
LCD_PUTC(bgetc());
|
Would send a character to the LCD if one is waiting.
Now the alternative is not to use a 'buffer' in this sense, but just use a string. You can write data to a string with sprintf. To append data, just sprintf to the string name plus it's existing length. The string can be output with the standard commands. Setting it's first character to null, 'clears' it.
Which approach is 'better' actually depends on what you are doing.
For instance if your LCD can only accept 100 characters per second, then it might be worth sending data to this from a timer interrupt. It's obviously very easy then to 'print' your data to a circular buffer and just have the interrupt send one character if there is one waiting. Efficient in lots of ways (no waiting for the LCD, the interrupt does almost nothing if no data is available, & minimal actual movement of data).
However if you just want to send the same message to two targets, and wait as each takes this, the 'string' approach is potentially simpler. |
|
|
nuclear__
Joined: 24 Jan 2015 Posts: 63
|
|
Posted: Mon Oct 30, 2017 7:17 am |
|
|
Very nice! I will approach your solution. A lot of homework.
Thanks |
|
|
|
|
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
|