[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,444
Likes
1,403
#1
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);

}
 

Eddyde

Registered
Registered
Joined
Oct 13, 2014
Messages
1,344
Likes
1,084
#2
I sounds like you could simply wire the two sensors in series, both would have to close to complete the circuit. You might even be able to hook them directly to a relay and do away with the Arduino, unless its needed for other functions.
 

jwmelvin

Registered
Registered
Joined
Jan 11, 2018
Messages
110
Likes
81
#3
Define a state variable for the motor status. If the motor is off, then only turn it on if the low beam is high; then, when the motor is on, only turn it off if the high beam is low.

if (stateMotor == LOW) { // motor is not running
if (stateSensorLow == HIGH) {
digitalWrite(RELAY2PIN, HIGH); // only turn motor on when level drops below SensorLow
stateMotor = HIGH; // track motor state
}
}
else { // motor is running
if (stateSensorHigh == LOW) {
digitalWrite(RELAY2PIN, LOW); // only stop motor when level rises above SensorHigh
stateMotor = LOW; // track motor state
}

It's possible to compact:

if (stateMotor == LOW && stateSensorLow == HIGH) {
digitalWrite(RELAY2PIN, HIGH);
stateMotor = HIGH;
}
else if (stateMotor == HIGH && stateSensorHigh == LOW) {
digitalWrite(RELAY2PIN, LOW); // only stop motor when level rises above SensorHigh
stateMotor = LOW;
}
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#4
Jay,

jwmelvin's code is right on target. He responded as I was creating essentially the same code. What he created is a state machine with 2 states: MOTOR_ON and MOTOR_OFF. While in the MOTOR_OFF state you just want to check the lower beam. While in the MOTOR_ON state you just want to check the upper beam.

By the way the method to enable the pullup resistors is:
pinMode(SENSOR2PIN, INPUT_PULLUP);
pinMode(SENSOR3PIN, INPUT_PULLUP);

Glen
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,444
Likes
1,403
#5
Thanks guys. It didn't occur to me to see it from the motor state. I will noodle this over tonight.

Old dog trying to learn just wish I had more time and brain cells to learn it better. I really love what you can do with these types of platforms but it is light years away from what I have spent my career doing.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,444
Likes
1,403
#6
My IR sensors did not arrive today so I will have to wait until tomorrow to try. I fiddled with the code and it compiles but I'm not sure the variable definitions are correct.

/*
Feeder
*/

#define RELAY2 10 //Feeder relay is on pin 10
#define SENSORLOW 2 //Feeder Low IR Sensor is on pin 2
#define SENSORHIGH 3 //Feeder High IR Sensor is on pin 3

// variables will change:
int stateMotor = 0; // variable for reading the motor status
int stateSensorLow = 0; // variable for reading the sensorLow status
int stateSensorHigh = 0; // variable for reading the sensorHigh status

void setup() {

pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
pinMode(SENSORLOW, INPUT_PULLUP); // initialize the sensorLow pin as an input:
pinMode(SENSORHIGH, INPUT_PULLUP); // initialize the sensorHigh pin as an input:

digitalWrite(SENSORLOW, HIGH); // turn on the pullup
digitalWrite(SENSORHIGH, HIGH); // turn on the pullup
}

void loop(){
if (stateMotor == LOW && stateSensorLow == HIGH) {
digitalWrite(RELAY2, HIGH); // only turn motor on when level drops below SensorLow
stateMotor = HIGH;
}
else if (stateMotor == HIGH && stateSensorHigh == LOW) {
digitalWrite(RELAY2, LOW); // only stop motor when level rises above SensorHigh
stateMotor = LOW;
}
}
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#7
Good morning Jay,

You're pretty close. Your code doesn't need the stateSensorLow and stateSensorHigh variables. That operation is handled directly with digitalRead(SENSORLOW) and digitalRead(SENSORHIGH) function calls. You could actually eliminate the stateMotor variable as the motor's ON/OFF state is actually stored in the pin. However, I think this code is more clear. Usually a more complex state machine has its state variable in memory.

The code below should work assuming the sensor logic levels are correct.

There are coding style conventions regarding indented code that I've included. Not all coders agree, but this is typical. It's all about readability.

I'm glad to see members of this site getting involved with software. While it looks difficult, it's really not any more complicated than planning the process to make a part on a machine; it's just a different mind-set.

Glen

/*
Feeder
*/

#define RELAY2 10 //Feeder relay is on pin 10
#define SENSORLOW 2 //Feeder Low IR Sensor is on pin 2
#define SENSORHIGH 3 //Feeder High IR Sensor is on pin 3

// state variables
int stateMotor = 0;

void setup() {
pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
pinMode(SENSORLOW, INPUT_PULLUP); // sensor Low with pullup enabled
pinMode(SENSORHIGH, INPUT_PULLUP); // sensor High with pullup enabled
}

void loop() {
if(stateMotor == LOW) {
if(digitalRead(SENSORLOW) == HIGH) { // turn on if Low sensor shows empty
digitalWrite(RELAY2, HIGH);
stateMotor = HIGH;
}
}
else {
if(digitalRead(SENSORHIGH == LOW) { // turn off if High sensor shows full
digitalWrite(RELAY2, LOW);
stateMotor = LOW;
}
}
}
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#8
Update: the indenting doesn't show up with this commenting system.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,444
Likes
1,403
#9
Good morning Jay,

You're pretty close. Your code doesn't need the stateSensorLow and stateSensorHigh variables. That operation is handled directly with digitalRead(SENSORLOW) and digitalRead(SENSORHIGH) function calls. You could actually eliminate the stateMotor variable as the motor's ON/OFF state is actually stored in the pin. However, I think this code is more clear. Usually a more complex state machine has its state variable in memory.

The code below should work assuming the sensor logic levels are correct.

There are coding style conventions regarding indented code that I've included. Not all coders agree, but this is typical. It's all about readability.

I'm glad to see members of this site getting involved with software. While it looks difficult, it's really not any more complicated than planning the process to make a part on a machine; it's just a different mind-set.

Glen
Thanks Glen. I'd love to know this stuff better. I find it fascinating but its learning another language. I do better if I can immerse myself.

I follow most of the code you have. I was getting definition errors without the sensor variables so that's why they were there. I'm still a little confused as to how the stateMotor variable is tied to the relay?
 

jwmelvin

Registered
Registered
Joined
Jan 11, 2018
Messages
110
Likes
81
#10
I'm still a little confused as to how the stateMotor variable is tied to the relay?
Manually, in that when you change the relay state you also change the stateMotor variable. I believe it is also possible to do a read operation on the relay output pin but I wasn’t sure so didn’t suggest that.
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#11
Jay,

The variable stateMotor keeps track of whether the motor is On or Off. It doesn't directly control the relay. That's done with the digitalWrite(RELAY2, x) statement.

To make things a bit more clear, I'll rename stateMotor to be motorOn. motorOn is a boolean variable with the values true or false.

// state variable declaration
bool motorOn = false;

When the program comes out of reset, motorOn is false. At the start of each pass through the loop the program looks at the motorOn variable. If motorOn is false (motor is Off), it looks at the Lower Sensor. If it needs to turn on, the program sets motorOn to true and turns the relay On with digitalWrite(RELAY2, HIGH). If the motor doesn't need to turn on, the program skips over the "else" statement to the bottom then jumps back to the top of the loop. To get into the "else" statement, motorOn must be true (motor is On) where it looks at the Upper Sensor. If the motor needs to turn Off, motorOn is set false and the relay is turned off with digitalWrite(RELAY2, LOW). Then the program jumps back o the start of the loop to repeat the process.

Since the comment system doesn't allow tabs, in the code below, I used 4 spaces for each tab indentation

#define RELAY2 10 //Feeder relay is on pin 10
#define SENSORLOW 2 //Feeder Low IR Sensor is on pin 2
#define SENSORHIGH 3 //Feeder High IR Sensor is on pin 3

// state variable
bool motorOn = false;

void setup() {
pinMode(RELAY2, OUTPUT); // initialize the RELAY2 pin as an output:
pinMode(SENSORLOW, INPUT_PULLUP); // sensor Low with pullup enabled
pinMode(SENSORHIGH, INPUT_PULLUP); // sensor High with pullup enabled

// this statement was missing on the original programs
digitalWrite(RELAY2, LOW); // make sure the relay is Off after reset
}

void loop() {
if(motorOn == false) {
if(digitalRead(SENSORLOW) == HIGH) { // turn On if Low sensor shows empty
digitalWrite(RELAY2, HIGH);
motorOn = true;
}
}
else {
if(digitalRead(SENSORHIGH == LOW) { // turn off if High sensor shows full
digitalWrite(RELAY2, LOW);
motorOn = false;
}
}
}

I've been using Arduino Nanos. They are powerful and cheap (about $4 each). So far I've built a stepper motor controller to replace the gear train on my G4000 lathe for feeding. One of these days I'll finish the version that will be able to do to threading in metric and US. I also just finished a DRO for the cross slide. It uses a $10 Harbor Freight caliper. It calculates diameters directly simplifying my work. It's working great on my current project which involves tight tolerances for ball bearings.

Glen
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,444
Likes
1,403
#12
Glen, thank you for the detailed explanation. That really helps and is much appreciated. Hopefully I will be able to give it a whirl tonight.

Your lathe projects sounds great. Do you have build threads on those?

I have often though about setting up a system on the cross slide to use a stepper motor and micro controller for constant surface speed turning. I fall short when it comes to the software.
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,444
Likes
1,403
#13
FYI to anyone following this thread, the code above is missing a ")" at "if(digitalRead(SENSORHIGH == LOW) { // turn off if High sensor shows full"

It should be "if(digitalRead(SENSORHIGH) == LOW) { // turn off if High sensor shows full"
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#14
Good catch. That's typical of software when you don't compile it before showing it to the world.

The commenting system removes extra spaces too. It didn't show up as I was typing it.

Here's the build thread for one of the projects.
Stepper replaces G4000 gear train for feeding

I'll put another together for the DRO, but it's not all that creative. It's been done many times.

Glen
 

jbolt

Active User
H-M Platinum Supporter ($50)
Joined
Dec 3, 2013
Messages
1,444
Likes
1,403
#15
It works!

I setup the sensors on a breadboard and it worked as planned so I decided to try adding a second feeder to the code. I did that and wired another sensor system on the breadboard and nothing?? The IR sensors were acting like they were not being read. I have the sensors powered by a separate bench supply so I checked that. I could see the emitters glowing in my phone camera so it didn't make any sense.

Thinking maybe I some how damaged the sensors I pulled it all apart and setup the single sensor code that has a LED and serial read so I could verify the Arduino was reading the sensor on the serial monitor. I also added a voltage regulator to be sure I would get a clean full 5v. Everything was laid loose and by pointing together or apart all was all working. I was getting messages on the serial monitor and the LED goes on off. Great so I checked all the IR sensors to be sure they all worked.

Thinking maybe I previously had a bad connection somewhere else I remounted the IR sensor to the breadboard and tried to break the beam. Nothing??? It was at that point I realized that at first I had been using a small steel ruler to break the beam but had changed to a postit note folded several times. Sure enough the IR goes right through the paper. Who knew? Works fine with the steel ruler. UGH! an hour wasted.

So I put it all together and tried the dual feeder code. Success!!! After that I added an alarm for another process. So far so good. Now to package it.

Here is my final code. Not sure if it is the proper way to format the dual feeder and alarm but it works.

/*
dual_feeder_w_alarm
*/

#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;

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, LOW); // make sure the relay is Off after reset
digitalWrite(RELAY2, LOW); // make sure the relay is Off after reset
}

void loop() {
if(motor1On == false) {
if(digitalRead(SENSOR1LOW) == HIGH) { // turn On if Low sensor shows empty
digitalWrite(RELAY1, HIGH);
motor1On = true;
}
}
else {
if(digitalRead(SENSOR1HIGH) == LOW) { // turn off if High sensor shows full
digitalWrite(RELAY1, LOW);
motor1On = false;
}
}

{
if(motor2On == false) {
if(digitalRead(SENSOR2LOW) == HIGH) { // turn On if Low sensor shows empty
digitalWrite(RELAY2, HIGH);
motor2On = true;
}
}
else {
if(digitalRead(SENSOR2HIGH) == LOW) { // turn off if High sensor shows full
digitalWrite(RELAY2, LOW);
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:
}
}
}
}

My prototyping mess :grin:

20180816_205504.png
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#16
Jay,

Your prototype looks pretty good to me. That's not a mess, it's progress.

Glen
 

P. Waller

H-M Supporter - Sustaining Member
H-M Platinum Supporter ($50)
Joined
Mar 10, 2018
Messages
404
Likes
248
#17
I've been using Arduino Nanos. They are powerful and cheap (about $4 each). So far I've built a stepper motor controller to replace the gear train on my G4000 lathe for feeding. One of these days I'll finish the version that will be able to do to threading in metric and US. I also just finished a DRO for the cross slide. It uses a $10 Harbor Freight caliper. It calculates diameters directly simplifying my work. It's working great on my current project which involves tight tolerances for ball bearings.

Glen
How would you incorporate the lathe C axis for threading?

I bought an Arduino Mega 2560 awhile ago, plugged it into a desktop once to see what it would do and it was not what I was looking for.
You can have it for the USPS cost from NJ. Of course this may be old tech by now. It does no good sitting on my desk so its next destination is the scrap.
 

gzoerner

Registered
Registered
Joined
Apr 20, 2016
Messages
42
Likes
61
#18
Mr. Waller,

Thanks for the offer, but I've already got an Arduino Mega 2560. It's got the same CPU as the Nano, but it's got a lot more Input/Output, Flash and RAM.

Don't scrap the Mega. Just plugging it into your computer doesn't demonstrate much. Once you've made up your mind that you want to "electronify" some of your machinery you will find that it's just the thing you need. There are a couple of things you need to make the Mega useful: an LCD display (I'd recommend a 16 character by 2 rows or 20 character by 4 rows with the I2C 2 wire interface (about $5 to $12 each) and a 4x4 keypad (about $2 each). With these two extras you can build just about anything. Software isn't for everyone, but I find it fascinating.

Threading is pretty straightforward. I have to change my current 24 slot tachometer wheel to 64 slots plus a Top Dead Center indicator. The stepper will synchronize to TDC and adjust it's speed on each tick of the tachometer sensor. The stepper system already has an electronic stop and in knows where "Home Position" is (just before the start of the thread) so it can return there after each pass. The speed of the stepper is a simple ratio calculation based on the spindle speed and the desired pitch. I will be able to produce right and left threads in any pitch either US or metric or any oddball thread in between.

This threading mechanism will be still a manual process. I just won't have to mess around with the gear train.

Glen
 

P. Waller

H-M Supporter - Sustaining Member
H-M Platinum Supporter ($50)
Joined
Mar 10, 2018
Messages
404
Likes
248
#19
Mr. Waller,

Thanks for the offer, but I've already got an Arduino Mega 2560. It's got the same CPU as the Nano, but it's got a lot more Input/Output, Flash and RAM.

Don't scrap the Mega. Just plugging it into your computer doesn't demonstrate much. Once you've made up your mind that you want to "electronify" some of your machinery you will find that it's just the thing you need. There are a couple of things you need to make the Mega useful: an LCD display (I'd recommend a 16 character by 2 rows or 20 character by 4 rows with the I2C 2 wire interface (about $5 to $12 each) and a 4x4 keypad (about $2 each). With these two extras you can build just about anything. Software isn't for everyone, but I find it fascinating.

Threading is pretty straightforward. I have to change my current 24 slot tachometer wheel to 64 slots plus a Top Dead Center indicator. The stepper will synchronize to TDC and adjust it's speed on each tick of the tachometer sensor. The stepper system already has an electronic stop and in knows where "Home Position" is (just before the start of the thread) so it can return there after each pass. The speed of the stepper is a simple ratio calculation based on the spindle speed and the desired pitch. I will be able to produce right and left threads in any pitch either US or metric or any oddball thread in between.

This threading mechanism will be still a manual process. I just won't have to mess around with the gear train.

Glen
I understand how it works, I program and run CNC lathes for a living.
The application that I looked at the Arduino controller for is unrelated to machine tool control, ended up using a Mitsubishi PLC which works flawlessly and the programming is easily changed, it has no other HMI then START, STOP and several OH SH!* stops (-:

Also cost was not an issue.
 
[6]
[5] [7]
Top