SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By Ardalan
#198145
Hi there, I have written written this code:
_______________________________________________________________
_______________________________________________________________

if ((distance < 50)&&(currentState=0))
{
currentState = 1;
}
else if ((distance < 50)&&(currentState=1))
{
currentState = 0;
_______________________________________________________________
_______________________________________________________________

What I am trying to say is if "distance" is less than 50, then turn "currentState" to 1 if it was already 0 and turn it to 0 if it was already 1.

Clearly, it is wrong because it's not working.

Can someone help me?

Thanks,

Ardalan
User avatar
By exeng
#198146
Base on your limited code fragment, I'm assuming that you basically want to toggle the state variable "currentState" only when distance is less than 50.

Assuming your currentState is defined as a boolean you could do the following:

int distance;
bool currentState = 0; // Assuming this is your initial state

// Test for distance less than 50 and toggle state
if(distance < 50)
{
currentState = !currentState; // Toggle state
}

These are of course also code fragments, not complete code, so you would need to incorporate them (the initialization and test) in the appropriate sections of your complete code.
By Ardalan
#198156
Yes. I want to toggle "currentState" between 0 and 1 for every 1 time distance becomes less than 50.

Can you please help me incorporate that into the whole code?
_____________________________________________
#include <LiquidCrystal.h>
#define trigPin 6
#define echoPin 7
LiquidCrystal lcd(11,10,9,2,3,4,5);

int currentState = 0;

void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(13,OUTPUT);
lcd.begin(16, 2);
lcd.setCursor(4, 0);
lcd.print("counter");
}

void loop() {
long duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(60);
digitalWrite(trigPin, HIGH);
delayMicroseconds(60);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;

if (distance < 50)
{
//I don't know what to do here

lcd.setCursor(4,1);
lcd.print(currentState);
if(currentState > 0) digitalWrite(13,HIGH); else digitalWrite(13,LOW);
delay(500);
}


Thanks. This is only my 2nd project.
User avatar
By exeng
#198163
Need some clarification...

You say
I want to toggle "currentState" between 0 and 1 for every 1 time distance becomes less than 50.
Do you mean if it's less than 50 on any read, then toggle currentState. Or to you mean toggle currentState when less than 50 if and only if the prior read was not less than 50?
User avatar
By exeng
#198164
Perhaps this will help me understand your desired behavior...
Assuming currentState is initialized to 0, what would be the expected values of currentState (abbv. CS in the table below) for each read of distance:
Of course Last CS will = New CS of any prior read.

[Read],Distance < 50],[Last CS],[New CS]
1, TRUE, 0, ?
2, TRUE, ?, ?
3, TRUE, ?, ?
4, FALSE, ?, ?
5, FALSE, ?, ?
6, TRUE, ?, ?
7, TRUE, ?, ?
8, FALSE, ?, ?
9, FALSE, ?, ?
10, TRUE, ?, ?
11, FALSE, ?, ?
By Ardalan
#198165
This is what I need: toggle currentState when less than 50 if and only if the prior read was not less than 50.

I figured out to put this in

if (distance < 50)
{
currentState = 1 - currentState;

to toggle between 0 and 1

But the problem is that if I hold my hand in front of the sensor, it keeps rapidly toggling.

How can I write it so that it only toggles once per object passing through it?

Is putting a delay() the only way or no?

Thanks
User avatar
By exeng
#198166
OK, so what may be happening is that once you enter the <50 state you are toggling your state variable at a rate roughly equivalent to 500ms delay and driving your on/off LED accordingly. If you want to slow down the toggle than yes, adjust the delay. But to me that may not be the behavior you really want.

How is your LED supposed to behave when your hand is in front of the sensor and distance < 50? I'm guessing here, but you either want it be on (solid) when <50 or you want it to blink when <50, then be off when >=50. Bare with me, I'm just still confused about what you want to happen. The code should not be difficult once we figure that out.
By Ardalan
#198167
Thanks for helping me Exeng,

The Light will turn on through pin 13 and stay on when I pass my hand through the ultrasound at less than 50cm.
I did set the relay to 1500ms so that I can remove my hand by then so that it will not flash on and off.
But ideally, I wanted to have the light turn on and stay on until I REMOVE MY HAND PAST 50CM AND PUT IT BACK AGAIN in which case it would turn off.

Described in another way: currentState toggles between 0 and 1 using the if (distance < 50) { currentState = 1 - currentState; line but only toggles once for every time the distance is less than 50cm

I hope that can make sense.
By Ardalan
#198168
So in the way you said it.......
when my hand goes in front of the ultrasound, the light should turn on if it was off and off if it was on and stay that way no matter how long I leave my hand in front of it. It should only toggle back after I remove my hand and then put it back.

Thanks Again!!
By paulvha
#198170
try to change the code to something like this:
Code: Select all
#include <LiquidCrystal.h>
#define trigPin 6
#define echoPin 7
LiquidCrystal lcd(11,10,9,2,3,4,5);

int currentState = 0;                     

void setup() {
    pinMode(trigPin, OUTPUT);
    pinMode(echoPin, INPUT);
    pinMode(13,OUTPUT);
    lcd.begin(16, 2);
    lcd.setCursor(4, 0);
    lcd.print("counter");
}

void loop() {
    long duration, distance;
    static int in_range = 0;               // make this a static
    
    digitalWrite(trigPin, LOW);
    delayMicroseconds(60);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(60);
    digitalWrite(trigPin, LOW);
    
    duration = pulseIn(echoPin, HIGH);
    distance = (duration/2) / 29.1;

    if (distance < 50)
    {
        if (in_range == 0)                  // NEW in distance
        {
            in_range = 1;                  // indicate we are in range
            currentState = 1- currentState;     
        
            lcd.setCursor(4,1);
            lcd.print(currentState);
        
            if(currentState) digitalWrite(13,HIGH); 
            else digitalWrite(13,LOW);
        
            delay(500);
        }
    }
    else
        in_range = 0;                       // indicate out of range now
}
User avatar
By exeng
#198174
Well damn you paulvha (just kidding) you beat me to it. Must be a time zone time. Yes that will work.

I had just this morning (PST) finished my version (very similar) and was about to post when I saw this. The difficult part was trying to understand what Ardalan wanted. Once he described it in full it made sense that he wanted to created a proximity sensor that toggled a switch.
By Ardalan
#198177
Thanks for sticking through this with me : )
I took a nice long stare at the code and I understand it now.

Thanks again, Exeng and Paulvha