Rotate servo without for() function

Hello all, I am new to this forum, so please apologise if I am doing anything wrong :slight_smile: (I read the guide but it might still happen^^)

I want to create a simple door alarm system with a sonar that is strapped onto a servo, scanning the room, and an led that signals anybody coming closer. As long as the distance to the sonar is >30cm I want the servo to rotate and if anything comes to close the Servo should stop and will point at the direction of where the distance was crossed.

As the standard servo "Sweep" code works with a for() function which includes a delay(), I noticed early that this is not feasible, as it is impossible to synchronise the servo and the sonar. With the for() the sonar only scans once every full rotation of the servo. Thus, I created a code that should rotate the servo without a for-function and which is synchronised with the sonar scans. The servo goes to the initial position and then only goes to position 0 and stops. I have spend a lot of time thinking through the code and I cannot see why it does that and only (very quickly) goes to 0. In the Serial monitor, the Servo goes directly from starting position (90) to 0 without any transition. My fear is that this has to do with any characteristics of servos or with the way that the Arduino-Programming-Language executes the loops. But I don't know anything about coding, so I definitely need help here. I was wondering if you could find, why the servo doesn't rotate if distance >30 or if anybody knows an alternative way of rotating the servo :slight_smile:


//help variable for switch case

int help = 1;

// Define sonar connections in order to change allocation more quickly later on

#define VCC_PIN 13 // vcc pin is attached to digital pin 13
#define TRIGGER_PIN 12 // sonar trigger pin is attached to digital pin 12
#define ECHO_PIN 11 // sonar echo ground pin is attached to digital pin 11
#define GROUND_PIN 10 // ground pin is attached to digital pin 10
#define MAX_DISTANCE 100 // maximum distance = 100 cm; every input above will be regulated to 100cm

// Variables Sonar

long duration;
int distance;

//Servo

#include <Servo.h>
Servo sweetservo;
int servoposition = 0;
int angleincrease = 1;

// Variables LED

int greenpin = 3;
int bluepin = 5;
int redpin = 6;

void setup() {
 
  Serial. begin(9600);  // data transmission rate for serial monitor

//sonar setup

  pinMode(ECHO_PIN, INPUT) ; // ECHO PIN receives sound signal
  pinMode(TRIGGER_PIN, OUTPUT) ; // TRIG PIN sends sound signal
  pinMode(GROUND_PIN, OUTPUT);  // tell pin 10 it is going to be an output
  pinMode(VCC_PIN, OUTPUT);  // tell pin 13 it is going to be an output

  digitalWrite(GROUND_PIN,LOW); // tell pin 10 to output LOW (OV, or ground)
  digitalWrite(VCC_PIN, HIGH) ; // tell pin 13 to output HIGH (+5V)
  
//servo setup

sweetservo.attach(9);
sweetservo.write (servoposition);

//led rgb setup

  pinMode(greenpin, OUTPUT);
  pinMode(bluepin, OUTPUT);
  pinMode(redpin, OUTPUT);

} //this bracket closes the setups

void loop() {

//data for serial monitor

  Serial.print("Distance: ") ;  // Prints the distance on the Serial Monitor
  Serial.println(distance);
//programm help variable

if (distance > 30) {help = 1;}
else {help = 2;}

switch(help) {


case 1:

  digitalWrite(TRIGGER_PIN, LOW);
  
  servoposition = servoposition + angleincrease;

  sweetservo.write(servoposition);
  
  if (servoposition = 180) {angleincrease = -1; }
  if (servoposition = 0) {angleincrease = 1; }
  
  delay(15);

  digitalWrite(TRIGGER_PIN, HIGH);
  
  servoposition = servoposition + angleincrease;

  sweetservo.write(servoposition);
  
  if (servoposition = 180) {angleincrease = -1; }
  if (servoposition = 0) {angleincrease = 1;}
  
  delay(15);

  digitalWrite(TRIGGER_PIN, LOW);
  
  duration = pulseIn(ECHO_PIN, HIGH);
  
  if (distance > MAX_DISTANCE){distance = MAX_DISTANCE ;}

  distance = duration*0.034/2;
  
break;

  
  case 2:

 digitalWrite(TRIGGER_PIN, LOW);
  delayMicroseconds(3);
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(12);
  digitalWrite(TRIGGER_PIN, LOW);

  duration = pulseIn(ECHO_PIN, HIGH);
  
  if (distance > MAX_DISTANCE){distance = MAX_DISTANCE ;}

  distance = duration*0.034/2;

break;
   
} //close switch

//RGB LED

if (distance > 30) {
  analogWrite(greenpin, 0);
  analogWrite(bluepin, 255);
  analogWrite(redpin, 255);
}
else {
  analogWrite(greenpin, 255-(8.5*(distance-30))); //this allows a smooth transition from yellow to red -> the value starts at 30*8.5=255 (which causes yellow) and linearly decreases to 0 (which causes red)
  analogWrite(bluepin, 255);
  analogWrite(redpin, 0);
}

} //this bracket closes the loops

Thank you so much! Just let me know if any important information is still missing!

Probably need == in these statements

  if (servoposition == 180) {angleincrease = -1; }
  if (servoposition == 0) {angleincrease = 1; }
1 Like

I wanna hug you so bad right now :smiley: Thank you so much, now it is working as intended! I can't belive that two "=" just cost me 5 hours of my life haha