SparkFun Forums 

Where electronics enthusiasts find answers.

For the discussion of Arduino related topics.
By Okcwby21
#193494
Hello

I am needing some help, I have been racking my brain on this for 2 weeks now. What I have 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. Below is where I have got on my code, I can get the prox to stop the motor, but that's all it does until I move my hand out of the way.


int proxPin = 2; // signal pin
int proxVal; //reading from proxPin
int motorPin = 12; // pin controlling motor
unsigned long lastTimeProxTriggered = 0; //the last time the prox was triggered
unsigned long interval = 2000; // how long the motor will delay
int motorPinState = HIGH;

void setup(){
//configure pin2 as an input and enable the internal pull-up resistor
pinMode(proxPin, INPUT_PULLUP);
pinMode(motorPin, OUTPUT);
}
void loop(){
unsigned long currentMillis = millis();
proxVal = digitalRead (proxPin);
digitalRead (motorPin);
// 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);

}
else if (proxVal == LOW && currentMillis-lastTimeProxTriggered >= interval ){
lastTimeProxTriggered = currentMillis;

digitalWrite (motorPin, HIGH);

}
}
#193590
For starters, this chunk of code needs reworking:
Code: Select all
  if (proxVal == LOW ){
    digitalWrite (motorPin, LOW);
    }
  // THIS CANNOT EXECUTE SINCE WE'VE ALREADY COVERED WHAT HAPPENS IF proxVal==LOW
  // THIS IS WHAT GETS EXAMINED IF proxVal<>LOW, YET YOU TEST IT AGAIN FOR ==LOW
  else if (proxVal == LOW && currentMillis-lastTimeProxTriggered >= interval ){
    lastTimeProxTriggered = currentMillis;
    digitalWrite (motorPin, HIGH);
    }
By Okcwby21
#193626
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;
   
 
  }
By Valen
#193652
Debouncing is always possible. But I think his code is fundamentally lacking something: state-memory based on the object itself.

He is actuating his motor directly based on sensor state. Once the proximity detector triggers the motor stops. Then wait, and turn the motor on again for the object to get out of view. Since detection happens in a split second, and mechanical acceleration of the motor takes time this is a blocking condition.As soon as the waiting period is over it energizes the motor pin, but in the next loop it thinks it detects an object again so stops it before it turned even one bit. And the sensor never changed it's output level during that.

If you implement a state-memory based on the process through which the object is handled then you can differentiate between the arriving state( motor is on, once proximity sensor fires transition to waiting-state), the waiting-state (motor is stopped, do nothing until time is passed then transition to leaving-state) and the leaving-state(motor is engaged, once proximity sensor is cleared transition to arriving-state). The leaving state transitions to arriving state as soon as the proximity sensor is cleared by the object, but never stops the motor during both states. The transitions are based on external (proximity sensor) or internal (clock-time) influences. But until those change in a particular order, there is no transition to the next state. So the motor get's the time to move the object out of the proximity location, and bring the next one in place.

The waiting-state could be implemented with a simple delay() function to make it simple to begin with. Later you can improve it with millis() to make it non-blocking during those seconds.
User avatar
By DanV
#193654
You are absolutely correct - I should have examined it more closely.

Try something along these lines
Code: Select all
int proxPin = 2; // signal pin
int proxVal; //reading from proxPin
int motorPin = 12; // pin controlling motor
unsigned long lastTimeProxTriggered = 0; //the last time the prox was triggered
unsigned long interval = 2000; // how long the motor will delay
int motorPinState = HIGH;
bool motorRun;
bool prevProxVal;

void setup(){
  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(proxPin, INPUT_PULLUP);
  pinMode(motorPin, OUTPUT);
  motorRun = FALSE;
 }

void loop(){
  unsigned long currentMillis = millis();
  proxVal = digitalRead (proxPin);
  digitalRead (motorPin);
  // 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
  // prox transitioned from LOW to HIGH
  if ((proxVal == HIGH) && (prevProxVal == LOW)) { 
    lastTimeProxTriggered = currentMillis;
    motorRun = TRUE;
    prevProxVal = proxVal;
    } 
  // prox transitioned from HIGH to LOW 
  if ((proxVal == LOW ) && (prevProxVal == HIGH)) {
    motorRun = FALSE;
    prevProxVal = proxVal;
    }
  if (motorRun == FALSE && currentMillis-lastTimeProxTriggered >= interval ){
    motorRun = TRUE;
    }
  if motorRun == TRUE then
    digitalWrite (motorPin, HIGH); 
  else
    digitalWrite (motorPin, LOW);
  }

 
By Okcwby21
#193664
Thank you guys for your help it is really appreciated, im going to study what you have said because i do want to learn how to write code. I find it intriguing at what you can do with these little devices. You have given me something to study and compare the way i was thinking to what i should have been thinking. Again thank you for your time and thoughts.