It's Alive!

After a lot more thinking (waking at 4:45AM with a sudden burst of inspiration), researching conditional inputs and stopping loops, and then running all this past a very helpful guy I have some working code.

Two separate inputs.
Three outputs.

Output one and two are a light and a tone that signal the user that it is time to wake up.
Input one and two are both buttons. These can be activated simultaneously or one at a time. The physical action to do this is the same as pandiculating (yawn and stretch).
Once both buttons have been pressed, the alarm stops and the bed tips the user into a standing position.
Then the bed returns to the zero state.

Here is video proof...




And here is the code...

#include <Servo.h>
#include <Bounce2.h>

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
      }
    }
};
class Sweeper
{
    Servo servo;               //the servo
    int pos;                  // current servo position
    int increment;            //increment to move for each interval
    int updateInterval;       // interval between updates
    unsigned long lastUpdate;  //last update of position
  public:
    Sweeper(int interval)
    {
      updateInterval = interval;
      increment = 1;
    }
    void Attach(int pin)
    {
      servo.attach(pin);
    }
    void Reset()
    {
      servo.write (0); // sets teh servo to position zero
      pos = 0;
    }
    void Detach()
    {
      servo.detach();
    }
    void Update()
    {
      if ((millis() - lastUpdate) > updateInterval) // time to update
      {
        lastUpdate = millis();
        pos += increment;
        servo.write(pos);
        Serial.println(pos);
        if (pos >= 125) // sets the distance of the sweep, then end of sweep
        {
          servo.write(0);
          while (1) {
          }

          // add this statement "increment = -increment;" and the servo will reverse direction once it was reached the top of the range
          // BUT HOW DO I GET THE SERVO TO DO ONE UP / DOWN CYCLE THEN STOP?
        }
      }
    }
};


Flasher LED(10, 200, 800);     // pin, on time, off time
Flasher BUZZER(11, 100, 900);  // pin, on time, off time
Sweeper sweeper1 (45);        // controls the speed of the servo (lower = faster)
Bounce debouncerA = Bounce(); // Instantiate a Bounce object
Bounce debouncerB = Bounce(); // Instantiate a Bounce object
const int BUTTON_A = 8; // constants won't change
const int BUTTON_B = 9;
bool bedMoveA = false;
bool bedMoveB = false;

void setup()
{
  debouncerA.attach(BUTTON_A, INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
  debouncerA.interval(25); // Use a debounce interval of 25 milliseconds
  debouncerB.attach(BUTTON_B, INPUT_PULLUP); // Attach the debouncer to a pin with INPUT_PULLUP mode
  debouncerB.interval(25); // Use a debounce interval of 25 milliseconds
  Serial.begin(9600);
  sweeper1.Attach(3);     // attaches sweeper1 servo to pin 3
  sweeper1.Reset();
}
void loop()
{
  debouncerA.update(); // Update the Bounce instance
  debouncerB.update(); // Update the Bounce instance
  Serial.println(bedMoveA);
  Serial.print(bedMoveB);
  if (debouncerA.fell()) // press button A
  {
    bedMoveA = true;
    Serial.print("bedMove");
  }
  if (debouncerB.fell()) // press button B
  {
    bedMoveB = true;
    Serial.print("bedMove");
  }
  if (bedMoveA && bedMoveB)
  {
    sweeper1.Update();
  }
  else  // or else loop the servo
  {
    LED.Update();
    BUZZER.Update();
  }
}
I am so happy :)

Comments