Need help with servo driven laser (probably simple)

Hi all,

For a school assignment due for tomorrow I need your help.
I am a total beginner with Arduino and I have a servo motor with a laser on top of that.
Which rotates 180 degrees constantly. Now I want my servo to stop turning when my laserReceiver module detects the laser.

For now my code is this:

#include <Servo.h>

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
const int pinLaser = 2; // output signal pin of laser module/laser pointer
const int pinReceiver = 3; // input signal pin of receiver/detector (the used module does only return a digital state)

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(pinLaser, OUTPUT); // set the laser pin to output mode
  pinMode(pinReceiver, INPUT); // set the laser pin to output mode
  digitalWrite(pinLaser, HIGH); // emit red laser
  Serial.begin(9600); // Setup serial connection for print out to console
}



void loop() {
    int value = digitalRead(pinReceiver); // receiver/detector send either LOW or HIGH (no analog values!)
     
  Serial.println(value); // send value to console
  delay(1000); // wait for 1000ms
  
  for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
  for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position

  }
}

As you can see the problem I have is that the laserReceiver only checks if it detects a laser at the beginning of the loop. My knowledge with code and looping is still not that great, so I hope someone can explain to me what code I need to make this work. My guess would be a while loop?

So in short: I want the servo to rotate but if the laserReceiver detects the laser I want the servo to stop turning. And then when the LaserReceiver is not detecting the laser it starts rotating again.

I hope someone can help me :slight_smile:
Thanks in Advance!

Try checking the receiver inside the for-loops.
Position the servo, check for detection. If receiver detects, wait until detection fails.
Not elegant but might put You on the track.
There are more sofisticated ways, using millis() and doing several things at the time, but can wait a few moments.

you have to put your detection inside your for() loops if you want to stop mid-turn.

A better approach (but maybe more advanced) would be to get rid of the for() loops and do something along the lines of the BlinkWithoutDelay example (File->Examples->02. Digital->BlinkWithoutDelay) such that you update your servo and read the state of your detection every 15 ms and then, based on the state of the detection, either do nothing or increment your position. If you hit a limit (0 or 180) then reverse direction.

A good idea. The servo needs some amount of time to settle and the receiver needs some little time to detect. How much? Maybe in the range of some tenths of milliSeconds.

blh64:
you have to put your detection inside your for() loops if you want to stop mid-turn.

A better approach (but maybe more advanced) would be to get rid of the for() loops and do something along the lines of the BlinkWithoutDelay example (File->Examples->02. Digital->BlinkWithoutDelay) such that you update your servo and read the state of your detection every 15 ms and then, based on the state of the detection, either do nothing or increment your position. If you hit a limit (0 or 180) then reverse direction.

Railroader:
Try checking the receiver inside the for-loops.
Position the servo, check for detection. If receiver detects, wait until detection fails.
Not elegant but might put You on the track.
There are more sofisticated ways, using millis() and doing several things at the time, but can wait a few moments.

Thank you Railroader and blh64,

I tried working with the BlinkWithoutDelay and got it a sort of working.
This is the code I have now:

#include <Servo.h>

unsigned long previousMillis = 0;
const long interval = 15;

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
const int pinLaser = 2; // output signal pin of laser module/laser pointer
const int pinReceiver = 3; // input signal pin of receiver/detector (the used module does only return a digital state)

void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  pinMode(pinLaser, OUTPUT); // set the laser pin to output mode
  pinMode(pinReceiver, INPUT); // set the laser pin to output mode
  digitalWrite(pinLaser, HIGH); // emit red laser
  Serial.begin(9600); // Setup serial connection for print out to console
}



void loop() {
  unsigned long currentMillis = millis();
  int value = digitalRead(pinReceiver);

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (value == LOW) {
    pos = 0; pos <= 180; pos += 2; {
    myservo.write(pos);              
    delay(15);
    int value = digitalRead(pinReceiver);
    
     
   Serial.println(value);
  
   }
    pos = 180; pos >= 0; pos -= 2; { 
     myservo.write(pos);             
       delay(15);                     
    }
    } 
    else {
      myservo.detach();
    }
  }
}

This works but my servo jitters weirdly. I understand this code is probably a mess but I'm glad it does something :slight_smile:

Now I have to find a way yo pause the servo because I couldn't get the servo to start again after I detach it. I tried myservo.attach(9); but it doesn't seem to work.

Your code needs some polishing. There are some remains of the old for-loop,

  pos = 180; pos >= 0; pos -= 2; { 
     myservo.write(pos);             
       delay(15);

It looks strange to me.

This works but my servo jitters weirdly. I understand this code is probably a mess but I'm glad it does something

It compiles because it is syntactically correct, but on the other hand, my hovercraft is full of eels.