Stair lighting using HC-SR04 having trouble

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, I am using 2 HC-SR04 ultrasonic sensors for a stair lighting project and am having trouble with the code. I can get it to work perfect travelling one way, but cannot get it to work properly the other.

I have it so the sensor at the bottom turns the leds on going up and the top sensor turns them off from bottom to top. What I want is for the top sensor to turn the lights on going down and the bottom sensor turn them off running down.

I have tried putting an "else" statement in between the code reversed which does work but not every time.

 

#include <FastLED.h>
#define trigPin_up 2
#define echoPin_up 3
#define trigPin_down 4
#define echoPin_down 5
#define LED_PIN     7
#define NUM_LEDS    13
CRGB leds[NUM_LEDS];

void setup() {

Serial.begin(9600);

FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);

pinMode(trigPin_up, OUTPUT);
pinMode(echoPin_up, INPUT);
pinMode(trigPin_down, OUTPUT);
pinMode(echoPin_down, INPUT);


}
void loop(){

short duration, distance;
digitalWrite(trigPin_up, LOW);
delayMicroseconds(2);
digitalWrite(trigPin_up, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin_up, LOW);
duration = pulseIn(echoPin_up, HIGH);
distance = (duration/2) / 29.1;

if (distance <= 20) {
leds[0] = CRGB(255, 225, 255);
FastLED.show();
delay(10); 
leds[1] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[2] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[3] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[4] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[5] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[6] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[7] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[8] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[9] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[10] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[11] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[12] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
leds[13] = CRGB(255, 255, 255);
FastLED.show();
delay(10);
}
{
short duration, distance;
digitalWrite(trigPin_down, LOW);
delayMicroseconds(2);
digitalWrite(trigPin_down, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin_down, LOW);
duration = pulseIn(echoPin_down, HIGH);
distance = (duration/2) / 29.1;

if (distance <= 20) {
leds[0] = CRGB(0, 0, 0);
FastLED.show();
delay(30); 
leds[1] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[2] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[3] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[4] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[5] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[6] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[7] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[8] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[9] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[10] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[11] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[12] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
leds[13] = CRGB(0, 0, 0);
FastLED.show();
delay(30);
}
}
}

This is where I'm up to can anyone help??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have it so the sensor at the bottom turns the leds on going up and the top sensor turns them off from bottom to top. What I want is for the top sensor to turn the lights on going down and the bottom sensor turn them off running down.

Try making a clear LIST of what you want (not what you "have it"), rather than a jumbled up sentence.  Breaking things down thoroughly & neatly in sentences is a first step in clear coding.

 

The person is going up?  Or the leds are going up?

the top sensor turns them off from bottom to top  WHEN?

 

I want my leds to handle these eight independent cases:

1)

2)

3)

etc

You will probably immediately see what is wrong after you unravel things

 

 

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would deal with this as a simple finite state machine. Then it becomes really easy and simple to debug.

 

1. Enter from bottom

2. On stair

3. Exit from top (don't forget possible turn around and exit from bottom)

4. Enter from top

5. On stair

6. Exit from bottom (ditto possible turn around)

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks Jim, that's exactly what I'm trying to do. My code seems to be doing this but intermittently. I understand that the program is running in a loop so what I am assuming is that if I walk past the bottom sensor going up the stairs the leds light up travelling up, when I get to the top of the stairs the top sensor should detect me and turn the leds off from the bottom travelling up. But if the loop isn't at that point I will have to wait in front of the sensor until it gets to the off command. Is that correct? If so is there any way of forcing the sensor to perform the desired command when I walk past?

Thanks

Dan 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry Dan... I view this as a simple OR gate function. The light comes on if either sensor is triggered. And use a time out after the last trigger to turn off the lights.

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The loop may very well be reading the sensors hundreds or more times a second...so there is no need for anyone to wait, unless perhaps the led sweep is in progress (in reality the led sweep would need immediate resync; no one is going to wait around).

 

How fast is this led sweep/light chaser along the stairwell? 2sec?  5 sec? 30sec? 1/2 sec?  

 

If an led sweep is in progress (say 3/4  of the way up or down the stairs...what do you want to do if some one approaches the steps?

What happens if someone is halfway up the steps and while some one else is just about exiting the bottom of the steps?

What happens if someone is 1/3 up the steps while some one else is just about getting ready to follow them up the steps?

 

Maybe in these conditions all the lights should be left on...only when the machine determines that everyone has exited, the lights go off in the direction of the last person detected leaving (top or bottom).

Of course, what happens if  someone is get through a beam (not detected at one end), or turns around on the stairs?  There should also be a max time to leave the lights on, unless something is sensed (say turn off within 2 minutes of last detection).   

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DapurDan wrote:
, but cannot get it to work properly the other.

I can't actually see any code for it working the other way. That could be the reason.

 

All you have posted is effectively:

 

while(1) {
    if (up_sensor_is_triggered)
       let_there_be_light();

    if (down_sensor_is_triggered)
       darkness_shall_fall();
    }
}

You now need to bring the concept of state into your code. Or put differently your code needs to know whether your are ascending or descending.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You prob need to be able to differentiate between getting ON the stairs and OFF the stairs.

If someone at the bottom gets ON & takes 3 steps up, about a second later someone gets on at the top, you don't want that to be mis-detected as the first person getting OFF.

How will you handle that?  It is not a state machine issue, but a detector issue.   You might scrape by by including some timing knowledge into the detection.

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!