Devising code to output fault message strings inbetween routine strings

I am writing a program which takes analog and digital measurements and outputs them to serial, a four line LCD and SD card once per second (using Millis). While processing the data it also looks for faulty/out of range measurements using if() commands.

For each 'fault' that is identified it successfully displays a corresponding fault message string on one line of the LCD for that second instead of one of the routine input measurement strings, however I would like each fault message string to display for three seconds. With there being four lines on the display, should I use four individual Millis examples with 3000ms intervals for this, or is there a better way?

Additionally, if more than four faults are due to be displayed at any one time how would I integrate a queue, while keeping each string on the same line of the display for the entire three second duration?

Your thoughts are very much appreciated.

DataL: For each 'fault' that is identified it successfully displays a corresponding fault message string on one line of the LCD for that second instead of one of the routine input measurement strings, however I would like each fault message string to display for three seconds. With there being four lines on the display, should I use four individual Millis examples with 3000ms intervals for this, or is there a better way?

This is a little confusing.

Your first line suggests that only one line of the LCD is used for fault messages. However your subsequent text gives the impression that there may be 3 separate fault messages on 3 different lines.

Assuming there are 3 different messages and each starts at a different time then, yes, each one needs its own timer.

Supposing that the message on line1 is the oldest what happens when its 3 seconds are up and there are still fault messages on lines 2 and 3?

Or you could make all the messages stay visible until 3 seconds after the newest message is displayed - that would only require one timer.

...R

With there being four lines on the display, should I use four individual Millis examples with 3000ms intervals for this, or is there a better way?

That depends on whether you want to update the lines that do not have errors independently of the lines that do have errors.

how would I integrate a queue

Pushing data onto a queue, popping data from a queue, and determining if there is anything in the queue are simple things. The key is defining the node to be pushed/popped. What that node will look like isn't clear, since we don't know what you need in the node. Perhaps a 16 element array containing the message and a byte containing the line number. A queue is relatively easily implemented as a doubly linked list. The downside of a queue is the need to dynamically allocate and free memory, which is in limited supply generally. But, it IS possible to do.

Robin2: This is a little confusing.

Your first line suggests that only one line of the LCD is used for fault messages. However your subsequent text gives the impression that there may be 3 separate fault messages on 3 different lines.

Assuming there are 3 different messages and each starts at a different time then, yes, each one needs its own timer.

Sorry, it's a little confusing to me too. I can envisage it, but how to put it in to words. Yes, each fault message will consume a whole on the display. It is a four line display, and any number of those lines can be displaying fault messages, with the potential for many more messages in a queue.

Robin2: Supposing that the message on line1 is the oldest what happens when its 3 seconds are up and there are still fault messages on lines 2 and 3?

If there are queued messages, the oldest in the queue will be assigned to that line for the next three seconds. If there are no more queued messages then it will display the relevant line of a different set of strings; those which display the analog and digital input measurements. That aspect works okay with the current one second duration fault message display using an if() for each line. I'll see if Millis doesn't interupt it.

PaulS: Pushing data onto a queue, popping data from a queue, and determining if there is anything in the queue are simple things. The key is defining the node to be pushed/popped.

Could you give me an example of a node in relation to a queue?

In allocating the queue memory would I have to presume a maximum queue length?

The fault messages are currently formed using snprintf as needed, from a fault number (given at time of fault identification) and a description string saved to progmem.

A related question is how best to store several dozen fault description strings, pointed to by their respective fault numbers. I only mention that now incase it is relevant, otherwise I'll leave it to another time.

Could you give me an example of a node in relation to a queue?

struct node
{
   char message[20];
   byte lineNumber;

   struct node *prev;
   struct node *next;
};

Then, to add the node to a linked list, you need a list class with a head node, a tail node, and methods to add a node to one end and to remove (and return) the node at that end.

Any C book will cover linked lists in plenty of detail.

They are a very good way to learn about pointers and how to access pointed to data.

Edit: Forgot the * on the next and prev pointers.

PaulS:
Any C book will cover linked lists in plenty of detail.

They are a very good way to learn about pointers and how to access pointed to data.

Great, thanks Paul. I’ll do some reading.