Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 11:08 01 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Gremlin in the UART works ?

Author Message
Bowden_P
Senior Member

Joined: 20/03/2019
Location: United Kingdom
Posts: 162
Posted: 12:56am 20 Nov 2020
Copy link to clipboard 
Print this post

Hi all,
I have been reading the post by MustardMan about the use of the UART with great interest. It has been quite a revelation I must say about UART technique! Many thanks Grogster and others too.

This post continues from my previous post "MM Comms via UART" of 12-Nov-20, sending and receiving random strings between 2 x MM v2 Backpacks, with input using a touch keypad. That worked successfully, so I set about including the code in my project, which uses an MM+ E100 as Sender, and an MM v2 Backpack as Receiver.

Using the code developed above, I thought it a good idea to prove the code in my project by sending a series of strings of 25 random characters of ASCII 32 to 126 - all printable characters. The string is sent straight back from the Receive end, and the Sender then checks that the sent and received strings are identical. The code sends 20 strings in total - 500 characters.

The code refused to work whatever I did, editing both the Sender and Receiver ends to keep them compatible. After a long session I gave up, and went to bed. The next day I switched on and everything worked perfectly! Another long session, and I eventually nailed the "cause" - if you can call it that.

It needs a specific sequence to fail - and this is where it gets really odd, but having repeated the sequence many times it seems to be true.

The sequence to a failure is to "edit" BOTH Sender and Receiver programs, save, then run them - guaranteed fail to communicate every time! Rerun, and there is a pass every time from there on. "Edit" just one end OR the other, and there is no problem. The "edit" here means just delete then retype a character - no overall change at all. Just editing without any change doesn't cause a fail.

To get at what might be the problem, I flushed the Rx Buffers immediately after opening the Comm ports with an INPUT$ instruction, and sure enough there was my Gremlin - one chr$(0) in each. This ONLY happens when BOTH ends are edited with a "change", and ONLY on the first run after the "edit".

Has anyone got an insight into what is happening here?

With best regards, Paul.
Nothing so constant as change.
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 03:15am 20 Nov 2020
Copy link to clipboard 
Print this post

Hi there.

The UART's have been extensively tested, and I use them all the time(hundreds of PCB's now), and I have never seen that issue.

The transmitting and receiving ends are not aware of each other, so there should be no way that you HAVE to edit BOTH ends before you see this problem.

I suspect floating input pins on both unit's RX line to the COM port.  Do you have pull-up resistors on the RX lines?  If not, please fit one to each.  10k should be fine.  The idea is to give the RX line a very firm idle-high signal right from the point you switch on or run the code.  Without them, when code makes the lines high, the other end might interpret that as a bit of data or somehow is deciding that there is a byte of value zero, so it saves it in the buffer.

Pull-up resistors SHOULD prevent that from happening, IF that is the reason.

Keep us posted on your progress.  If I find time at the weekend, I will hook up to E28's to talk to each other like that, and see if I can also replicate your issue.
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 04:50am 20 Nov 2020
Copy link to clipboard 
Print this post

Rule number 1.
Always flush out the serial buffers when starting your program.
There can be all sorts of half sent messages there to confuse the issue.

Jim
VK7JH
MMedit
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 2170
Posted: 08:33am 20 Nov 2020
Copy link to clipboard 
Print this post

Rule 2
Never expect the UART to have precisely what you want when you want it. For machine-to-machine comms, always have clear start and end markers for a frame of data and always get to a known state before you start assembling a "frame" of data on the receive side. Ignore everything until you get your start marker and possibly anything after your end marker (unless it is another start). ASCII has special characters for precisely this as a hangover from comms years ago; STX and ETX. Your payload them comes in between these two - but it is only a convention, you can use any characters you like:

jhsdfjhqkdf<STX>hello world<ETX>sjkkekehrwkr
\ ignored /     \ payload /     \ ignored /

Take a look at the packet structure halfway down the protocol section here for ideas: http://www.fruitoftheshed.com/MMBasic.Short-range-radio-network-not-WiFi-SLAVE-module-Uses-cheapie-433MHz-modules-or-HC-12.ashx?HL=stx


On the subject of assembling the frame of data, do it under your control as data arrives.

* One character at a time is fairly fool-proof for looking for your start and end markers, but slower.
* Accepting all available data is faster but you need to make arrangements for when you have the end of one frame and the beginning of the next in a single INPUT$.
Edited 2020-11-20 19:07 by CaptainBoing
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9610
Posted: 09:49am 20 Nov 2020
Copy link to clipboard 
Print this post

Rule 3: Always validate your data AFTER you have received what you THINK is a valid packet.

I do this in one system, by reading the data bytes in one-at-a-time looking for the EOM(end of message) marker byte, which I usually use decimal 27 - Escape.

Once you have the packet, I check its length.  If the length is wrong, it is assumed to be a corrupted packet, and the data is discarded.  If the length is correct, I perform the next test: Check for a valid byte at a SPECIFIC place inside the data packet.  In my case, packets contain a mode byte, and it is always in the same place in the packet, so I analyse that to find out if it is one of the few valid ones.  If not, the packet is discarded.

You could also do the checksum method which has been around for donkeys years.
Take your data packet, ADD UP all the decimal values of all the ASCII bytes that make up the message, and add that as a byte(or two - depending on length) to the end of your packet then send THAT.

At the receiving end, you read the bytes, then you decode the checksum byte(s) and save that value in a variable.  You then add up the decimal values of all the ASCII bytes received in the message, and compare that value, to the checksum value.  If they both match, the data is valid.  If they don't match, the data was garbled from one end to the other.

Checksum is a really simple and easy method to confirm valid data, and despite its age(it is part of the COM spec from 40+ years ago!), it still works very well to validate data.

You don't HAVE to apply any of these rules, but it is a good idea, as it will make your serial handling code robust and relatively problem-free.
Smoke makes things work. When the smoke gets out, it stops!
 
Bowden_P
Senior Member

Joined: 20/03/2019
Location: United Kingdom
Posts: 162
Posted: 12:46pm 20 Nov 2020
Copy link to clipboard 
Print this post

Hi Grogster, CaptainBoing and TassyJim,
Thanks for all your replies. The chorus of Rules from 3 different posters is very informative - many thanks.

Grogster -
I absolutely agree with you - edit pre-history just can't be a factor in this, but it is SO consistent I had to mention it!
I didn't doubt the UART firmware. As you say, being tested extensively over many applications would have exposed any bugs.

In the Initialisation sub of my project code I make a simple handshake with the UART lines to confirm the connections. This starts with the Tx pins digital output HIGH, and the Rx pins as digital inputs. After all the DIM's etc, I have a sequence of Sender drives LOW/ Receiver responds LOW, Sender then drives HIGH/Receiver responds HIGH. All pins are then cleared to OFF before the Comms OPEN instruction.

I don't have pullup resistors on the lines, so I'll fit those.When I looked at the Rx pins when not connected to a Tx pin I found they have an o/c o/p of 2V, and a pullup current of about 300uA when connected to 0V.There is no current sink above 2V, when connected to the 3.3V supply.

Many thanks for your time and plan to experiment with a couple of E28's.

As for validating packets and checksums, I am just getting wise to this!

TassyJim -
Thanks for that confirmation of flushing the Rx buffer. During my debugging, a painfully slow discovery!

CaptainBoing -
Thanks for the link. I have bookmarked it for detailed study.

I initially had code to validate each character as it came in - as per Geoff's example code in the manuals, but found it to be slow as you state, about 2000baud was reliable.

I changed to a fixed packet size, with the UART interrupt set to that size, and speed increased dramatically - 1 Megabaud+, even with the MM v2 Backpack at one end, and both end's clocks at 40MHz. A character informs the Rx when the data string is spread across more than 1 packet, and the code re-assembles the data successfully. At the moment I don't send multiple packets in a burst, but one-at-a-time with a sufficient delay between for the Rx interrupt and main loop processing to complete on each one.

Defining a packet is clearly important to maintain sync, so I'll work on that.

With best regards, Paul.

p.s. I gave up increasing the baud rate when the Backpack gave an error "Baud rate too high" at 2.36 MegaBaud.
Nothing so constant as change.
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 08:39pm 20 Nov 2020
Copy link to clipboard 
Print this post

A possible cause of the failure after every double edit could be that after an edit (and obvious save) the interpreter is 'reset' to a fresh state, and the UART ports (pins) are turned to floating inputs. Then when your program starts, it opens the ports and receives what it thinks is a start bit. With no transitions following, a solitary start bit is interpreted as a 0x00.

After it has operated/run once, perhaps the pins don't quite go into the same state, so you don't get a false start bit, and hence get nothing in the buffer? Just a guess.

With many years of hardware under my belt, I've seen some weird (but eventually explainable) things. And I still fall into traps.

My latest project (a dual channel RS485 device) I had left the 'mode' control pins of both 485 drivers floating (connected to the micro, but not driven). After driving the control pins things were good, but until that time I was getting no end of trouble. Probing the pins they looked fine. However, looking at a consequential signal it was all over the place! Probing the 'mode' pin made it stable.

The assumption that the uP weak-pull-up would default the 'mode' to high was wrong. After a couple of 10K resistors it worked fine. The lesson keeps coming back time and again - if you want a particular default state, deliberately pull to that state, and don't ever rely on the uP to do it for you.
 
Bowden_P
Senior Member

Joined: 20/03/2019
Location: United Kingdom
Posts: 162
Posted: 12:00am 21 Nov 2020
Copy link to clipboard 
Print this post

Hi all,
Having fitted 10K pullup resistors to the Rx ends of each line, I have seen NO more occurrences of spurious characters at all after many tries of combinations of editing, non-editing, power-on etc, so I think that Gremlin is truly squashed! Many thanks Grogster for that advice.

As mentioned above I found that an Rx pin has a pullup to 2v, with no current flow above this, so any coupled mains or micro-generated pickup may have influenced things when the Comms ports were being set up - who knows! I don't know what the switching thresholds are for the Rx pin, but a 2v level isn't far off mid rail, leaving the pin vulnerable to pickup. I'll be leaving the Rx buffer flush in the code too, just to make sure of a clean start.

One last thing - very roughly how long a cable can the Comms ports drive. I am using audio twin individually screened cable for the connection 1m long. Would you expect to be able to drive to say 5m without any buffering?

Thanks to all posters for your inputs, With regards, Paul.
Nothing so constant as change.
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3378
Posted: 12:07am 21 Nov 2020
Copy link to clipboard 
Print this post

  Bowden_P said  One last thing - very roughly how long a cable can the Comms ports drive. I am using audio twin individually screened cable for the connection 1m long. Would you expect to be able to drive to say 5m without any buffering?


I don't know precisely for the CMM2, but for the Armmite H7 and F4, I was able to successfully transmit over 50 feet of CAT6. This was without extensive testing for reliability.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 07:08am 21 Nov 2020
Copy link to clipboard 
Print this post

Generally the faster you go the shorter the length.

John
 
Bowden_P
Senior Member

Joined: 20/03/2019
Location: United Kingdom
Posts: 162
Posted: 12:36pm 21 Nov 2020
Copy link to clipboard 
Print this post

Hi Lizby and JohnS,
Wow - 50 feet is impressive straight from the chip pins! There must be a significant capacitance in the cable at that length. I don't intend to extend beyond my current 1m, and will stick to about 230400 baud, even though I have seen complete reliability at higher speeds in my setup.

With regards, Paul.
Nothing so constant as change.
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025