Sequencing of outputs for a 7 segment display

Hello Guys,
I have been working over a project in which i have around 10 small pumps in a line at a distant place in my farm and if any one of them gets stop i wants to display its respective number over a Seven Segment display in my place. I am using ESP8266 LOLIN NodeMcu and a custom made common cathode 7 segment led.

I am successful in communicating NodeMCU and i can also know which pump is stopped but the main issue arise here because the data from pumps are a single bit status either ON or OFF so for 10 pumps 10 bit parallel data is input each bit shows the status of each pump.
When i transfer this data over the WiFi, my Receiver side code also inputs it as a parallel data, so for EXAMPLE : If Pump No. 1 is stopped i have a high bit at the Pump 1 status and i can process it to get a Numeric Value "1" display over the 7 segment display
But suppose if Pump No. 1 and Pump No.6 both stops at same time then code fails as it process both inputs at one time and the output at display seems to be a fusion of number "1" and "6" ie all led high or number "8" on output display.

So For this Concern if two or more pump stops, i want it to show the status of one pump for a few seconds → then a small delay of all led Off → then the other one stopped one and so on.
I tried everything like logic using Delays, millis, if and for loops but i am unable to achieve this condition

So i request if any of the kind hearts could help me here in this concern, i am also attaching my Server and Client both sketches you can also review it. But the code is upto the single bit parallel outputs only.

Thanks & Regards,
Rajat Sharma

Modified_Direct_Server.ino (3.85 KB)

Modified_Direct_Client.ino (4 KB)

Please read the instructions for posting to understand how to show your code.

I suggest you get a ready-made display module with a MAX7219 driver such as this.

This gives you eight digits and is controlled by just three Arduino pins. Not worth your while putting it together yourself and this gives you many more options in the display - including some slightly odd-looking but readable words. :grinning:

If you wish to proceed as you have indicated, I'd suggest the following as below. However, 10 LEDs are the natural way to display the information. You'd need a 16 bit port expander or two 8 bit shift registers or something similar. You could even arrange the LEDs in a matrix and use a single MAX7219 chip.

Put sensorValue1 to sensorValue10 in an array.
In the loop() , you check every 5 or so seconds if there is something to display by advancing from the current position (that is the current sensor value you are displaying - if any) and stopping when you have either found one or you have advanced 10 positions (wrapping around if necessary). When you find an active sensorValue to display, you have to store an index to it.

So, for example, say both sensorValue2 and sensorValue8 are active.

In the first check period, you advance to sensorValue2. You stop because you find it active and display 2.
In the next check period, you advance from sensorValue2 to sensorValue8. You stop because you find it active and display 8.
In the next check period, you advance from sensorValue8 to sensorValue2, wrapping round at the end of the array. You stop because you find it active and display 2. This repeated.
When 2 and 8 are no longer active, in the next check period you stop scanning after checking 10 array positions, from the current position, wrapping round as necessary.

Pseudocode

for each sensor input
{
  if sensor input is active
  {
    clear display
    display sensor number
    delay 1 second
  }
}

or

for each sensor input
{
  if sensor input is active
  {
    display sensor number
    delay 1 second
  }
  else    clear display
}

aarg:
Pseudocode

for each sensor input

{
  if sensor input is active
  {
    clear display
    display sensor number
    delay 1 second
  }
}



or


for each sensor input
{
  if sensor input is active
  {
    display sensor number
    delay 1 second
  }
  else    clear display
}

Thanks for the suggestion, but i already tried this.
This works well in Arduino Uno but it fails in NodeMCU. :frowning: :frowning: :frowning:

I think this technique use delays and since delay blocks the program this don't let the data to transfer.

Anyways thanks, if any other support you have, please share its really appreciated

Anyways thanks, if any other support you have, please share its really appreciated

Here is how you implement a for loop using a state machine:

for(i=3; i<6; i++) {<somecode>}

decomposes as the sequence

i=3;
while (i<6) {
<somecode>
i++;
}

For the state machine you would do something like

if (state == INITIALIZE) {
 i=3;
 state = RUN;
}
else if (state == RUN and i<6) {
 <somecode>
 i++;
}
else {
 state = IDLE;
}

To activate it, you just assert:

state = INITIALIZE;

Or, you can use a switch case statement:

switch (state) {

case:INITIALIZE
   i=3;
   state = RUN;
   break;

case:RUN
 if (i<6) {
   <somecode>
   i++;
  }
  else
  {
    state = IDLE;
  }
 break;

case: IDLE
  break;
}

I just noticed that something is incomplete in the switch/case part... I think because I'm using my laptop and the example didn't get updated there. Treat it as a starting point. The if-else version is correct.

EDIT - I updated the switch/case...

. . . since delay blocks the program . . .

An ESP8266 is very intolerant of blocking code. Usually delay() statements are OK because these, on an ESP8266, do not fully block. In any loop which may be protracted, use the yield() statement to free the processor for other activities.

Anyway, failures due to blocking code trigger a vary visible "WDT" (watch dog timer) error in the serial console. Are you seeing these ?