How to stop a program HSERIN blocking

Thread Starter

camerart

Joined Feb 25, 2013
3,730
Stopping a device from sending, depends on the device. There were several different protocols for controlling a serial data stream. But both sides must agree to the protocol.

In early RS232, special signals separate from the data stream were used. Look up RTS/CTS if you’re curious. This technique is rarely used today.

Then there was XON/XOFF, where a reserved character was sent to start/stop transmission. The remote device would have to support these protocols.

Do your devices support flow control? Then whatever they use, you code for.

Software serial libraries do support multiple data streams, but usually restrict communications to one virtual port at a time.

Can any of your devices support a retransmit request? You can code collision detection and request retransmission in case of a collision (garbled reception = collision)

It comes down to what your remote devices support. If they don’t support flow control or retransmission requests, there may be no solution.

You may be able to compensate by extrapolating or interpolating the missed data. If that satisfies your requirements.

Otherwise, I don’t have an answer.
Hi D,
The GPS for example, can be programmed.. I know they are set to transmit once/sec, but can be programmed to five times/sec, and possibly add a stop sending bit, but I haven't looked into that so far..

That leaves them set to their default of once/sec.

If the program only used one INPUT at the UART, it waits for the [ $ ] at the beginning of every sentence, and finalises at the end of the sentence by [ LF or ? ]

We have two UART INPUTS so I added a switch chip to the PCB called DATASWITCH which can be switched by the program.

It is set to switch after a full sentence has been READ and it's information saved.

The REMOTE program has a [ $ and ? ] at the beginning and end of every SENT sentence, so that the program can collect it in the same way as above.

Actually the program works, but sometimes the program stops, this is why I'm testing HSERGET.

Thanks,
C.
 

jjw

Joined Dec 24, 2013
823
Hi E,
Yes, I follow.

The DATASWITCH only switches after a full message has been READ and saved, whatever it's length, or it waits till the next '$ of the same type' message. Once saved, the message can be checked for [ RXI (1) and RXI(5) ]

Once completely in, it then switches DATASWITCH to the other type of message, and again does not switch until a full message has been READ and saved, starting with [ $ ] and ending with [ ? or LF ]

I'm pretty sure this is the case! (although you're giving me doubts) This is the intention of how it should be programmed.

C.
How long can you wait to get the gps message?
I assume, that the controls from the base should be received pretty often.
The sync problem was discussed in ETO half a year ago.
https://www.electro-tech-online.com...-data-between-two-sources.155679/post-1341739
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
How long can you wait to get the gps message?
I assume, that the controls from the base should be received pretty often.
The sync problem was discussed in ETO half a year ago.
https://www.electro-tech-online.com...-data-between-two-sources.155679/post-1341739
Hi J, TRANSMITTER
1/ My use of BASE and REMOTE on the LINK thread, are incorrect. Hopefully I will remember to add TRANSMITTER or REMOTE to the reply in future. (I won't explain further now)

2/ There is a good explanation of how a UART works, that spells out what 'E' has been trying to tell me. I now get it!

In the explanation, START and PARITY BITS were mention. I think this is why [ $ and LF ] are used in my CODE (Not written by me)

This means that corrupt results could be gleaned from any $sentence, so must be watched out for.

Sentences end with [ LF ] or [ ? ]

Arriving at the UART is a long string of sentences with no gaps, but a [ $ ] at the beginning and a [ LF ] at the end of each, then a gap.

Using the [ $ and LF ] to separate any sentence DATA is gleaned and used for control etc. If the result is too far out, because of the above, then I hope to remember to ignore it, by CODE.

If the DATA READS as useful, then the DATASWITCH will switch over.

Above 'S' has kindly included sections of the D/S, with sections from the UART. Already in the CODE 'E' had written some of it in.

I have added a section that cleans out the 'blockage' I hope, and will posted later.

Thanks,
C.
 

ericgibbs

Joined Jan 29, 2010
18,865
We have two UART INPUTS so I added a switch chip to the PCB called DATASWITCH which can be switched by the program.
hi C,
Which device are you using for the DataSw.?, circuit section diagram would help.
E

EDIT:
Checking your post #62 and noting all the other functions you plan to add to this PIC, I would say the chance of getting a final, reliable working solution is minimal.
I would recommend that you rethink the project and have only the peripherals that are necessary, every time we get a working program, you add another piece of hardware.

Create and post, a flow chart and a timing diagram for the final project.
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,730
hi C,
Which device are you using for the DataSw.?, circuit section diagram would help.
E

EDIT:
Checking your post #62 and noting all the other functions you plan to add to this PIC, I would say the chance of getting a final, reliable working solution is minimal.
I would recommend that you rethink the project and have only the peripherals that are necessary, every time we get a working program, you add another piece of hardware.

Create and post, a flow chart and a timing diagram for the final project.
Hi E,
The SCH and PCB are here:
https://forum.allaboutcircuits.com/...l-by-location-pic-in-oshonsoft.148795/page-18 #342

and the MODULES/PERIPHERALS are (above link) #1.

The MAIN PIC is an 18F4620 which controls the DATASWITCH.

I am unable to draw a flow chart, as the project was an idea, that I thought possible, but didn't know how, and since conception, I've had to change PICs add a second PIC etc. I just develop it with all of the help I get here, in the best way I can, which while being perhaps annoying to some, I hope the rest of us 'almost enjoy it.

I have all of the MODULES connected to the PCB and working, apart from this blocking program, and quite a lot of tidying up, as faults are found.
C.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
Hi,
Does this look ok?
C
P.S. I've added a TEXT file of corrupt messages if anyone wants to SImulate it.

EDIT: P.S. I've added a TEXT file of corrupt messages. Copy and paste all at once and enter it into the SEND STRING box in the HARDWARE UART. This is to simulate what a string of messages may look like if the DATASWITCH switched out of SYNC, and how the program would cope with a series of truncated messages..
 

Attachments

Last edited:

ericgibbs

Joined Jan 29, 2010
18,865
hi C,
This is your corrupt data, I have added the missing characters with RED chars.
The corrupt data is as I expected, missing data at the string start and end.
E
AA2 26-May-19 18.15.gif
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
hi C,
This is your corrupt data, I have added the missing characters with RED chars.
The corrupt data is as I expected, missing data at the string start and end.
E
View attachment 178273
Hi E,
To clarify, the 'corrupt data' text was to copy (all at once) and paste into the Simulator HARDWARE UART, SEND STRING box, and let me know what it outputs.

I'm not sure if you did this and got errors. Let me know please.
C.
 
Last edited:

ericgibbs

Joined Jan 29, 2010
18,865
hi C,
I did state.
This is your corrupt data, I have added the missing characters with RED chars.

I don't see any purpose in pasting that data into the UART send box.???

You must address the sync timing problem of the two data strings within your program.

E
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
hi C,
I did state.
This is your corrupt data, I have added the missing characters with RED chars.

I don't see any purpose in pasting that data into the UART send box.???

You must address the sync timing problem of the two data strings within your program.

E
Hi E,
Ok, I've edited #86.

I don't see a SYNC problem, as only 1x RX will be connected at any 1x time, but I will think more about it.
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
hi C,
I did state.
This is your corrupt data, I have added the missing characters with RED chars.

I don't see any purpose in pasting that data into the UART send box.???

You must address the sync timing problem of the two data strings within your program.

E
Hi E,
Where you say that you 'repaired' my corrupt data, with RED digits, this implies, that I was receiving this data. I'm not sure if this is what you thought.
.
To clarify: My corrupt data text, was what I perceived to be what may arrived at the UART 'unsynced', and is for testing using the Simulator and the SEND STRING box, and can be edited to suit.

C.
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,730
Hi,
Leaving aside the 'sync' warning at #89 for now.

I have a full program that runs ok LIVE, i,e, it LOOPS ok and shows correct TEMPERATURE, PRESSURE, DEGREES, on the SCREEN, but doesn't glean the $sentences.

I've been testing LIVE using PIR1.RCIF, in varies routines, but haven't got it right yet.

e,g,
1/ Hserin char 'With no PIR1.rcif , LOOPS ok, must have $sentences (or program stops at HSERIN), then gleans them

2/ If PIR1.RCIF = 1 Then Hserin char 'LOOPS OK, doesn't glean $sentences.

3/ If PIR1.RCIF = 0 Then Goto skip1 'LOOPS ok, doesn't glean $sentences.

Above are 3x results, with the consequences commented out.
Previously, there was an example of [ If PIR1.RCIF = 0 Then (LOOP back till 0 turns to 1) ] This type of solution can't be used, in case there is no signal = no $sentence = the program stops.

Any ideas, please?
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
hi C,
One method to escape from a loop is by using a Timer with Interrupt.
E
Morning E, [ TRANSMITTER ]

In this full program, I had previously added a TMR1 Timer, but at the moment it is commented out, while I try PIR1.RCIF tests. NOTE: I want the program to keep LOOPing, so everything else (when no $sentences) is working.

LIVE TESTS

Since #91, I've added:
---------------------------------------------------------------------------------
If PIR1.RCIF = 1 Then
char = RCREG
char = RCREG
Goto hserinchar
Else
Goto skip1
Endif
----------------------------------------------------------------------------------
Now it is working, but not cleanly.
With both GPS and REMOTE 'ON' I can see the LEDs switching, which tells me that the DATASWITCH is also switching, but it takes far too long to switch.
C.
 

ericgibbs

Joined Jan 29, 2010
18,865
hi,
Your clip:
If PIR1.RCIF = 1 Then; this is testing for a Receive input, its Set=1 if a RX char has been received.
char = RCREG; these two Ops flush the RX buffer, IF RCIF=1
char = RCREG
Goto hserinchar ; this will always goto 'hserinchar' if RCIF=1
Else
Goto skip1; If RCIF=0 ie: no char in RX buffer goto skip1
End

The above routine will give you problems.

Please post the 'hserinchar' code.

E
 

Thread Starter

camerart

Joined Feb 25, 2013
3,730
hi,
Your clip:
If PIR1.RCIF = 1 Then; this is testing for a Receive input, its Set=1 if a RX char has been received.
char = RCREG; these two Ops flush the RX buffer, IF RCIF=1
char = RCREG
Goto hserinchar ; this will always goto 'hserinchar' if RCIF=1
Else
Goto skip1; If RCIF=0 ie: no char in RX buffer goto skip1
End

The above routine will give you problems.

Please post the 'hserinchar' code.

E
Hi E,
Here is the GET_DATA CODE, including 'hserinchar':
NOTE: The RETURN at the bottom, returns to GOTO GET_DATA in the MAIN program.
C
 

Attachments

sagor

Joined Mar 10, 2019
912
...

Since #91, I've added:
---------------------------------------------------------------------------------
If PIR1.RCIF = 1 Then
char = RCREG
char = RCREG
Goto hserinchar
Else
Goto skip1
Endif
----------------------------------------------------------------------------------
C.
Wrong, wrong, wrong... Reading RCREG will most likely CLEAR the PIR1.RCIF flag, and if there happen to be two characters in the buffer, you would have overwritten the first character with the second RCREG read.
If PRI1.RCIF = 1 then go do the Hserin read. Then go back and check PIR1.RCIF flag again to make sure it is clear. If not clear, that means there is a second character in the RCREG buffer, go do a second Hserin read to get the second character. Keep reading PIR1.RCIF and RCREG (direct or via Hserin) until that flag is =0.

To summarize:
When there is a character in RCREG, PIR1.RCIF is automatically set = 1. RCREG is a 2 character buffer, giving time to read the characters if program is busy doing other things before detecting PIR1.RCIF. It is when you read RCREG and only when that buffer becomes empty, that PRI1.RCIF is cleared by the system automatically. You must always read RCREG (by whatever routine you use) and then check PRI1.RCIF to see if you "got all of it".
Hserin does this itself, but waits for PIR1.RCIF to be set before reading RCREG, and thus hangs in a loop waiting for PIR1.RCIF to get set. By checking that flag externally, before calling Hserin, you can avoid that lockup with Hserin.
Hserget ignores the PIR1.RCIF flag, and simply reads RCREG, whether there is a character or not. Hserget returns a zero if it detects there is no character (PIR1.RCIF = 0), else it gets the character in RCREG.
Both routines will work without any lockup or error if you check the PIR1.RCIF flag before doing any type of "read".

Finally, always check the OERR and any other error flags before even checking PIIR1.RCIF or doing any read... Any error makes the read redundant, and clearing/resetting the UART enable bit will clear RCREG and any status flags.
 

sagor

Joined Mar 10, 2019
912
Ok, I think you are on the right track now. However, at the end of:
Code:
nxt_rxin:
If PIR1.RCIF = 0 Then  'char = nothing
    str1(0) = 0
    rxi = 0
    Goto skip1
Else
    If PIR1.RCIF = 1 Then  'CHAR = $ or other
                        Hserin char
            If char = "?" Or char = 0x0a Then Goto msg_eol
            If char = "$" Then
                str1(0) = "$"  'CHAR = $
                rxi = 1
                If str1(0) = "$" Then
                        For x = 1 To rxi
                            Goto nxt_rxin
                            str1(rxi) = char
                            rxi = rxi + 1
                            'If char <> "$" Then'????????????????????
                        Next x
                            'Endif'?????????????????????
                Endif
            Endif
    Endif
Endif
You should go back to nxt_rxin, to check a second time for any characters still in the UART buffers. Only once PIR1.RCIF = 0 do you know that you have read everything received by the UART so far. How you process that, I'm not sure, but you have to loop until you have PIR1.RCIF = 0. It may make more sense to loop back to the first statement after the "ELSE" for force a second read (and check the PRI1.RCIF flag again)
Also, you are forgetting to check the validity of rxi when you increment it. What if it overflows? When you say rxi = rxi+1, you should then check if it is too big, and if so, reset it and produce some form of READ error message.

Sorry about all the "wrongs", but I have posted a few times already about the importance of reading PIR1.RCIF to make sure you have read everything that is in the buffers, and if that flag is clear, there is nothing to read (so don't do any read commands). Hence I think I sent one "wrong" for every post I made about that issue (I think, but I may be "wrong" on the count...)
 

sagor

Joined Mar 10, 2019
912
I'm thinking this code may be more "correct":
nxt_rxin:
If PIR1.RCIF = 0 Then 'char = nothing
str1(0) = 0
rxi = 0
Goto skip1
Else
nxt_rxchk:
If PIR1.RCIF = 1 Then 'CHAR = $ or other 'No need for this line, check at end instead
You already know PIR1.RCIF =1 because the test above for =0 is false

Hserin char
If char = "?" Or char = 0x0a Then Goto msg_eol
If char = "$" Then
str1(0) = "$" 'CHAR = $
rxi = 1
If str1(0) = "$" Then
For x = 1 To rxi
Goto nxt_rxin
str1(rxi) = char
rxi = rxi + 1
if rxi > "limit" then goto someerror
'If char <> "$" Then'????????????????????
Next x
'Endif'?????????????????????
Endif
Endif
Endif
If PIR1.RCIF = 1 Then goto nxt_rxchk
Endif
 
Last edited:
Top