[Shooting range Project] Switching target's position

Hello team,

So today, i'm coming to check for some help & advice on how to debug my current project.
The simulator i'm using for this project : Clic on me!

I'm trying to create a specific target for a shooting range project - It will be down range at 25m, and a remote wired box will hold the 2 position switch that is in front of the shooter, on the table.
When the shooter starts it's cycle, he switches ON the switch & goes on until switching it to OFF.

We're changing the state of the target that is in front of the shooter by piloting a Servo motor betwen 0 & 90°.

So there's what the projet should do :slight_smile:

  • While the imput on pin 2 is HIGH (and stay's HIGH)
    1: The target goes from 0° position (stand-by) to it's working position 90°
    2: The target stay's at this 90° position for a random time that is betwen 2s & 8s
    3: Once the random time is over, the target goes to it's stand-by position at 0° for random time betwen 2s & 8s
    4: Once the random time is over, we start all this again.

This needs to work in a loop, the time the imput is HIGH.
As soon as the imput goes LOW, our target goes to it's stand-by position at 0° until the imput goes HIGH again.

I tried several way's to include my "process" into the loop, with IF's, ELSE's & IF ELSE conditions, but all the time i got stuck in one moment of the cycle, wich get unblocked by changing the switch position (From HIGH to LOW or LOW to HIGH).

Would you guy's maybe be kind enough to send me your though's & ideas ?
Thanks in advance.

#include <Servo.h>

Servo servo;
int buttonPin = 2; // Pin used for the digital input
int buttonState = 0; // State of the digital input
int previousButtonState = 0; // Previous state of the digital input
unsigned long changeTime = 0; // Time when the servo should change position
int currentPosition = 0; // Current position of the servo (0 or 90 degrees)
bool done = true;

void setup() {
  servo.attach(9); // Attach the servo to pin 9
  pinMode(buttonPin, INPUT); // Configure the pin for digital input
  digitalWrite(buttonPin, HIGH); // Enable the internal pull-up resistor

  randomSeed(micros()); // Initialize the random number generator with a value based on the micros() time at startup
}

void loop() {
  buttonState = digitalRead(buttonPin); // Read the state of the digital input

  if (buttonState != previousButtonState) { // If the state of the digital input has changed
    if (buttonState == HIGH) { // If the digital input is in the HIGH position
      servo.write(0); // Turn the servo to 0 degrees
      changeTime = millis() + random(2000, 6000); // Calculate the time to change to position 90
      currentPosition = 0;
      done = false;
    } else { // If the digital input is in the LOW position
      servo.write(0); // Reset the servo to 0 degrees
      currentPosition = 0;
      done = true; 
    }
  } else if (buttonState == HIGH && millis() >= changeTime && !done) { // If the state of the digital input has not changed
    if (currentPosition == 0) { // MOVED from above: Already waited at position 0
        servo.write(90); // Turn the servo to 90 degrees
        changeTime = millis() + random(2000, 6000); // Calculate the time to change BACK to position 0
        currentPosition = 90;
    } else { // Already waited at some other position that is NOT zero
      servo.write(0); // Turn the servo to 0 degrees
      currentPosition = 0;
      done = true; // Don't keep checking until flipped off and then back on
    }
  }

  previousButtonState = buttonState; // Save the state of the digital input for the next iteration
}

First master the Change in State example.


Also, do some research into how to use a State Machine in your sketches.

This may be a good place for a state machine.

My tutorial on state change detection with active low inputs (using internal pullups).

  1. The slide switch has the potential of being left in the "working" position. I would use a momentary contact switch (pushbutton) and have the unpressed condition HIGH (servos to standby position), with the pressed condition LOW (servos to working position)
  2. Name your pins...
int servoPin = 9; // give names to pins
  1. Name your servo positions in the definition section so if you want different positions, you only edit one variable.
standBy = 0; // servo standby position
working = 90; // servo working position
  1. Name your random minimum and maximum time so changing the times takes only one variable edit for the whole sketch.
randMIN = 2000; // min random time
randMAX = 6000; // max random time
  1. Now it is time to attach your servo instance to a pin:
  servo.attach(servoPin); // Attach the servo to pin 9
  1. These two lines:
  // pinMode(buttonPin, INPUT); // Configure the pin for digital input
  // digitalWrite(buttonPin, HIGH); // Enable the internal pull-up resistor

could be written like this:

  pinMode(buttonPin, INPUT_PULLUP); // configure pin as input and attach internal pullup resistor
  1. randomSeed(micros()) will take the same micros() each run (from power applied). Maybe try:
  randomSeed(analogRead(A0)); // Initialize the random number generator with a value based on noise on a floating Analog pin zero.
  1. Avoid hard-coding "magic number"... consider making this change:
      // servo.write(0); // Turn the servo to 0 degrees
      servo.write(standBy); // Turn the servo to standBy position
  1. Use the named random min/max from above:
      // changeTime = millis() + random(2000, 6000); // Calculate the time to change to position 90
      changeTime = millis() + random(randMIN, randMAX); // Calculate the time to change to position 90

Why keep it HIGH? Why not "pin 2 goes high" is enough to move the servos to "working" then start counting, then move the servos to "standby?" This would use the pushbutton.

I guess it's an ON/OFF switch function. Although, you could get the same function using the change of state of the switch to toggle the run/standby mode.

Yes, that is where the potential of leaving it in one state exists, and why I see a momentary contact switch would suit this better. No chance of leaving it "on" and the system is ready to be started again from an known state.

Hello sir,

Thank you a lot for all the good advices you sent me, wich i all use now in the updated version of the code itself.

Regarding this :

I'm someone that works in the industry, but on the wiring/hardware side, and use a lot of 2 position switches wich for sure can make the system be left in the working position forever.
But i think you're right, having a push-button & then just track the current state of the button & it's previous state to make it change our system from ON to OFF.

I'm still looking at the two links i got sent, to see how things work & how i should implement em in the code itself.

Thanks for the replies so far.

1 Like

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