Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 01:51 29 Nov 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 : Capturing serial data with Micromite

Author Message
SteveIzett
Newbie

Joined: 04/05/2023
Location: Australia
Posts: 24
Posted: 02:12am 04 May 2023
Copy link to clipboard 
Print this post

I'm wondering if I could please have some help with capturing rs232 ascii serial data?
I am seeking to extract/parse information from a Dynon Skyview aircraft EFIS system.

I began by seeking to capture and parse a 74 ascii character sentence containing flight data.
The sentence begins with a ‘!’ character and ends the CR & LF characters and contains data like Airspeed and Course etc.

What I have managed to achieve is intermittent. Parsing of a retrieved data string is OK.
The problem is the string containing the target sentence does not reliably begin at the beginning of the sentence, being the ‘!’ character.

Is my understanding correct - I'm thinking that once a serial port is opened, the uart would start buffering incoming characters into a FIFO. But how do you then Input/retrieve that data starting at the beginning of a new sentence.

I thought that was the purpose of the 'int-trigger' option of the Open command.

The code I found/copied used the following:

Open "COM1:9600,80,Com1_Rx_Int,=10" As #1
A buffer larger than the 74 characters of a full sentence. (Maybe to small)
Interrupt triggered by a ‘LF’ character (last character of a sentence)

sub Com1_Rx_Int
  Rx-Flag = 1 'Data available
       Dynon_adahrs$ = input$(82,#1)   'read more chars to ensure the buffer is empty
  Rx_data_error_Flag = 0 'clear a flag ready for error testing
  If len(Dynon_adahrs$) <> 74 then ‘if not the correct sentence length set an error flag
    Rx_data_error_Flag = 1
endif
end sub

In the Main Program Loop
If Rx_Flag = 1 then   'data is available after rx interrupt
If Rx_data_error_flag = 0 Then
Parse the data items of interest and act apporopriately
Clear old sentence data ready for new data
…….


My thinking:
I thought it a good idea to use interrupts to maximise time available for other tasks.
I've seen GPS code that just sits there waiting for a '$' character but that seemed wasteful of processor time.

What I think I’ve learnt is that by the time the interrupt gets the data from the buffer there is no guarantee it begins with a new sentence (‘!’ character).
I thought this was the point of an interrupt being able to be triggered by the reception of a particular character.

I would appreciate being pointed in the right direction so as to enable efficient code that gets a sentence into the Dynon_adahrs string beginning with the first character - ‘!’ character!

Having achieved this, I would then like to be able to read and parse a serial stream contains two different repeating sentences.
Each begins with the ‘!’ character. The second character of each sentence identifies it as either Flight (74 character ADAHRS) data or Engine (225 character EMS) data sentences.

Help would be greatly appreciated.

Sincerely, Steve, Perth WA.
 
Hawk

Senior Member

Joined: 15/07/2021
Location: Australia
Posts: 141
Posted: 02:20am 04 May 2023
Copy link to clipboard 
Print this post

Hi Steve,
Once your interrupt has triggered, have you considered reading the data from the buffer and discarding all the data until you get to the '!' character?  Presumeably this data is the end of a previous message.

You then read data into your message$ until you get a <CR><LF>.  Then process your message$.

You may be better increasing the size of your buffer to store up to two messages, and then raise the interrupt after the <CR><LF> has been received, indicating that there is potentally a whole message ready to process.

Cheers,
Mike
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6101
Posted: 02:20am 04 May 2023
Copy link to clipboard 
Print this post

You need to 'flush' the input buffer before using the received data.

The simplest way with your data is to read each line/packet and discard until the first character of the string is the desired "!"
After that there shouldn't be any lost packets but I would keep the rx buffer at 256 bytes.

Not all mites have the advantage of an interrupt on a specific character so don't be tempted to change chips.

Jim
Edited 2023-05-04 12:21 by TassyJim
VK7JH
MMedit   MMBasic Help
 
SteveIzett
Newbie

Joined: 04/05/2023
Location: Australia
Posts: 24
Posted: 05:45am 04 May 2023
Copy link to clipboard 
Print this post

Thanks Mike and Jim.
I'll. increase the buffer to its default which I think is 256.
How do you flush the receive buffer?
is it by 'Input'ing a larger sample than the buffer and then disregarding it?

Cheers

Steve
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3805
Posted: 06:57am 04 May 2023
Copy link to clipboard 
Print this post

To flush, you'd use a loop reading chars until you find the "!".

But it isn't a good habit to sit looping in an interrupt routine.

I'd stop using the LF (the =10) part.  Also, that will work on 'mites that don't support the =10 thing. Your main routine can easily test for chars being available and process them.

If you keep the =10, just set a flag and have some other part of your program do what you need.

John
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6101
Posted: 07:03am 04 May 2023
Copy link to clipboard 
Print this post

Yes.
read a reasonable size string and discard.
repeat until nothing gets returned.  
This assumes that there is a reasonable time between data packets.

I would set the RX buffer to 1024 bytes to allow for the engines data.

Read a few bytes - 32 would do.
Look for a "!"
if found trim the preceding characters off, determine which packet is being received and fetch the remainder. It might take a couple of reads to gather it all. Just keep asking for whatever the remaining number of characters is.
Do any checking.
Make sure you have the CRLF ending.
I would expect there to be a CRC or at least a checksum.

repeat.


Jim
VK7JH
MMedit   MMBasic Help
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9131
Posted: 07:12am 04 May 2023
Copy link to clipboard 
Print this post

Here is how I would do it:

Open the serial port with an interrupt to trigger every say 20 characters
In the interrupt copy all received data into a longstring using LONGSTRING APPEND
This then runs in the background capturing the data without missing anything

REPEAT
Then in the main program you can use the LINSTR function to find your start character.
Use LONGSTRING TRIM to remove the characters to the left of the start character if any
Test for  CRLF using LINSTR and when found use LGETSTR$ to copy the complete message into a normal string for processing
END REPEAT
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6101
Posted: 07:20am 04 May 2023
Copy link to clipboard 
Print this post

I am not sure if his maximite has LONGSTRING...
VK7JH
MMedit   MMBasic Help
 
SteveIzett
Newbie

Joined: 04/05/2023
Location: Australia
Posts: 24
Posted: 07:50am 04 May 2023
Copy link to clipboard 
Print this post

Im wondering about the pros and cons of the interrupt routine reading one character at a time vs reading a whole buffers worth of data. Any wisdom and code fragments you recommend.

Cheers

Steve
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2140
Posted: 08:10am 04 May 2023
Copy link to clipboard 
Print this post

"Capturing serial data with a MicroMite"

MM2 perhaps?
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3805
Posted: 09:36am 04 May 2023
Copy link to clipboard 
Print this post

I'd read one char at a time in the interrupt unless I had a compelling reason to do otherwise. Save the char. Let the main code deal with it from there.  If you feel like it, the interrupt code could set a flag for "!" seen and another flag for LF seen.

LONGSTRING doesn't look worthwhile here. You're dealing in short simple stuff.

Keep it simple :)

John
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3152
Posted: 01:00pm 04 May 2023
Copy link to clipboard 
Print this post

Micromite offers interrupt upon receipt of a specific character, e.g.:
OPEN "COM1: 300, 256, MyInt, =10"

will interrupt upon receipt of linefeed. See Appendix A – Serial Communications.
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
SteveIzett
Newbie

Joined: 04/05/2023
Location: Australia
Posts: 24
Posted: 02:22pm 04 May 2023
Copy link to clipboard 
Print this post

Thanks everyone. Very helpful.
I'll have a go tomorrow.
Cheers

Steve
 
SteveIzett
Newbie

Joined: 04/05/2023
Location: Australia
Posts: 24
Posted: 12:20pm 05 May 2023
Copy link to clipboard 
Print this post

Hi people.

I increased the size of the buffer and the code works just fine.
Thanks again for the help.

Steve
 
Print this page


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

© JAQ Software 2024