Code advice: monitor 2 switches & control 1 relay

My first post, I'll try to do it right.

Background:
I have a motor driven collator that drops items into a vertical collector tube where the items stack up and await further processing.

Goal:
Install two normally closed switches on the collector tube, (one low/one high,) to control a relay that switches the collator.
When the collector tube is empty, both switches are closed and the collator runs. As items stack in the tube the lower switch will open but collator continues until both switches open.

The easy part: If both switches closed, power to relay.
Once relay is powered: If lower switch opens, continue to power relay until upper switch opens.
When both switches open, turn off relay.

The tricky part.
Once the relay is powered and the machine is operational, each switch will open (randomly and momentarily) as product falls past the switches.
The sketch must differentiate between switch sustained state (open or closed) vs intermittent blips, closed/open/closed, as product falls past the switches.
Presumably switch bounce has to be considered too?

I am new to Arduino. Can anyone help with code suggestions, snippets or even search terms likely to get me to my goal?

What sort of switches are you using?

If you want to detect whether a switch is OPEN continuously for a certain time this pseudo code is how to do it

read the switch
if the switch is closed {
     save the value of millis() in a variable (let's call it lastClosedMillis)
}

if (millis() - lastClosedMillis >= interval) {
   switch has been open throughout interval
}

repeat

...R

Robin2:
What sort of switches are you using?

If you want to detect whether a switch is OPEN continuously for a certain time this pseudo code is how to do it

read the switch

if the switch is closed {
save the value of millis() in a variable (let's call it lastClosedMillis)
}

if (millis() - lastClosedMillis >= interval) {
switch has been open throughout interval
}

repeat




...R

Thanks for that. The switches look like this:

The sketch must differentiate between switch sustained state (open or closed) vs intermittent blips, closed/open/closed, as product falls past the switches.
Presumably switch bounce has to be considered too?

Since your time requirement for a switch to be open or closed is a considerable amount of time(computer wise), that will take care of any switch bounce. A bounce will be no different than a falling product activating the switch.

If you are ever going to count the products falling through the tube, then debounce timing is critical to differentiate the two.

IF your product relates to either human food or pharmaceuticals, then your whole system must be compliant with those laws.

Paul

Paul_KD7HB:
The sketch must differentiate between switch sustained state (open or closed) vs intermittent blips, closed/open/closed, as product falls past the switches.
Presumably switch bounce has to be considered too?

Since your time requirement for a switch to be open or closed is a considerable amount of time(computer wise), that will take care of any switch bounce. A bounce will be no different than a falling product activating the switch.

If you are ever going to count the products falling through the tube, then debounce timing is critical to differentiate the two.

IF your product relates to either human food or pharmaceuticals, then your whole system must be compliant with those laws.

Paul

Thank you for your reply. I did say product but this isn't for anything commercial, let alone food or pharmaceuticals. Objects might better describe what I'm doing. I am now 24 hours into Arduino and it hadn't occurred to me that objects falling past the switches = bounce and I can fine tune that out. That is helpful.

Where I'm falling down: I want the motor start triggered when the bottom switch closes but continue running until the top switch is satisfied. I have no problem starting the sequence with the bottom switch but I don't know how to ignore the bottom switch once the motor is running. I am looking at while loops but obviously in over my head. Again, thanks for taking the time to comment.

warnmar10:
I have no problem starting the sequence with the bottom switch but I don't know how to ignore the bottom switch once the motor is running. I am looking at while loops but obviously in over my head. Again, thanks for taking the time to comment.

You need a variable to record the state of the system. Let's call it motorRun and normally it has the value 'N'. When the bottom switch is triggered it changes the value to 'Y'. But the bottom switch has no code to change the value back to 'N'.

The top switch will change the value to 'N' when it has been triggered for whatever interval you require.

When the value is 'Y' the code to make the motor run will turn the motor on. When the value is 'N' it will turn the motor off.

Note that the switches don't know there is a motor and the motor doesn't know there are switches. The only link between them is the motorRun variable.

...R

So I have it working except for the debounce on switch 2. I am attempting to utilize the Bounce2 library as in: https://playground.arduino.cc/Code/Bounce

I can’t seem to get the syntax correct to apply debounce to my switch 2.

// After setting up the button, setup the object
 bouncer .attach( inputPin );
 bouncer .interval(5);

In my case I believe it should be:

 bouncer .attach( buttonPin2 );
bouncer .interval(250);

I get: exit status 1
‘bouncer’ was not declared in this scope

This is what I have so far, working but for need debounce on switch 2:

#include <Bounce2.h>

const int  buttonPin1 = 8;    
const int  buttonPin2 = 7;
const int  Relay = 2;       

int stateButton1 = 0;
int stateButton2 = 0;
int laststateButton1 = 0;
int laststateButton2 = 0;

void setup() {
   pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT);
   pinMode(Relay, OUTPUT);
   Bounce  bouncer  = Bounce();
}

void loop() {
  stateButton1 = digitalRead(buttonPin1);
  stateButton2 = digitalRead(buttonPin2);
   
  if (stateButton1 != laststateButton1) 
    {
    digitalWrite(Relay, LOW);     
    }
    
  else if (stateButton2 == laststateButton2) 
    {
    digitalWrite(Relay, HIGH); 
    }
}

Can anyone help with where/how to insert the code snippet for bouncer?

void setup() {
   pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT);
   pinMode(Relay, OUTPUT);
   Bounce  bouncer  = Bounce();

Creating the Bounce object in setup() will be useless. You won't be able to use the object in loop().

The Bounce library came with examples.

PaulS:

void setup() {

pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(Relay, OUTPUT);
  Bounce  bouncer  = Bounce();



Creating the Bounce object in setup() will be useless. You won't be able to use the object in loop().

The Bounce library came with examples.

Per your suggestion I paid much closer attention to the examples. I now have it mimicking the bounce2buttons example (I think…) and it will compile and load but it changed nothing about how my sketch functions. The intent is that after buttonPin1 goes low, buttonPin2 will remain high even if the switch is released for up to 250ms. Is that you you read my sketch?

#include <Bounce2.h>

const int  buttonPin1 = 8;    
const int  buttonPin2 = 7;
const int  Relay = 2;       

int stateButton1 = 0;
int stateButton2 = 0;
int laststateButton1 = 0;
int laststateButton2 = 0;
Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();



void setup() {
   pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT);
   pinMode(Relay, OUTPUT);
   
   debouncer1.attach(buttonPin1);
   debouncer1.interval(250);
      
   debouncer2.attach(buttonPin2);
   debouncer2.interval(250);
}

void loop() {
  debouncer1.update();
  debouncer2.update();
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();
  
  stateButton1 = digitalRead(buttonPin1);
  stateButton2 = digitalRead(buttonPin2);
   
  if (stateButton1 != laststateButton1) 
    {
    digitalWrite(Relay, LOW);     
    }
    
  else if (stateButton2 == laststateButton2) 
    {
    digitalWrite(Relay, HIGH); 
    }
}

I paid much closer attention to the examples. I now have it mimicking the bounce2buttons example (I think...) and it will compile and load but it changed nothing about how my sketch functions.

That's because you are still using the digitalRead() instead of value1 and value2 from the debounced readings.

You should probably be making use of the .rose() and .fell() functions available in bounce2

The intent is that after buttonPin1 goes low, buttonPin2 will remain high even if the switch is released for up to 250ms. Is that you you read my sketch?

No. Can you explain what you are trying to do. Do you want a lock out on buttonPin2 for 250 ms after buttonPin1 is pressed so that the relay is LOW for at least 250 ms?

EDIT: OK I reread the thread and I see what you are trying to do.

When I re-read the problem stated in your Original Post

Once the relay is powered and the machine is operational, each switch will open (randomly and momentarily) as product falls past the switches.
The sketch must differentiate between switch sustained state (open or closed) vs intermittent blips, closed/open/closed, as product falls past the switches.

I remain convinced that the suggestion I made in Reply #5 will deal with the entire problem without any need for a bounce library.

...R

Robin2:
When I re-read the problem stated in your Original PostI remain convinced that the suggestion I made in Reply #5 will deal with the entire problem without any need for a bounce library.

...R

I believe you are correct. I was trying to figure out how to implement your suggestion when I stumbled onto the combination that worked but for the bouncing switch issue. I have been a code hacker for less than 3 days, setting and checking variables is something I will work on but for now I'm just copying code I find and stringing it together. Now that I have it functioning exactly as I had imagined it would I will go back and refine and attempt your suggestion.

cattledog:
That’s because you are still using the digitalRead() instead of value1 and value2 from the debounced readings.

You should probably be making use of the .rose() and .fell() functions available in bounce2

Thank you for pointing that out to me, that was the solution. My sketch is doing exactly what I wanted… for now.

#include <Bounce2.h>

const int  buttonPin1 = 8;    
const int  buttonPin2 = 7;
const int  Relay = 2;       

Bounce debouncer1 = Bounce();
Bounce debouncer2 = Bounce();

void setup() {
   pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT);
   pinMode(Relay, OUTPUT);
   
   debouncer1.attach(buttonPin1);
   debouncer1.interval(500);
      
   debouncer2.attach(buttonPin2);
   debouncer2.interval(500);
}

void loop() {
  debouncer1.update();
  debouncer2.update();
  int value1 = debouncer1.read();
  int value2 = debouncer2.read();
  
   if ( value1 != HIGH ) {
    digitalWrite(Relay, HIGH);
  } 
  else if  (value2 != LOW ){
    digitalWrite(Relay, LOW);
  }
}