How to organize code for a count down time based sequence to multiple Outputs NASA style?

I could use a programming nudge..

I am set to make a mock NASA-like Launch Control panel based off a 'T-' countdown and 'T+'countup - centered around a larger 7-seg LED display of course. I'd also like to feature LEDs to represent the engine quincunx, fuel, panel indicators with 'ignition', 'liftoff', 'stage sep' etc and so on. (My plan would include more than 10 and less than 100? LEDs) All this to start from a minute or two before launch and on to about the first stage separation sequence ~3 min... Official audio tracks to play in background and in sync with the clock. I'm also wanting to add inputs by switches and buttons but concerned more about organizing the outputs to a specific and time based sequence that would mimic what you'd see sitting at the Booster console in 1969.

Question:
(1) for the precise clockwork- should I use a DS3231 or something else?
(2) rather than piles of if <clock = time> ..then statements how to organize the LEDs and code - a 2D array perhaps?
(3) I've seen a setup where an Arduino polls switch throws and send forth output to LEDs and reports to an RPi that masters the operations and plays audio..

Appreciate a guiding thought or a push in a direction.

Thanks!

Sounds like a job for the Giga

aren't all these events scheduled during a launch cycle, so aren't they at planned times?

and do you just an LED(s) to turn on?

couldn't you just have a table of times and an LED pin # to turn on?

What kind of precision do you need? Using millis() timing over 3 minutes would not be off by more than a few 10s of milliseconds, if that. DS3231 is great for keeping time of day (one second resolution).

Data in a 2D array with a state machine. Take a look toward the end of this state machine tutorial page. >> https://github.com/j-bellavance/Tutorials/blob/master/State%20machines%20Tutorial/Part%201/State%20machine%20with%20Arduino%20Part%201.pdf

Those can be added to the state machine.

Some non-blocking timing tutorials:
Blink without delay().
Blink without delay detailed explanation
Beginner's guide to millis().
Several things at a time.

Interesting. Sounds like a cool project. Please post video when it is done,.

2 Likes

Is that GigaDevice with the Arm Cortex?

Dual core, yes.

Yes, that's why I proposed the Array.. But I'm wondering if an array that big might bog down the MCU... any ideas?

Thanks - I'll have a look at that link. I'm good on the use of millis() to prevent time blockage - no problem there. But I do know arrays that get kinda big can get dirty. Also, I am wondering how to catch the events when watching the clock as most times the code is elsewhere at the exact moment I want. Any ideas besides using if time >1:00 and <1:01 kinda catch?

With non-blocking code the code execution is never anywhere for very long. The loop() function should repeat hundreds if not thousands of times each second. Code written like that can be very responsive. The several things at a time illustrates how to do that.

While loops and for loops are not used, in non-blocking code, unless they are very short in duration.

A network of remote MCUs running their own code to control their one device with a main MCU synchronizing time and initiating remote MCU routines. MIL-STD-1553

1 Like

Measuring the arrays+for(;;) loop code you pointed out in #4, it checks at 23K loops/sec for a responsiveness of 42us.

/*
 LightShow.ino
 Author: Jacques Bellavance
 Released: October 13, 2017
           under GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 b

 This code is to demonstrate the use of state machines in an Arduino sketch.
 It is fully explained in the tutorial: State machine with Arduino (Part 1)

  Changes from the previous sketch are shown with <<<<<

*/

//We use tables for the attributes of each LED

enum LedStates{ON, OFF};                                      //The two possible states for an LED
LedStates ledState[8] = {ON, ON, ON, ON, ON, ON, ON, ON};     //<<<<<All LEDs start states are ON
byte ledPin[8] = {2, 3, 4, 5, 6, 7, 8, 9};                    //<<<<<The pins for the LEDs (Don't forget resistors for all LEDs)
int delayOff[8] = {5240, 2560, 1280, 640, 320, 160, 80, 40};  //<<<<<The time in milliseconds that each LED will stay off
int delayOn[8] =  {2560, 1280,  640, 320, 160,  80, 40, 20};  //<<<<<The time in milliseconds that each LED will stay on
unsigned long chrono[8];

void blinkMachine(byte i) {                         //<<<<<We added a parameter: the index for the LED [0..7]
  switch (ledState[i]) {                              //<<<<<Use ledState of LED i
    case OFF: {                                         //state is OFF
      if (millis() - chrono[i] >= delayOff[i]) {          //<<<<<Use chrono and delayOff of LED i
        chrono[i] = millis();                               //<<<<<Reset chrono of LED i
        digitalWrite(ledPin[i], HIGH);                      //<<<<<Write HIGH to LED i 
        ledState[i] = ON;                                   //<<<<<State of LED i is now ON
      }
      break;                                              //Get out of switch
    }
    case ON: {                                          //state is ON
      if (millis() - chrono[i] >= delayOn[i]) {           //<<<<<Use chrono and delayOff of LED i
        chrono[i] = millis();                               //<<<<<Reset chrono of LED i
        digitalWrite(ledPin[i], LOW);                       //<<<<<Write LOW to LED i 
        ledState[i] = OFF;                                   //<<<<<State of LED i is now OFF
      }
      break;                                           //Get out of switch
    }
  }
}

void setup() {
  for (byte i = 0 ; i < 8 ; i++) {      //<<<<<For all leads [0..7]
   pinMode(ledPin[i], OUTPUT);            //<<<<<The pin mode of LED i is OUTPUT
   digitalWrite(ledPin[i], HIGH); }       //<<<<<Bring the pin of LED i HIGH (We said that Start state of all LEDs is ON on line 17)
   Serial.begin(115200);
}

void loop() {
  for (int i = 0 ; i < 8 ; i++)      //<<<<<For all leads [0..7] 
    blinkMachine(i);                   //<<<<<Run the machine with LED i
  report();
}


void report(){
  static uint32_t count = 0;
  static uint32_t last = 0;
  ++count;
  if(millis() - last < 1000) return;
  last += 1000;
  Serial.print(" iterations:");
  Serial.print(count);
  Serial.print(" msPerIteration:");
  Serial.print(1000.0/count,3);
  Serial.println();
  count = 0;
}
 iterations:23607 msPerIteration:0.042
 iterations:23707 msPerIteration:0.042
 iterations:23684 msPerIteration:0.042
 iterations:23665 msPerIteration:0.042
2 Likes

Can you recommend a source to acquire?

how big, how many events?

gcjr - I don't have an exact number but, I don't want to be too limited. A lot happens at during the launch phases. One complication is this, I'd like to incorporate other outputs - like vintage panel meters, possibly a OLED spewing fake data, one of those matricies like a Caution and Warning style - maybe 9 or so LEDs with that in a 3x3. Cost my pull me back.

so would having a table with events/actions that take place at scheduled times work? there could be different types of actions: turning on/off an LED, change in text on some display, oled or 7-segment, moving a servo.

each table entry could have a time, device-type, device-iD, info.

some code to wait for one or more of the next table entry times to come to pass. a device type identifies some code to process the info for a specific device of that type, turn on/of led, display text on that device, move a servo to some position. may not be that much code but a lot of data

Yes, gcjr - now we're talking! That's what I am thinking - and that could make for easy changes and additions as I go along.. exactly what I am thinking. I'm wondering about the consequences from a lot of data as you say and the limits inside of an array.

Even with lots of LEDs, they may not need a huge array of distinct "events". For instance a 100 LED progress graph might be controlled by a single function that updates the 100 LEDs event that is called by one periodic event celled every 100ms. One of the arrays might be of pointers to callback functions, with each controlling a lot of data that need not be stored in the array.

xfpd: Been rolling this option around in my head. It could be a good way to go but it's just costly. I figured one master MCU could host the clock and report time to the slaves and display time on the LED display. In ways I could build out smaller at first and then add-on sub panels. You think i2c or serial for this?

For low-volume data:

The only one I know is the online store that's sold out. Sorry.