Arduino motor control with proximity sensor help

Hello

Basically if it was an LED I want the LED to be turned off when a proximity sensor detects an object, then after 2 seconds I want the LED to come back on while the prox is still sensing the object, so that it can clear the prox and start the code over for the next object to be picked up by the prox. I have changed my code so many times, and all I can come up with is the prox senses the object and turns off led but with object in front of prox i cant get nothing else to happen.

I was just useing led as an example, it is actually a motor that is turning an arm that is going in front of prox to stop motor at 12:00 position, but once arm is in front of the prox motor stops. I need something to turn on motor after a 2 second delay to clear prox and restart again. I want motor to stop for 2 seconds at 12:00 position then turn motor on till it reaches 12:00 again. I have learned a lot in this Venture but I am stuck and I need to get this project going. I am sure it's quite easy but I am new to this.

I have been working on a project, while trying to figure out how to control it, that is how i found out about Arduino, needless to say the Arduino world is new to me. The project consists of controlling a wheel chair motor via a 100 amp solid state relay with a proximity sensor. what i am trying to accomplish is the shaft of the motor will be at the center of an arm so that the prox sensor will detect when the motor has rotated to the 12:00 position. Once the prox senses the arm I want the motor to stop for 1.5 seconds and then rotate again until prox senses the arm again which will be 1/2 revolution being that it will see both ends of the arm in 1 rev pausing for 1.5 seconds each time before rotating again. The code i wrote allows me to stop the motor when the prox senses the arm but i have been trying for a week to figure out how to get it to only stop for 1.5 seconds then rotate again. Pin 12 is going to control side of the solid state relay not the actual motor. Code is below.

int sensorVal;

void setup(){
//configure pin2 as an input and enable the internal pull-up resistor

pinMode(2, INPUT_PULLUP);
pinMode(12, OUTPUT);

}

void loop(){
sensorVal = digitalRead(2);
// The Logic is inverted a low on pin 2 means a sinking switch is activated
// and a high on pin 2 means the switch is unactivated and pulled up by the internal resistor
// this is not a problem since the controller can interpret the data any way we tell it to

if (sensorVal == HIGH){
digitalWrite(12, HIGH);
}
if (sensorVal == LOW ){
digitalWrite (12, LOW );

}
}

Can this even be done with just the Arduino alone or do i need a motor or relay shield. I have tried putting in delays but it does not react the way i need it to.

Thanks in advance

You want wait 1.5 seconds in off state ?.

you can use delay function.

void setup(){
//configure pin2 as an input and enable the internal pull-up resistor

pinMode(2, INPUT_PULLUP);
pinMode(12, OUTPUT);

}

void loop(){
sensorVal = digitalRead(2);
// The Logic is inverted a low on pin 2 means a sinking switch is activated
// and a high on pin 2 means the switch is unactivated and pulled up by the internal resistor
// this is not a problem since the controller can interpret the data any way we tell it to

if (sensorVal == HIGH){
digitalWrite(12, HIGH);
//delay(1500);
}
if (sensorVal == LOW ){
digitalWrite (12, LOW );
delay(1500);  //wait for 1.5 seconds
}
}

Yes i want delay in off state. I tried useing delay but with my Limited knowledge of code
All i could get it to do is delay for 1.5 sec before it turned the motor back on after the prox was cleared just needed the motor to turn on for a small amount of time to clear prox then repeat, i knew there must be a way But didnt know how to write it. Thanks very much for the reply.

You can use delay function in your logic where ever you want. Make a variable for your proximity sensor. and clear it when you want.

SureshKumar2610:
You can use delay function in your logic where ever you want.

.... but that doesn't mean you should.

I have been trying delay but dont know how to cancel out the input from prox, so what happens when i put my hand in front of prox motor stops and thats it, when i move my hand out of the way there is a delay before the motor turns on. Another option i started useing was millis but with the same result. What i cant figure out is how to cancel the input from the prox after 2 seconds so that the motor turns long enough to move the arm out of the way of the prox.

Here is some new code I have been trying but cant get to work the way I want it I am stuck.

int proxVal = 2; // prox value
int motorPin = 12; // pin controlling motor
unsigned long lastTimeProxTriggered = 0; //the last time the prox was triggered
unsigned long currentStateProx = 2000; // how long the motor will delay

void setup(){
//configure pin2 as an input and enable the internal pull-up resistor
pinMode(proxVal, INPUT_PULLUP);
pinMode(motorPin, OUTPUT);
digitalRead (proxVal);

}

void loop(){
proxVal = digitalRead(2);
lastTimeProxTriggered = millis;

// The Logic is inverted a low on pin 2 means a sinking switch is activated
// and a high on pin 2 means the switch is unactivated and pulled up by the internal resistor
// this is not a problem since the controller can interpret the data any way we tell it to

if (proxVal == HIGH){
digitalWrite (motorPin, HIGH);

}
if (proxVal == LOW ){
digitalWrite (motorPin, LOW);

}
if (proxVal == LOW && lastTimeProxTriggered >= currentStateProx ){
digitalWrite (motorPin, HIGH);

}
}

int proxVal = 2; // prox value
int motorPin = 12; // pin controlling motor
unsigned long lastTimeProxTriggered = 0; //the last time the prox was triggered
unsigned long currentStateProx = 2000; // how long the motor will delay

void setup(){
//configure pin2 as an input and enable the internal pull-up resistor
pinMode(proxVal, INPUT_PULLUP);
pinMode(motorPin, OUTPUT);
digitalRead (proxVal); why using this. what is the purpose ?

}

void loop(){
proxVal = digitalRead(2); what is this ?
lastTimeProxTriggered = millis;

First you should study how to give the input and get output from Arduino.
You can study under Arduino reference. offline also goto help in your Arduino software and choose reference.

In your Arduino software has examples. choose "blink" and "button" examples .look the example.

You'll make things easier for yourself, and probably see what SK2610 is getting at, if you change proxVal to proxPin, but still have a proxVal to read it into.

So instead of:

int proxVal=2;

..... say:

int proxPin=2; //proximity sensor connected to this pin
int proxVal;    //the reading from the proximity sensor will go in here

Then later when you need to know what the sensor is saying:

proxVal = digitalRead(proxPin);

Thanks for your replies but I have been studying my problem every day before and after work for 3 weeks for countless hours, I am about to take a hammer to this arduino and buy a plc off ebay I can program that. I have rewrote this code what seems to be a million different ways according to what I think looks like it should be. After studying lots of examples I'm just not getting it. can someone at least tell me where I am going wrong. last code I tried but again with no luck. it probably isn't even close but to me it looks right.

// constants won't change. They're used here to
// set pin numbers:
const int proxPin = 2; // the number of the prox pin
const int motorPin = 12; // the number of the motor pin
int motorPinState = HIGH; // state of the motor on or off
int previousProxState = HIGH; // last state of the prox
int currentMillis;
unsigned long previousTime = 0; // last time the prox sensed arm
unsigned long motorPause = 2000; // how long motor will pause

void setup() {
// initialize the motor pin as an output:
pinMode(motorPin, OUTPUT);
// initialize the prox pin as an input:
pinMode(proxPin, INPUT_PULLUP);
}

void loop() {
// read the state of the prox value:
proxState = digitalRead(proxPin);
currentMillis = millis();
motorPinState = digitalRead (motorPin);

// check if the prox is active.
// if it is, the motor is on:
if (proxState == HIGH) {
// turn motor on:
digitalWrite(motorPin, HIGH);
}
if (proxState == LOW){
// turn motor off:
digitalWrite(motorPin, LOW);
}
if (motorPinState == LOW && currentMillis - previousTime >= motorPause);
digitalWrite (motorPin, HIGH);

previousTime = currentMillis;

}

Until you take the time to put Serial.write and Serial.print, and Serial.println after EVERY line in "loop" telling you where the program is executing and also display the values used in that line of code and the result, you will never understand what is causing the problem.

Just looking will never get you anywhere.

Paul

Paul_KD7HB:
Until you take the time ....

And while you're at it can we see a schematic please, as well of details of the proximity sensor? And also can you post the code in [code]...[/code] tags so it's much easier to read and copy/paste into IDE.

This doesn't make sense to me (from opening post):

I want the LED to come back on while the prox is still sensing the object, so that it can clear the prox

I don't see how you can "clear" a sensor which is still seeing something. Maybe I'm not understanding "clear" in this context.

That is confusing i was just useing led as an example its actually an arm on my motor that the prox senses and stops the motor, by clear the prox i mean after the motor stops for 2 sec the arm needs to get out of the way of the prox. I need to ignore the signal from the prox after the 2 seconds is up, otherwise nothing happens because the arm stays in front of the prox.

I thought that arduino was exactly what i needed for my project, and that it was something i could do i guess i just dont understand it. This has consumed so much of my time trying to learn, only thing I learned from it is im not a programmer.

Okcwby21:
by clear the prox i mean ... the arm needs to get out of the way of the prox.

Aaaaaaah...

Ok well I'm just starting work for the day so I'll try have a proper look tonight.

Please though, humour us and provide a connection diagram. Makes life much easier. Just sketch it by hand and upload a cellphone photo.'

I think an interrupt is what i need i have been trying to figure out how to use attach interrupt.
Thanks again for your help I really do appreciate it.

Very unlikely that you need an interrupt.

Most likely need to distinguish between the sensor being covered and having just become covered, but I'll have a proper look tonight (my time).

Here is my schematic.

OP's schematic inline:

OK here's code to do what you want to do, if I understood the requirement.

Code below has a delay()-less millis()-based "pulse" blinking all the time: I like to do that to prove that no code is doing any blocking. If the pulse hangs then something else is out of whack. As it stands, the pulse is steady....

So sketch fires up with the motor running, or in my case, a led is lit. That can stay like that forever, just means the motor hasn't moved the arm in front of the sensor.

When you block the sensor, the motor stops, ie led goes out. Two seconds of delay()-less millis()-based time later, the led comes on ie the motor moves.

That's your signal to move hand from the sensor, as if the motor had moved the arm. It doesn't matter if you take ages to move your hand, that just means the motor is sulking or the arm is verrrrrry wide :wink: Led / motor stays on until next blockage.

Note: in real life, the arm will never clear the sensor until the motor starts up after 2 seconds, since it's the motor that moves the arm. In our hand-in-front-of-sensor-sim, you could clear the sensor before the led comes back on. I haven't trapped that since it can't happen in real life.

Hope this helps? YMMV, I may have misinterpreted the requirement.

//http://forum.arduino.cc/index.php?topic=456060.0
//I have pololu sds01a digital sensor, output low when detects

//motor (led in fact for now) runs and spins an arm in front of the sensor
//when sensor sees arm, the motor must stop for 2s then start agin

//pulse
//delay()-less blink to prove all is non-blocking
byte pulsePin = 6;
bool pulseState = false;
int pulseRate = 500; //ms
unsigned long previousMillisPulse = 0;

//sensor
byte proxPin = 2;
bool proxVal;
bool proxValPrev = true; //sensor is clear

//motor
unsigned long motorPauseInterval = 2000; //ms
unsigned long stoppedTheMotorAt = 0;
bool weAreTiming = false;
byte motorPin = 7;


unsigned long currentMillis;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("Setup started.... ");
  //switch off led13 because it annoys the crap out of me
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  pinMode(pulsePin, OUTPUT);
  pinMode(motorPin, OUTPUT);
  digitalWrite(motorPin, HIGH); //assume high is "on", and starts "on"

  pinMode(proxPin, INPUT); //sensor is active low
  //   but doesn't need pullup
  //   becuase it's high when not detecting

  Serial.println("setup ended");

}//setup

void loop() {
  // put your main code here, to run repeatedly:
  currentMillis = millis();
  pulse(); //prove there's no blocking

  //now check to see if sensor has changed and if so that it's a new detection
  //remember my sensor is active low: normally high, goes low when detects
  checkProx();

  //and if we are timing (ie the motor is stopped)
  //     check to see if it's time to spin it again
  checkTime();
}//loop

void pulse()
{
  if (currentMillis - previousMillisPulse >= pulseRate)
  {
    pulseState = !pulseState;
    digitalWrite(pulsePin, pulseState);
    previousMillisPulse = currentMillis;
  }
}//pulse

void checkProx()
{
  proxVal = digitalRead(proxPin);

  if (proxVal != proxValPrev) //it changed
  {
    if (proxVal == LOW) //low means detection, changed to low means new detection
    {
      Serial.println("new detection");
      //new detection means stop the motor and start the clock
      digitalWrite(motorPin, LOW);
      weAreTiming = true;
      stoppedTheMotorAt = currentMillis;
    }
    proxValPrev = proxVal;
  }

}//checkProx

void checkTime()
{
  if (weAreTiming)
  {
    if (currentMillis - stoppedTheMotorAt >= motorPauseInterval) //time to move again
    {
      digitalWrite(motorPin, HIGH);
      weAreTiming = false;
    }
  }
}//checkTime