UART/CODE problem Oshonsoft

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi,
I have an intermittent error, on an 18F4431.
There is a GPS connetected to PIN 1, where the GPS read at the pin, shows it correctly at 38400 Baud.
The 4431 sends it via SPI to an 18F46K20, which shows it on a computer terminal.
Sometimes the 46K20 stops outputting, even though the 4431 still show it's input correctly.
If I pull down the 4431 MCLR pin momentarily, it most times resets and the 46K20 starts the output again.
Any clues please? could it be the GPS Baud rate?
C.
 

Ian Rogers

Joined Dec 12, 2012
1,134
Hi C.

I have seen your code and you restart the serial port on framing and overrun errors. It could be the GPS, but that will be because the data flow is slightly out.

What is the FOSC of your system? You'll need to check that you are indeed rebooting the serial port When there is an error, flush the port with a dummy read.

Here is how to deal with both
C:
if(OERR)
{
    do
    {
        temp = RCREG;
        temp = RCREG;
        temp = RCREG;
        CREN = 0;
        CREN = 1;

    } while(OERR);
}

if(FERR)
{
    temp = RCREG;
    TXEN = 0;
    TXEN = 1;
}
Notice the dummy read and switch off / on of the transmitter when the framing error happens.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi C.

I have seen your code and you restart the serial port on framing and overrun errors. It could be the GPS, but that will be because the data flow is slightly out.

What is the FOSC of your system? You'll need to check that you are indeed rebooting the serial port When there is an error, flush the port with a dummy read.

Here is how to deal with both
C:
if(OERR)
{
    do
    {
        temp = RCREG;
        temp = RCREG;
        temp = RCREG;
        CREN = 0;
        CREN = 1;

    } while(OERR);
}

if(FERR)
{
    temp = RCREG;
    TXEN = 0;
    TXEN = 1;
}
Notice the dummy read and switch off / on of the transmitter when the framing error happens.
Hi I,
Thanks.
Here's my later CODE:
============================================
If PIE1.RCIE = 1 Then
'overrun error
If RCSTA.OERR = 1 Then
RCSTA.CREN = 0 'disable UART
RXIRQchar = RCREG '1 'clear UART RX registers
RXIRQchar = RCREG '2
RCSTA.CREN = 1 'reenable UART
Gosub IRQinitBuf 're-init buffer, discard bad sentence
Goto RXIRQdone 'done, wait for next character
Endif 'OERR

'framing error
If RCSTA.FERR = 1 Then
RXIRQchar = RCREG 'Read char to clear RCIF and FERR
Gosub IRQinitBuf 'Re-init buffer, discard bad sentence
Goto RXIRQdone 'wait for next
Endif 'FERR
---------------------------------------------------------------
IRQinitBuf:
rxpsn = 0 'init index
buf_fill = 0 'stop filling until $
buf_done = 0 'not done filling buf
RXerr = 0 'no error

ms05_RXguard = RXguardSet_GNRMC 'set guard timer

RCSTA.CREN = 1
RXIRQchar = RCREG
RXIRQchar = RCREG
PIE1.RCIE = 1
Return
===========================================
Here's my interpretation of your suggestion:
If RCSTA.OERR = 1 Then
temp = RCREG 'TEMP = DUMP ¦
temp = RCREG
temp = RCREG
RCSTA.CREN = 1

While RCSTA.OERR
Wend
Endif

If RCSTA.FERR = 1 Then
temp = RCREG
TXSTA.TXEN = 0
TXSTA.TXEN = 1
Endif
===========================================

The TX PIN is only used as the SLAVE SELECT for SPI, no TX.

The FOSC is 8mHz X4= 32mHz

It still fails :(
C
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi,
The Prog UART is set to 9600 Baud, but the GPS was 38,400 , so I changed it to 9600. No difference (fail)
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi,
Can anyone tell me what tests, I can carry out to find out what's going on, in the SLAVE.
This can't be simulated!
C.
 

Ian Rogers

Joined Dec 12, 2012
1,134
So the uart is receive only?? then you will need to set TXEN to off permanent.

If you look at the sample use the OERR flag and read the dummy until it is clear

if OERR or FERR then..... Read dummy until both are clear.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
So the uart is receive only?? then you will need to set TXEN to off permanent.

If you look at the sample use the OERR flag and read the dummy until it is clear

if OERR or FERR then..... Read dummy until both are clear.
Hi I,
I've used your setting, plus tried a few different ones, plus TX OFF, still fails.
Could it be something else?
C
 

Ian Rogers

Joined Dec 12, 2012
1,134
Just remember 1 thing.. Framming errors won't shut anything down.. Overrun errors will, so I would assume overrun error.
If you need a concrete baud, then get a crystal best suited for it. either 18.432Mhz or 11.0592Mhz will be spot on.
If you are running at 20Mhz SPBRG can be loaded with a few figures.

Here are a couple of options..
if BRGH = 0 set the SPBRG to 32 but the serial is crap at 1.36% so 9470 baud .. If BRGH =1 set the SPBRG to 129 then 9620 baud and its 0.16% better but not perfect.

The overrun error flag is set until the fault clears, but transmission can then get out of sync, so realistically all transmission should be restarted.. I use 20Mhz and set to 9620 as above. I have a small buffer of 30 bytes but I only use 12 bytes during transmission.
It seems to work for me.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Just remember 1 thing.. Framming errors won't shut anything down.. Overrun errors will, so I would assume overrun error.
If you need a concrete baud, then get a crystal best suited for it. either 18.432Mhz or 11.0592Mhz will be spot on.
If you are running at 20Mhz SPBRG can be loaded with a few figures.

Here are a couple of options..
if BRGH = 0 set the SPBRG to 32 but the serial is crap at 1.36% so 9470 baud .. If BRGH =1 set the SPBRG to 129 then 9620 baud and its 0.16% better but not perfect.

The overrun error flag is set until the fault clears, but transmission can then get out of sync, so realistically all transmission should be restarted.. I use 20Mhz and set to 9620 as above. I have a small buffer of 30 bytes but I only use 12 bytes during transmission.
It seems to work for me.
Hi I,
I'm trying to fully understand what you're saying!

The last paragraph mentiones transmission, but there is no transmission, only reception.

The project has used 8Mhz crystals, x4 for years, and this problem, has only just appeared, so I suspect something else.

It has been mentioned many times, to keep the INTERRUPTs as short as possible, and as you know, I use CODE written by forums members, that maybe doesn't comply with this, and so far this has been ok.
I think I'll try to shorten the INTERRUPTs first, and see if this works.
Now, how to do?
C
 

Ian Rogers

Joined Dec 12, 2012
1,134
Transmission is just a term. the GPS and Pic have a "transmission" whether the receiver is one or transmitter is one the other or both. Saying that, you can view the periods between the transmission by scope.

I'll explain... The GPS will spew a sentence out with a terminator. You close in on that terminator and parse the sentence.

If the quiet period is long enough, by all means do it in the interrupt.. Set your scope to .5hz and watch the serial data
1694083386993.png
Two packets with a quiet time between.. That's the time when the buffer needs parsing, that's your window.

In C, I could probably do a 30 byte buffer in a quarter less time. Not saying Vlads compiler work is inefficient but it wont be as efficient as a decent C compiler optimised to the hilt. If the next string arrives while the interrupt is busy the first bit, let alone byte, will throw it out of sync. If you can use a ring buffer and wait for a start and also an end it'll be more concrete.

Look at the GPS document. You may be able to set the transmission delays giving more time to sort yourself out.

I once did a modbus job, ModBus over ethernet, but the packets were required every 100mS so I struggled to do anything. most of the time ( pic18) was just preping for modbus.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Transmission is just a term. the GPS and Pic have a "transmission" whether the receiver is one or transmitter is one the other or both. Saying that, you can view the periods between the transmission by scope.

I'll explain... The GPS will spew a sentence out with a terminator. You close in on that terminator and parse the sentence.

If the quiet period is long enough, by all means do it in the interrupt.. Set your scope to .5hz and watch the serial data
View attachment 302271
Two packets with a quiet time between.. That's the time when the buffer needs parsing, that's your window.

In C, I could probably do a 30 byte buffer in a quarter less time. Not saying Vlads compiler work is inefficient but it wont be as efficient as a decent C compiler optimised to the hilt. If the next string arrives while the interrupt is busy the first bit, let alone byte, will throw it out of sync. If you can use a ring buffer and wait for a start and also an end it'll be more concrete.

Look at the GPS document. You may be able to set the transmission delays giving more time to sort yourself out.

I once did a modbus job, ModBus over ethernet, but the packets were required every 100mS so I struggled to do anything. most of the time ( pic18) was just preping for modbus.
Hi I,
I'll go through this a bit at a time.
First, I'll slow the GPS from 5/sec to 4/sec, and see what happens.
C
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi I,
The GPS was mistakenly set to it's default of 38400 Baud, which worked with errors as mentioned. Once I set it to 9600, I haven't got it to work since. All of the settings are 9600, and alsways have been, apart from occassional default values.
EDIT: GPS itself is now set-back to it's default of 38400, the 4431 is set to 9600, and it's started working again. (with errors)

Note: I've had some windows replaced, and had to move my workbecnch with the Oscilloscope. It's now back with a view,, so I'll try your test.
C.
 
Last edited:

Thread Starter

camerart

Joined Feb 25, 2013
3,596
According to the Datasheet 9600 baud is the default. Also afer 100 errors it shuts down.
ref here https://content.u-blox.com/sites/de...ox8-M8_ReceiverDescrProtSpec_UBX-13003221.pdf
It also recommends keeping sentences below 1 second, so it cannot be overpowering the pic.
What oscilator are you using at your end.. External or internal.
Hi I,
I'm sure somewhere along the line it defaults to 38400, and I think the M8Ns comes like that.

The location needs to be pretty fast, for flying, and I think 1/sec would be inpractical, this is why I set 5/sec.

I'll have to work it though and see if I can isolate the problem.

There is an external 8mHz crystal, which is set in the PIC x4.
C
 

Ian Rogers

Joined Dec 12, 2012
1,134
I very much doubt the GPS is not on the correct Baud rate It'll be your device.
The pic18f4431 runs at 9600 baud, but the GPS defaults to 38400?? it would never work at all. Ergo the GPS unit is sending at 9600 or you would know about it.

Just for clarity... I use a pic18f46k22 and a remote picf25k22 both at 20Mhz.. so even though the baud isn't spot on they are perfectly out of sync together, so no issues.

When I first used a pic12f675 I use an internal 4Mhz ( apparently precision ) crystal.. Didn't work very well until I trimmed it positive, so the never match properly.. It would be interesting to see if you are getting an interrupt clash... What else runs with an interrupt?
 

sagor

Joined Mar 10, 2019
866
I agree with Ian in that you should use a crystal frequency that creates an exact UART baud rate, especially in your case. His example of a 8Mhz crystal giving 0.16% error is typical. That means at 0..16% error for a 60 character received string (10 bits each - 1 start, 8 data, 1 stop bit), you will be off by about 1 bit. Not a major error with enough stop bits. However, if your data strings are longer, or continuous, your error increases to the point where you may get a framing error. If your crystal is off just a bit, your error may be a couple of bits on a long string.
Try setting your serial data to 2 stop bits. That gives more time for the UART to re-syncronize to a proper start bit. That may help eliminate any framing error. Or, get a crystal that gives exact UART baud rates, like 7.3728Mhz, 11.0592Mhz or 18.432Mhz.

If you error is overrun, then you are not processing the data fast enough, or getting too much of it. Try to reduce the "extra" data from the GPS module. You can remove certain strings from being sent. That removes the extra processing you have to do to process strings that may not be of value to your program. Strip down the GPS data to just what you need, no more.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi I and S,
Regarding the 38400 Baud. The GPS is connected to the 18F4431 RX pin. It has been almost working for weeks. When I put it on U-center to program it, I noticed it showed 38400. Reading straight off the GPS to a terminal showed 38400. I set it to 9600, and it didn't work until I switched it back?

Regarding SPI between the two PICs, this seems fine.

I'll be seing my mate tomorrow, and we can go though the past few answers together, and see if we can figure out what's happening. He understands stop bits and stuff.

I'll get some Crystals, for Baud
C.
 

Thread Starter

camerart

Joined Feb 25, 2013
3,596
Hi,
Just saw this:
================================
• Enhanced Addressable USART: This serial
communication module is capable of standard
RS-232 operation and provides support for the
LIN/J2602 bus protocol. Other enhancements
include automatic baud rate detection and a 16-bit
Baud Rate Generator for improved resolution.
When the microcontroller is using the internal
oscillator block, the EUSART provides stable
operation for applications that talk to the outside
world without using an external crystal (or its
accompanying power requirement).
=============================
C
 
Top