View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Sep 01, 2023 9:41 am |
|
|
Oh my God, you are using a software UART!.. Aaargh. No wonder you have
problems. If you are even fractionally late getting to the read, bits will be
missed. You talked about UART3, as if you had a hardware UART.
You need first of all to use a simulator, and run the whole code between
the calls to the kbhit, and verify that this will always be completed
in less than the character time. The software UART absolutely _requires_
you are sitting waiting for the character before it arrives. No buffering
possible or existing.
No the hardware UART's have two characters of hardware buffering. No
software buffering unless you enable it.
Do you have any interrupts running at all?. If so you need to use the
disable_interrupts option on the software serial of there will be timing
errors. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Fri Sep 01, 2023 9:55 am |
|
|
sigh.................
for some 'silly' reason I thought that PIC had 5 HW UARTS.....
There is very,very little chance of getting a software UART to do your task !!
OK, it could be done, but you need to be very clever with cutting code..
Honestly the BEST solution, is to replace with a PIC that HAS at least 4 HW UARTS.
seems you need 3 ,now, and I'm betting my PICStart+, you'll need another before this thread is finished !
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Fri Sep 01, 2023 11:40 am |
|
|
I too, thought the chip had more hardware UARTs.
Have to ask what the other connections are used for?. It is possible that
he might be better using the software UART for one of the other channels.
Honestly the chances of getting this to work are very poor. Could the RX line be tricked to generate an interrupt?. If so would improve the chance of
getting this to work, and increasing the speed would also jelp. |
|
|
JerryR
Joined: 07 Feb 2008 Posts: 167
|
|
Posted: Fri Sep 01, 2023 11:59 am |
|
|
Hi Guys:
Sounds like you two understand the capabilities of the SW UART better than I. Guess I should have specified SW UART was being used.
Well, according to two other Engineers this same code and hardware works well with the previously developed hardware that interfaces to it.
Just how "crippled" is the SW UART? Really hard to imagine I'm going to be able to sell a hardware redesign to the customer to accommodate a new uC. Might need a plan B.
Thanks guys. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Fri Sep 01, 2023 1:00 pm |
|
|
JerryR wrote: | Hi Guys:
Sounds like you two understand the capabilities of the SW UART better than I. Guess I should have specified SW UART was being used.
Well, according to two other Engineers this same code and hardware works well with the previously developed hardware that interfaces to it.
Just how "crippled" is the SW UART? Really hard to imagine I'm going to be able to sell a hardware redesign to the customer to accommodate a new uC. Might need a plan B.
Thanks guys. |
A SW UART requires nearly 100% of the processor's attention for reliable reception. If you have other interrupts, they'll divert this so-called attention and that will lead to receive errors.
In order of increasing effort/code complexity:
1. If whatever is connected to the SW UART has a predictable transmit pattern (i.e. it always broadcasts every x ms or it only broadcasts when you prompt it to), simply disable interrupts while you're receiving data from it. Of course, whatever else requires attention will therefore lack said attention.
2. Get fancy with the CCP or a gated timer connected to the RX line. Use the CCP to figure out where the start bit is, when the line transitions (and thus the bit(s) just sent, and finally recognition of the stop bit will cause the routine to examine what it just received and thus what the transmitted character must have been. Hugely complex, but will be effective as long as there aren't too many 'other' interrupts, and as long as these other interrupts are quite short to execute. You could also opt for a gated timer approach whereby the timer counts if the incoming line allows it to. You'd need another timer synchronized with the bit time, and every time it rolls over, take a look at the gated timer's count. You'd need to discern whether a 1 or 0 was sent based on this timer's value, but getting the thing to sync properly with the bit timer won't be trivial. |
|
|
JerryR
Joined: 07 Feb 2008 Posts: 167
|
|
Posted: Fri Sep 01, 2023 1:26 pm |
|
|
Thanks all for your interest.
Just to add more information:
The "transmitter, under development, does produce an attention signal to the receiver when it has eight bytes of command traffic for the "receiver". The "receiver", using the SW UART, does block global interrupts when it hears this attention signal from the transmitter. So there should be noting happening, as far as interrupts, during SW UART processing. When the eight bytes are received and processed, this attention signal is not asserted and global interrupts are re-enabled.
The current accessory board that communicates with the receiver, seems to work correctly and I'm producing the same signal manipulations and traffic as it according to o-scope, logic analyser and PC COM port.
Thinking of a plan B, now. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sat Sep 02, 2023 3:07 am |
|
|
OK.
I'd suggest you change in one massive way.
Have a timer programmed to timeout just slightly after the time for all
the bytes.
When you get the signal, start this.
Then receive the bytes just directly into a buffer. Do not try to process them
while receiving. All the loop does is receive all the bytes. If the timer times
out, abort, flag that something is wrong, and stop.
When all eight bytes have been received, then perform the processing.
The key is that you have no time to perform the processing between the
bytes. When one byte finishes the next will start almost immediately. With
the hardware UART, you have the byte time to process. With the software
UART, you do not. The next byte can occur immediately. So you cannot
afford to be doing the processing you show between the bytes. You have to
do this after the transmission completes.
The maths you are doing in the receive CRC part of your code takes too
long. Basically this takes more than the half a bit time you have to get
back waiting for the next byte. Hence your problem. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sat Sep 02, 2023 2:01 pm |
|
|
do all that Mr. T says !!!
The 'failsafe' timer is a must have addition.
Nothing is worse than having a SW UART stuck forever because the serial cable 'magically' disconnected itself midway while collecting bytes.......BTDT...not a great day that was !!!
If you look at CCS manual ,their examples( FAQ section) show a 'timed serial' , though using the HW UART, it's the same 'failsafe' method.
When you cut code, think like the product is bound for Mars and HAS to work no matter what goofy thing, that no one thought of , happens.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Sun Sep 03, 2023 7:32 am |
|
|
The critical thing to understand here is just how little time you have between
bytes. Assuming the bytes are sent 'back to back', the code must be back
at the "if (kbhit" line in less than half a bit time. Now at your serial rate this
is just under 8uSec. If you get back later than this the read code will be
sampling 'late' in the bits. Result the data shift you are seeing. Now the
simple act of saving a byte to an array and incrementing a pointer will take
several uSec, so adding another 5uSec for the maths, takes you out of the
acceptable time. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Sun Sep 03, 2023 4:05 pm |
|
|
One possible 'trick' (learned from Microchip ) is to lower the baudrate.
If possible, change to 19,200 or 9600. That allows a lot of time between bits to do other things......
Early on Microchip's apnotes showed PS2 mouse code, in assembler ( I did say early ! ) and they did a LOT in between bits.
While probably not an option for you, still, it's worth the read. |
|
|
JerryR
Joined: 07 Feb 2008 Posts: 167
|
|
Posted: Mon Sep 04, 2023 7:56 am |
|
|
Solved!
Well guys, I should be whipped for not considering the simplest!
I was returning my attention signal from the addon board, before the last byte transmitted a that caused the serial read to bail out early which corrupted the last one or two bytes. Now have transmitted ~1500 commands without a single CRC mismatch.
Well, I learned a lot and, unfortunately wasted your time. But please accept my sincere thanks for riding along with me.
All the best |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9243 Location: Greensville,Ontario
|
|
Posted: Mon Sep 04, 2023 8:15 am |
|
|
It's always good to 'shake up the gray cells', once in awhile !!
sure glad you FOUND the cause AND a solution....
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19539
|
|
Posted: Mon Sep 04, 2023 9:04 am |
|
|
Key thing is that the software serial does need the whole attention of the CPU.
Sounds as if you were actually interrupting or going to some other code,
either of which would cause a disaster... :(
Glad you have found what was causing it. |
|
|
|