How to add sensors to this object oriented sketch

Hi,

I’m new to Arduino programming and I found this sketch here which works really well for having multiple leds do different things. I’d like to figure out how to control the OnTime of led1 with a potentiometer on A0 and the OffTime of led1 with a pot on A1; and then the OnTime of led2 with a pot on A2 and OffTime of led2 with a pot on A3 (I’ve figured out the wiring already) Any help with the code would be greatly appreciated.

Here’s the code I’m currently using (it doesn’t have the analogue inputs yet)

    class Flasher
    {
    	// Class Member Variables
    	// These are initialized at startup
    	int ledPin;      // the number of the LED pin
    	long OnTime;     // milliseconds of on-time
    	long OffTime;    // milliseconds of off-time
     
    	// These maintain the current state
    	int ledState;             		// ledState used to set the LED
    	unsigned long previousMillis;  	// will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(int pin, long on, long off)
      {
    	ledPin = pin;
    	pinMode(ledPin, OUTPUT);     
    	  
    	OnTime = on;
    	OffTime = off;
    	
    	ledState = LOW; 
    	previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
         
        if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
        {
        	ledState = LOW;  // Turn it off
          previousMillis = currentMillis;  // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
        {
          ledState = HIGH;  // turn it on
          previousMillis = currentMillis;   // Remember the time
          digitalWrite(ledPin, ledState);	  // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, 100, 400);
    Flasher led2(13, 350, 350);
     
    void setup()
    {
    }
     
    void loop()
    {
    	led1.Update();
    	led2.Update();
    }

Have you looked at the IDE examples to see how to read Analog inputs?

If you are not needing to use a class for this project:
Get rid of the class, make a function instead, read the POTs the CALL the function.
Or
Keep the class, modify the update function in the class to read A0 and A1 etc.

Thank you LarryD,

I've modified the code to try to incorporate the analogue potentiometers but now the two Leds blink at the same rate no matter which pot I adjust.

Here's the new code:

    // editing now
    
    class Flasher
    {
      // Class Member Variables
      // These are initialized at startup
      int ledPin;      // the number of the LED pin
      long OnTime;     // milliseconds of on-time
      long OffTime;    // milliseconds of off-time
      int ApinOn;   // the number of the A pin to control on
      int ApinOff;  // the number of the A pin to control off
      int ValOn;    //place to store value of apin on
      int ValOff;   //place to store value of apin off
     
      // These maintain the current state
      int ledState;                 // ledState used to set the LED
      unsigned long previousMillis;   // will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(int pin, long ApinOn, long ApinOff)
      {
      ledPin = pin;
      pinMode(ledPin, OUTPUT); 
      
      ledState = LOW; 
      previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
        
        ValOn = analogRead(ApinOn);
        ValOff = analogRead(ApinOff);
         
        if((ledState == HIGH) && (currentMillis - previousMillis >= ValOn))
        {
          ledState = LOW;  // Turn it off
          previousMillis = currentMillis;  // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= ValOff))
        {
          ledState = HIGH;  // turn it on
          previousMillis = currentMillis;   // Remember the time
          digitalWrite(ledPin, ledState);   // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, A2, A3);
    Flasher led2(13, A0, A1);
     
    void setup()
    {
    }
     
    void loop()
    {
      led1.Update();
      led2.Update();
    }

Ok I think I got it going now. Now I need to figure out how to scale the potentiometer input values.

    // working now- now need to figure out scaling the pot values
    
    class Flasher
    {
      // Class Member Variables
      // These are initialized at startup
      int ledPin;      // the number of the LED pin
      long OnTime;     // milliseconds of on-time
      long OffTime;    // milliseconds of off-time
      int ApinOn;   // the number of the A pin to control on
      int ApinOff;  // the number of the A pin to control off
      int ValOn;    //place to store value of apin on
      int ValOff;   //place to store value of apin off
     
      // These maintain the current state
      int ledState;                 // ledState used to set the LED
      unsigned long previousMillis;   // will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(int pin, int ApinO, int ApinOf)
      {
      
      ledPin = pin;
      ApinOn = ApinO;
      ApinOff = ApinOf;
      pinMode(ledPin, OUTPUT); 
      
      ledState = LOW; 
      previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
        
        ValOn = analogRead(ApinOn);
        ValOff = analogRead(ApinOff);
         
        if((ledState == HIGH) && (currentMillis - previousMillis >= ValOn))
        {
          ledState = LOW;  // Turn it off
          previousMillis = currentMillis;  // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= ValOff))
        {
          ledState = HIGH;  // turn it on
          previousMillis = currentMillis;   // Remember the time
          digitalWrite(ledPin, ledState);   // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, A2, A3);
    Flasher led2(13, A0, A1);
     
    void setup()
    {
    }
     
    void loop()
    {
      led1.Update();
      led2.Update();
    }

int ApinOn; // the number of the A pin to control on
int ApinOff; // the number of the A pin to control off
. . .
Flasher(int pin, long ApinOn, long ApinOff)

In the constructor, you need to initialize ApinOn and ApinOff with the parameters you are receiving.
.

You can use the map function to scale.

map:

Thank you!

    // Thank You
    
    class Flasher
    {
      // Class Member Variables
      // These are initialized at startup
      int ledPin;      // the number of the LED pin
      long OnTime;     // milliseconds of on-time
      long OffTime;    // milliseconds of off-time
      int ApinOn;   // the number of the A pin to control on
      int ApinOff;  // the number of the A pin to control off
      int ValOn;    //place to store value of apin on
      int ValOff;   //place to store value of apin off
     
      // These maintain the current state
      int ledState;                 // ledState used to set the LED
      unsigned long previousMillis;   // will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(int pin, int ApinA, int ApinB)
      {
      
      ledPin = pin;
      ApinOn = ApinA;
      ApinOff = ApinB;
      pinMode(ledPin, OUTPUT); 
      
      ledState = LOW; 
      previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
        
        int ValOn = analogRead(ApinOn);
        int ValOff = analogRead(ApinOff);
        ValOn = map(ValOn, 0, 1023, 0, 5000);
        ValOff = map(ValOff, 0, 1023, 0, 5000);
         
        if((ledState == HIGH) && (currentMillis - previousMillis >= ValOn))
        {
          ledState = LOW;  // Turn it off
          previousMillis = currentMillis;  // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= ValOff))
        {
          ledState = HIGH;  // turn it on
          previousMillis = currentMillis;   // Remember the time
          digitalWrite(ledPin, ledState);   // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, A2, A3);
    Flasher led2(13, A0, A1);
     
    void setup()
    {
    }
     
    void loop()
    {
      led1.Update();
      led2.Update();
    }

Looks good.
Congrats!

BTW
Things like pin numbers can be type byte to save RAM:
byte pinNumber; //

int ledState;
Can be:
byte ledState;

previousMillis = currentMillis; // Remember the time
You might want to use this way to prevent creep in future sketches.
previousMillis = previousMillis + ValOn; // Remember the time

LarryD,

What is the difference between using int and byte?
I assume I save some space with byte- if that's the case can I change all instances of int to byte?

type int reserves 2 bytes (16 bits) for your variables.
type byte reserves 1 byte (8 bits) for your variables.

if your variable is 0-255 then use byte.
Also, uint8_t and unsigned char are the same as byte.

http://playground.arduino.cc/Code/DatatypePractices
.

Ok, I think I got it. Now I'm wondering how to add a momentary button on a digital input that would make all of the leds light while held and then resume normal operation. I think I'd need to do this with an interrupt?

    // cell motor sketch changing from int-byte and time change. Thanks LarryD- I saved about 60 bytes
    
    class Flasher
    {
      // Class Member Variables
      // These are initialized at startup
      byte ledPin;      // the number of the LED pin
      byte ApinOn;   // the number of the A pin to control on
      byte ApinOff;  // the number of the A pin to control off
      int ValOn;    //place to store value of apin on
      int ValOff;   //place to store value of apin off
     
      // These maintain the current state
      byte ledState;                 // ledState used to set the LED
      unsigned long previousMillis;   // will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(byte pin, byte ApinA, byte ApinB)
      {
      
      ledPin = pin;
      ApinOn = ApinA;
      ApinOff = ApinB;
      pinMode(ledPin, OUTPUT); 
      
      ledState = LOW; 
      previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
        
        int ValOn = analogRead(ApinOn);
        int ValOff = analogRead(ApinOff);
        ValOn = map(ValOn, 0, 1023, 0, 5000);
        ValOff = map(ValOff, 0, 1023, 0, 5000);
         
        if((ledState == HIGH) && (currentMillis - previousMillis >= ValOn))
        {
          ledState = LOW;  // Turn it off
          previousMillis = previousMillis + ValOn; // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= ValOff))
        {
          ledState = HIGH;  // turn it on
          previousMillis = previousMillis + ValOff; // Remember the time
          digitalWrite(ledPin, ledState);   // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, A2, A3);
    Flasher led2(13, A0, A1);
     
    void setup()
    {
    }
     
    void loop()
    {
      led1.Update();
      led2.Update();
    }

Add a new class function that turns on the LEDs when the function is called.
In loop, read the switch, if it is LOW, call the new function, if it is HIGH call the update functions.

daviddavidc:
Ok, I think I got it. Now I'm wondering how to add a momentary button on a digital input that would make all of the LEDs light while held and then resume normal operation. I think I'd need to do this with an interrupt?

Sad.

You have no idea what an interrupt is, do you? But the name sounded good to use for something. :grinning:

You have your code more-or-less correctly constructed. The concept is that the loop is continuously cycling no matter what, and makes decisions along the way.

So you read your pushbutton in the loop before your "flash" code and decide as a branch whether to proceed to the flash code, or to switch all the lights on. The only trick to this is that you need to re-initialise previousMillis in each instance so that the flashing re-starts on time when the button is released.

Alternate approach to multiple flashes:

// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  10;
const int led3Pin =  11;
const int button1 =  4;
int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
char bstate1 = 0;
unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check 
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(led2Pin, OUTPUT);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle LED if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (led1State == LOW) {
      led1State = HIGH;
    }
    else {
      led1State = LOW; 
    } 
    digitalWrite(led1Pin, led1State);
  } 

  // Act if the latter time (ms) has now passed on this particular counter,
  if (timeout(&count2, 300UL )) {
    if (led2State == LOW) {
      led2State = HIGH;
    }
    else {
      led2State = LOW; 
    } 
    digitalWrite(led2Pin, led2State);
  } 

  if (timeout(&count3, 77UL )) {
    if (led3State == LOW) {
      led3State = HIGH;
    }
    else {
      led3State = LOW; 
    } 
    digitalWrite(led3Pin, led3State);
  } 
}

Ok I think this will work. I think my if and if else statements are correct. Sure there are ways to make this more efficient as well.
Here's the code:

    // cell motor sketch changing from int-byte and time change
    
    class Flasher
    {
      // Class Member Variables
      // These are initialized at startup
      byte ledPin;         // the number of the LED pin
      byte ApinOn;         // the number of the A pin to control on
      byte ApinOff;        // the number of the A pin to control off
      int ValOn;               // place to store value of apin on
      int ValOff;              // place to store value of apin off
      byte ButtonOn = 2;       // the number of the on button
      byte ButtonOff = 3;      // the number of the off button
      byte ButtonStateOn;      // place to store val of ButtonOn
      byte ButtonStateOff;     // place to store val of ButtonOff
      
     
      // These maintain the current state
      byte ledState;                 // ledState used to set the LED
      unsigned long previousMillis;   // will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(byte pin, byte ApinA, byte ApinB)
      {
      
      ledPin = pin;
      ApinOn = ApinA;
      ApinOff = ApinB;
      pinMode(ledPin, OUTPUT); 
      
      
      ledState = LOW; 
      previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
        
        
        pinMode(ButtonOn, INPUT);					//tell the pin what to do
        pinMode(ButtonOff, INPUT);         			//tell the pin what to do
        ButtonStateOn = digitalRead(ButtonOn);
        ButtonStateOff = digitalRead(ButtonOff);
        
        
        int ValOn = analogRead(ApinOn);				// read pin and store val
        int ValOff = analogRead(ApinOff);			// read pin and store val
        ValOn = map(ValOn, 0, 1023, 0, 5000);		// map the value for on time
        ValOff = map(ValOff, 0, 1023, 0, 5000);		// map the value for off time
        
        
        // check for the on button
        if (ButtonStateOn == HIGH) {
    	// if button is pressed turn LED on
    	digitalWrite(ledPin, HIGH);
    	}
    	
    	// check for the off button
    	else if (ButtonStateOff == HIGH) {
    	// if button is pressed turn LED off
    	digitalWrite(ledPin, LOW);
    	}
        
        // if no button is pressed resume normal operations
        
        else if((ledState == HIGH) && (currentMillis - previousMillis >= ValOn))
        {
          ledState = LOW;  // Turn it off
          previousMillis = previousMillis + ValOn; // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= ValOff))
        {
          ledState = HIGH;  // turn it on
          previousMillis = previousMillis + ValOff; // Remember the time
          digitalWrite(ledPin, ledState);   // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, A2, A3);
    Flasher led2(13, A0, A1);
     
    void setup()
    {
    }
     
    void loop()
    {
      led1.Update();
      led2.Update();
    }

Ok I think this will work.

What results did you get?

Note, you could put the decision in loop()
.

LarryD:
Note, you could put the decision in loop()

Note, you should put the decision in loop()

Thanks so much! Yeah so that didn't work out. I added it to the loop and it works now. Seems like I might be able to clean it up a bit and make it a bit more elegant.
Here it is so far:

    // cell motor sketch with pots for on time/off time and 2 different buttons for all on and all off
    
    class Flasher
    {
      // Class Member Variables
      // These are initialized at startup
      byte ledPin;         // the number of the LED pin
      byte ApinOn;         // the number of the A pin to control on
      byte ApinOff;        // the number of the A pin to control off
      int ValOn;               // place to store value of apin on
      int ValOff;              // place to store value of apin off

      
     
      // These maintain the current state
      byte ledState;                 // ledState used to set the LED
      unsigned long previousMillis;   // will store last time LED was updated
     
      // Constructor - creates a Flasher 
      // and initializes the member variables and state
      public:
      Flasher(byte pin, byte ApinA, byte ApinB)
      {
      
      ledPin = pin;
      ApinOn = ApinA;
      ApinOff = ApinB;
      pinMode(ledPin, OUTPUT); 
      
      
      ledState = LOW; 
      previousMillis = 0;
      }
     
      void Update()
      {
        // check to see if it's time to change the state of the LED
        unsigned long currentMillis = millis();
        
        
       
        
        
        int ValOn = analogRead(ApinOn);        // read pin and store val
        int ValOff = analogRead(ApinOff);     // read pin and store val
        ValOn = map(ValOn, 0, 1023, 0, 5000);   // map the value for on time
        ValOff = map(ValOff, 0, 1023, 0, 5000);   // map the value for off time

        
        if((ledState == HIGH) && (currentMillis - previousMillis >= ValOn))
        {
          ledState = LOW;  // Turn it off
          previousMillis = previousMillis + ValOn; // Remember the time
          digitalWrite(ledPin, ledState);  // Update the actual LED
        }
        else if ((ledState == LOW) && (currentMillis - previousMillis >= ValOff))
        {
          ledState = HIGH;  // turn it on
          previousMillis = previousMillis + ValOff; // Remember the time
          digitalWrite(ledPin, ledState);   // Update the actual LED
        }
      }
    };
     
     
    Flasher led1(12, A2, A3);
    Flasher led2(13, A0, A1);
     
    void setup()
    {
 
    }
     
    void loop()
    
      { 


     byte ButtonOn = 20;                 // the number of the on button
     byte ButtonOff = 21;                   // the number of the off button

     byte pin1 = 13;
     byte pin2 = 12;
     pinMode(ButtonOn, INPUT);          //tell the pin what to do
     pinMode(ButtonOff, INPUT);             //tell the pin what to do
     digitalWrite(ButtonOn, HIGH);      // set pull up
     digitalWrite(ButtonOff, HIGH);		// set pull up
          
        // check for the on button
     if (digitalRead(ButtonOn) == LOW) {
      // if button is pressed turn LED on
      digitalWrite(pin1, HIGH);
      digitalWrite(pin2, HIGH);
      }
      
      // check for the off button
     else if (digitalRead(ButtonOff) == LOW) {
      // if button is pressed turn LED off
      digitalWrite(pin1, LOW);
      digitalWrite(pin2, LOW);
      }
        
        // if no button is pressed resume normal operations
    
      else {
      led1.Update();
      led2.Update();
    }
      }