Sensor for car lift

I was changing into my wetsuit when I remembered this last three lines. There is no reason to delay(500), and it may account for some inconsistent behaviour of the sketch.

Some delay is useful as it affords a kind of poor man's global debouncing or deglitching, I suggest 50 ms as plenty for that and little enough so there are no UI inplications.

a7

ok i set it to 50ms and it works better. But one issue is that my hand goes 5 times on sensor and it works perfectly....then a try once more and buzzer is quiet...once more...nothing....third time and goes back in action.

My next issue is the relay(rele in my case). In my original program it was always ON....when the sensor was triggered it went OFF. Now in this program the relay is always on.

I think I see why, oh wait, no I don't, because we can't see where you've ended up with your efforts.

Post a link to the wokwi that has your leatest code, or say that you are updating the one you already posted.

which is OK, but again can make some trash of the thread.

When I post a wokwi sim, when I am sure it is ready for world-wide exposure, I use wokwi' s ability to lock the sim so it won't ever be different from what I post and send everybody to look at.

a7

oops sorry. So ma latest code is here:

#define trigPin 13
#define echoPin 12
#define led 11
#define rele 10
#define buzzer 9

int buzzerState = 0;
unsigned long currentMillis;
unsigned long previousMillis = 0;
const long interval = 5000;

void setup() {

 Serial.begin (9600);

 pinMode(trigPin, OUTPUT);

 pinMode(echoPin, INPUT);

 pinMode(led, OUTPUT);

 pinMode(buzzer, OUTPUT);

 pinMode(rele, OUTPUT);

}

void loop() {

 long duration, distance;

 digitalWrite(trigPin, LOW);

 delayMicroseconds(2);

 digitalWrite(trigPin, HIGH);

 delayMicroseconds(10);

 digitalWrite(trigPin, LOW);

 duration = pulseIn(echoPin, HIGH);

 distance = (duration / 2) / 29.1;

 if (distance < 10)

 { digitalWrite(led, HIGH);
   if (buzzerState == 0)
   {
     currentMillis = millis();
     tone(buzzer, 2500);
      
   }
    if (currentMillis - previousMillis >= interval)
        {
         previousMillis = currentMillis;
        
         noTone(buzzer);
         buzzerState = 1;
        }
   digitalWrite(rele, LOW);

 }

 else {

   digitalWrite(led, LOW);
   noTone(buzzer);
   buzzerState = 0;
   digitalWrite(rele, HIGH);

 }
 Serial.print(distance);

 Serial.println(" cm");

 delay(50);

 }

Is the project CONTROLLING the lift or just providing an alarm?
Because I wonder who'd be willing to get underneath a car that's held up by a lift controlled with hobbyist-quality hardware and running code written by:

Nothing to wory abouth this project. The lift has 2 sensors/switches that are always on. When you bring the lift up to its final position the sensors go off and lift stops. This does not control nothing else in the lift. In that circuit of two sensors/switches i put beside my switch (optocoupler). So this is completly safe. In case of arduino failing or something else the lift would stop. I can give you the schematics of the circuit for better undertanding.

Here you can see 2 switches SQ1 and SQ2

So if you can imagine...my arduino sensor which optocoupler could be SQ3.

In worst case scenrio the lift would just stop lifting.

OK you and your friend got closer. Here's it fixed, I hope. If you read my reply #3, and carefully look at the code below (and run it in the wokwi), you will see you have been arrived at where I was directing you.

  • Turn on the buzzer when the distance requires the buzzer.

  • Turn off the buzzer after it has been on for N milliseconds.

Play with it here. Read the code for clues.

// https://wokwi.com/projects/349517308198126162
// https://forum.arduino.cc/t/sensor-for-car-lift/1058371

# define trigPin 13
# define echoPin 12
# define led 11
# define rele 10
# define buzzer 9

int buzzerState = 0;

unsigned long currentMillis;
unsigned long previousMillis;

const long interval = 777;    // was 5000 - life too short!

void setup()
{
  Serial.begin (115200);  // it's 2022, not 1984

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(led, OUTPUT);
  pinMode(rele, OUTPUT);

  pinMode(buzzer, OUTPUT);
}

void loop()
{
  long distance;

  distance = getEcho();
  currentMillis = millis();

// check distance, set LED and relay and maybe launch a tone burst
  if (distance < 10) { 
    if (buzzerState == 0) {
      tone(buzzer, 1000); // hearing this better at 1000 Hz
      buzzerState = 1;    // no more tone until we've seen the distnace go > 10
      previousMillis = currentMillis;
    }

    digitalWrite(led, HIGH);
    digitalWrite(rele, LOW);
  }
  else {
//    noTone(buzzer);  would immediately stop buzzer
    buzzerState = 0;      // allow again the tone to trigger on

    digitalWrite(led, LOW);
    digitalWrite(rele, HIGH);
  }

// always check to see if a tone burst has gone on long enough  
  if (currentMillis - previousMillis >= interval)
      noTone(buzzer);

// print the distance occasionally
  static unsigned long lastPrint;
  if (currentMillis - lastPrint > 777) {
    Serial.print(distance);
    Serial.println(" cm");

    lastPrint = currentMillis;
  }
//  delay(50); no delay is necessary. loop() is running at full speed.
}

long getEcho()
{
  long duration, distance;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  distance = (duration / 2) / 29.1;

  return distance;
}

I added a few things in there, if you have questions just ask.

a7

You see how easily a simple oversight can go wrong with no ill intent.
I hope you have good insurance, a propensity for modified cars, and willingness to repair the roof.

He is manually controlling lifting and lowering buttons.
The Arduino here only connected to S3 (safety engaging button) in worst case Arduino will not trigger S3 and lift will keep going up but since he is manually controlling S1 he can stop it

I don't think there will be more damage than some scratches on car roof

Thank you alto777. When i come home today i will try this on the real deal "circuit" :slight_smile:

And this is the schematics for the lift with my sensor included for better understanding on what i am doing:

SQ3 = relay (rele) in my code

when the wire 14 and 15 is open the lift stops.

ok i tested this....next issue is that the distance is higher then before for the sensor. when a change it to 5 for example it almost stays the same. And another interesting observation....when i come closer to the sensor with my hand the buzzer squeals like a pig :smiley:

my serial monitor:

slika

it goes to 10....and then 1....there is nothing between 1 and 10 (cm)

(i moved my hand slow and stedy)

Can you show us the video of it

i will show when i go home.
I was wondering....i have a few arduino's in drawer and i was wondering that we could simplify this by using another arduino just for signaling the buzzer.

So this is my code for the buzzer:


int buzzer = 9;
int buttonPin = 2;


void setup() {
  pinMode(buzzer, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
  int buttonState = digitalRead(buttonPin);
 
  if (buttonState == LOW) {
    
    tone(buzzer,2500);
    delay(300);
    noTone(buzzer);
    delay(300);
    tone(buzzer,2500);
    
    
    

  
  }

  if (buttonState == HIGH) {
    noTone(buzzer);
  }
}

so i would need in this case just to beep 3- 4 times when switch is pressed...and then be quiet forever :slight_smile:

then when you turn switch off nothing happens....when you turn back switch again buzzer goes 3 -4 times then quiet.

Can someone edit this code i made here :slight_smile:

We (probably all) think adding a second Arduino board just for signaling the buzzer is actually complicating things.

Now you have code that works, but it turns out you don't want a 5 (or whatever) second stab of your tone, rather 3 - 4 beeps 300 ms ON 300 ms OFF.

In the code @alto777 posted in # 50, the variable buzzerState now tracks with the tone/noTone condition.

Instead, use it as the control for your beeping. You'll need to fix the way you do the pulsed tone to make all the elements in the code play nice with each other.

In that code is a pattern for doing things in the loop() once in a while. This lets us see the reading but updates at a leisurely 1.3 Hz:

// print the distance occasionally
  static unsigned long lastPrint;
  if (currentMillis - lastPrint > 777) {
    Serial.print(distance);
    Serial.println(" cm");

    lastPrint = currentMillis;
  }

If you can come to a good understanding of why that *if* statement is being executed like 19000 times a second, and the mechansim for only doing something occasionally, in this case, every 777 ms, you will have the basic idea behind the way to avoid adding an Arduino board as a savings of anything. Trust me.

If you exploit the same pattern but put 300 in there as the "a while" parameter, you will have a way to dole out some beeps.

a7

@alto777 is there any thing special in 777 I h seen your code and you have used 777ms multiple times

so here is the video how this turn out. The sound is not the best (in real the buzzer noise is even louder). Here you can see thah even the LED is flickering and acting strange.

video:

Video

You should check it with a flat Cardboard.

No, just a not-random number, a nice amount of time but not an eternity. :wink:

@accord37 here's a sketch that might save youi an Arduino board and the kind of fun you'd have getting two boards to co-operate.

I added a swtich that must be pressed to get the lift operating again.

Now the question is would you get under something running on software hastily scribbled and lightly test by someone who has an eye out the window for his beach buddy?

Test it here yourselfse : Lift Alarm Demo

// https://wokwi.com/projects/349705577895559764
// https://forum.arduino.cc/t/sensor-for-car-lift/1058371

# define trigPin 13
# define echoPin 12
# define led 11
# define rele 10
# define buzzer 9

# define ACK  7   // must acknowledge fault to egenrize

int buzzerState = 0;   

unsigned long currentMillis;
unsigned long previousMillis;

const long interval = 777;    // was 5000 - life too short!

void setup()
{
  Serial.begin (115200);  // it's 2022, not 1984

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);

  pinMode(ACK, INPUT_PULLUP);

  pinMode(led, OUTPUT);
  pinMode(rele, OUTPUT);

  pinMode(buzzer, OUTPUT);
}

void loop()
{
  long distance;

  distance = getEcho();
  currentMillis = millis();
  bool acknowledge = !digitalRead(ACK);    // reset alarm mecahnism?

  static bool operate = true;

  bool enteredAlarm = false;       // edges
  static unsigned char alarmState;                    // 1 = too close
  if (distance < 10) {

    if (acknowledge) enteredAlarm = true;       // no reset if we still on the ceiling

    if (!alarmState) {
      alarmState = 1;
      enteredAlarm = 1;
    }

    digitalWrite(led, HIGH);
    digitalWrite(rele, LOW);
    operate = false;          // lockout open relay, LED on
  }
  else {  // distance > 10
    if (alarmState) {
      alarmState = 0;
    }

    if (operate) {
      digitalWrite(led, LOW);
      digitalWrite(rele, HIGH);
    }
    else if (acknowledge) operate = true;
  }

  beepMachine(enteredAlarm);

//  delay(20);  // until I am sure I don't need to
}

enum {IDLE, OFF, ON,};  // yuck. anonynous enum. So sue me.

# define BEEPS 3        // beep three times each

void beepMachine(bool enter)
{
  static unsigned long lastBeep;
  static unsigned char beepCount;

  static unsigned char beepState = IDLE;

  unsigned long now = currentMillis;  // I know I know
  bool timeTo = now - lastBeep > 125;

  switch (beepState) {
  case IDLE :
    if (!enter) break;  //idling, no alarm raised, so

    beepCount = BEEPS;
    timeTo = true;
    beepState = OFF;
    enter = false;

  case OFF :
    if (!timeTo) break;
    if (!beepCount) {
      beepState = IDLE;
      break;
    }
    tone(buzzer, 440);
    beepState = ON;
    lastBeep = now;
    break;

  case ON :
    if (!timeTo) break;
    noTone(buzzer);
    beepState = OFF;
    beepCount--;
    lastBeep = now;
    break;
  }

  if (enter) {  // an entry not handled by having been IDLE
                // just makes the alarm keep sounding
    beepCount = BEEPS;
  }
}

long getEcho()
{
  long duration, distance;

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);

  distance = (duration / 2) / 29.1;

  return distance;
}

a7