News:

PROTON pic BASIC Compilers for PIC, PIC24, dsPIC33

Main Menu

Buffered HrsIn

Started by joesaliba, Dec 13, 2022, 10:49 AM

Previous topic - Next topic

joesaliba

Hi,

Using 18F26K22 with limited experience regarding USART.

I have a code that will service several routines, and by the time these are being serviced, occasionally, I receive a 7 byte data from the USART.

Using the standard HrsIn, I do not always get this data because maybe the code is doing the said service routines.

I tried adding the Buffered HrsIn to the code, but this will hang everything.

Disabling all other part of code, in the main routine right after the HrsIn, I tried to toggle an LED, but nothing happens.

How can: -

1. Get the code going with 18F26K22 using Buffered HrsIn
2. Check and get data at a later time from received buffer after my routines have been serviced

Thank you

Joe 

   

keytapper

I think you need an interrupt driven routine.
So the routine will accumulate all the incoming bytes and will set a flag when the buffer is full. If you want to check the data earlier than the full buffer there might be necessary a circular buffer.
The circular buffer has one pointer for the incoming byte and one for the output. If the difference from the two is zero, that means non bytes.
Ignorance comes with a cost

JonW

#2
Joe look at this thread, it should work on your device changing the relevant register positions for the interrupts etc  Its not a circular buffer but could easily be adapted.  The code just waits for a termination character and then sets a flag so the message can be processed. Alternatively you can start a timer and reset it after each received byte as the buffer is filling and then process the rx buffer once the timer has timed out.


Int Driven Uart

joesaliba

Thank you for your inputs,

I will have a read and make some tests.

In the mean time I found this which I think it acts like a circular buffer.

Will let you know with the results.

Thank you

Joe

JonW

That's not circular, its similar to what i posted in the other thread and is a linear buffer.

This code HERE that Les wrote is circular.

joesaliba

Thanks Jon, will read more and tests.

joesaliba

Ok,

Somehow I managed to get the data using the Buffered Hserin, which is working with the 18F26K22.

I tried changing the registers for the K42 Jon point me to, but there where two registers that I cannot know with what to replace.

Now that I am receiving data, I want to build up the data I am receiving.

Am I correct to say that I cannot use the Wait with this code?

I used the following but not working: -

HRSIn {350, ex_get_Butt}, Wait ($65)    ' Wait for $65 to continue retrieving data; Object ID
    HRSIn Str L1_Data\7                     ' then capture the next 7 bytes
 

joesaliba

I must add that I added my routine to check for $65 and acquire the rest of data.

I asked just to be sure I cannot use the wait.

Thank you

Joe

JonW

HRSIN function with wait is useful and simple if you only have a single task or other tasks running in the ISR, however If you are using an interrupt to gather serial data then you will want to directly access the RCREG and move the received bytes into an array and will not require the HRSIN function at all.  Think of it as once a byte hits the UART buffer an interrupt occurs and you are then directed to the ISR (if you enable the correct interrupt), where you then move the received byte to your array and exit as fast as you can. 

If you want to wait for $65 then once you are in the interrupt routine (ISR) you can check the RCREG to see if $65 is in the buffer.  If it is then you can set an bit flag to indicate to your main routine that there is a message in the buffer and you can then process that message in your own time. Even with a linear buffer you can use a byte variable as a message flag to indicate there are multiple messages in the receive buffer array and in this case you would search the array for the termination byte $65 and process, then move to the next message until the receive pointer is 0.  Circular buffers are more suited to this and theoretically don't hit a maximum but rather overwrite old data and have 2 or more pointers.

The Uarts do vary from device to device so ensure you read the datasheet.

joesaliba

Hi Jon,

Thanks for your detailed explanation.

In fact I have done something similar as you explained in my main code and is working ok.

Note. I am looking for a $65 as the start and for 3 $FF as the end.

This will validate the data received.

MyByte = HRSIn1, {1000, TimedOut}   ' Receive a byte, with a 2 second timeout

        if mybyte = $65 then
            count = 0
            index = 0
            do
                MyByte = HRSIn1, {2000, TimedOut}   ' Receive a byte, with a 2 second timeout
                l1_data[index] = mybyte

                if mybyte = $FF then
                    inc count
                endif

                inc index

            loop until count = 3
        endif

keytapper

#10
You might use the label ahead of the HrsIn, so it loops back and waits until all the bytes are received.
mybyte = 0
TimedOut:
if mybyte = $65 then
    count = 0
    index = 0
    l1_data[index] = mybyte
    if mybyte = $FF then
        inc count
        if count > 3 then goto next_case
    endif
    inc index
end if
MyByte = HRSIn1, {1000, TimedOut}
next_case:
I discourage the use of Wait in a ISR, because is blocking all the process.
Ignorance comes with a cost

joesaliba

Thanks Keytapper,

I went that route, as I posted.

Regards

Joe