[4]

Arduino Code Help

[3]
[10] Like what you see?
Click here to donate to this forum and upgrade your account!

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#31
We are getting closer. I took one of the Bounce2 library examples for a single button and led and used that for one sensor and a relay. That worked fine for the individual sensors.

Next I took jwmelvins code and reduced it down to one top/bottom sensor and one relay. In this configuration with the sensor beams unbroken he relay does not activate like it should. Using a dowel I would trip the bottom sensor then top sensor and then pull out the dowel and the relay would activate. For some reason the sensors need to be cycled before the relay pin will pull low. That is a problem if the system is empty at startup it will never fill.

Using the single top/bottom sensor and relay code I verified each sensor/relay combination worked but only after a full cycle of the sensors.

Next I uploaded the full code and verified that the sensors need to be cycled before they will work properly.

Now I need to understand why the relay isn't activating at startup with the system empty? I tried setting the bool motorOn to true but that did not make a difference. Changing the sensor delay time does not affect that either.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#32
I forgot to add that in the void setup the digitalWrite(RELAY1, is set to LOW at startup the relay will activate at startup but will not turn off until the sensors are cycled. So same problem in reverse.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#33
Looking at the sunsorsUpdate in the void loop, is it because this part of the code is looking for a state change (low/high, high/low) is the problem. Does there need to be a separate sensor state "read" of the bottom sensor state first or is the rose/fell the problem which needs to be something else?
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#34
More progress.

I added this to the beginning of the void loop and it works with one sensor array plugged into either port. The other sensor array is not behaving properly and still needs to by cycled but the issue follows the sensor array. I'm going to rebuild that sensor array and see if that cures it.

void loop() {
sensor1low.update(); // update sensor1low instance:
sensor2low.update(); // update sensor12low instance:

int value1 = sensor1low.read(); //get updtaed value:
int value2 = sensor2low.read(); //get updtaed value:

if ( value1 == HIGH ) {
digitalWrite(SENSOR1LOW, LOW );
}
else {
digitalWrite(SENSOR1LOW, HIGH );
}
if ( value2 == HIGH ) {
digitalWrite(SENSOR2LOW, LOW );
}
else {
digitalWrite(SENSOR2LOW, HIGH );
}
 

P. Waller

H-M Supporter - Sustaining Member
H-M Platinum Supporter ($50)
Joined
Mar 10, 2018
Messages
631
Likes
411
#35
millis() simply returns the current timer value.
It is definitely best to avoid using the delay() function as it will bite you eventually.

What you want to do is debounce a signal. You don't want to detect intermittent changes, only stable changes, as defined by remaining in a state for a certain time period (for you, longer than the time it takes an object to pass through the beam). While you can use a number of methods including a timer that measures from the initial change using the millis() function, I recommend using a library that is already made for this. I use it every time I want a button input to my system, because mechanical buttons have bounce in their electrical contacts.

I rewrote your code to take advantage of the Bounce2 library. Let me know if it makes sense to you.
Is this not PID? Does Arduino not support it.
 

gzoerner

Active Member
Registered
Joined
Apr 20, 2016
Messages
48
Likes
63
#36
Jay,

I hope you've got your system up and running. It's been an interesting journey. You've now been exposed to and solved some of the typical problems associated with microcontroller programming. You have explored: 1) state machines; 2) validating (debouncing) input signals; 3) the pitfalls of delay() in the main loop.

Hopefully you are energized to explore programming further.

Glen
 

jwmelvin

Active Member
Registered
Joined
Jan 11, 2018
Messages
120
Likes
85
#37
Is this not PID? Does Arduino not support it.
Arduino does support PID and I’ve used it in a couple of temperature-controller projects. It’s an interesting idea to use it here as it would achieve a steady feed rate. But you would need a sensor that detects the height more continuously rather than at two points.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#38
Jay,

I hope you've got your system up and running. It's been an interesting journey. You've now been exposed to and solved some of the typical problems associated with microcontroller programming. You have explored: 1) state machines; 2) validating (debouncing) input signals; 3) the pitfalls of delay() in the main loop.

Hopefully you are energized to explore programming further.

Glen
Yes I got it running late last night. Took me most of two days to find the missing piece of code to get the sensors to behave properly. I'm not sure if what I added is the cleanest approach but it works. I must have done 50 iterations before I got things in the right order to work. I must admit I almost gave up.

Thank you Glen and jwmelvin for all your help.
 

jwmelvin

Active Member
Registered
Joined
Jan 11, 2018
Messages
120
Likes
85
#39
Sorry for my delay here @jbolt. I realized the problem quite quickly - the debounce code looks for transitions and there is never a transition if the lower sensor starts empty. Of course, you don't need to debounce the lower sensor, so I just switched those to the original method of reading the sensor directly. Hopefully you have a chance to look at what I did in the attached at let me know what you think. If you did it a different way, I'm interested to see what you did. Sorry again for taking so long; hopefully you learned something in the process.

I left comments where I made changes to help explain.

Edit: of course, my code may still have problems, but hopefully it is useful for something.

Edit 2: I wanted to shorten the main loop (same code, more compact) and saw I hadn't fixed the problem you identified earlier of repeating feeder1 instead of changing to feeder2, so I now fixed that (in v2.2). This is the code I used for the compact loop (v2.3):

Code:
void loop() {
    sensorsUpdate();

    if (motor1On == false && digitalRead(SENSOR1LOW) == HIGH) startFeeder1();
    else if (motor1On && sensor1high.fell()) stopFeeder1();

    if (motor2On == false && digitalRead(SENSOR2LOW) == HIGH) startFeeder2();
    else if (motor2On && sensor2high.fell()) stopFeeder2();

    checkASensor();
}

The full v2.3:
Code:
/*
Feeder (v2.3)
    using Bounce2 library to get stable sensor states
    see https://github.com/thomasfredericks/Bounce2/wiki
*/

#include <Bounce2.h>

#define ASENSOR 7 //alarm IR sensor is on pin 7
#define ALED 8 //alarm LED is on pin 8
#define ABUZZ 9 //alarm buzzer relay is on pin 10
#define RELAY1 10 //feeder1 relay is on pin 10
#define RELAY2 11 //feeder2 relay is on pin 11
#define SENSOR1LOW 2 //feeder1 Low IR Sensor is on pin 2
#define SENSOR1HIGH 3 //feeder1 High IR Sensor is on pin 3
#define SENSOR2LOW 4 //feeder2 Low IR Sensor is on pin 4
#define SENSOR2HIGH 5 //feeder2 High IR Sensor is on pin 5

// state variable
int asensorState = 0;
bool motor1On = false;
bool motor2On = false;

// edits for Bounce  - detecting stable signal
#define  SENSORDELAY 250  // milliseconds that the sensor must be stable to change reading
Bounce sensor1high = Bounce();
Bounce sensor2high = Bounce();
// Bounce sensor1low = Bounce();
// Bounce sensor2low = Bounce();

void setup() {
    pinMode(ALED, OUTPUT); // initialize the ALED pin as an output:
    pinMode(ABUZZ, OUTPUT); // initialize the ABUZZ pin as an output:
    pinMode(ASENSOR, INPUT); // initialize the ASENSOR pin as an input:
    pinMode(RELAY1, OUTPUT); // initialize the RELAY1 pin as an output:
    pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
    pinMode(SENSOR1LOW, INPUT_PULLUP); // sensor1 Low with pullup enabled
    pinMode(SENSOR1HIGH, INPUT_PULLUP); // sensor1 High with pullup enabled
    pinMode(SENSOR2LOW, INPUT_PULLUP); // sensor2 Low with pullup enabled
    pinMode(SENSOR2HIGH, INPUT_PULLUP); // sensor2 High with pullup enabled

    digitalWrite(ASENSOR, HIGH); //turn on the pullup
    digitalWrite(RELAY1, HIGH); // make sure the relay is Off after reset
    digitalWrite(RELAY2, HIGH); // make sure the relay is Off after reset

    // edits for Bounce
    sensor1high.attach(SENSOR1HIGH);
    sensor1high.interval(SENSORDELAY);
    sensor2high.attach(SENSOR2HIGH);
    sensor2high.interval(SENSORDELAY);
    // no need for the following because we don't need to debounce the lower sensors
    // sensor1low.attach(SENSOR1LOW);
    // sensor1low.interval(SENSORDELAY);
    // sensor2low.attach(SENSOR2LOW);
    // sensor2low.interval(SENSORDELAY);
}

void loop() {
    sensorsUpdate();

    if (motor1On == false && digitalRead(SENSOR1LOW) == HIGH) startFeeder1();
    else if (motor1On && sensor1high.fell()) stopFeeder1();

    if (motor2On == false && digitalRead(SENSOR2LOW) == HIGH) startFeeder2();
    else if (motor2On && sensor2high.fell()) stopFeeder2();

    checkASensor();
}

void sensorsUpdate(){
    sensor1high.update();
    sensor2high.update();
    // no need to update the following since we don't need to debounce the lower sensors
    // sensor1low.update(); 
    // sensor2low.update(); 
}
void stopFeeder1(){
    digitalWrite(RELAY1, HIGH); // turn motor off
    motor1On = false; // record motor state
}
void stopFeeder2(){
    digitalWrite(RELAY2, HIGH); // turn motor off
    motor2On = false; // record motor state
}

void startFeeder1(){
    digitalWrite(RELAY1, LOW); // turn motor on
    motor1On = true; // record motor state
}
void startFeeder2(){
    digitalWrite(RELAY2, LOW); // turn motor on
    motor2On = true; // record motor state
}

void checkASensor(){
    asensorState = digitalRead(ASENSOR); // read the state of the ASENSOR value:

    if (asensorState == LOW) { // check if the sensor beam is broken, if it is, the sensorState is LOW: 
    digitalWrite(ALED, LOW); // turn LED on: 
    digitalWrite(ABUZZ, LOW); // turn BUZZER on:
    } 
    else { 
    digitalWrite(ALED, HIGH); // turn LED off:
    digitalWrite(ABUZZ, HIGH); // turn BUZZER off:
    }
}
And I guess, for completeness, the revised v.2.2:
Code:
/*
Feeder (v2.2)
    using Bounce2 library to get stable sensor states
    see https://github.com/thomasfredericks/Bounce2/wiki
*/

#include <Bounce2.h>

#define ASENSOR 7 //alarm IR sensor is on pin 7
#define ALED 8 //alarm LED is on pin 8
#define ABUZZ 9 //alarm buzzer relay is on pin 10
#define RELAY1 10 //feeder1 relay is on pin 10
#define RELAY2 11 //feeder2 relay is on pin 11
#define SENSOR1LOW 2 //feeder1 Low IR Sensor is on pin 2
#define SENSOR1HIGH 3 //feeder1 High IR Sensor is on pin 3
#define SENSOR2LOW 4 //feeder2 Low IR Sensor is on pin 4
#define SENSOR2HIGH 5 //feeder2 High IR Sensor is on pin 5

// state variable
int asensorState = 0;
bool motor1On = false;
bool motor2On = false;

// edits for Bounce  - detecting stable signal
#define  SENSORDELAY 250  // milliseconds that the sensor must be stable to change reading
Bounce sensor1high = Bounce();
Bounce sensor2high = Bounce();
// Bounce sensor1low = Bounce();
// Bounce sensor2low = Bounce();

void setup() {
    pinMode(ALED, OUTPUT); // initialize the ALED pin as an output:
    pinMode(ABUZZ, OUTPUT); // initialize the ABUZZ pin as an output:
    pinMode(ASENSOR, INPUT); // initialize the ASENSOR pin as an input:
    pinMode(RELAY1, OUTPUT); // initialize the RELAY1 pin as an output:
    pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
    pinMode(SENSOR1LOW, INPUT_PULLUP); // sensor1 Low with pullup enabled
    pinMode(SENSOR1HIGH, INPUT_PULLUP); // sensor1 High with pullup enabled
    pinMode(SENSOR2LOW, INPUT_PULLUP); // sensor2 Low with pullup enabled
    pinMode(SENSOR2HIGH, INPUT_PULLUP); // sensor2 High with pullup enabled

    digitalWrite(ASENSOR, HIGH); //turn on the pullup
    digitalWrite(RELAY1, HIGH); // make sure the relay is Off after reset
    digitalWrite(RELAY2, HIGH); // make sure the relay is Off after reset

    // edits for Bounce
    sensor1high.attach(SENSOR1HIGH);
    sensor1high.interval(SENSORDELAY);
    sensor2high.attach(SENSOR2HIGH);
    sensor2high.interval(SENSORDELAY);
    // no need for the following because we don't need to debounce the lower sensors
    // sensor1low.attach(SENSOR1LOW);
    // sensor1low.interval(SENSORDELAY);
    // sensor2low.attach(SENSOR2LOW);
    // sensor2low.interval(SENSORDELAY);
}

void loop() {
    sensorsUpdate();
    if (motor1On == false) { // motor is stopped
        if(digitalRead(SENSOR1LOW) == HIGH)  { // low sensor shows empty
        // if (sensor1low.rose()) { // low sensor _transitioned to_ empty (this doesn't work because there isn't a transition when it starts empty)
            startFeeder1();
        }
    }
    else { // motor is running
        if (sensor1high.fell()) { // high sensor full
            stopFeeder1();
        }
    }
    if (motor2On == false) { // motor is stopped
        if(digitalRead(SENSOR2LOW) == HIGH)  { // low sensor shows empty
        // if (sensor2low.rose()) {  // low sensor _transitioned to_ empty (this doesn't work because there isn't a transition when it starts empty)
            startFeeder2();
        }
    }
    else { // motor is running
        if (sensor2high.fell()) { // high sensor full
            stopFeeder2();
        }
    }

    checkASensor();
}
void loop() {
    sensorsUpdate();
    if (motor1On == false && digitalRead(SENSOR1LOW) == HIGH) startFeeder1();
    else if (sensor1high.fell()) stopFeeder1();
    if (motor2On == false) if(digitalRead(SENSOR2LOW) == HIGH) startFeeder2();
        }
    }
    else { // motor is running
        if (sensor2high.fell()) { // high sensor full
            stopFeeder1();
        }
    }

    checkASensor();
}
void sensorsUpdate(){
    sensor1high.update();
    sensor2high.update();
    // no need to update the following since we don't need to debounce the lower sensors
    // sensor1low.update(); 
    // sensor2low.update(); 
}
void stopFeeder1(){
    digitalWrite(RELAY1, HIGH); // turn motor off
    motor1On = false; // record motor state
}
void stopFeeder2(){
    digitalWrite(RELAY2, HIGH); // turn motor off
    motor2On = false; // record motor state
}

void startFeeder1(){
    digitalWrite(RELAY1, LOW); // turn motor on
    motor1On = true; // record motor state
}
void startFeeder2(){
    digitalWrite(RELAY2, LOW); // turn motor on
    motor2On = true; // record motor state
}

void checkASensor(){
    asensorState = digitalRead(ASENSOR); // read the state of the ASENSOR value:

    if (asensorState == LOW) { // check if the sensor beam is broken, if it is, the sensorState is LOW: 
    digitalWrite(ALED, LOW); // turn LED on: 
    digitalWrite(ABUZZ, LOW); // turn BUZZER on:
    } 
    else { 
    digitalWrite(ALED, HIGH); // turn LED off:
    digitalWrite(ABUZZ, HIGH); // turn BUZZER off:
    }
}
 
Last edited:

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#40
Sorry for my delay here @jbolt. I realized the problem quite quickly - the debounce code looks for transitions and there is never a transition if the lower sensor starts empty. Of course, you don't need to debounce the lower sensor, so I just switched those to the original method of reading the sensor directly. Hopefully you have a chance to look at what I did in the attached at let me know what you think. If you did it a different way, I'm interested to see what you did. Sorry again for taking so long; hopefully you learned something in the process.

I left comments where I made changes to help explain.

Edit: of course, my code may still have problems, but hopefully it is useful for something.

Edit 2: I wanted to shorten the main loop (same code, more compact) and saw I hadn't fixed the problem you identified earlier of repeating feeder1 instead of changing to feeder2, so I now fixed that (in v2.2). This is the code I used for the compact loop (v2.3):

Code:
void loop() {
    sensorsUpdate();

    if (motor1On == false && digitalRead(SENSOR1LOW) == HIGH) startFeeder1();
    else if (motor1On && sensor1high.fell()) stopFeeder1();

    if (motor2On == false && digitalRead(SENSOR2LOW) == HIGH) startFeeder2();
    else if (motor2On && sensor2high.fell()) stopFeeder2();

    checkASensor();
}

The full v2.3:
Code:
/*
Feeder (v2.3)
    using Bounce2 library to get stable sensor states
    see https://github.com/thomasfredericks/Bounce2/wiki
*/

#include <Bounce2.h>

#define ASENSOR 7 //alarm IR sensor is on pin 7
#define ALED 8 //alarm LED is on pin 8
#define ABUZZ 9 //alarm buzzer relay is on pin 10
#define RELAY1 10 //feeder1 relay is on pin 10
#define RELAY2 11 //feeder2 relay is on pin 11
#define SENSOR1LOW 2 //feeder1 Low IR Sensor is on pin 2
#define SENSOR1HIGH 3 //feeder1 High IR Sensor is on pin 3
#define SENSOR2LOW 4 //feeder2 Low IR Sensor is on pin 4
#define SENSOR2HIGH 5 //feeder2 High IR Sensor is on pin 5

// state variable
int asensorState = 0;
bool motor1On = false;
bool motor2On = false;

// edits for Bounce  - detecting stable signal
#define  SENSORDELAY 250  // milliseconds that the sensor must be stable to change reading
Bounce sensor1high = Bounce();
Bounce sensor2high = Bounce();
// Bounce sensor1low = Bounce();
// Bounce sensor2low = Bounce();

void setup() {
    pinMode(ALED, OUTPUT); // initialize the ALED pin as an output:
    pinMode(ABUZZ, OUTPUT); // initialize the ABUZZ pin as an output:
    pinMode(ASENSOR, INPUT); // initialize the ASENSOR pin as an input:
    pinMode(RELAY1, OUTPUT); // initialize the RELAY1 pin as an output:
    pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
    pinMode(SENSOR1LOW, INPUT_PULLUP); // sensor1 Low with pullup enabled
    pinMode(SENSOR1HIGH, INPUT_PULLUP); // sensor1 High with pullup enabled
    pinMode(SENSOR2LOW, INPUT_PULLUP); // sensor2 Low with pullup enabled
    pinMode(SENSOR2HIGH, INPUT_PULLUP); // sensor2 High with pullup enabled

    digitalWrite(ASENSOR, HIGH); //turn on the pullup
    digitalWrite(RELAY1, HIGH); // make sure the relay is Off after reset
    digitalWrite(RELAY2, HIGH); // make sure the relay is Off after reset

    // edits for Bounce
    sensor1high.attach(SENSOR1HIGH);
    sensor1high.interval(SENSORDELAY);
    sensor2high.attach(SENSOR2HIGH);
    sensor2high.interval(SENSORDELAY);
    // no need for the following because we don't need to debounce the lower sensors
    // sensor1low.attach(SENSOR1LOW);
    // sensor1low.interval(SENSORDELAY);
    // sensor2low.attach(SENSOR2LOW);
    // sensor2low.interval(SENSORDELAY);
}

void loop() {
    sensorsUpdate();

    if (motor1On == false && digitalRead(SENSOR1LOW) == HIGH) startFeeder1();
    else if (motor1On && sensor1high.fell()) stopFeeder1();

    if (motor2On == false && digitalRead(SENSOR2LOW) == HIGH) startFeeder2();
    else if (motor2On && sensor2high.fell()) stopFeeder2();

    checkASensor();
}

void sensorsUpdate(){
    sensor1high.update();
    sensor2high.update();
    // no need to update the following since we don't need to debounce the lower sensors
    // sensor1low.update();
    // sensor2low.update();
}
void stopFeeder1(){
    digitalWrite(RELAY1, HIGH); // turn motor off
    motor1On = false; // record motor state
}
void stopFeeder2(){
    digitalWrite(RELAY2, HIGH); // turn motor off
    motor2On = false; // record motor state
}

void startFeeder1(){
    digitalWrite(RELAY1, LOW); // turn motor on
    motor1On = true; // record motor state
}
void startFeeder2(){
    digitalWrite(RELAY2, LOW); // turn motor on
    motor2On = true; // record motor state
}

void checkASensor(){
    asensorState = digitalRead(ASENSOR); // read the state of the ASENSOR value:

    if (asensorState == LOW) { // check if the sensor beam is broken, if it is, the sensorState is LOW:
    digitalWrite(ALED, LOW); // turn LED on:
    digitalWrite(ABUZZ, LOW); // turn BUZZER on:
    }
    else {
    digitalWrite(ALED, HIGH); // turn LED off:
    digitalWrite(ABUZZ, HIGH); // turn BUZZER off:
    }
}
And I guess, for completeness, the revised v.2.2:
Code:
/*
Feeder (v2.2)
    using Bounce2 library to get stable sensor states
    see https://github.com/thomasfredericks/Bounce2/wiki
*/

#include <Bounce2.h>

#define ASENSOR 7 //alarm IR sensor is on pin 7
#define ALED 8 //alarm LED is on pin 8
#define ABUZZ 9 //alarm buzzer relay is on pin 10
#define RELAY1 10 //feeder1 relay is on pin 10
#define RELAY2 11 //feeder2 relay is on pin 11
#define SENSOR1LOW 2 //feeder1 Low IR Sensor is on pin 2
#define SENSOR1HIGH 3 //feeder1 High IR Sensor is on pin 3
#define SENSOR2LOW 4 //feeder2 Low IR Sensor is on pin 4
#define SENSOR2HIGH 5 //feeder2 High IR Sensor is on pin 5

// state variable
int asensorState = 0;
bool motor1On = false;
bool motor2On = false;

// edits for Bounce  - detecting stable signal
#define  SENSORDELAY 250  // milliseconds that the sensor must be stable to change reading
Bounce sensor1high = Bounce();
Bounce sensor2high = Bounce();
// Bounce sensor1low = Bounce();
// Bounce sensor2low = Bounce();

void setup() {
    pinMode(ALED, OUTPUT); // initialize the ALED pin as an output:
    pinMode(ABUZZ, OUTPUT); // initialize the ABUZZ pin as an output:
    pinMode(ASENSOR, INPUT); // initialize the ASENSOR pin as an input:
    pinMode(RELAY1, OUTPUT); // initialize the RELAY1 pin as an output:
    pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
    pinMode(SENSOR1LOW, INPUT_PULLUP); // sensor1 Low with pullup enabled
    pinMode(SENSOR1HIGH, INPUT_PULLUP); // sensor1 High with pullup enabled
    pinMode(SENSOR2LOW, INPUT_PULLUP); // sensor2 Low with pullup enabled
    pinMode(SENSOR2HIGH, INPUT_PULLUP); // sensor2 High with pullup enabled

    digitalWrite(ASENSOR, HIGH); //turn on the pullup
    digitalWrite(RELAY1, HIGH); // make sure the relay is Off after reset
    digitalWrite(RELAY2, HIGH); // make sure the relay is Off after reset

    // edits for Bounce
    sensor1high.attach(SENSOR1HIGH);
    sensor1high.interval(SENSORDELAY);
    sensor2high.attach(SENSOR2HIGH);
    sensor2high.interval(SENSORDELAY);
    // no need for the following because we don't need to debounce the lower sensors
    // sensor1low.attach(SENSOR1LOW);
    // sensor1low.interval(SENSORDELAY);
    // sensor2low.attach(SENSOR2LOW);
    // sensor2low.interval(SENSORDELAY);
}

void loop() {
    sensorsUpdate();
    if (motor1On == false) { // motor is stopped
        if(digitalRead(SENSOR1LOW) == HIGH)  { // low sensor shows empty
        // if (sensor1low.rose()) { // low sensor _transitioned to_ empty (this doesn't work because there isn't a transition when it starts empty)
            startFeeder1();
        }
    }
    else { // motor is running
        if (sensor1high.fell()) { // high sensor full
            stopFeeder1();
        }
    }
    if (motor2On == false) { // motor is stopped
        if(digitalRead(SENSOR2LOW) == HIGH)  { // low sensor shows empty
        // if (sensor2low.rose()) {  // low sensor _transitioned to_ empty (this doesn't work because there isn't a transition when it starts empty)
            startFeeder2();
        }
    }
    else { // motor is running
        if (sensor2high.fell()) { // high sensor full
            stopFeeder2();
        }
    }

    checkASensor();
}
void loop() {
    sensorsUpdate();
    if (motor1On == false && digitalRead(SENSOR1LOW) == HIGH) startFeeder1();
    else if (sensor1high.fell()) stopFeeder1();
    if (motor2On == false) if(digitalRead(SENSOR2LOW) == HIGH) startFeeder2();
        }
    }
    else { // motor is running
        if (sensor2high.fell()) { // high sensor full
            stopFeeder1();
        }
    }

    checkASensor();
}
void sensorsUpdate(){
    sensor1high.update();
    sensor2high.update();
    // no need to update the following since we don't need to debounce the lower sensors
    // sensor1low.update();
    // sensor2low.update();
}
void stopFeeder1(){
    digitalWrite(RELAY1, HIGH); // turn motor off
    motor1On = false; // record motor state
}
void stopFeeder2(){
    digitalWrite(RELAY2, HIGH); // turn motor off
    motor2On = false; // record motor state
}

void startFeeder1(){
    digitalWrite(RELAY1, LOW); // turn motor on
    motor1On = true; // record motor state
}
void startFeeder2(){
    digitalWrite(RELAY2, LOW); // turn motor on
    motor2On = true; // record motor state
}

void checkASensor(){
    asensorState = digitalRead(ASENSOR); // read the state of the ASENSOR value:

    if (asensorState == LOW) { // check if the sensor beam is broken, if it is, the sensorState is LOW:
    digitalWrite(ALED, LOW); // turn LED on:
    digitalWrite(ABUZZ, LOW); // turn BUZZER on:
    }
    else {
    digitalWrite(ALED, HIGH); // turn LED off:
    digitalWrite(ABUZZ, HIGH); // turn BUZZER off:
    }
}
jwmelvin,
Thanks for providing that. I will take a look and see what you did.

I posted my fix in post #34 above and just added a sensor update before the debounce code to force the sensors into a state change. The best I could do with my limited understanding. I'll post the full code later.

The irony of this exercise is by the time we implemented the dual sensors on Sunday we found the "buffer" we wanted became unnecessary due to some improvements we made in the out flow processing. We are currently just running a single sensor with debounce which I will admit was easy to write the code for after going through this.

I may use the dual sensor code on an automatic bullet and case feeder I have been making which was the inspiration for the machine we have running now.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,484
Likes
1,433
#41
Here is the code with my modification in bold.

/*
Feeder
using Bounce2 library to get stable sensor states
see https://github.com/thomasfredericks/Bounce2/wiki
*/

#include <Bounce2.h>

#define ASENSOR 7 //alarm IR sensor is on pin 7
#define ALED 8 //alarm LED is on pin 8
#define ABUZZ 9 //alarm buzzer relay is on pin 9
#define RELAY1 10 //feeder1 relay is on pin 10
#define RELAY2 11 //feeder2 relay is on pin 11
#define SENSOR1LOW 2 //feeder1 Low IR Sensor is on pin 2
#define SENSOR1HIGH 3 //feeder1 High IR Sensor is on pin 3
#define SENSOR2LOW 4 //feeder2 Low IR Sensor is on pin 4
#define SENSOR2HIGH 5 //feeder2 High IR Sensor is on pin 5

// state variable
int asensorState = 0;
bool motor1On = false;
bool motor2On = false;

// edits for Bounce - detecting stable signal
#define SENSORDELAY 50 // milliseconds that the sensor must be stable to change reading
Bounce sensor1high = Bounce();
Bounce sensor2high = Bounce();
Bounce sensor1low = Bounce();
Bounce sensor2low = Bounce();

void setup() {
pinMode(ALED, OUTPUT); // initialize the ALED pin as an output:
pinMode(ABUZZ, OUTPUT); // initialize the ABUZZ pin as an output:
pinMode(ASENSOR, INPUT); // initialize the ASENSOR pin as an input:
pinMode(RELAY1, OUTPUT); // initialize the RELAY1 pin as an output:
pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
pinMode(SENSOR1LOW, INPUT_PULLUP); // sensor1 Low with pullup enabled
pinMode(SENSOR1HIGH, INPUT_PULLUP); // sensor1 High with pullup enabled
pinMode(SENSOR2LOW, INPUT_PULLUP); // sensor2 Low with pullup enabled
pinMode(SENSOR2HIGH, INPUT_PULLUP); // sensor2 High with pullup enabled

digitalWrite(ASENSOR, HIGH); //turn on the pullup
digitalWrite(RELAY1, HIGH); // make sure the relay is Off after reset
digitalWrite(RELAY2, HIGH); // make sure the relay is Off after reset

// edits for Bounce
sensor1high.attach(SENSOR1HIGH);
sensor1high.interval(SENSORDELAY);
sensor2high.attach(SENSOR2HIGH);
sensor2high.interval(SENSORDELAY);
sensor1low.attach(SENSOR1LOW);
sensor1low.interval(SENSORDELAY);
sensor2low.attach(SENSOR2LOW);
sensor2low.interval(SENSORDELAY);
}

void loop() {
sensor1low.update(); // update sensor1low instance:
sensor2low.update(); // update sensor12low instance:

int value1 = sensor1low.read(); //get updtaed value:
int value2 = sensor2low.read(); //get updtaed value:

if ( value1 == HIGH ) {
digitalWrite(SENSOR1LOW, LOW );
}
else {
digitalWrite(SENSOR1LOW, HIGH );
}
if ( value2 == HIGH ) {
digitalWrite(SENSOR2LOW, LOW );
}
else {
digitalWrite(SENSOR2LOW, HIGH );
}


sensorsUpdate();
if (motor1On == false) { // motor is stopped
if (sensor1low.rose()) { // low sensor empty
startFeeder1();
}
}
else { // motor is running
if (sensor1high.fell()) { // high sensor full
stopFeeder1();
}
}
if (motor2On == false) { // motor is stopped
if (sensor2low.rose()) { // low sensor empty
startFeeder2();
}
}
else { // motor is running
if (sensor2high.fell()) { // high sensor full
stopFeeder2();
}
}

checkASensor();
}

void sensorsUpdate(){
sensor1high.update();
sensor1low.update();
sensor2high.update();
sensor2low.update();
}
void stopFeeder1(){
digitalWrite(RELAY1, HIGH); // turn motor off
motor1On = false; // record motor state
}
void stopFeeder2(){
digitalWrite(RELAY2, HIGH); // turn motor off
motor2On = false; // record motor state
}

void startFeeder1(){
digitalWrite(RELAY1, LOW); // turn motor on
motor1On = true; // record motor state
}
void startFeeder2(){
digitalWrite(RELAY2, LOW); // turn motor on
motor2On = true; // record motor state
}

void checkASensor(){
asensorState = digitalRead(ASENSOR); // read the state of the ASENSOR value:

if (asensorState == LOW) { // check if the sensor beam is broken, if it is, the sensorState is LOW:
digitalWrite(ALED, LOW); // turn LED on:
digitalWrite(ABUZZ, LOW); // turn BUZZER on:
}
else {
digitalWrite(ALED, HIGH); // turn LED off:
digitalWrite(ABUZZ, HIGH); // turn BUZZER off:
}
}
 
[6]
[5] [7]
Top