Sequence of outputs

int Enable_output = 0;
int Vi_output = 0;
int Vn_output = 0;
int Up_output = 0;
int Dwn_output = 0;

long StartTime = 0;
long interval = 60000;

void setup() {

  pinMode(48, OUTPUT);                                      //TIC Enable switch pin 48 = output
  pinMode(47, OUTPUT);                                      //TIC Vi switch pin 47 = output
  pinMode(43, OUTPUT);                                      //TIC Vn switch pin 43 = output
  pinMode(39, OUTPUT);                                      //TIC Dwn switch pin 39 = output
  pinMode(35, OUTPUT);                                      //TIC Up switch pin 35 = output
  digitalWrite(48, LOW);                                    //Write Enable switch low on startup
  digitalWrite(47, LOW);                                    //Write Vi switch low on startup
  digitalWrite(43, LOW);                                    //Write Vn switch low on startup
  digitalWrite(39, LOW);                                    //Write Dwn switch low on startup
  digitalWrite(35, LOW);                                    //Write Up switch low on startup
}

void loop() {

  unsigned long currentTime = millis();
  unsigned long previousTime = currentTime - StartTime;
  if (previousTime > interval) {
    StartTime = currentTime;
  }

  if (previousTime < 5000) // 0 to 10 second point in the 50 second loop
{
    Vi_output = LOW;
    Vn_output = LOW;
    Up_output = LOW;
    Dwn_output = LOW;
    Enable_output = LOW;
  }
  if (previousTime > 5000 && currentTime < 35000 )  // if inbetween 20 to 25 second point in the 50 second loop
  {
    Vi_output = HIGH;
    Vn_output = LOW;
    Up_output = HIGH;
    Dwn_output = LOW;
    Enable_output = HIGH;
  }
  if (previousTime > 35001 && currentTime < 55001 ) // if inbetween 25 to 35 second point in the 50 second loop
  {
    Vi_output = LOW;
    Vn_output = HIGH;
    Up_output = HIGH;
    Dwn_output = LOW;
    Enable_output = HIGH;
  }
  if (previousTime > 55001 && currentTime < 60000 )  // if inbetween 25 to 35 second point in the 50 second loop
  {
    Vi_output = LOW;
    Vn_output = LOW;
    Up_output = LOW;
    Dwn_output = LOW;
    Enable_output = LOW;
  }
  digitalWrite(48, Enable_output); //Enable
  digitalWrite(47, Vi_output);// Vi
  digitalWrite(43, Vn_output); //Vn
  digitalWrite(35, Up_output); //Up
  digitalWrite(39, Dwn_output); //Dwn
}

I am trying to produce a combined state of outputs within a 60second period.

0-5sec = all outputs low //standby time
5-35sec = vi, up and enable high //up at speed 1
35-55sec = vn, up and enable high //up at speed 2
55-60sec = all outputs low //standby time

If I manually write the pins without using any timing function the outputs switch fine, so wiring and connections is not an issue.

Please could anyone offer any help, I have looked at the millis tutorials but can't see the error?

0-5sec = all outputs low //standby time
5-35sec = vi, up and enable high //up at speed 1
35-55sec = vn, up and enable high //up at speed 2
55-60sec = all outputs low //standby time

You never do anything with 'dwn'. Why not just connect it to ground and save yourself a pin?

Also didn't you mean

  if (previousTime > 5000 && previousTime < 35000 )  // if inbetween 5 to 35 second point in the 50 second loop

instead of

  if (previousTime > 5000 && currentTime < 35000 )  // if inbetween 20 to 25 second point in the 50 second loop

Did you notice that a lot of your // comments are wrong?

Here:

  if (previousTime < 5000) // 0 to 10 second point in the 50 second loop
...
  if (previousTime > 5000 && currentTime < 35000 )  // if inbetween 20 to 25 second point in the 50 second loop

What happens if previousTime == 5000?

Why didn't you give names to your output pins?

you are all mixed up in your variables names

  if (previousTime > 5000 && currentTime < 35000 )  // if inbetween 20 to 25 second point in the 50 second loop

previousTime is already the the ∆t, currentTime is millis...

You never do anything with 'dwn'. Why not just connect it to ground and save yourself a pin?

Sorry the "Dwn" pin was something that I am planning on using when expanding this sequence, ive removed it for brevity. See amended code below.

Did you notice that a lot of your // comments are wrong?

Again, apologies....I had been changing my mind on the duration of each section, please see the amended code below.

What happens if previousTime == 5000?

My eventual aim is to continuously loop between the following two sequences, but for simplicity I am just trying to get the first sequence to work first.
NOTE: I've changed the timings and edited the original post, please see the code below.

SEQUENCE 1:
0-5sec = all outputs low //standby time
5-20sec = up and enablelow speed //up at speed 1
20-40sec = up and enable high speed //up at speed 2
40-55sec = up and enable low speed //up at speed 1
55-60sec = all outputs low //standby time

SEQUENCE 2:
0-5sec = all outputs low //standby time
5-20sec = down and enablelow speed //down at speed 1
20-40sec = down and enable high speed //down at speed 2
40-55sec = down and enable low speed //down at speed 1
55-60sec = all outputs low //standby time

int Enable_output = 0;
int Vi_output = 0;
int Vn_output = 0;
int Up_output = 0;

long StartTime = 0;
long interval = 60000;

void setup() {

  pinMode(48, OUTPUT);                                      //TIC Enable switch pin 48 = output
  pinMode(47, OUTPUT);                                      //TIC Vi switch pin 47 = output
  pinMode(43, OUTPUT);                                      //TIC Vn switch pin 43 = output
  pinMode(35, OUTPUT);                                      //TIC Up switch pin 35 = output
  digitalWrite(48, LOW);                                    //Write Enable switch low on startup
  digitalWrite(47, LOW);                                    //Write Vi switch low on startup
  digitalWrite(43, LOW);                                    //Write Vn switch low on startup
  digitalWrite(35, LOW);                                    //Write Up switch low on startup
}

void loop() {

  unsigned long currentTime = millis();
  unsigned long previousTime = currentTime - StartTime;
  if (previousTime > interval) {
    StartTime = currentTime;
  }

  if (previousTime < 5000)                           // 0 to 5 second point in the 60 second loop
    // all switch output off, stationary
  {
    Vi_output = LOW;
    Vn_output = LOW;
    Up_output = LOW;
    Enable_output = LOW;
  }
  if (previousTime > 5000 && previousTime < 20000 )  // if inbetween 5 to 20 second point in the 60 second loop
    // Travel up at low speed
  {
    Vi_output = HIGH;
    Vn_output = LOW;
    Up_output = HIGH;
    Enable_output = HIGH;
  }
  if (previousTime > 20001 && previousTime < 40000 ) // if inbetween 20 to 40 second point in the 60 second loop
    // Travel up at high speed
  {
    Vi_output = LOW;
    Vn_output = HIGH;
    Up_output = HIGH;
    Enable_output = HIGH;
  }
  if (previousTime > 40001 && previousTime < 55000 )  // if inbetween 40 to 55 second point in the 60 second loop
    // Travel up at low speed
  {
    Vi_output = HIGH;
    Vn_output = LOW;
    Up_output = HIGH;
    Enable_output = HIGH;
  }
  if (previousTime > 55001 && previousTime < 60000 )  // if inbetween 55 to 60 second point in the 60 second loop
    // all switch outputs off
  {
    Vi_output = LOW;
    Vn_output = LOW;
    Up_output = LOW;
    Enable_output = LOW;
  }
  digitalWrite(48, Enable_output);               //Enable
  digitalWrite(47, Vi_output);                   //Vi low speed
  digitalWrite(43, Vn_output);                   //Vn high speed
  digitalWrite(35, Up_output);                   //Up direction

}

0-5sec = all outputs low //standby time
5-35sec = vi, up and enable high //up at speed 1
35-55sec = vn, up and enable high //up at speed 2
55-60sec = all outputs low //standby time

..then it was..

SEQUENCE 1:
0-5sec = all outputs low //standby time
5-20sec = up and enablelow speed //up at speed 1
20-40sec = up and enable high speed //up at speed 2
40-55sec = up and enable low speed //up at speed 1
55-60sec = all outputs low //standby time

SEQUENCE 2:
0-5sec = all outputs low //standby time
5-20sec = down and enablelow speed //down at speed 1
20-40sec = down and enable high speed //down at speed 2
40-55sec = down and enable low speed //down at speed 1
55-60sec = all outputs low //standby time

Who's up and who's down now?

-jim lee

Try this.

long StartTime = 0;
long interval = 60000;

unsigned char viPin = 47;
unsigned char vnPin = 43;
unsigned char upPin = 35;
unsigned char enablePin = 48;

unsigned char pinList[] = { enablePin, viPin, viPin, viPin };
const int pinListLength = sizeof(pinList) / sizeof(pinList[0]);

void setup() {
  for (int i = 0; i < pinListLength; i++) {
    pinMode(pinList[i], OUTPUT);
    digitalWrite(pinList[i], LOW);
  }
}

void loop() {

  unsigned long currentTime = millis();
  unsigned long previousTime = currentTime - StartTime;
  if (previousTime > interval) {
    StartTime = currentTime;
  }

  if (previousTime < 5000)                           // 0 to 5 second point in the 60 second loop
    // all switch output off, stationary
  {
  digitalWrite(viPin, LOW);
  digitalWrite(vnPin, LOW);
  digitalWrite(upPin, LOW);
  digitalWrite(enablePin, LOW);
  }
  else if (previousTime < 20000 )  // if inbetween 5 to 20 second point in the 60 second loop
    // Travel up at low speed
  {
  digitalWrite(viPin, HIGH);
  digitalWrite(vnPin, LOW);
  digitalWrite(upPin, HIGH);
  digitalWrite(enablePin, HIGH);
  }
  else if (previousTime < 40000 ) // if inbetween 20 to 40 second point in the 60 second loop
    // Travel up at high speed
  {
  digitalWrite(viPin, LOW);
  digitalWrite(vnPin, HIGH);
  digitalWrite(upPin, HIGH);
  digitalWrite(enablePin, HIGH);
  }
  else if (previousTime < 55000 )  // if inbetween 40 to 55 second point in the 60 second loop
    // Travel up at low speed
  {
  digitalWrite(viPin, HIGH);
  digitalWrite(vnPin, LOW);
  digitalWrite(upPin, HIGH);
  digitalWrite(enablePin, HIGH);
  }
  else // if inbetween 55 to 60 second point in the 60 second loop
    // all switch outputs off
  {
  digitalWrite(viPin, LOW);
  digitalWrite(vnPin, LOW);
  digitalWrite(upPin, LOW);
  digitalWrite(enablePin, LOW);
  }
}

You have a difficult time with inequalities!
This:

 if (previousTime > 40001 && previousTime < 55000 )  // if inbetween 40 to 55 second point in the 60 second loop
...  }
  if (previousTime > 55001 && previousTime < 60000 )  // if inbetween 55 to 60 second point in the 60 second loop

Consider what numbers are excluded... 55000 and 55001... so your tests would miss them completely.

IF you are comfortable with grabbing libraries off github and installing them..

This should do the trick for you..

#include <comPlayer.h>

// These are currently set for some LEDs I had hooked up.
#define VI_PIN       3//47
#define VN_PIN       9//43
#define UP_PIN       10//35
#define ENABLE_PIN   13//48



// *********** class that sets your output pins *********** 
//
// This would be the .h part..
//
// *********** 

class setPins : public comObj {

   public:
                     setPins(bool viState,bool vnState,bool upState,bool enableState);
      virtual        ~setPins(void);

      virtual  void  doCommand(void);

               bool  mViState;
               bool  mVnState;
               bool  mUpState;
               bool  mEnableState;
};



// *********** class that sets the output pins *********** 
//
// This would be the .cpp part..
//
// ***********


setPins::setPins(bool viState,bool vnState,bool upState,bool enableState)
   : comObj(0) {

   mViState = viState;
   mVnState = vnState;
   mUpState = upState;
   mEnableState = enableState;
}


setPins::~setPins(void) {  }

void setPins::doCommand(void) {

   digitalWrite(VI_PIN,mViState);
   digitalWrite(VN_PIN,mVnState);
   digitalWrite(UP_PIN,mUpState);
   digitalWrite(ENABLE_PIN,mEnableState);
}



// *********** This is the main code part *********** 
//
// For now it just has my best guess at sequence one. Later, if this works
// You can setup sequence two and try swapping them in and out. Once the code
// "sees" there is commands in the list, it auto start playing them.
//
// Therefore to start a list, fill it with commands. To make it run over and over
// call it's repeat() method to with true. And it'll run forever. To stop a repeating
// list from running, call its clearComs() method. This will dump out the commands.
// Fill to start, clear to stop.
//
// IF multiple sequences are filled with commands? They will run concurrantly.
// (At the same time) Now wouldn't that be fun?
//
// ***********


comPlayer   sequence;

void setup(void) {
   
   pinMode(VI_PIN,OUTPUT);
   pinMode(VN_PIN,OUTPUT);
   pinMode(UP_PIN,OUTPUT);
   pinMode(ENABLE_PIN,OUTPUT);
   //setupSeqence1();
   //sequence.repeat(true);
   setupSeqence2();
   sequence.repeat(true);
}

 
void setupSeqence1(void) {

   setPins* comPtr;
   sequence.clearComs();  // Dump whatever is in there now.
   
   comPtr = new setPins(false,false,false,false);  // 0-5sec  = all outputs low // standby time
   sequence.addCom(comPtr);  
   comPtr = new comObj(5000.0);
   sequence.addCom(comPtr);

   comPtr = new setPins(true,false,true,true);   // 5-20sec = up and enablelow speed // up at speed 1
   sequence.addCom(comPtr);
   comPtr = new comObj(15000.0);
   sequence.addCom(comPtr);

   comPtr = new setPins(false,true,true,true);    // 20-40sec = up and enable high speed //up at speed 2
   sequence.addCom(comPtr);
   comPtr = new comObj(20000.0);
   sequence.addCom(comPtr);
   
   comPtr = new setPins(true,false,true,true);    // 40-55sec = up and enable low speed //up at speed 1
   sequence.addCom(comPtr);
   comPtr = new comObj(5000.0);
   sequence.addCom(comPtr);

   comPtr = new setPins(false,false,false,false);  // 55-60sec = all outputs low //standby time
   sequence.addCom(comPtr);
   comPtr = new comObj(5000.0);
   sequence.addCom(comPtr);
}



// For now a test sequence.
void setupSeqence2(void) {

   setPins* comPtr;
   sequence.clearComs();  // Dump whatever is in there now.
   
   comPtr = new setPins(false,false,false,false);
   sequence.addCom(comPtr);  
   comPtr = new comObj(1000.0);
   sequence.addCom(comPtr);
   
   comPtr = new setPins(true,false,false,false);
   sequence.addCom(comPtr);  
   comPtr = new comObj(1000.0);
   sequence.addCom(comPtr);

   comPtr = new setPins(false,true,false,false);
   sequence.addCom(comPtr);  
   comPtr = new comObj(1000.0);
   sequence.addCom(comPtr);

   comPtr = new setPins(false,false,true,false);
   sequence.addCom(comPtr);  
   comPtr = new comObj(1000.0);
   sequence.addCom(comPtr);

   comPtr = new setPins(false,false,false,true);
   sequence.addCom(comPtr);  
   comPtr = new comObj(1000.0);
   sequence.addCom(comPtr);
}


void loop(void) {
   
   idle();  // Non blocking call that runs the list thing.
   // Want to do other things in loop()? Go ahead just DON'T USE delay();
}

What it is, is a sequencer. This one has been setup for your 4 outputs. Each step will either write out the 4 outputs or wait for a specified time. set, wait, set, wait.. and as written it will do this over and over.

The neat thing is, its completely modifiable. Don't like the list, just edit it. Want multiple different lists? Setup different list filling functions. Need another output? You can see how I added them in, add in another.

There are two libraies you will need to make this work. LC_baseTools from the library manager. And LC_comPlayer from github here is the link to that.

Good luck, If you need help installing the second library let me know.

-jim lee

Also, I thought of several ways you could improve the inline version (yours, mine) without the library (which would be fine too). But I didn't go that far because it seemed more appropriate to let you think about it for a while and maybe see the same things. Really, the pin configurations (e.g. HIGH, LOW, HIGH, HIGH) should be in an array or struct, with a function to set the pins based on the contents of a selected element. Another approach, which might also dovetail with that, is that you could have 3 functions, e.g. runHalt(), runSlow(), runFast() that set the pins. Then your timing section would only be a few lines long, and much easier to comprehend.

void  runHalt() {
    Vi_output = LOW;
    Vn_output = LOW;
    Up_output = LOW;
    Enable_output = LOW;
  }
...
  if (previousTime < 5000)                          // 0 to 5 second point in the 60 second loop
    // all switch output off, stationary
    runHalt();
  else if (previousTime < 20000 )  // if inbetween 5 to 20 second point in the 60 second loop
    // Travel up at low speed
    runSlow();
...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.