Else will not be true in my loop! Going mad...

HI!

I am trying to get my hc-sr04 sensor to control a servo when something approches 20 cm to it.

Code almost works, it just will not do anything when the sensor reads less than 20 cm. Thereby the if statement is always true each loop. The servo is turning, so wires are correct.

Hope anyone can help me!

int trigPin = 11;    //Trig - green Jumper
int echoPin = 12;    //Echo - yellow Jumper

#include <Servo.h>
Servo myservo;

long duration, cm;
 
void setup() {
  //Serial Port begin
  Serial.begin (9600);
  //Define inputs and outputs
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  myservo.attach(0);
  myservo.write(0);
}
 
void loop()
{
 
 
  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
 
  // convert the time into a distance
  cm = (duration/2) / 29.1;
  
  Serial.print(cm);
  //Serial.print("cm");
  Serial.println();
  
  delay(250);
  if (cm > 20){
    myservo.write(90);
    //Serial.print("under 20");
  }
  else{
    myservo.write(0);
    //Serial.print("over 20");
  delay(250);
  }

}

Moderator edit: CODE TAGS!

Please edit your post to use code tags. Thanks mod! See, How to use this forum.

What is the pinMode doing inside the loop?

But all it looks like is the math is just wrong... You are printing the cm, so what is it printing?

Why are you using a serial pin to drive a servo?

Damn, missed that because it's hard coded :confused:

Sorry i didn't use code tags!

I am such a noob, so i found the beginning of the code online. The start of the code is printing the distance, so i tried to add an if and else statement so make the servo turn in readings of over and under 20 cm.

Hi,

 if (cm > 20){
    myservo.write(90);
    //Serial.print("under 20");
  }
  else{
    myservo.write(0);
    //Serial.print("over 20");
  delay(250);
  }

I think you have the > when you need the < comparison.
cm > 20, if cm is greater then 20, true then
cm < 20, if cm is less than 20, true then
Tom.... :slight_smile:

Tom, I tried your suggestion, but it didn't help.

I guess I could not tell you guys my problem properly.

PROBLEM: The servo should turn 90 degrees if the sensor registrates a distance closer than 20 cm.

Now, nothing happens to the servo no matter the readings from the sensor.
The serial reader shows the correct distances.

I think there is something wrong with my if/else statement.

Really appreciate your help :slight_smile:

Have you fixed the problems already pointed out?

I removed the line

 pinMode(echoPin, INPUT);

I thought they were nessescary to get a distance value from the sensor, but turns out it works anyway.

But I do not understand what AWOL mean about why I am using a serial pin to control a servo. After reading arduinos websites, I thought this was a good way to do it? Do you think the basics of the code is wrong?

Servo attached to pin 0, while pin 0 is distracted doing your serial printing.
What movement makes you think it's somewhat working? The write to 0 in the setup? Or does it go to 90? Do you know what numbers correlate to what positions? You need to give the servo time to travel as well since you're flooding it with results.

caen2812:
I removed the line

 pinMode(echoPin, INPUT);

I thought they were nessescary to get a distance value from the sensor, but turns out it works anyway.

All pins default to INPUT unless declared as OUTPUT, but it's still a good habit to declare as INPUT. Your change made no difference other than making you feel like you made a difference.

I do not understand what you mean by saying that pin 0 is distracted doing serial printing?

Anyway, changed the code to the following:

 int trigPin = 11;    //Trig - green Jumper
int echoPin = 12;    //Echo - yellow Jumper

#include <Servo.h>
Servo myservo;

long duration, cm;
 
void setup() {
  //Serial Port begin
  Serial.begin (9600);
  //Define inputs and outputs
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  myservo.attach(1);
  myservo.write(0);
}
 
void loop()
{
 
 
  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
 
  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  
  duration = pulseIn(echoPin, HIGH);
 
  // convert the time into a distance
  cm = (duration/2) / 29.1;
  
  Serial.print(cm);
  //Serial.print("cm");
  Serial.println();
  
  delay(250);
  if (cm < 20){
    myservo.write(90);
    delay(1000);
    //Serial.print("under 20");
  }
  else{
    myservo.write(0);
    delay(2000);
    //Serial.print("over 20");
  delay(250);
  }

}

Now, the servo makes a few millisecond buzz every 2 seconds over 20 cm and every second under 20 cm.

I do not understand why it doesn't work. The sensor should have time to turn now, can anyone see what is wrong?

caen2812:
I do not understand what you mean by saying that pin 0 is distracted doing serial printing?

Pin 0 and pin 1 are the fixed pins for Serial communication. Which you start by doing Serial.begin(). So they are already in use. Free pins 0 and 1 and use a different pin for the servo.

You have a servo running from a serial line still. Pins 0 and 1 are the hardware serial pins on the Uno/Mega/Nano/Mini etc.

Don't use them for anything but serial if you call Serial.begin()

Changed it to 9 and it works like a dream! Thank you guys so much! :smiley: