Introducing a proximity sw as an end to the loop

Been jigging with this for a while,

Basic system -
UNO Board,
Arduino spdt relay, SRD-05VDC-SL-C (set to normally open)
Arduino vibration sensor or accelerometer, WYPH SW-420
DFROBOT Inductive Prox 5V NPN normally open.

Relay drives a 6V, 3rpm geared motor on a seperate power supply.
Motor has an elliptical shaped rotor on the spindle.
Prox picks up the rotor twice per revolution, giving it two home positions or stop positions 180 degrees apart (at least that is what I’m trying to achieve)

Started out editing a basic LED blink code & it really only needed the Delays adjusted to 5000msec to give me 90 degrees of rotation in each step of the loop - 5 sec on, 5 sec off, 5 sec on again…

The Loop is initiated by the input from the Vibration sensor.

All good up until this point, but now trying to introduce the input from the prox as a point to end the loop is giving me some grief.

It is now just running a continuous loop of 5 on 5 off over & over. Even after I removed the last line of the loop - digitalwrite (relay, OFF)

As you will see in this, I’m using a “current condition v’s previous condition” code that I borrowed & began tweaking but it has me stumped now.

Can any of you guys pls suggest a fix, or even a better way to code this device pls?

/*//==============================================================================//
 * Vibration Sensor interfacing with Arduino
 * Date: - 15-04-2019
 * Author:- Sourav Gupta
 * For:- circuitdigest.com
 */ //=============================================================================//
#include <Arduino.h>
#include <stdio.h>
 
#define ON 1
#define OFF 0
 
/*
 * Pin Description
 */
int vibration_Sensor = A5;
int relay = 13;
int prox = A1;
 
/*
 * Programme flow Description
 */
int present_condition = 1;
int previous_condition = 0;
 
/*
 * Pin mode setup
 */
void setup() {
pinMode(vibration_Sensor, INPUT);
pinMode(relay, OUTPUT);
pinMode(prox, INPUT);
}
 
/*
 * relay run
 */
void (relay_run)();
 
/*
 * main_loop
 */
 
void loop() {
previous_condition = present_condition;
present_condition = digitalRead(A5); // Reading input from the A5 Pin of the Arduino.
previous_condition = digitalRead(A1); // Reading input from proximity.
 
if (present_condition != previous_condition) 
(relay_run)();     //if present condition is not equal to previous condition (receiving voltage from Both A1 & A5), Begin Loop.

if 
  (previous_condition)
digitalWrite(relay, OFF);  //once back to previous condition (reading voltage from A1 only), End Loop.
}

 
void (relay_run) () {
digitalWrite(relay, ON);
delay(5000);
digitalWrite(relay, OFF);
delay(5000);
digitalWrite(relay, ON);
}

Thx, Mick.

A couple of comments

int vibration_Sensor = A5;
int prox = A1;

Why give pins names when you don't use them afterwards ?

  present_condition = digitalRead(A5); // Reading input from the A5 Pin of the Arduino.
  previous_condition = digitalRead(A1); // Reading input from proximity.

The names of the variables make no sense to me as you are comparing a reading from the proximity sensor with that from the vibration sensor

And those 3 lines don't make sense

previous_condition = present_condition;
present_condition = digitalRead(A5); // Reading input from the A5 Pin of the Arduino.
previous_condition = digitalRead(A1); // Reading input from proximity.

as you overwrite previous_condition anyway...

I did not get exactly what the system is or should do.

what/who is generating vibration?
what do you want to achieve with the proximity sensor?

J-M-L:
I did not get exactly what the system is or should do.

what/who is generating vibration?
what do you want to achieve with the proximity sensor?

It is an Long Range target indicator. The "paddle" or rotor rises up from behind a metal target at distances out past 1200yds where hearing or seeing the impact becomes very difficult, nigh impossible.

The Vibration sensor picks up the impact on the plate.
The whole unit is suspended behind the target.

Helibob.
It was a code that I adopted & have just edited names, pinmodes etc.
Much of it is still the original because I'm not up to writing from scratch just yet.

Still very green at working with C++
My back ground is mechanical, not electrical.

pls be gentle with me! LoL!

You tube clip of its 1st run using only time delays.

Timing varies due to temp & battery condition, that is why I'm trying to introduce a home position (well two actually)

Another clip of me bench testing it during the build which will help you see what it is.

Mick.

Please explain exactly what you want the code to do

You say

The Loop is initiated by the input from the Vibration sensor.

So what part does the proximity sensor play in the project ?

End the loop.
Or put it in a reset condition ready to sense the next impact & run the loop again.

The Prox is to give it a home position relative to the position of the motor spindle.

Mick.

I'm not sure I fully understand what you're doing. Why is the indicator double ended?

I assume the requirement is: if the vibration sensor detects a hit, run the motor until the proximity sensor goes off and continue until it comes on again - is that it?

Edit: there must be more - the indicator needs to reset after some time to prepare for the next shot.

OK if I get it right:

  • the gig is installed behind a target
  • you shoot from afar on the target
  • if the bullet hits the target, the vibration sensor picks up the impact and this triggers a motor that raises a flag for a bit of time and then brings the flag down

Am I correct?

so basically the loop just sits there asking the vibration sensor: "did you hear something yet?" and when the answer is yes, you just enter a small animation for the motor.

why do you need to know the motor position? I would assume that the motor behave in a relatively repeatable way so you spin for x seconds and the flag becomes visible and then you spin for x seconds in the opposite direction and the flag is hidden again (goes back to the default pos).
(EDIT: answer was above)

J-M-L:
why do you need to know the motor position? I would assume that the motor behave in a relatively repeatable way so you spin for x seconds and the flag becomes visible and then you spin for x seconds in the opposite direction and the flag is hidden again (goes back to the default pos).

You got it I think. He said that temperature and battery condition make the movement inconsistent if he relies on time alone. The home switch allows the system to recalibrate each time it operates (I think).

ah - I should have refreshed my web page before sending. did not see that.

OK then indeed during the "raising the flag" sequence, it's not just time but counting the ticks from the sensor.

this would be a small state machine in the loop, something like this:

J-M-L:
ah - I should have refreshed my web page before sending. did not see that.

OK then indeed during the "raising the flag" sequence, it's not just time but counting the ticks from the sensor.

this would be a small state machine in the loop, something like this:

Close,
The prox is only energising the A1 pin while it is in the horizontal position.
(It is just a non contact limit switch, normally open)
So A1 will be reading voltage from it the whole time the motor is in it's "home" or horizontal position.

Once the loop is initiated by the vibration sensor (digitalRead A5), the flag will move off the prox (A1) so there is no voltage (or ticks) coming from it during the raising of the flag, it is only on the second "digitalWrite (relay, ON)" when the flag is going down that it will pick up the prox again after 180 degrees of rotation & this is the point I need it to end the loop & go back to a "wait condition" (waiting for the next impact to initiate the loop again)

So a basic sequence of events:-
-Wait position - reading voltage at A1
-Initiate run - sensing voltage from A5 whilst still reading voltage from A1 until it begins to move.
-1st run 5 sec, (ignoring input from A1 at the time of initiation)
-pause 5 sec, (no input from A1 at this point, & ignoring any further input from A5)
-2nd run, until A1 is energised again, stop.

wildbill:
You got it I think. He said that temperature and battery condition make the movement inconsistent if he relies on time alone. The home switch allows the system to recalibrate each time it operates (I think).

^^^^^What he said!

Cheers, Mick.

wildbill:
I'm not sure I fully understand what you're doing. Why is the indicator double ended?

I assume the requirement is: if the vibration sensor detects a hit, run the motor until the proximity sensor goes off and continue until it comes on again - is that it?

Edit: there must be more - the indicator needs to reset after some time to prepare for the next shot.

It is only really double ended for ballance so it is not loading the motor too much.
It also helps keep the duration of the cycle at 15 seconds (using a 3rpm motor)

See above post to answer the second bit.

Cheers, Mick.

Use a boolean flag which is set true when a hit is registered. Use if(flag == true) to enable/start the sequence of events - or use a state machine implemented with the switch/case construct.

When the prox _becomes* _ true again the sequence is complete - set the boolean flag to false and wait for the next hit.

  • IDE -> file/examples/digital/statechangedetection

dougp:
Use a boolean flag which is set true when a hit is registered. Use if(flag == true) to enable/start the sequence

Just a quick comment on this, a Boolean is already a truth type so you don’t need the comparaison.

For example In English you don’t say if it is raining is true then take your umbrella. You just say if it is raining then take your umbrella. Of course people would understand you if you use the first one but that will sound weird. Same goes with the compiler => just Use if(flag) when flag is a bool - and of course use a meaningful name for the variable like if (targetWasHit) {...}then code is easy to read

I took your code to read while I was trying to understand what you're doing - as ever, it seems so obvious now that I can't see why I didn't get it straight away, but que sera.

Anyway, I transformed it into something that I think does what you need. Do you want it, or are using this as a learning experience?

J-M-L:
Just a quick comment on this, a Boolean is already a truth type so you don't need the comparaison.

A good point. I phrased it that way just to make it obvious for those who aren't as far along.

wildbill:
Anyway, I transformed it into something that I think does what you need. Do you want it,

Yes pls.

Will be a learning curve either way.

Only just beginning to work with c++
I have experience with g code but this is all new to me atm.

Thx, Mick

#define ON 1
#define OFF 0

const unsigned long IndicatorDelay=5000;
const unsigned long IndicatorHideTime=5000;

byte vibration_Sensor = A5;
byte relay = 13;
byte proximitySensor = A1;

int present_condition = 1;
int previous_condition = 0;

void setup()
{
pinMode(vibration_Sensor, INPUT);
pinMode(relay, OUTPUT);
pinMode(proximitySensor, INPUT);
DoIndicatorCycle();  // Make sure Indicator is hidden
}

void loop()
{
if(digitalRead(vibration_Sensor)==HIGH)
  {
  DoIndicatorCycle();   
  }
}

void DoIndicatorCycle()
{
ShowIndicator();
delay(IndicatorDelay);
RunMotor(IndicatorHideTime);  
}

void ShowIndicator()
{
digitalWrite(relay, ON);
while(digitalRead(proximitySensor)==LOW)
  ;
digitalWrite(relay, OFF);    
}

void RunMotor(unsigned long Milliseconds)
{
digitalWrite(relay, ON);
delay(Milliseconds);
digitalWrite(relay, OFF);  
}

Thx mate.
I’m up the Bush for a few days but will paste it into the Arduino ini when I get home so I can see the formatting a bit better than here on my phone.
It looks like you have basically broken the loop into two sections. Initiate & execute?

Thx, Mick.