Async serial result dependency design pattern/code

Hmm, started messing with the cellular module driver, and soon realized that the sophistication required to ensure that expected results are delivered from the module in a timely manner is more difficult than first ancipated.

I have Googling and looking into codeshare for inspiration without being able to find anything usable.

The serial communication in the cellular module is running in its own thread, receiving stuff from the module, and only printing it, and checking for know errors in the return values, but not being able to get back on a specific request. Basically it does not relate calls and return values.

This works in test setup, but as I am moving on, I need to improve this significantly.

Any inspiration appreciated. :slight_smile:

How about passing a structure with all required data for the request and a callback delegate. As soon as the request is done the callback can be used to report back. Similar to how it is done in .Net

Take a look at this code…its only working because I step through it…

Return values from all calls should be checked, and basically error-handling and maybe return-value-dependent logics should be deployed…

I like your idea but I think its not the right pattern for the job…?


                serialLine.Write("AT+CMMSINIT \r\n"); // Init
                serialLine.Write("AT+CMMSINIT=? \r\n"); // Init
                serialLine.Write("AT+CMMSCURL=\"http://mmsc.tdc.dk:8002\"\r\n "); // MMS center
                serialLine.Write("AT+CMMSCID=1\r\n");  // bearer context id
                serialLine.Write("AT+CMMSPROTO=\"194.182.251.15\",8080 \r\n");
                serialLine.Write("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\" \r\n");
                serialLine.Write("AT+SAPBR=3,1,\"APN\",\"mms\"\r\n");
                serialLine.Write("AT+SAPBR=1,1\r\n");
                serialLine.Write("AT+SAPBR=2,1\r\n");
                serialLine.Write("AT+CMMSEDIT=1\r\n"); //Start creation
                serialLine.Write("AT+CMMSDOWN=\"PIC\"," + image.Length.ToString() + ",5000000\r\n");
                Thread.Sleep(5000); //Need to wait for CONNECT
                serialLine.Write(image);
                serialLine.Write("AT+CMMSRECP=\"+4522169XXX\"\r\n");
                serialLine.Write("AT+CMMSVIEW \r\n");
                serialLine.Write("AT+CMMSSEND \r\n");
                serialLine.Write("AT+CMMSEDIT=0 \r\n");

:think:

@ njbuch - I don’t see you reading back responses. Are there any responses?

Yeah, for each command the module returns with a copy of the command (in some case, and if command-echo is on) and a return value. Which often is OK but also can be values, timestamps, signal-strength and more.

In the above example there is a few places where it would be VERY relevant to check for return values, but I had no imperatives to do it, so thats the reason for this question.

According to @ John this issue is on the list of stuff to do on the cellular driver, I assume he might have an idea about how to solve this.

@ njbuch

Seems very simple to me, unless I’ve missed something.
Start with reading from the serial port where you do need the result. Then parse the string to get the data.

You might find something useful in my rs232 codeshare code:
https://www.ghielectronics.com/community/codeshare/entry/748

There is a SendLine function that sends a message and waits for the return message. It only blocks the thread that calls it. (there is a message queue that tracks command/responses) It has survived some good random testing with multiple threads flooding the serial port with messages.

1 Like

Wauw, this looks promising. Thanks a lot.

Can you confirm that I need the SugaredSerial and SugaredPort classes only, and using them correctly from the cellulardriver would be the trick?

yes, those are low level classes and don’t need anything else. They should be pretty clean.