Counter for turning on/off servo sweep using obstacle sensor?

I'm trying to make a Servo sweep at a desired speed using a potentiometer. So far, I've achieved that much.

But I want to make that same servo (and therefore the sweeping) turn on and off whenever a sensor (IR infrared obstacle avoidance sensor) detects something close (very similar to a push button counter?)

However, in the code I'm currently using, something weird is happening:

By the second (2) push, the servo starts sweeping with the speed designated by the potentiometer.

But the sensor/serial monitor wont mark the third (3) push. I don't get why. Sometimes after many tries the third push will be perceived randomly, but I still haven't figured out why.

Then the fourth (4) and fifth (5) pushes are easily perceived by the sensor and noted on the serial monitor, but nothing happens.

It is only on the sixth (6) push that the servo starts sweeping again. And then the sensor/serial monitor won't work properly again (like in the second push). And just like in pushes 4 and 5, pushes 8 and 9 are perciebed but do nothing.

Here's the code:

#include <Servo.h>

Servo ServoFeliz;

int pos = 0;

int sensor_pin = 7; //IR sensor pin
int sensorCounter = 0;   // counter for the number of sensor changes
int sensorState = 0;         // current state of the sensor
int lastSensorState = 0;     // previous state of the sensor

int potpin = A0; =/potentiometer pin
int PotpinVal; //potentiometer val


//**********


void setup() {

  pinMode (sensor_pin, INPUT);
  
  ServoFeliz.attach(9);

  Serial.begin(9600);
}


//**********


void loop() {

  PotpinVal = analogRead(potpin);
  PotpinVal = map(PotpinVal, 1, 1023, 1, 25); // lectura del valor del potenciometro (entre 1 y 1023

  sensorState = digitalRead(sensor_pin);

  // compare the sensorState to its previous state
  if (sensorState != lastSensorState) {
    // if the state has changed, increment the counter
    if (sensorState == HIGH) {
      // if the current state is HIGH then the sensor went from off to on:
      sensorCounter++;
      Serial.println("on");
      Serial.print("number of button pushes: ");
      Serial.println(sensorCounter);
    } else {
      // if the current state is LOW then the sensor went from on to off:
      Serial.println("off");
    }
    // Delay a little to avoid bouncing
    delay(15);
  }
  // save current state as last state, for next time through the loop
  lastSensorState = sensorState;


  if (sensorCounter % 4 == 1) {
    ServoFeliz.write(0);
    delay(15);
  } else  if (sensorCounter % 4 == 2) {
    for (pos = 0; pos <= 180; pos += 1) {
      // in steps of 1 degree
      ServoFeliz.write(pos);
      delay(PotpinVal);
    }
    for (pos = 180; pos >= 0; pos -= 1) {
      ServoFeliz.write(pos);
      delay(PotpinVal);
    }
  } else  if (sensorCounter % 4 == 3) {
    ServoFeliz.write(0);
    delay(15);
  }
}

All I really want is for the IR sensor to work as an on off switch
(Sensor HIGH&LOW= on, and next HIGH&LOW = off.).
I don't want the servo to only work when the sensor is on HIGH and stop working when the sensor is LOW. That would defeat the purpose of the mechanism.

I would really appreciate any help.

Please follow the advice given in the link below when posting code, in particular the section entitled 'Posting code and common code problems'

Use code tags (the </> icon above the compose window) to make it easier to read and copy for examination

why is a counter being used?

the counter is increments each time the sensor becomes active and there is a 4 count cycle where every 3rd step the servo cycles.

why not have the code that cycles the servo be conditional on the sensorState?

1 Like

Okay, that makes sense. But how do I do that? I have successfully added a conditional that makes the servo start, but I can't seem to make it stop.

#include <Servo.h>

Servo ServoFeliz;

int pos = 0; //servo position

int sensor_pin = 7; //IR sensor pin
int sensorPushed = 0; //IR sensor pushes

int potpin = A0; //potentiometer pin
int PotpinVal; //potentiometer value


//**************************************************************************************


void setup() {

  pinMode (sensor_pin, INPUT);

  ServoFeliz.attach(9);

  Serial.begin(9600);
}


//**************************************************************************************


void loop() {

  PotpinVal = analogRead(potpin);
  PotpinVal = map(PotpinVal, 1, 1023, 1, 25); // potentiometer val between 1-1023/1-25

  if (digitalRead(sensor_pin) == LOW) { //if sensor goes off then the push is true
    sensorPushed = 1;
    Serial.println("pushed");
  }


  if ( sensorPushed ) {

    for (pos = 0; pos <= 180; pos += 1) {
      ServoFeliz.write(pos);
      delay(PotpinVal);
    }
    for (pos = 180; pos >= 0; pos -= 1) {
      ServoFeliz.write(pos);
      delay(PotpinVal);
    }

  }

  if ( sensorPushed ) {

    ServoFeliz.write(0);
    delay(15);

  }

}

This is why I though a counter would help. But, same as before, once the servo starts sweeping, the sensor wont read any more "pushes", nor will the serial monitor.

because the code never resets sensorPushed when the pin goes HIGH

why not

#include <Servo.h>
Servo ServoFeliz;
int pos = 0; //servo position
int sensor_pin = 7; //IR sensor pin
int sensorPushed = 0; //IR sensor pushes
int potpin = A0; //potentiometer pin
int PotpinVal; //potentiometer value
//**************************************************************************************
void setup() {
    pinMode (sensor_pin, INPUT);
    ServoFeliz.attach(9);
    Serial.begin(9600);
}

//**************************************************************************************
void loop() {
    PotpinVal = analogRead(potpin);
    PotpinVal = map(PotpinVal, 1, 1023, 1, 25); // potentiometer val between 1-1023/1-25

    if (digitalRead(sensor_pin) == LOW) { //if sensor goes off then the push is true
        for (pos = 0; pos <= 180; pos += 1) {
            ServoFeliz.write(pos);
            delay(PotpinVal);
        }
        for (pos = 180; pos >= 0; pos -= 1) {
            ServoFeliz.write(pos);
            delay(PotpinVal);
        }
    }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.