1

I wrote a program for a night light. There are 4 modes:

  • on,
  • adjustable brightness,
  • timer,
  • off.

For input, instead of using a button, I am using a distance sensor. Once a certain distance is read (eg. when passing your hand over the distance sensor) it changes to the next mode.

For the adjustable brightness mode it reads the distance sensor and is mapped to a PWM. The output pin is connected to a MOSFET which is switching a 12 volt LED.

This seems a slow way to cycle thru the system. I would like instead, if the user waved their hand over the sensor, it would turn on or off. However, if the user waited for 3 seconds with their hand over the sensor it would enable a dimmable mode. I'm not concerned about the timer function anymore and will be removing it.

All the code is already there except I need help writing a function that will keep track of how long its been reading a certain distance. Let's say for instance if the sensor reads a distance between 1 inch to 3 inches for 3 seconds it will then go into the dimmable mode. If it's under that then it will only toggle on/off. If the hand remains longer then 3 seconds it will also trigger the dimmable mode.

//----------------------------------------------------------
// USING A DISTANCE SENSOR TO CYCLE THRU DIFFERENT MODE
// FOR AN LED NIGHT LIGHT
// vonderasche
//----------------------------------------------------------

// declares library for distance sensor
#include <NewPing.h>
// constants
#define TRIGGER_PIN  12
#define ECHO_PIN     13
#define MAX_DISTANCE 200
const unsigned long onTime = 5000;
const unsigned long onTimer = 1200000;

int state = 1;

// declares NewPing object
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
    Serial.begin(9600);
}

void loop() {
    delay(50);
    // take distances reading
    int distance = sonar.ping_in();
    static enum { ON, ADJUST, TIMER } state;

    // if distance range is between certain values switch the state
    if (distance > 1 && distance < 3) {
        switch(state) {
        case ON:
          {
            // turns LEDs on
            Serial.println("ON");
            analogWrite(3, 255);
            analogWrite(5, 255);
            state = ADJUST;
            delay(1000);
          }
          break;
        case ADJUST:
          {
            // allows user to set brightness based on hand distance to sensor
            Serial.println("Adjusting Brightness");
            int distance2 = 0;
            int mappedBrightness = 0;
            unsigned long previousMillis = millis();
            unsigned long currentMillis = millis();

            // timer for setting brightness
            while ((currentMillis - previousMillis) < onTime) {
                int distance2 = sonar.ping_in();
                if (distance2 >= 1 && distance2 <= 6) {
                    mappedBrightness = map(distance2, 0, 6, 13, 255);
                    analogWrite(3, mappedBrightness);
                    analogWrite(5, mappedBrightness);
                }
                currentMillis = millis();
            }
            Serial.print("Mapped Brightness = ");
            Serial.println(mappedBrightness);
            delay(1000);
            state = TIMER;
          }
          break;

        case TIMER:
          {
            Serial.println("TIMER - 20 MINS");
            // variable declaration
            unsigned long ontime = 50;
            unsigned long previousMillis = millis();
            unsigned long currentMillis = millis();

            // dims leds to 25 percent
            analogWrite(3, 64);
            analogWrite(5, 64);
            delay(1000);
            // timer for leds
            while ((currentMillis - previousMillis) < onTimer) {
                int distance2 = sonar.ping_in();
                //breaks timer if hand swipe
                if (distance2 >= 1 && distance2 <= 4) {
                    break;
                }
                currentMillis = millis();
            }
            // turn off leds - either hand swipe happened or timer is up
            Serial.println("Turn off LEDs.");
            analogWrite(3, 0);
            analogWrite(5, 0);
            delay(1000);
            state = ON;
          }
          break;
        }
    }
}
  • 1
    Is the dimmer mode used to the case ADJUST: state or planned for another state ? – J. Piquard Jan 2 '17 at 20:30
  • The dim mode works. Right now the program progresses from case one to case four in sequence. I would rather have on/off or if the hand is held over the sensor long enough the dim mode is triggered – Michael Niebauer Jan 2 '17 at 20:55
  • So if delay < 3s ==> switch between ON & OFF state, otherwise ==> go to the ADJUST state ? But is the brightness controlled by the extra delay instead of distance2 ? And what about the TIMER state ? – J. Piquard Jan 2 '17 at 21:02
1

This is not too different from the long press of a button. Lets consider the code to detect a long button press of greater than 3 seconds.

buttonState = digitalRead(PIN1);

if (buttonstate == HIGH)
{
    if ((currentMillis - previousMillis) > THREE_SECONDS)
    {
        // Put your code here
    }
}
else  // ie. buttonState == LOW
{
    previousMillis = currentMillis;
}

OK, so the code could be optimized. However, it shows the code for a long button press and hopefully its easy to understand for any newbies out there. The code above reads the button state and if it is HIGH (ie. pressed), it will then check to see if the timer has run for more than 3 seconds. However, if the button is released, the timer resets.

Now lets consider the code for a distance sensor:

int distance = sonar.ping_in();

if (distance >= 1 && distance <= 3)
{
    if ((currentMillis - previousMillis) > THREE_SECONDS)
    {
        // Put your code here
    }
}
else  // ie. outside of the range
{
    previousMillis = currentMillis;
}

You will notice that only the first two lines change. I hope this helps!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.