Pages: [1]   Go Down
Author Topic: blink without delay example for simultaneous functions  (Read 654 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 146
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have been advised time and again to embrace the "blink without delay" example to perform functions independently.  This sketch is a failed attempt to program two solenoids to fire randomly, not consecutively. Although they are random, one activates after the other in sequence. Am I asking Arduino to do something it wasn't designed to do? 

Code:
int solOne =2;
int solTwo =4;
int solState = LOW;           
long previousMillis = 0;
long interval = 10;
long randOn1 = 0;                  // Initialize a variable for the ON time
long randOff1 = 0;
long randOn2 = 0;                  // Initialize a variable for the ON time
long randOff2 = 0;


void setup() {
  randomSeed (analogRead (0));
  pinMode (solOne, OUTPUT);
  pinMode (solTwo, OUTPUT);
}
void loop()
{
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis > interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    if (solState == LOW)
      solState = HIGH;
    else
      solState = LOW;
    OneSol();
    TwoSol();
    delay(1000);
  }
}
void OneSol()
{
  randOn1 = random (100, 1200);    // generate ON time between 0.1 and 1.2 seconds
  randOff1 = random (200, 900);    // generate OFF time between 0.2 and 0.9 seconds
  digitalWrite(solOne, HIGH);   // sets the solenoid on
  delay(randOn1);                // waits for a random time while ON
  digitalWrite(solOne, LOW);    // sets the solenoid off
  delay(randOff1); 
}
void TwoSol()
{
  randOn2 = random (150, 500);    // generate ON time between 0.1 and 1.2 seconds
  randOff2 = random (100, 1900);    // generate OFF time between 0.2 and 0.9 seconds
  digitalWrite(solTwo, HIGH);   // sets the solenoid on
  delay(randOn2);                // waits for a random time while ON
  digitalWrite(solTwo, LOW);    // sets the solenoid off
  delay(randOff2); 
}


Logged

California
Offline Offline
Faraday Member
**
Karma: 92
Posts: 3446
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.mushclient.com/forum/bbshowpost.php?bbsubject_id=11411
Logged

East Anglia (UK)
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4396
May all of your blinks be without delay()
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looking at your code I see that the call to TwoSol() always follows the call to OneSol() so it is no wonder that the solenoids always work in sequence, and you exacerbate that by using delay() in the functions which is exactly what you are trying to avoid.
Logged

Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8974
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Your code says:

If 1/100th of a second has passed since the time was last noted:
begin
   note the time.
   Toggle 'solState' which is never used.

       Turn on Solenoid One
       delay between 100 and 1200 milliseconds
       Turn off Solenoid One
       delay between 200 and 900 milliseconds

       Turn on Solenoid Two
       delay between 150 and 500 milliseconds
       Turn off Solenoid Two
       delay between 100 and 1900 milliseconds

    delay 1000 milliseconds
end


Since your IF statement takes at least 1.45 seconds (all those delays) the 1/100th of a second will always have passed before you check again.  To do 'Blink Without Delay' you have to take out ALL the delays.
Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Full Member
***
Karma: 0
Posts: 146
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Great advise, great because I understand what you are describing, which is not always the case. First time I've actually gotten two of anything to function independently. Now for the random business which I assume is just a matter of editing. Thanks again.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 146
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After looking at web examples, I assumed this would generate random solenoids. I am puzzled why it doesn't. The two ignore the random and fire at 1/2 and one second just as before.


const byte solOne = 2;
const byte solTwo = 4;

// Time periods of blinks in milliseconds (1000 to a second).
 unsigned long solOneinterval = 0;//500
 unsigned long solTwointerval = 0;//1000

// Variable holding the timer value so far. One for each "Timer"
unsigned long solOnetimer;
unsigned long solTwotimer;

void setup ()
  {
  pinMode (solOne, OUTPUT);
  pinMode (solTwo, OUTPUT);
  solOnetimer = millis ();
  solTwotimer = millis ();
  }  // end of setup

void toggleSolOne ()
  {
   if (digitalRead (solOne) == LOW)
      digitalWrite (solOne, HIGH);
   else
      digitalWrite (solOne, LOW);

  // remember when we toggled it
  solOnetimer = millis (); 
  }  // end of toggleGreenLED

void toggleSolTwo ()
  {
   if (digitalRead (solTwo) == LOW)
      digitalWrite (solTwo, HIGH);
   else
      digitalWrite (solTwo, LOW);

  // remember when we toggled it
  solTwotimer = millis (); 
  }  // end of toggleRedLED

void loop ()
  {

  // Handling the blink of one LED.
  solOneinterval = random (100,500); ?????????
  if ( (millis () - solOnetimer) >= solOneinterval)
     toggleSolOne ();
  solTwointerval = random (500,1000); ????????
  // The other LED is controlled the same way. Repeat for more LEDs
  if ( (millis () - solTwotimer) >= solTwointerval)
    toggleSolTwo ();

/* Other code that needs to execute goes here.
   It will be called many thousand times per second because the above code
   does not wait for the LED blink interval to finish. */

}  // end of loop
Logged

The Netherlands
Offline Offline
Edison Member
*
Karma: 51
Posts: 1729
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Use code tags.


Looks to me like you are resetting your random value every iteration.
Check the timer first, if it has ended call the toggle, and after that reset the random value still within the braces { } that belong to the if statement (you aren't using those yet).
Then the random value will not be reset every iteration (which is more than several thousand times per second).

« Last Edit: August 17, 2013, 04:10:21 pm by MAS3 » Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Offline Offline
Full Member
***
Karma: 0
Posts: 146
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Obviously not resetting the random correctly. Also, what are code tags (dumb question).

Code:

const byte solOne = 2;
const byte solTwo = 4;

// Time periods of blinks in milliseconds (1000 to a second).
unsigned long solOneinterval = 0;//500
unsigned long solTwointerval = 0;//1000

// Variable holding the timer value so far. One for each "Timer"
unsigned long solOnetimer;
unsigned long solTwotimer;

void setup ()
{
  pinMode (solOne, OUTPUT);
  pinMode (solTwo, OUTPUT);
  solOnetimer = millis ();
  solTwotimer = millis ();
}  // end of setup

void toggleSolOne ()
{
  if (digitalRead (solOne) == LOW)
    digitalWrite (solOne, HIGH);
  else
    digitalWrite (solOne, LOW);

  // remember when we toggled it
  solOnetimer = millis ();
  solOneinterval = 0; [font=Verdana]//////[/font]
}  // end of toggleGreenLED

void toggleSolTwo ()
{
  if (digitalRead (solTwo) == LOW)
    digitalWrite (solTwo, HIGH);
  else
    digitalWrite (solTwo, LOW);

  // remember when we toggled it
  solTwotimer = millis ();
  solTwointerval = 0;[font=Verdana]///////// [/font]
}  // end of toggleRedLED

void loop ()
{
  solOneinterval = random (100,500);
  if ( (millis () - solOnetimer) >= solOneinterval)
    toggleSolOne ();

  solTwointerval = random (500,1000);
 
  if ( (millis () - solTwotimer) >= solTwointerval)
    toggleSolTwo ();

 


Logged

The Netherlands
Offline Offline
Edison Member
*
Karma: 51
Posts: 1729
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What did you change, apart from using the code tags this time to show your code and remove some comments ?
Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Offline Offline
Full Member
***
Karma: 0
Posts: 146
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Added  "solOneinterval = 0;" below else.
Logged

The Netherlands
Offline Offline
Edison Member
*
Karma: 51
Posts: 1729
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Setting that value to 0 doesn't help a lot here.

You are still setting the random interval every time the loop runs.
You should only set a new value after the old one had reached its end.

So change this part of your code:
Code:
void loop ()
{
  solOneinterval = random (100,500);
  if ( (millis () - solOnetimer) >= solOneinterval)
    toggleSolOne ();

  solTwointerval = random (500,1000);
  
  if ( (millis () - solTwotimer) >= solTwointerval)
    toggleSolTwo ();

  

}  

To:
Code:
void loop ()
{
  if ( (millis () - solOnetimer) >= solOneinterval)
    {
     toggleSolOne ();
     solOneinterval = random (100,500);                 // A new value is set after the old value has done it's job
     }
  
  if ( (millis () - solTwotimer) >= solTwointerval)
    {
     toggleSolTwo ();
     solTwointerval = random (500,1000);                // A new value is set after the old value has done it's job
     }
  

}  
« Last Edit: August 17, 2013, 05:52:17 pm by MAS3 » Logged

Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8974
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You're getting close.  This should do what you want:
Code:

const unsigned long sloenoidOneMinOnTime = 100;
const unsigned long sloenoidOneMaxOnTime = 1200;
const unsigned long sloenoidOneMinOffTime = 200;
const unsigned long sloenoidOneMaxOffTime = 900;

const unsigned long sloenoidTwoMinOnTime = 100;
const unsigned long sloenoidTwoMaxOnTime = 1200;
const unsigned long sloenoidTwoMinOffTime = 200;
const unsigned long sloenoidTwoMaxOffTime = 900;

const byte solenoidOnePin = 2;
const byte solenoidTwoPin = 4;

// Time periods of blinks in milliseconds (1000 to a second).
unsigned long solenoidOneInterval = 0;
unsigned long solenoidTwoInterval = 0;

// Variable holding the timer value so far. One for each "Timer"
unsigned long solenoidOneTimerStart = 0;
unsigned long solenoidTwoTimerStart = 0;

void setup() {
  pinMode (solenoidOnePin, OUTPUT);
  pinMode (solenoidTwoPin, OUTPUT);
  solenoidOneInterval = random (sloenoidOneMinOnTime,sloenoidOneMaxOnTime);
  solenoidTwoInterval = random (sloenoidTwoMinOnTime,sloenoidTwoMaxOnTime);
}  // end of setup

void solenoidOne () {
  if (millis() - solenoidOneTimerStart >= solenoidOneInterval) {
    solenoidOneTimerStart = millis();
    if (digitalRead (solenoidOnePin)) {  // If HIGH
      // Toggle solenoid off
      digitalWrite (solenoidOnePin, LOW);
      solenoidOneInterval = random (sloenoidOneMinOffTime,sloenoidOneMaxOffTime);
    }
    else {
      // Toggle solenoid on
      digitalWrite (solenoidOnePin, HIGH);
      solenoidOneInterval = random (sloenoidOneMinOnTime,sloenoidOneMaxOnTime);
    }
  }
}

void solenoidTwo () {
  if (millis() - solenoidTwoTimerStart >= solenoidTwoInterval) {
    solenoidTwoTimerStart = millis();
    if (digitalRead (solenoidTwoPin)) {  // If HIGH
      // Toggle solenoid off
      digitalWrite (solenoidTwoPin, LOW);
      solenoidTwoInterval = random (sloenoidTwoMinOffTime,sloenoidTwoMaxOffTime);
    }
    else {
      // Toggle solenoid on
      digitalWrite (solenoidTwoPin, HIGH);
      solenoidTwoInterval = random (sloenoidTwoMinOnTime,sloenoidTwoMaxOnTime);
    }
  }
}

void loop () {
  solenoidOne();
  solenoidTwo();

Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Offline Offline
Full Member
***
Karma: 0
Posts: 146
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Perfect!  For the ALD (Arduino Learning Disabled), solving this puzzle seems both necessary and impossible.  Thanks again. 
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 639
Posts: 34724
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Also, what are code tags (dumb question).

http://forum.arduino.cc/index.php/topic,148850.0.html
Logged

Pages: [1]   Go Up
Jump to: