Pages: [1]   Go Down
Author Topic: trigger for solenoid valves and high-speed strobe... skipping millis.  (Read 1616 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello. i'm thinking about building a trigger that fires off a sequence of pneumatic 12V solenoids valves (LEDs at this point) and a high-speed flash for some photography work. I've purchased one of these: http://arduino-direct.com/sunshop/index.php?l=product_detail&p=155 and am slowly making progress on the code. fyi, my skill level is still pretty basic.

the first code i wrote worked great, but included delays which made it tricky to control the simultaneous opening 2 "valves". i dug around the forum and found a bit of code that doesn't use delay and is what this is based on.

Code:
/// code based on http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1288016644/15#15

const int relay1Pin = 12; // the number of the Relay pins
const int relay2Pin = 11;
const int relay3Pin = 10;
const int relay4Pin = 9;
const int flashPin = 8; // opto-isolator anode connected to digital pin 8
const int buttonPin = 2;

int flashState = LOW;
int globalReset = 4000;

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(relay1Pin, OUTPUT); // initialize the Relay pins as an output:
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  pinMode(flashPin, OUTPUT); // declare flashPin as as OUTPUT
  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{

  if (btnMillis != 0)
  {  
    unsigned long timePassed = millis() - btnMillis;
    int relay1Delay = 1000;
    int relay1Duration = 1500;  
    int relay2Delay = 1250;
    int relay2Duration = 1500;
    int relay3Delay = 1450;
    int relay3Duration = 1600;
    int relay4Delay = 1550;
    int relay4Duration = 1700;
    int flash1Delay = 1500;
    int flash1Duration = 20;
    int relay1Timer = relay1Delay+relay1Duration;
    int relay2Timer = relay2Delay+relay2Duration;
    int relay3Timer = relay3Delay+relay3Duration;
    int relay4Timer = relay4Delay+relay4Duration;
    int flash1Timer = flash1Delay+flash1Duration;
    
    //Flash
    if (timePassed >= flash1Delay && timePassed <= flash1Delay)
    {
flashState = HIGH;
       digitalWrite(flashPin, flashState); // trigger flash by bringing digital output to high
    }

    if (timePassed >= flash1Timer && timePassed <= flash1Timer)
    {
flashState = LOW;
         digitalWrite(flashPin, flashState); // set it back to low
    }
    
    //Relay 1
    if (timePassed >= relay1Delay && timePassed <= relay1Delay+50)
    {
digitalWrite(relay1Pin, HIGH); //turn on Relay 1 pin
    }

    if (timePassed >= relay1Timer && timePassed <= relay1Timer+50)
    {
digitalWrite(relay1Pin, LOW); //turn off Relay 1 pin
    }


    //Relay 2
    if (timePassed >= relay2Delay && timePassed <= relay2Delay)
    {
digitalWrite(relay2Pin, HIGH); //turn on Relay 2 pin
    }

    if (timePassed >= relay2Timer && timePassed <= relay2Timer)
    {
digitalWrite(relay2Pin, LOW); //turn off Relay 2 pin
    }
    
    //Relay 3
    if (timePassed >= relay3Delay && timePassed <= relay3Delay)
    {
digitalWrite(relay3Pin, HIGH); //turn on Relay 3 pin
    }

    if (timePassed >= relay3Timer && timePassed <= relay3Timer)
    {
digitalWrite(relay3Pin, LOW); //turn off Relay 3 pin
    }
    
    //Relay 4
    if (timePassed >= relay4Delay && timePassed <= relay4Delay)
    {
digitalWrite(relay4Pin, HIGH); //turn on Relay 4 pin
    }

    if (timePassed >= relay4Timer && timePassed <= relay4Timer)
    {
digitalWrite(relay4Pin, LOW); //turn off Relay 4 pin
    }
    
    
    //Longest off time, to re-enable the button
    if (timePassed >= globalReset)
    {
btnMillis = 0;
    }
  }
}

void btnDown()
{
  if (btnMillis != 0) return;
  btnMillis = millis();
}

the problem i'm having, is that it's erratically not turning on/off a light or popping off the strobe. wondering if this has anything to do with the button not being bounced? still trying to figure that one out with the attachInterrupt.

would be grateful if someone could see what's being overlooked or has any suggestions.

thanks!

« Last Edit: April 27, 2011, 07:34:26 pm by photony » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so i've tried a few things in trying to find out where the problem is coming from to no avail. it still seems to be skipping random "if" statements.

i've tried changing the if statements from:
Code:
if (timePassed >= relay1Timer && timePassed <= relay1Timer)
to:
Code:
if ((timePassed >= relay1Timer) && (timePassed <= relay1Timer))
then tried:
Code:
if (timePassed == relay1Delay+relay1Duration)

also added a debounce inside the interrupt. sounds like this is not recommended, but has been used with success on the forum... not so in my case. smiley-wink

i finally just paired down the interrupt to :

Code:
void btnDown()
{
    btnMillis = millis();
}
doesn't look like the interrupt was the problem.

still on the hunt.

perhaps i'm asking this in the wrong forum and should be posting this in the programming forum?
Logged

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8474
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I haven't looked at the code yet but there's an error in the schematic, you need a current-limiting resistor for the opto LED.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8474
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This isn't a problem but bad practice

 
Code:
 
    int relay1Delay = 1000;
    int relay1Duration = 1500; 
    int relay2Delay = 1250;
    int relay2Duration = 1500;
    int relay3Delay = 1450;
    int relay3Duration = 1600;
    int relay4Delay = 1550;
    int relay4Duration = 1700;
    int flash1Delay = 1500;
    int flash1Duration = 20;
    int relay1Timer = relay1Delay+relay1Duration;
    int relay2Timer = relay2Delay+relay2Duration;
    int relay3Timer = relay3Delay+relay3Duration;
    int relay4Timer = relay4Delay+relay4Duration;
    int flash1Timer = flash1Delay+flash1Duration;

You are creating a heap of local variables every time loop() is run when they are really just constants. Use #define of "const int" and put them outside the function.

______
Rob

Logged

Rob Gray aka the GRAYnomad www.robgray.com

0
Offline Offline
Full Member
***
Karma: 2
Posts: 156
It was all digital
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi photony

I would do arrays for controling this.
Somthing like this:

Code:
// 4 Realys + strope
// Relays from output 12 to 9
// Strope on output 2

const int elements = 5;
const int outputList[elements] = {12,11,10,9,2};
const int onTime[elements] = {1000,1250,1450,1550,1500};
const int offTime[elements] = {2500,2750,3050,3250,1520};
const int buttonPin = 2;

unsigned long myTime = 0;

void setup(){
  for (int i = 0; i <= elements; i++){
    pinMode(outputList[i], OUTPUT); // they are all outputs now
  }
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH); // enable pullup
}

void loop(){
  while(buttonPin == LOW){   // this is dirty for buttonpress
    myTime = millis();
    for (int i = 0; i <= elements; i++){
      if ((myTime >= onTime[i]) and (myTime <= offTime[i])){
        digitalWrite(outputList[i], HIGH);
      }
      else {
        digitalWrite(outputList[i], LOW);
      }
    }
  }
}
Compiled but not tested.

Feel free to be inspired  smiley

-Fletcher
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey, thank you both for taking a look!

greynomad, i've takin out all of the const int and changed them to #defines and still no luck. it will work fine for a couple of tries, then skip an if, go back to normal, then skip an if again. i put a bunch of prints in to show what was being skipped, and it seemed completely random, but usually just 1 or 2 at a time. i felt like the prints might have made it a little worse... so i yanked those out.

so here is the code as it currently stands:

Code:
#define relay1Pin 12 // the number of the Relay pins
#define relay2Pin 11
#define relay3Pin 10
#define relay4Pin 9
#define flashPin 8 // opto-isolator anode connected to digital pin 8
#define buttonPin 2
#define globalReset 3800 // time to activate button again.
#define relay1Delay 1000 // time until relay1 fires
#define relay1Duration 1500  //duration of relay1 fire
#define relay2Delay 1250
#define relay2Duration 1500
#define relay3Delay 1450
#define relay3Duration 1600
#define relay4Delay 1550
#define relay4Duration 1700
#define flash1Delay 1500
#define flash1Duration 100
#define relay1Timer relay1Delay+relay1Duration //total time of delay and duration
#define relay2Timer relay2Delay+relay2Duration
#define relay3Timer relay3Delay+relay3Duration
#define relay4Timer relay4Delay+relay4Duration
#define flash1Timer flash1Delay+flash1Duration

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(relay1Pin, OUTPUT); // initialize the Relay pins as an output:
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  digitalWrite(relay1Pin, HIGH);  // i currently have relay1Pin and relay2Pin plugged into the relay which is why i'm defaulting this to high
  digitalWrite(relay2Pin, HIGH);
  pinMode(flashPin, OUTPUT); // declare flashPin as as OUTPUT
  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{

  if (btnMillis != 0)
  { 
    unsigned long timePassed = millis() - btnMillis;
 
    //Flash
    if (timePassed == flash1Delay)
    {
        digitalWrite(flashPin, HIGH); // trigger flash by bringing digital output to high
    }

    if (timePassed == flash1Delay+flash1Duration)
    {
         digitalWrite(flashPin, LOW); // set it back to low
    }
   
    //Relay 1
    if (timePassed == relay1Delay)
    {
digitalWrite(relay1Pin, LOW); //turn on Relay 1 pin
    }

    if (timePassed == relay1Delay+relay1Duration)
    {
digitalWrite(relay1Pin, HIGH); //turn off Relay 1 pin
    }


    //Relay 2
    if (timePassed == relay2Delay)
    {
digitalWrite(relay2Pin, LOW); //turn on Relay 2 pin
    }

    if (timePassed == relay2Delay+relay2Duration)
    {
digitalWrite(relay2Pin, HIGH); //turn off Relay 2 pin
    }
   
    //Relay 3
    if (timePassed == relay3Delay)
    {
digitalWrite(relay3Pin, HIGH); //turn on Relay 3 pin
    }

    if (timePassed == relay3Delay+relay3Duration)
    {
digitalWrite(relay3Pin, LOW); //turn off Relay 3 pin
    }
   
    //Relay 4
    if (timePassed == relay4Delay)
    {
digitalWrite(relay4Pin, HIGH); //turn on Relay 4 pin
    }

    if (timePassed == relay4Delay+relay4Duration)
    {
digitalWrite(relay4Pin, LOW); //turn off Relay 4 pin
    }
   
    //Longest off time, to re-enable the button
    if (timePassed >= globalReset)
    {
btnMillis = 0;
    }
  }
}

void btnDown()
{
    if (btnMillis != 0) return;
    btnMillis = millis();
}


so, still no idea why this is skipping functions. should i be using something like MsTimer2? i also still don't understand if it's running the void loop over and over why it would continuously skip the same random if.

and thanks for the heads up on missing the resistor for the 4N28. some of the diagrams i've found have included them others have not. i'm still having trouble getting it to fire the physical flash every time even though the flash has been set to HIGH (could see it in the print)... when i test with an LED it works perfectly. makes me think i might have blow the chip!

fletcher, thanks! i tried running that code and i couldn't get the button to work. i tried switching the lows to highs and highs to lows, disabled the pullup, and still couldn't get it running. the arrays are a little over my head. i understand what it's doing but if i wanted to rewrite that to include the ability to default the relays to high HIGH and the flash to LOW i'm not sure how i would go about that. so i'm def. inspired! ... but a little bewildered as well! smiley-wink
Logged

Copenhagen, Denmark
Offline Offline
Edison Member
*
Karma: 32
Posts: 1206
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code you have is simple enough, there is no reason to "skip in if". No delay() or Serial.print (that has a side effect very much like delay()!) or such like.

I am wondering if something is causing us to "miss" running through the loop for each and every possible millis(): your timePassed could contain, say , 998, 999, 1001, 1002 and then it would "miss" the if ( timePassed == 1000 ).

One way is to rewrite your ifs with >= or something like that. Maybe something like
Code:
if timepassed >= relay4Delay && timepassed<=relay4Delay+relay4Duration )
    digitalWrite(relay4Pin, HIGH) ;
  else
    digitalWrite(relay4Pin, LOW) ;
Admitedly this wastefully writes to each digital pin on every loop(), but it wont break or wear anything out as it only will cause a single on and off change on a pin for each of your cycles.

On the other hand I wonder if the interrupt is being triggered real often and causing the missing millis() ? I have not yet had a need for an interrupt, a bit of carefull coding has always enabled me to poll/test my inputs often enough.  (See this project  - apart from reading the motor switch it also handled Serial IO with the pc and some calculations/parsing ASCII)

At the end of loop() where the if (btnMillis != 0) end
Code:
} else { // i.e. btnMillis==0
if (digitalRead(2)==HIGH) btnMillis=millis() ;} // end the big if
A pin is INPUT by default, but it would be "better" to do a pinMode(2,INPUT) in setup(), too.

So, two different approaches for finding or working around the fault.
Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 156
It was all digital
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi again

There was a few errors in my code:
1) Flash pin was listet as pin no 2 in the list - same as button pin.
2) The timings has to be relative so two timers are needed.
3) Reading of the button pin has to be "digitalRead()"

I have added a fail-safe feature. When button is unpressed all outputs goes off.

This code compiles and it works:

Code:
// 4 Realys4 Realys + strope
// Relays from output 12 to 9
// Strope on output 8
// Button on input 2

const int elements = 5;
const int outputList[elements] = {12,11,10,9,8};
const int onTime[elements] = {1000,1250,1450,1550,1500};
const int offTime[elements] = {2500,2750,3050,3250,1520};
const int buttonPin = 2;

unsigned long myTime1, myTime2 = 0;

void setup(){
  for (int i = 0; i <= elements; i++){
    pinMode(outputList[i], OUTPUT); // they are all outputs now
  }
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH); // enable pullup
}

void loop(){
  if (digitalRead(buttonPin) == HIGH){ // No button press
    myTime1 = millis();
    for (int i = 0; i <= elements; i++){  // Turn all off when no button press
      digitalWrite(outputList[i], LOW);
    }
  }
  if (digitalRead(buttonPin) == LOW){   // Button is pressed
    myTime2 = millis();
    for (int i = 0; i <= elements; i++){
      if (((myTime2 - myTime1) >= onTime[i]) and ((myTime2 - myTime1) <= offTime[i])){
        digitalWrite(outputList[i], HIGH);
      }
      else {
        digitalWrite(outputList[i], LOW);
      }
    }
  }
}

-Fletcher
« Last Edit: April 27, 2011, 04:43:27 pm by Fletcher Chr » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey Msquare and Fletcher

fletcher, just tested out your code and it works great. still a little over my head, but i can see what it's doing for the most part. thanks for taking the time on that! one thing i noticed is while setting up the array for the first time (perhaps while going through "outputList" in the setup?) it fires everything off  and goes through the sequence when the code is sent to the arduino. i tried setting the buttonPin to LOW in hopes that it wouldn't fire everything off if you made a change in timing and had to reload the .pde. but wasn't sure how to change that or if it was all part of creating the array?

Msqaure, your code is similar to the if statements i started with... but while double checking the code this was based on they were adding "+50" milliseconds to the second half of the if statement. i pulled a dumb move and took that out. so my if statements had the same possibility of missing that one milli like:

Code:
if (timePassed == relay1Delay+relay1Duration)

and

Code:
if (timePassed >= relay1Timer && timePassed <= relay1Timer)

looking at your code made me realize i comparing the same numbers (only giving 1 milli) when i needed to give it a range like yours, and what the code originally had, to give it the ability to miss a milli.

Code:
if ((timePassed >= relay1Delay) && (timePassed <= relay1Timer))

so this new code has all the previous suggestions applied (hope they are all correct) and everything, but my octocoupler, seems to be working a.o.k. ...will ask about that in another forum.

thanks to everyone again!

Code:
#define relay1Pin 12 // the number of the Relay pins
#define relay2Pin 11
#define relay3Pin 10
#define relay4Pin 9
#define flashPin 8 // opto-isolator anode connected to digital pin 8
#define buttonPin 2
#define globalReset 3800 // time to activate button again.
#define relay1Delay 1000 // time until relay1 fires
#define relay1Duration 1500  //duration of relay1 fire
#define relay2Delay 1250
#define relay2Duration 1500
#define relay3Delay 1450
#define relay3Duration 1600
#define relay4Delay 1550
#define relay4Duration 1700
#define flash1Delay 1500
#define flash1Duration 100
#define relay1Timer relay1Delay+relay1Duration //total time of delay and duration
#define relay2Timer relay2Delay+relay2Duration
#define relay3Timer relay3Delay+relay3Duration
#define relay4Timer relay4Delay+relay4Duration
#define flash1Timer flash1Delay+flash1Duration

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(relay1Pin, OUTPUT); // initialize the Relay pins as an output:
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  digitalWrite(relay1Pin, HIGH); 
  digitalWrite(relay2Pin, HIGH);
  pinMode(buttonPin, INPUT);
  pinMode(flashPin, OUTPUT); // declare flashPin as as OUTPUT
  attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
}

void loop()
{

  if (btnMillis != 0)
  { 
    unsigned long timePassed = millis() - btnMillis;
 
    //Flash
    if ((timePassed >= flash1Delay) && (timePassed <= flash1Timer))
    {
        digitalWrite(flashPin, HIGH); // trigger flash by bringing digital output to high
    }
    else {
         digitalWrite(flashPin, LOW); // set it back to low
    }
   
    //Relay 1
    if ((timePassed >= relay1Delay) && (timePassed <= relay1Timer))
    {
digitalWrite(relay1Pin, LOW); //turn on Relay 1 pin
    }
    else {
digitalWrite(relay1Pin, HIGH); //turn off Relay 1 pin
    }


    //Relay 2
    if (timePassed >= relay2Delay && timePassed <= relay2Timer)
    {
digitalWrite(relay2Pin, LOW); //turn on Relay 2 pin
    }
    else {
digitalWrite(relay2Pin, HIGH); //turn off Relay 2 pin
    }
   
    //Relay 3
    if (timePassed >= relay3Delay && timePassed <= relay3Timer)
    {
digitalWrite(relay3Pin, HIGH); //turn on Relay 3 pin
    }
    else {
digitalWrite(relay3Pin, LOW); //turn off Relay 3 pin
    }
   
    //Relay 4
    if (timePassed >= relay4Delay && timePassed <= relay4Timer)
    {
digitalWrite(relay4Pin, HIGH); //turn on Relay 4 pin
    }
    else {
digitalWrite(relay4Pin, LOW); //turn off Relay 4 pin
    }
   
    //Longest off time, to re-enable the button
    if (timePassed >= globalReset)
    {
btnMillis = 0;
    }
  } else { // i.e. btnMillis==0
    if (digitalRead(2) == HIGH)
    btnMillis=millis();
  } // end the big if
}

void btnDown()
{
    if (btnMillis != 0) return;
    btnMillis = millis();
}
Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 156
It was all digital
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi photony

Quote
it fires everything off  and goes through the sequence when the code is sent to the arduino.

This is becurse I use a different setup for detection of the button press. I'm useing the internal pull-up recistor. If you remove the wire from pin 2 to you button setup the Arduino will not go though the sequence at startup. If you connect pin 2 (though a button) to gnd the sequence will start.
I tested my code with a wire connected between pin 2 and gnd. Connection: Sequence is running, no connection: Sequence is not running (and for safety reason - all outputs goes off).

Why do you do this in setup()?
Code:
digitalWrite(relay1Pin, HIGH);  
  digitalWrite(relay2Pin, HIGH);

I'm a bit unsure how btnMillis is updated since you have both an interrupt and a digital reading of the button pin:
Code:
attachInterrupt(0, btnDown, RISING); //0 = digital pin 2 or 1 = digital pin 3
Code:
if (btnMillis != 0)
  {
Code:
else { // i.e. btnMillis==0
    if (digitalRead(2) == HIGH)
    btnMillis=millis();
Code:
void btnDown()
{
    if (btnMillis != 0) return;
    btnMillis = millis();
}

I'm a bit unsure what is happening in your code ... smiley-fat

-Fletcher
« Last Edit: April 28, 2011, 03:51:13 am by Fletcher Chr » Logged

Copenhagen, Denmark
Offline Offline
Edison Member
*
Karma: 32
Posts: 1206
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Indeed - the point for reading the button was to get rid of the interrupt. In this particular case it is totally "over the top" to use an interrupt.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hey fletcher,

regarding this:

Code:
digitalWrite(relay1Pin, HIGH);  
digitalWrite(relay2Pin, HIGH);

sorry, i had that commented on in the previous version and took it out "// i currently have relay1Pin and relay2Pin plugged into the relay which is why i'm defaulting this to high"

from the relay's website "USE: Connect +5V and Gnd to Arduino, Connect Arduino output pins to J5 2,3,4,5  NOTE: Set pin LOW to turn on relay, HIGH for off."

which is also why i said in regards to your code...  "i understand what it's doing but if i wanted to rewrite that to include the ability to default the relays to high HIGH and the flash to LOW i'm not sure how i would go about that..."

your code works perfectly but i don't have the knowledge of arrays to add the additional setting to set the default to high or low. i see i can add something like:

Code:
const int setDefault[elements] = {HIGH,HIGH,LOW,LOW,LOW};

but not sure how to get that generated into the rest of the code?


as for the attachInterrupt AND the reading of the button pin... i didn't know you shouldn't have both (until now) i put that in because of the suggestion from Msquare above... i guess at the time i didn't realize he was saying take the attachInterrupt out and put in the else statement. thanks for catching that! here is the new code:


Code:
#define relay1Pin 12 // the number of the Relay pins
#define relay2Pin 11
#define relay3Pin 10
#define relay4Pin 9
#define flashPin 8 // opto-isolator anode connected to digital pin 8
#define buttonPin 2
#define globalReset 3500 // time to activate button again.
#define relay1Delay 1000 // time until relay1 fires
#define relay1Duration 1500  //duration of relay1 fire
#define relay2Delay 1250
#define relay2Duration 1500
#define relay3Delay 1450
#define relay3Duration 1600
#define relay4Delay 1550
#define relay4Duration 1700
#define flash1Delay 1500
#define flash1Duration 20
#define relay1Timer relay1Delay+relay1Duration //total time of delay and duration
#define relay2Timer relay2Delay+relay2Duration
#define relay3Timer relay3Delay+relay3Duration
#define relay4Timer relay4Delay+relay4Duration
#define flash1Timer flash1Delay+flash1Duration

unsigned long btnMillis = 0; //clock value to be stored at the time milli() is called

void setup()
{
  pinMode(relay1Pin, OUTPUT); // initialize the Relay pins as an output:
  pinMode(relay2Pin, OUTPUT);
  pinMode(relay3Pin, OUTPUT);
  pinMode(relay4Pin, OUTPUT);
  digitalWrite(relay1Pin, HIGH);  
  digitalWrite(relay2Pin, HIGH);
  pinMode(buttonPin, INPUT);
  pinMode(flashPin, OUTPUT); // declare flashPin as as OUTPUT
}

void loop()
{

  if (btnMillis != 0)
  {  
    unsigned long timePassed = millis() - btnMillis;
 
    //Flash
    if ((timePassed >= flash1Delay) && (timePassed <= flash1Timer))
    {
        digitalWrite(flashPin, HIGH); // trigger flash by bringing digital output to high
    }
    else {
         digitalWrite(flashPin, LOW); // set it back to low
    }
    
    //Relay 1
    if ((timePassed >= relay1Delay) && (timePassed <= relay1Timer))
    {
digitalWrite(relay1Pin, LOW); //turn on Relay 1 pin
    }
    else {
digitalWrite(relay1Pin, HIGH); //turn off Relay 1 pin
    }


    //Relay 2
    if (timePassed >= relay2Delay && timePassed <= relay2Timer)
    {
digitalWrite(relay2Pin, LOW); //turn on Relay 2 pin
    }
    else {
digitalWrite(relay2Pin, HIGH); //turn off Relay 2 pin
    }
    
    //Relay 3
    if (timePassed >= relay3Delay && timePassed <= relay3Timer)
    {
digitalWrite(relay3Pin, HIGH); //turn on Relay 3 pin
    }
    else {
digitalWrite(relay3Pin, LOW); //turn off Relay 3 pin
    }
    
    //Relay 4
    if (timePassed >= relay4Delay && timePassed <= relay4Timer)
    {
digitalWrite(relay4Pin, HIGH); //turn on Relay 4 pin
    }
    else {
digitalWrite(relay4Pin, LOW); //turn off Relay 4 pin
    }
    
    //Longest off time, to re-enable the button
    if (timePassed >= globalReset)
    {
btnMillis = 0;
    }
  } else { // i.e. btnMillis==0
    if (digitalRead(2) == HIGH)
    btnMillis=millis();
  } // end the big if
}

thanks Msquare! you just responded as i was posting this.
Logged

0
Offline Offline
Full Member
***
Karma: 2
Posts: 156
It was all digital
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi photony

You are right about the use of array with default behaviour.

I have modifyed the code - It compiles but I have no chance to test it on this side of the weekend

Code:
// 4 Realys4 Realys + strope
// Relays from output 12 to 9
// Strope on output 8
// Button on input 2

const int elements = 5;
const int outputList[elements] = {12,11,10,9,8};
const int onTime[elements] = {1000,1250,1450,1550,1500};
const int offTime[elements] = {2500,2750,3050,3250,1520};
const boolean unPressed[elements] = {1,1,1,1,0};
const int buttonPin = 2;

unsigned long myTime1, myTime2 = 0;

void setup(){
  for (int i = 0; i <= elements; i++){
    pinMode(outputList[i], OUTPUT); // they are all outputs now
  }
  pinMode(buttonPin, INPUT);
  digitalWrite(buttonPin, HIGH); // enable pullup
}

void loop(){
  if (digitalRead(buttonPin) == HIGH){ // No button press
    myTime1 = millis();
    for (int i = 0; i <= elements; i++){  // Turn all outputs to default when no button press
      digitalWrite(outputList[i], unPressed[i]);
    }
  }
  // Now time for some action
  if (digitalRead(buttonPin) == LOW){   // Button is pressed
    myTime2 = millis();
    for (int i = 0; i <= elements; i++){
      if (((myTime2 - myTime1) >= onTime[i]) and ((myTime2 - myTime1) <= offTime[i])){
        digitalWrite(outputList[i], !unPressed[i]);  // Not sure if the "!" trick works ....
      }
      else {
        digitalWrite(outputList[i], unPressed[i]);
      }
    }
  }
}

I'm not sure if the !unPressed part works - it should though since the elements in the list are declared as boolean.

-Fletcher
« Last Edit: April 29, 2011, 08:44:03 am by Fletcher Chr » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

excellent. thanks fletcher! just tried it out and everything runs seamlessly, but you are correct the "i" trick doesn't work. smiley-wink . when i hit the button while the sequence was running it would start over... not a big deal unless you think it is. i can just make sure not to touch it once the sequence starts!

thanks again!
Logged

Pages: [1]   Go Up
Jump to: