Serial "Blocking" can adversely affect the performance of a program. With blocking enabled, the program stops and waits for serial data. If the data never comes the program just sits there doing nothing. Receiving the data in the background allows the program to do other tasks while waiting for serial data to arrive.
Great Cow Basic can easily set up a "scratchpad" or buffer to receive serial data while the program is doing other stuff.
How it works:
When a byte of data arrives in the USART receive buffer an interrupt is triggered. In the Interrupt service routine (ISR) the byte is quickly moved to the scratchpad/buffer and the "pointer" (hserptr) is incremented. When the next byte arrives it is placed in the next location in the buffer and so on. When the pointer reaches the end of the buffer it overflows to zero and starts over . So this is a circular or ring buffer. Some may call it a "buffer ring".
The interrupt routine completes in about 14us with the chip running at 8MHz. A byte of serial data at 115200 bps takes ~ 86us to clock in to the USART receive buffer. So it is no problem to background receive data at rates exceeding 115,200 bps.
The buffer can be small or large depending upon the application and chip capability.
Below is a working code snippet using a PIC18F25K22. I have sized the scratchpad/buffer at 64 bytes for this snippet. However, it can be larger or smaller. For example if you are receiving data from a GPS module with very large data packets you may want to increase the size.
It is up to you to write code to fetch the data from the buffer (Array).
To test the program send data from a Terminal App to the PIC.
''' Great Cow Basic
''' Hserial Background Receive Snippet
''' 17.06.2016
''' By WMR
#chip 18F25K22, 8
#config OSC = INTIO67, MCLRE = EXTMCLR
#define LCD_IO 10
#define LCD_I2C_Address_1 0x4E
#define I2C_MODE Master
#define I2C_DATA PORTA.1
#define I2C_CLOCK PORTA.2
#define I2C_DISABLE_INTERRUPTS ON
#define LCD_Speed Fast
CLS
#define USART_BAUD_RATE 115200
'TX = Pin 17 RC7
'RX = Pin 18 RC6
Dim hserbuffer (64) 'Create Sctatchpad/Buffer
Dim hserptr as byte 'Buffer Pointer
hserptr = 0 'Clear to zero
Print "Demo Started"
Wait 1 s
'Flush the buffer (Not really necessary)
for ii = 0 to 63
hserbuffer(ii) = 0
next
'Interrupt on data byte received
On Interrupt UsartRX1Ready call HSER_INT
''' Run this program then open a terminal app
''' at 115200 baud and send "Hello World" to
''' the Comport. The display should read 11
''' the first time then will increment by 11
''' each successive time until the buffer
''' overflows to zero.
;------ Main Loop -------
Do
cls
print Hserptr
wait 500 ms
Loop
;------------------------
SUB HSER_INT
' Do this quicky and get out !
hserreceive hserbuffer(hserptr) 'get the byte
hserptr++ 'increment pointer
if hserptr > 63 then hserptr = 0 'circular buffer
end sub 'overflow to zero
Last edit: William Roth 2016-06-17
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If I was going to use this MCU to MCU communication. What would the TX code look like? I am thinking of using it as a custom RF gate/garage door opener. Send maybe 8 bytes as a key.
Good work on the RX side :)
Thanks!
Nick
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What you are looking at are called "Front End" modules that communicate with the outside world via an SPI interface. Unless you are trying to develop something like a transparant UART with these, there is really no need to use RS232 type serial background receive. Everything is done via SPI.
These are smart modules that do most of the packet handling chores and have built in data buffers. The code featured here would not be needed.
The NRF24L01+ modules require thst you write code to configure each register in the NRF Chip. GCB does not yet have a library for these modules.
If you want something that will be fast and easy to implement I might suggest lookkng at the INHAOS LC-2000PA Modules. A bit more expensive but with much better range and will probably save you weeks of datasheet analysis and code writing.
Last edit: William Roth 2016-07-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Receiving Serial Data In The Background
This requires a PIC microcontroller with a USART.
Serial "Blocking" can adversely affect the performance of a program. With blocking enabled, the program stops and waits for serial data. If the data never comes the program just sits there doing nothing. Receiving the data in the background allows the program to do other tasks while waiting for serial data to arrive.
Great Cow Basic can easily set up a "scratchpad" or buffer to receive serial data while the program is doing other stuff.
How it works:
When a byte of data arrives in the USART receive buffer an interrupt is triggered. In the Interrupt service routine (ISR) the byte is quickly moved to the scratchpad/buffer and the "pointer" (hserptr) is incremented. When the next byte arrives it is placed in the next location in the buffer and so on. When the pointer reaches the end of the buffer it overflows to zero and starts over . So this is a circular or ring buffer. Some may call it a "buffer ring".
The interrupt routine completes in about 14us with the chip running at 8MHz. A byte of serial data at 115200 bps takes ~ 86us to clock in to the USART receive buffer. So it is no problem to background receive data at rates exceeding 115,200 bps.
The buffer can be small or large depending upon the application and chip capability.
Below is a working code snippet using a PIC18F25K22. I have sized the scratchpad/buffer at 64 bytes for this snippet. However, it can be larger or smaller. For example if you are receiving data from a GPS module with very large data packets you may want to increase the size.
It is up to you to write code to fetch the data from the buffer (Array).
To test the program send data from a Terminal App to the PIC.
Last edit: William Roth 2016-06-17
Hi,
If I was going to use this MCU to MCU communication. What would the TX code look like? I am thinking of using it as a custom RF gate/garage door opener. Send maybe 8 bytes as a key.
Good work on the RX side :)
Thanks!
Nick
The TX code will depend upon what kind of RF device you choose. A cheap. ASK type module will need different code than a smart FSK type.
What RF modules did you have in mind ?
I have this module:
http://www.ebay.com/itm/4X-4PCS-Arduino-NRF24L01-2-4GHz-Wireless-RF-Transceiver-Module-New-/221898840423?hash=item33aa339967:g:2UsAAOSw4HVWCQJG
Thought maybe this is adaptable?
Nick
What you are looking at are called "Front End" modules that communicate with the outside world via an SPI interface. Unless you are trying to develop something like a transparant UART with these, there is really no need to use RS232 type serial background receive. Everything is done via SPI.
These are smart modules that do most of the packet handling chores and have built in data buffers. The code featured here would not be needed.
The NRF24L01+ modules require thst you write code to configure each register in the NRF Chip. GCB does not yet have a library for these modules.
If you want something that will be fast and easy to implement I might suggest lookkng at the INHAOS LC-2000PA Modules. A bit more expensive but with much better range and will probably save you weeks of datasheet analysis and code writing.
Last edit: William Roth 2016-07-02
Simple, yet brilliant!