Hello,
I have a break beam sensor and a relay. I want the relay to open when the sensor is blocked for 10 seconds. Then when the sensor is unblocked, I want the relay to open. I've tinkered around with blink without delay, changing it, but still can't make it work. I can measure the time between the sensor being blocked and unblocked, but that doesn't help. I'm just looking for a push in the right direction with this. I'm fairly new to this so any help would be appreciated.
Thanks
Shan19801980:
I have a break beam sensor and a relay. I want the relay to open when the sensor is blocked for 10 seconds. Then when the sensor is unblocked, I want the relay to open.
I imagine one of those opens should say close.
But basically if you know when the sensor BECOMES blocked then it's easy to tell 10 seconds after that time. The trick is remembering the time when the last time round the loop the sensor wasn't blocked and this time round it is. Then you just effectively say if it's still blocked and timeNow - timeItBecameBlocked >= 10000 do something.
Blocked/unblocked and relay open/close will obviously be pins going high or low but I don't know what pins or what direction. That's why if you post the code you've currently tried using the blink without delay/millis() techniques it will be much easier to help you. See "How to use this forum - please read" at the top of every forum for how to post the code.
Steve
I changed the relay to an LED for testing. Its works the first time, but then turns the LED will turn on at different times.
int firstSensorState = 0;
int firstSensorLastState = 0;
int secondSensorState = 0;
int secondSensorlastState = 0;
const int FIRST_CONV_SENSOR = 5;
const int SECOND_CONV_SENSOR = 8;
const int RELAY_PIN = 2;
const int LED_PIN = 13;
unsigned long previousMillis = 0;
const long INTERVALl = 5000;
void setup() {
pinMode(RELAY_PIN, OUTPUT);
pinMode(FIRST_CONV_SENSOR, INPUT);
pinMode(SECOND_CONV_SENSOR, INPUT);
digitalWrite(FIRST_CONV_SENSOR, HIGH);
digitalWrite(SECOND_CONV_SENSOR, HIGH);
Serial.begin(9600);
}
void loop() {
unsigned long currentMillis = millis();
firstSensorState = digitalRead(FIRST_CONV_SENSOR);
secondSensorState = digitalRead(SECOND_CONV_SENSOR);
if(firstSensorState == LOW) {
if(currentMillis - previousMillis >= INTERVAL) {
Serial.println("Blocked for 10 seconds or more");
digitalWrite(LED_PIN, HIGH);
previousMillis = currentMillis;
}
}else {
digitalWrite(LED_PIN, LOW);
}
firstSensorLastState = firstSensorState;
secondSensorlastState = secondSensorState;
}
Sorry I can't make any sense of that. You now seem to have two sensors not one. But although you read SECOND_CONV_SENSOR you never do anything with the result. You also save various "last states" but then never look at them again.
So what exactly is/are your sensor(s) and how are they connected? And importantly what does "the sensor is blocked" in your original post actually mean in terms of the results of your digitalRead()s?
BTW there is now a pinMode(pin, INPUT_PULLUP) so you don't need to use the strange-looking old technique of configuring them as INPUT and then writing HIGH to them.
Steve
The other sensor isn't even connected right now. It does nothing at the moment, just in the code.
Should I do this?
if(!firstSensorSensorState && firstSensorLastState) {
Serial.println("Blocked for 10 seconds or more");
digitalWrite(LED_PIN, HIGH);
previousMillis = currentMillis;
}
I didnt know about pinMode(pin, INPUT_PULLUP), I will look into that.
How will that tell you anything about something happening for "10 seconds or more"? Have a look at the StateChangeDetection example in the IDE for the correct way to tell when the sensor CHANGES state.
Steve
Whether you need the INPUT_PULLUP mode depends on the sensor. Likely not. It won't hurt, though.
You need state change detection as mentioned above:
bool sensorState;
bool oldSensorState;
sensorState = digitalRead(sensor);
if (oldSensorState == LOW && sensorState == HIGH) { // State just went high.
timeSensorChanged = millis(); // Record when that happened.
}
oldSensorState = sensorState; // Keep track of what it was.
The the relay has to go HIGH after 10 seconds of sensor HIGH as long as sensor is HIGH, and LOW otherwise:
if (sensorState == HIGH && millis() - timeSensorChanged > 10000) {
digitalWrite(RELAY, HIGH);
}
else {
digitalWrite(RELAY, LOW);
}
That's pretty much all there's to it.