Combining code, help please

hi guys, i have to sets of code that i need to combine into one;

the first, this is the one that needs to be included into the second, its basically an led random breathing program. For those star trek fans out there, im using this for the bussard collectors on the nacelles.

heres the code

//random led breathing

#include <math.h>                             // mathematical functions
#define ledNumber 2                           // number of leds used
int ledPins[ledNumber] = { 1, 0, };    // assign the PWM pins
float fadingInterval[ledNumber];              // fading time variable
int remainingIntervals[ledNumber];
int ledPin1 = 2;
int ledPin2 = 3;
//------------------------------------------------------------------------------
void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  //Serial.begin(115200);
  randomSeed(analogRead(0));
  for (int i = 0; i < ledNumber; i++)
  {
    fadingInterval[i] = random(1000, 3000);       // assign random fading time
    remainingIntervals[i] = fadingInterval[i];
   // Serial.print("remainingIntervals[i]  "); Serial.println(remainingIntervals[i]);
  }
}
//------------------------------------------------------------------------------
void loop() {
  analogWrite(ledPin1, 135);
  analogWrite(ledPin2, 135);
  for ( int i = 0; i < ledNumber; i++)
  {
    float b = (exp(sin(remainingIntervals[i] / fadingInterval[i] * PI)) - 0.975) * 145.0;
    //Serial.print("b  "); Serial.println(b);
    if (i == 1 || i == 5)     // if led on pin 10 or 9
      b = b * 2.0;             // bright  0.2x  less
    //Serial.print("b2  "); Serial.println(b);
    analogWrite(ledPins[i], b);

    if (!--remainingIntervals[i]) {
      fadingInterval[i] = random(1000, 3000);
      remainingIntervals[i] = fadingInterval[i];
    }
  }
}

now heres the core code, everything in this code currently works exactly as it should, as you can see its gone through multiple revisions to get it cooperating and as condensed as possible, but its a nice bit of coding. it has 4 spare pwm pins available and the code to be integrated only needs 3 pins (only 2 are pwm)

here it is

// The Enterprise revision 2.48

#include <LedFader.h>
#include <LedFlasher.h>

// pin assignments
const byte StrobesPin = 13;
const byte NavigationPin = 12;
const byte DeflectorbluePin = 11;   // PWM controls nacelles and impulse engines
const byte DeflectororangePin = 10;    // PWM controls nacelles and impulse engines
//unused pin 9 pwm
const byte CabinPin = 8;
const byte ShuttlebayPin = 7;
//unused pin 6 pwm
//unused pin 5 pwm
const byte TorpedoPin = 4;
//unused pin 3 pwm
const byte RCSPin = 2; 


// Faders                           pin           min  max  millis    on?    stop?
LedFader deflectororangeFader (DeflectororangePin, 0,   40,  3000,   false,  true);
LedFader deflectorblueFader   (DeflectorbluePin,   0,   40,  3000,   false,  true);

// Flashers                pin          off-time  on-time       on?
LedFlasher strobes    (StrobesPin,        1700,      100,     false);
LedFlasher navigation (NavigationPin,     3500,      100,     false);

// states for the state machine
typedef enum
  {
  initialState,
  wantCabin,                 // ALWAYS ON
  wantRCS,                   // ALWAYS ON
  wantStrobes,               // ALWAYS ON
  wantTorpedostartup,        // ALWAYS ON  
  wantDeflectororangestartup,// Startup mode
  wantShuttleBaystartup,     // Startup mode
  wantImpulseorangestartup,  // Startup mode
  wantNacellvioletstartup,   // Startup mode
  wantShuttleBayon,          // Impulse mode
  wantTorpedoon,             // Impulse mode
  wantShuttleBayoff,         // Warp mode
  wantTorpedooff,            // Warp mode
  wantImpulseMode,
  wantWarpMode,
    
  } states;

// state machine variables
states state = initialState;
unsigned long lastStateChange = 0;
unsigned long timeInThisState = 1000;

void setup ()
  {
  pinMode (CabinPin, OUTPUT);
  pinMode (RCSPin, OUTPUT);
  pinMode (ShuttlebayPin, OUTPUT);
  pinMode (NavigationPin, OUTPUT);
  pinMode (StrobesPin, OUTPUT);
  pinMode (TorpedoPin, OUTPUT);
  
  // set up faders, flashers  
  deflectororangeFader.begin ();
  deflectorblueFader.begin ();
  strobes.begin ();
  navigation.begin ();
  }  // end of setup
        
void doStateChange ()
  {
  lastStateChange = millis ();    // when we last changed states
  timeInThisState = 1000;         // default one second between states

  switch (state)
   {
    case initialState:
         state = wantCabin;
         break;
         
    case wantCabin:
         digitalWrite (CabinPin, HIGH);
         state = wantRCS;
         break;
         
    case wantRCS:
         digitalWrite (RCSPin, HIGH);
         state = wantDeflectororangestartup;
         break;
         
    case wantDeflectororangestartup:
         deflectororangeFader.on();
         state = wantShuttleBaystartup;
         break;
 //doors open here         
    case wantShuttleBaystartup:
         digitalWrite (ShuttlebayPin, HIGH);
         state = wantStrobes;
         break;
         
    case wantStrobes:
         strobes.on();
         navigation.on();
         state = wantTorpedostartup;
         break;
         
    case wantTorpedostartup:
         digitalWrite (TorpedoPin, HIGH);
         state = wantImpulseMode;              
         timeInThisState = 30000;
         break;
         
//impulse mode
    case wantImpulseMode:
         deflectorblueFader.off();
         deflectororangeFader.on();
         state = wantShuttleBayon;
         break;
         
//doors need to open here         
    case wantShuttleBayon:
         digitalWrite (ShuttlebayPin, HIGH);
         state = wantTorpedoon;
         break;
         
    case wantTorpedoon:
         digitalWrite (TorpedoPin, HIGH);
         state = wantWarpMode;
         timeInThisState = 30000;  
         break;
         
//warp mode         
   case wantWarpMode:
        deflectororangeFader.off();
        deflectorblueFader.on();
        state = wantShuttleBayoff;
        break;
        
//doors need to close here        
   case wantShuttleBayoff:
        digitalWrite(ShuttlebayPin, LOW);
        state = wantTorpedooff;
        break;
        
   case wantTorpedooff:
        digitalWrite(TorpedoPin, LOW);
        state = wantImpulseMode;
   timeInThisState = 30000;     
         // what next?
         break;
         
    
         
    }  // end of switch on state
  }  // end of doStateChange


void loop ()
  {
   if (millis () - lastStateChange >= timeInThisState)
     doStateChange ();
   // update faders, flashers
   deflectororangeFader.update ();
   deflectorblueFader.update ();
   navigation.update ();
   strobes.update ();
  // other stuff here like testing switches
  }  // end of loop

now i have no idea where to begin combining the two, essentially, the bussards (led breathing program) needs to activate at the same time as the nacelles in the startup section of the code and continue indefinatly.

i could use your guys expertise here and really appreciate the help

You will need to rewrite the first (breathing) code to be none blocking. Your for loops block so they must run all the way through before they relinquish control.

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

Replace the for loop with an if, else if, else structure. Make so that it does 1 iteration (step) of the for loop code for each time through loop or each time that a step is due as indicated by a timer.

thats going to be a problem because i dont even see how its blocking.

I see. The for loops execute very quickly.

1 Like

Sometimes it is as simple as merging the code lines of the 2 setup() functions and merging the code lines of the 2 loop() functions. If neither code is "blocking", this should, in principal, work.

generic code combining:

look at the structure of all code:

#include<this_library>
#include<that_library>

#define this_variable
#define that_variable

( objects derived from libraries )
RTC_DS3231 rtc;
( with related defines )
#define RTC_INT_PIN 04 // the pin that is connected to SQW on the RTC
#define TEST_PIN 38 // middle pushbutton as system test

...so you can cut and paste it into another program

a wall of variable declarations:

float temperature_C;
float temperature_F;
float pressure_hPa;
float Pressure;
float pressure_inHg;
float Humidity;
float seaLevelPressure_hPa;
float seaLevelPressure_inHg;
float dewpoint_F;
float dewpoint_C;
String fsbid;
String loRaMessage;
String alarmStatus;
String temperature;
String pressure;
String humidity;
String readingID;

choose one program as the host. chop the other one into sections. copy the library includes from the code to be inserted and drop it into the libraries. section of the host cut the defines from the code to be inserted and drop it into the defines section of the host

I strive to put the setup functions into the sequence they will be called during setup, and keep these RUN ONCE functions in a separate block from CALLED ROUTINES which can be called multiple times from different places

every big program you encounter was created by splicing shorter code together. every experienced programmer has known good code he can drop into new code. when you encounter large programs, study them. not for what they do; for how the programmer arranged and combined and organized and commented them.

Using floats is slow enough, trig functions is just asking for it.
I pre-table sine values for one quadrant, I have them for all and cosine is the same data in reverse. Arduino IDE lets you store tables in program space. I store unsigned ints = sine x 10000. I do the math in 32 bit unsigned long to prevent overflow... radius x table value / 10000 gives me 4 places.
I store 90 degrees and if I need closer I interpolate like it's the early 70's.

I use the fastled library for WS28xx addressable RGB leds. I change the LEDS array and call the .show() function.

You have options you're not exploring.

The only weird thing I see in your code is that you update lastStateChange inside the called doStateChange () function instead of doing it inside the true clause itself, this way :

   if (millis () - lastStateChange >= timeInThisState) {
      lastStateChange += timeInThisState;
      doStateChange (); // <-- THIS FUNCTION SHOULD NOT MODIFY THE "lastStateChange" VARIABLE
   }

But even without, combining codes should be straight forward. Just append the various sections together as previously mentioned.

okay so im still concerned about the first reply saying how the breathing led is blocking, but i cant see where its actually performing the block (so to speak)

i see what your all saying about chop shop the codes. and will give it a go but also, dont see the point if the breathing code is actually blocking.

ok so here it is, i bit the bullet but could use a second oppinion before i load it up

// The Enterprise revision 2.48

#include <LedFader.h>
#include <LedFlasher.h>
#include <math.h>                             // mathematical functions
#define ledNumber 2  

int ledPins[ledNumber] = { 6, 5, };    // assign the PWM pins
float fadingInterval[ledNumber];              // fading time variable
int remainingIntervals[ledNumber];

// pin assignments
const byte StrobesPin = 13;
const byte NavigationPin = 12;
const byte DeflectorbluePin = 11;   // PWM controls nacelles and impulse engines
const byte DeflectororangePin = 10;    // PWM controls nacelles and impulse engines
//unused pin 9 pwm
const byte CabinPin = 8;
const byte ShuttlebayPin = 7;
//unused pin 6 pwm
//unused pin 5 pwm
const byte TorpedoPin = 4;
//unused pin 3 pwm
const byte RCSPin = 2; 

int ledPin1 = 9;
int ledPin2 = 3;

// Faders                           pin           min  max  millis    on?    stop?
LedFader deflectororangeFader (DeflectororangePin, 0,   40,  3000,   false,  true);
LedFader deflectorblueFader   (DeflectorbluePin,   0,   40,  3000,   false,  true);

// Flashers                pin          off-time  on-time       on?
LedFlasher strobes    (StrobesPin,        1700,      100,     false);
LedFlasher navigation (NavigationPin,     3500,      100,     false);

// states for the state machine
typedef enum
  {
  initialState,
  wantCabin,                 // ALWAYS ON
  wantRCS,                   // ALWAYS ON
  wantStrobes,               // ALWAYS ON
  wantTorpedostartup,        // ALWAYS ON  
  wantDeflectororangestartup,// Startup mode
  wantShuttleBaystartup,     // Startup mode
  wantImpulseorangestartup,  // Startup mode
  wantNacellvioletstartup,   // Startup mode
  wantShuttleBayon,          // Impulse mode
  wantTorpedoon,             // Impulse mode
  wantShuttleBayoff,         // Warp mode
  wantTorpedooff,            // Warp mode
  wantImpulseMode,
  wantWarpMode,
    
  } states;

// state machine variables
states state = initialState;
unsigned long lastStateChange = 0;
unsigned long timeInThisState = 1000;

void setup ()
  {
  pinMode (CabinPin, OUTPUT);
  pinMode (RCSPin, OUTPUT);
  pinMode (ShuttlebayPin, OUTPUT);
  pinMode (NavigationPin, OUTPUT);
  pinMode (StrobesPin, OUTPUT);
  pinMode (TorpedoPin, OUTPUT);
  
  // set up faders, flashers  
  deflectororangeFader.begin ();
  deflectorblueFader.begin ();
  strobes.begin ();
  navigation.begin ();

  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  //Serial.begin(115200);
  randomSeed(analogRead(0));
  for (int i = 0; i < ledNumber; i++)
  {
    fadingInterval[i] = random(1000, 3000);       // assign random fading time
    remainingIntervals[i] = fadingInterval[i];
   // Serial.print("remainingIntervals[i]  "); Serial.println(remainingIntervals[i]);
  }
  
  }  // end of setup
        
void doStateChange ()
  {
  lastStateChange = millis ();    // when we last changed states
  timeInThisState = 1000;         // default one second between states

  switch (state)
   {
    case initialState:
         state = wantCabin;
         break;
         
    case wantCabin:
         digitalWrite (CabinPin, HIGH);
         state = wantRCS;
         break;
         
    case wantRCS:
         digitalWrite (RCSPin, HIGH);
         state = wantDeflectororangestartup;
         break;
         
    case wantDeflectororangestartup:
         deflectororangeFader.on();
         state = wantShuttleBaystartup;
         break;
 //doors open here         
    case wantShuttleBaystartup:
         digitalWrite (ShuttlebayPin, HIGH);
         state = wantStrobes;
         break;
         
    case wantStrobes:
         strobes.on();
         navigation.on();
         state = wantTorpedostartup;
         break;
         
    case wantTorpedostartup:
         digitalWrite (TorpedoPin, HIGH);
         state = wantImpulseMode;              
         timeInThisState = 30000;
         break;
         
//impulse mode
    case wantImpulseMode:
         deflectorblueFader.off();
         deflectororangeFader.on();
         state = wantShuttleBayon;
         break;
         
//doors need to open here         
    case wantShuttleBayon:
         digitalWrite (ShuttlebayPin, HIGH);
         state = wantTorpedoon;
         break;
         
    case wantTorpedoon:
         digitalWrite (TorpedoPin, HIGH);
         state = wantWarpMode;
         timeInThisState = 30000;  
         break;
         
//warp mode         
   case wantWarpMode:
        deflectororangeFader.off();
        deflectorblueFader.on();
        state = wantShuttleBayoff;
        break;
        
//doors need to close here        
   case wantShuttleBayoff:
        digitalWrite(ShuttlebayPin, LOW);
        state = wantTorpedooff;
        break;
        
   case wantTorpedooff:
        digitalWrite(TorpedoPin, LOW);
        state = wantImpulseMode;
   timeInThisState = 30000;     
         // what next?
         break;
         
    
         
    }  // end of switch on state
  }  // end of doStateChange


void loop ()
  {
   if (millis () - lastStateChange >= timeInThisState)
     doStateChange ();
   // update faders, flashers
   deflectororangeFader.update ();
   deflectorblueFader.update ();
   navigation.update ();
   strobes.update ();
  // other stuff here like testing switches

  analogWrite(ledPin1, 135);
  analogWrite(ledPin2, 135);
  for ( int i = 0; i < ledNumber; i++)
  {
    float b = (exp(sin(remainingIntervals[i] / fadingInterval[i] * PI)) - 0.975) * 145.0;
    //Serial.print("b  "); Serial.println(b);
    if (i == 1 || i == 5)     // if led on pin 10 or 9
      b = b * 2.0;             // bright  0.2x  less
    //Serial.print("b2  "); Serial.println(b);
    analogWrite(ledPins[i], b);

    if (!--remainingIntervals[i]) {
      fadingInterval[i] = random(1000, 3000);
      remainingIntervals[i] = fadingInterval[i];
    }
  }
  }  // end of loop

its not pretty but seperated the 2 codes by empty lines for locating the seperate codes, if all goes well, then i'll neaten it up

He actually already replied post #4 :

=> no blocking code there, the for() loop will execute so quickly, any workaround would be a loss of time. (while(), do...while() and for() loops are to be avoided but only if they really take time)

now i see, i did wonder what was meant by that. it was a little cryptic aha.

well then, i'll link up the wires tomorrow and load up the code. (the arduino nano is already installed into the model along with all the wiring loom. for those interested its a 4ft long model of the enterprise e)

i was originally going to use a seperate digispark board to drive the bussard collectors effect but decided i'd go ahead and modify the main code to integrate the bussards. but needed a little nudge which you guys gave, so i appreciate that.

hopefully all goes well tomorrow, after a long day of running a good 200m of wires and much soldering i need sleep aha

You are running tasks besides running two leds?

pinMode (CabinPin, OUTPUT);
  pinMode (RCSPin, OUTPUT);
  pinMode (ShuttlebayPin, OUTPUT);
  pinMode (NavigationPin, OUTPUT);
  pinMode (StrobesPin, OUTPUT);
  pinMode (TorpedoPin, OUTPUT);
  
  // set up faders, flashers  
  deflectororangeFader.begin ();
  deflectorblueFader.begin ();
  strobes.begin ();
  navigation.begin ();
  }  // end of setup
 

Less cycles for your code!

The float use you do, needs major optimizing but for you to see.....

Make debug prints with micros time stamps (miilis is not good for small values or differences) to show how long it takes a process to let other processes run. How long to run each for-next loop with no guessing.

If you have 2 non-blocking sketches to combine, make them into functions and put both function calls in loop and the variables they need into the sketch and both should run if there's room on the chip. How fast they run depends on how much they do in loop(). But if they don't use the same variable names, they should run independent of each other.

But really, time how long those floating point higher level operations take and just what you're trying that can't be done in a few percent of the cycles? Be aware that micros ticks once every 4 ms, the low 2 bits are always zero. Millis is worse and it takes paragraphs to lay that out.
In close timing, micros() is your overkill friend. 1 micro is 16 cycles.

ok so i loaded it up, but the bussards come on immedately, so i was wondering how i'd go about adding in a delay of the code beginning and the bussards turning on but not blocking so the remainder of the code activates and the bussards come on in time with the nacceles.

Your comments say pins 9 and 3 are unused . . . and then they're used.

yeah i commented those lines for reference when combining codes is all. thats why they are only comments.

My intro to business code was fixing bugs in the company accounting package. I person wrote (his PhD thesis) and 4 others fixed on a rush basis to where I learned to only read the code and since then for me the code is the comments especially when it's got bugs! The comments don't mention those, how good is that?
Don't get me wrong, it's real nice when the code does what the comments say, how they say but when they go sort of XY the comment is good as a crash investigation, the wreckage tells more than the mayday.

so back to the point, is it possible to write in a delay to get the breathing code element to begin at a certain time after initial power up?

Try not to think "delay" (it's too convenient to think of a function with the same name), try to think "passage of time"

How about for forum archive purposes we go through merging small non-blocking sketches like blink a led on time with count loop()s per second and print that every second? Later, buttons and debounce where the real world effects affect your code is worth a step of its own?