Arduino Code Help

Jay,
I assumed you had a liquid that your were measuring. Your thinking is on the right track.

If you have objects falling through both beams, the code needs to integrate the samples to ignore the objects that are just passing through. Generally, it's not a good idea to use the millis() function in the main loop as it causes the code to stop until the time delay is completed. However, in this case I think it will be OK. Here's a simple implementation.

if(digitalRead(SENSOR1HIGH) == LOW) { // a part is detected in the beam
millis(xxx); // wait enough milliseconds to let the part fall through
if(digitalRead(SENSOR1HIGH) == LOW) { // look again to see if the beam is still broken
digitalWrite(RELAY1, HIGH);
motor1On = false;
}
}

What's going on here: when you detect an object in the beam, wait long enough to let it fall through then look again. If it's still there then turn the motor off. Otherwise ignore it.

Glen
 
Glen,
In my limited understanding I don't think millis() can be used this way? From what I have read isn't millis() used to compare time of the sensor state?

I though we didn't want to use a simple delay function as it pauses the code and the other sensors may miss events?

I have been looking at this example of millis() which I think is what I'm looking for but it is based on a button press and release so it gets confusing to me on how to use that when comparing the state of two sensors.

When I use the code example you provided I get this error.

Arduino: 1.8.5 (Windows 10), Board: "Arduino Nano, ATmega328P"

F:\1-Jay\Arduino\Progressive Press Control\Feeder2\Feeder_Alarm_Rev2\Feeder_Alarm_Rev2.ino: In function 'void loop()':

Feeder_Alarm_Rev2:45: error: too many arguments to function 'long unsigned int millis()'

millis(100);// Ignore passing object

^

In file included from sketch\Feeder_Alarm_Rev2.ino.cpp:1:0:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:140:15: note: declared here

unsigned long millis(void);

^

Feeder_Alarm_Rev2:61: error: too many arguments to function 'long unsigned int millis()'

millis(100);// Ignore passing object

^

In file included from sketch\Feeder_Alarm_Rev2.ino.cpp:1:0:

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:140:15: note: declared here

unsigned long millis(void);

^

Feeder_Alarm_Rev2:81: error: expected '}' at end of input

}

^

Feeder_Alarm_Rev2:81: error: expected '}' at end of input

exit status 1
too many arguments to function 'long unsigned int millis()'
 
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.
 

Attachments

  • feeder2.txt
    3.6 KB · Views: 5
jwmelvin,

I ran your code and the motors do not turn on.

I'm curious why motor1On / sensor1 is duplicated? Should the second occurrence be motor2On / sensor2?

void loop() {
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 (motor1On == false) { // motor is stopped
if (sensor1low.rose()) { // low sensor empty
startFeeder1();
}
}
else { // motor is running
if (sensor1high.fell()) { // high sensor full
stopFeeder1();
}
 
Yes, of course, sorry about that. The bold names should have a 2 in them.

That won't, however, explain the issue with the motors not turning on. You did copy the Bounce2 library to the correct location and it shows up in your Arduino environment?

If it were me, I'd make a simple test program to debug the issue and make sure I am reading the sensors correctly.
 
I changed the other lines to have 2 in them but as you say that does not fix the issue. I downloaded the bounce2 zip file from github and used Add Zip. Library to install it. It sows up in the library and the code compiles so I'm assuming it is installed correctly.

Ha ha set up a simple test program he says..... I'll see what I can do.
 
Jay,

Sorry for the wrong code earlier. I'm away from my Arduino development PC on a road trip. If you substitute "delay(xxx)" for "millis(xxx) in the code that I sent earlier and you should be OK. Mr. Melvin is correct regarding millis(). It simply returns the number of milliseconds since the system was reset. delay(xxx) is the proper function. It delays the code for the number of milliseconds you specify.

Glen
 
H
Not sue if this is the correct forum but here goes. I'm hoping there are some Arduino guru's here.

I trying to setup a feed motor that uses the state of two IR sensors to control a relay to cycle a motor on and off. The intent is to give some head room in the feed system to keep the motor from turning on/off constantly. The sensors will be spaced apart, high and low. When the space between the two sensors is full (both beams broken) the motor is of. As the system feeds the the top beam will become unbroken but the motor stays off until the lower beam is unbroken. When both beams are unbroken then the motor turns on. As the feed tube fills the lower beam will become broken but the motor stays on until the feed tube is full (both beams broken) then the motor turns off.

I have a single sensor working but I'm struggling on how to incorporate the second sensor.

Code so far.

/*
Feeder
*/

#define LEDPIN 12 //Motor staus LED is on pin 12
#define RELAY2PIN 10 //Feeder relay is on pin 10

#define SENSOR2PIN 2 //Feeder IR Sensor2 is on pin 2
#define SENSOR3PIN 3 //Feeder IR Sensor3 is on pin 3

// variables will change:
int sensor2State = 0, lastState=0; // variable for reading the sensor2 status
int sensor3State = 0, lastState=0; // variable for reading the sensor3 status

void setup() {
// initialize the LED pin as an output:
pinMode(LEDPIN, OUTPUT);
// initialize the RELAY2PIN pin as an output:
pinMode(RELAY2PIN, OUTPUT);
// initialize the sensor2 pin as an input:
pinMode(SENSOR2PIN, INPUT);
// initialize the sensor3 pin as an input:
pinMode(SENSOR3PIN, INPUT);

digitalWrite(SENSOR2PIN, HIGH); // turn on the pullup
digitalWrite(SENSOR3PIN, HIGH); // turn on the pullup

}

void loop(){
// read the state of the sensor2 value:
sensorBF2State = digitalRead(SENSOR2PIN);
// read the state of the sensor3 value:
sensorBF3State = digitalRead(SENSOR3PIN);

// check if the sensor3 beam is broken
// if it is, the sensor3State is LOW:
if (sensor3State == LOW) {
// turn RELAY2PIN off:
digitalWrite(RELAY2PIN, LOW);

}
else {
// turn RELAY2PIN on:
digitalWrite(RELAY2PIN, HIGH);

}
ears a link to a timmer interupt tutorial.

https://learn.adafruit.com/multi-tasking-the-arduino-part-2/timers

Stu
 
jwmelvin,
On the machine using your code the relay pin is not being pulled to ground (turn on relay) regardless of the sensor conditions. I setup a single sensor array and relay on a breadboard and I get the opposite result with the relay being pulled to ground regardless of the sensor conditions. I'll try adding the second sensor/relay to the breadboard later and see what happens.

Glen,
I changed the code to add the delay to the upper sensor for both motors. Motor2 motor cycles on/off properly with the sensor2 conditions. However motor1 cycles on/off by the the upper sensor only and does not wait for the lower sensor to be empty? Without the delay both motors behave properly with the sensor conditions (except for the part dropping by).

I renamed the sensors because the HIGH/LOW was getting confusing.

/*
Feeder
*/

#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 SENSOR1BOTTOM 2 //feeder1 Bottom IR Sensor is on pin 2
#define SENSOR1TOP 3 //feeder1 Top IR Sensor is on pin 3
#define SENSOR2BOTTOM 4 //feeder2 Bottom IR Sensor is on pin 4
#define SENSOR2TOP 5 //feeder2 Top IR Sensor is on pin 5

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

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(SENSOR1BOTTOM, INPUT_PULLUP); // sensor1 bottom with pullup enabled
pinMode(SENSOR1TOP, INPUT_PULLUP); // sensor1 top with pullup enabled
pinMode(SENSOR2BOTTOM, INPUT_PULLUP); // sensor2 bottom with pullup enabled
pinMode(SENSOR2TOP, INPUT_PULLUP); // sensor2 top 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
}

void loop() {
if(motor1On == false) {
if(digitalRead(SENSOR1BOTTOM) == HIGH) { // turn On if bottom sensor shows empty
digitalWrite(RELAY1, LOW);
motor1On = true;
}
}
else {
if(digitalRead(SENSOR1TOP) == LOW) { // check sensor
delay(250); // ingnore passing by sensor
if(digitalRead(SENSOR1TOP) == LOW) { // turn off if top sensor shows full
digitalWrite(RELAY1, HIGH);
motor1On = false;
}
}
}

{
if(motor2On == false) {
if(digitalRead(SENSOR2BOTTOM) == HIGH) { // turn On if bottom sensor shows empty
digitalWrite(RELAY2, LOW);
motor2On = true;
}
}
else {
if(digitalRead(SENSOR2TOP) == LOW) { // check sensor
delay(250); //ingore part passing by sensor
if(digitalRead(SENSOR2TOP) == LOW) { // turn off if top sensor shows full
digitalWrite(RELAY2, HIGH);
motor2On = false;
}
}
}

{
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,
On the machine using your code the relay pin is not being pulled to ground (turn on relay) regardless of the sensor conditions. I setup a single sensor array and relay on a breadboard and I get the opposite result with the relay being pulled to ground regardless of the sensor conditions. I'll try adding the second sensor/relay to the breadboard later and see what happens.

I was thinking of something a lot simpler. Like a sensor and a print statement. Try to get bounce working with a sensor so you are comfortable with it. Then build from there. It’s worth it.

Did you try a shorter delay for bounce like 50 ms?

I really urge you not to use delay() as a way of achieving what you want. If you can’t get bounce working I can help you do it another way. But I stopped doing things the hard way once I found bounce.
 
Back
Top