Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 04:18 27 Apr 2024 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 : MM+: Yeah, pause for serial comms......

Author Message
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9061
Posted: 08:27am 30 Nov 2020
Copy link to clipboard 
Print this post

Just spent an hour or two trying to work out WHY a MM+ chip would not respond correctly to serial comms sent to it @ 2400 baud.

The code would not respond, but I could send a message, then CTRL-C stop the code, and manually suck the message from the serial port buffer - and it was perfect.

The problem was that I was LOOP-ing till the code saw something in the buffer, then executing the required data processing - which failed 95% of the time.

I was not using any delay between the LOOP and THEN sucking the data out - something I should have thought of sooner, but there you go!  

The problem was that as soon as the serial port buffer was one byte or greater, the LOOP exited to the next bit of code, which was to extract the code sent and act on it.

It was looping and executing the following code BEFORE the full message had arrived in the buffer.  I forgot how much faster the MM+ is in relation to the MM2, which was sending the data.

Once I detected a byte in the buffer, a simple PAUSE 500 was plenty, to allow all of the message to arrive in the buffer, and then the code on the MM+ executed perfectly.

You gotta remember that the MM+(and by extension, the CMM2 probably) is much faster then a slow-ish serial baud rate, and if you don't wait for all the message to arrive before you process it - well.....enough said.      
Smoke makes things work. When the smoke gets out, it stops!
 
Chopperp

Guru

Joined: 03/01/2018
Location: Australia
Posts: 1032
Posted: 10:29am 30 Nov 2020
Copy link to clipboard 
Print this post

Your sample code for the your Wireless Nodes had a pause in it to wait for all the data to arrive. I thought you would have done that regardless of what processor you were using .

Glad you sorted it out. Something to remember (Along with a million other things)  

Speaking of Wireless nodes, I need to order another one if your are still supplying them.
ChopperP
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1985
Posted: 10:50am 30 Nov 2020
Copy link to clipboard 
Print this post

I tend not to trust the buffer to hold the message anyway - it can arrive in bits and the software has to manage that.

When I am expecting a string, I always have a termination character (often CR or ETX) and I simply extract data from the buffer as it arrives and build it up in a variable. Only when I get my terminator do I then set a flag to say "come and get it".

This way I don't care how slow or punctuated the data dribbles in or how fast/slow the platform is. It just wraps itself around the problem at hand. I snag chars one at a time so I don't have to specially handle the beginning of another message - If you grab all that's available and some of that is a new message after the terminator, you have to "put it back" so as to ensure the following message isn't corrupted.

This bit of code works on CR and runs purely asynchronously with the rest of the code on the main thread - this gives an almost multi-tasking appearance to the running system.


Main:
...
 DO
  IF LOC(#GSM)<>0 THEN
   A$=INPUT$(1,#GSM):C=ASC(A$)
   SELECT CASE C
    CASE 13 'terminator so
     IF LN$<>"" THEN
      LNBuf$=LNBuf$+LN$
      FlagSet GotCR
      EXIT DO
     END IF
    CASE 0 TO 31 'ignore
    CASE ELSE 'agrgregate the string
     LN$=LN$+A$
   END SELECT
  END IF
...
 LOOP


hth

h
 
Tinine
Guru

Joined: 30/03/2016
Location: United Kingdom
Posts: 1646
Posted: 12:34am 01 Dec 2020
Copy link to clipboard 
Print this post

  CaptainBoing said  I tend not to trust the buffer to hold the message anyway - it can arrive in bits and the software has to manage that.

When I am expecting a string, I always have a termination character (often CR or ETX) and I simply extract data from the buffer as it arrives and build it up in a variable. Only when I get my terminator do I then set a flag to say "come and get it".


Yup, we're on the same wavelength. I never wait for the comms buffer. As data comes through, I accumulate it whilst doing other stuff. Pause is rarely used in my programs.  
 
MustardMan

Senior Member

Joined: 30/08/2019
Location: Australia
Posts: 175
Posted: 01:38am 01 Dec 2020
Copy link to clipboard 
Print this post

I too dislike putting fixed delays in my programs (regardless of language). Often it is the easiest solution to a problem, but it always unconsciously 'rubs'.

Most times data has a terminating character, but sometimes it does not.

In assembler I have dealt with the occasional 'variable length data packet with no terminator' situation with timers... I set one of the hardware timers to be the accepted time between bytes, plus some slack. Every time the UART triggers an interrupt (from receiving a byte) I extract the byte into a buffer, and reset the timer. If nothing arrives when the timer interrupt fires, I use that to set a flag 'message complete'. It works really well.

Silly example, receiving keyboard input... set the timer to 3 seconds...
User has a choice of 'yes/no/maybe' (ie: variable length responses), and types 'yes' but forgets to hit the <enter> key. I am not stuck waiting for a <CR> and can respond meaningfully within a reasonable timeframe.

I've never tried it in BASIC - I suspect other latencies would render the procedure rather problematic.

Cheers,
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9061
Posted: 03:59am 01 Dec 2020
Copy link to clipboard 
Print this post

@ ChopperP: Yes, I did, didn't I!  I was a bit drunk last night, so I'll put it down to that. Yes, still have wireless nodes.

@ CaptainBoing & Tinnie: Yes, I WAS saving the data a byte at a time, looking for an EOM byte.  This is pretty much my standard method.  The problem was, that without the pause, when the code tried to read another byte from the buffer, the buffer was empty, so the code did not complete correctly, or exited with the wrong message.  As soon as I detect something in the buffer, wait half a second or so, THEN extract and examine the message.  That works.  You can't save what you haven't got.  Only 2400 baud, and the MM+ at 100MHz can input bytes from the buffer in a loop way faster then the 2400 baud at which they arrive, so if you don't wait for the message to actually arrive in the buffer, you will empty the buffer before the message is complete, and you get a corrupted result or mostly NUL bytes.
Smoke makes things work. When the smoke gets out, it stops!
 
Print this page


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

© JAQ Software 2024