Hello everyone.
I am new (like brand new) to writing Arduino scripts and have been tasked with designing and building a golf ball color sorter. In short, I am using an Arduino Uno, Adafruit PCA9685 to drive the servos, and an E18-D80NK IR sensor to detect the arrival of a ball within the 2" OD aluminum tube. The desired process is as follows:
-Ball arrives at Gate 1
-IR sensor detects arrival of ball
-Gate 1 opens for 350ms to allow ball to pass
-ball stops at Gate 2, below the color sensor
-Color is read
-Stepper motor moves a ramp that distributes the ball into its appropriate color bin
-Gate 2 opens allowing ball to be distributed
-Rinse an Repeat
As I am new to this I am taking the script writing one small section at a time. I have calibrated the servos for MAX/MIN values can move them at will with a simple script.
The Problem:
When incorporating the IR Sensor; using the digitalRead function along with an If/Else statement I am not getting the desired behavior. When a ball passes in front of the sensor the gate instantly opens (a delay is desired to allow ball to settle to a stop within the tube) and stays open until the ball has passed outside the sensors range. The issue here is that there may at some point be multiple balls in the tube in line to have their color read, therefore it is integral that the sensor read the arrival of the ball, delay, then open Gate 1 for a specific amount of time before closing and allowing the rest of the code to read.
My interpretation of the problem is that by using digitalRead, the script is constantly reading the state of the IR sensor which so long as a ball is present, will cause it to remain open.
Is there a way to simply check the state of the sensor at the beginning of the loop, and then disregard after its state has been applied to the If/Else statement?
The code as of now is shown below. Please note that all the commented out section are as such when getting the results I described.
I have also included a PDF with markups to convey he context of the issue. If any more info is required please let me know...
(posted edited for corrections in PDF; both gates were labeled 1 which was incorrrect)
#include <Wire.h> #include <Adafruit_PWMServoDriver.h> Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(); #define SERVOMIN 90 // this is the 'minimum' pulse length count (out of 4096) #define SERVOMAX 620 // this is the 'maximum' pulse length count (out of 4096) #define IRSTATE 2 uint8_t servonum = 0; void setup() { pwm.begin(); pwm.setPWMFreq(60); //pinMode(IRSTATE, INPUT_PULLUP); yield(); } void loop() { int S = digitalRead(IRSTATE); if(S == 1){ pwm.setPWM(2, 0, 95); //GATE 1 OPEN delay(350); pwm.setPWM(2, 0, 152); //GATE 1 CLOSED //pwm.setPWM(0, 0, 163); //GATE 2 OPEN //pwm.setPWM(0, 0, 110); //GATE 2 CLOSED //delay(8000); }else{ pwm.setPWM(2, 0, 152); //GATE 1 CLOSED //delay(500)
@spaghetticallahan First try making the 350ms delay longer, maybe 1000. Second, I am unsure what sensor you are reading, but if it is a PIR type then they need warm-up time and are not really suited to this task. What is the part number of the sensor?
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
The part number for the sensor is: E18-D80NK IR
The 350ms delay on the servo is necessary to only allow one ball to pass. I could increase it some, and decrease the mounting angle of the tube to slow the flow of balls but 350ms with the pictured angle was happy medium had arrived at through experimenting. Does the code look as though it should work as is?
@spaghetticallahan That sensor is new to me. I am working with the standard PIR sensor and know how fussy it is but not the one you are using. Why not just use a micro switch to detect that the ball is in position?
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
A couple of suggestions/observations:
Your program listing fnishes in the middle of the 'else' section ... it might just be a curly bracket missing.
---
Perhaps, it is just lack of imagination and patience on my part, but I am not completely clear what you are expecting the machine to do at every point. So in case I am not the only one who is not clear where the problems first show...
This is one of those classic situations, where the clearest definition (that is provided) of what is wanted is a code listing ... but something doesn't work as desired, which means the code listing probably has bug.
What is needed is a full description, in addition to what you have provided, (which is also all good information,) that clearly describes the actions and events, for both what you desire and what actually happens, so we can easily visualise and pinpoint where they differ.
Can I suggest you make a kind of twin timeline sketch, listing all of the events and actions, up to and including where your what you want to happen, and what actually happens differs?
Hopefully, then someone on the forum can suggest a solution.
Best wishes, Dave
@spaghetticallahan I don't see a library for the IR sensor in your sketch. That device may need more than just a digitalRead.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
I like the idea of a microswitch instead of the IR sensor, as the application would be similar, however, the ID of the tube is 1.75" which leaves about .100" slop around the ball. This creates an issue when actuating the switch reliably. After some thought, I definitely agree that the IR sensor will not work. If not for any other reason, one of the balls to be detected is black... which absorbs IR light. Maybe a laser sensor with detection of the beam being broken? Any thoughts on that as an alternative?
In the example codes I had found for use with this sensor no additional libraries were included.
As a supplement, to my above message:
Looking at the supplier site https://hobbycomponents.com/sensors/213-ir-infrared-obstacle-avoidance-sensor-e18-d80nk
Suggests that the sensor is a 'simple' IR LED and IR detector diode ... and their example is consistent with yours, in that a simple digitalRead statement, will indicate whether it not it is seeing a beam reflected by an object.
Assuming it is detecting a ball, and appropriately changing state according to the presence or absence of the ball, then it is doing its job as I would expect.
Re-reading your description, it sounds like your program is opening the gate, to allow the first ball to proceed, but not then following a sequence of steps to 'process' that ball.
Whilst, it may not be the most efficient scheme, I would start with a program that does not return to check for another ball at that first gate, until it has completely finished with dealing with the first ball.
As I suggested above, I suggest you draw a proper timeline of events ... just imagine the gates, selectors, etc. are all manually operated, and write a set of instructions to operate them, assuming the operator has no understanding of the process ... they must just follow your instructions.
Hopefully the required program flow will become clearer to you.
Best wishes, Dave
How about putting a cheap limit switch in the floor of the pipe where the ball stops. The weight of the ball will close the switch and give an unambiguous signal of the ball's arrival.
I would suggest (if you can afford an extra servo) to install a servo whose arm can be lowered partway between the target ball (which just stopped) and the ball behind it. This will allow you to release the target ball without having to worry about releasing any of the other balls following it.
When the target ball closes the limit switch it means that a ball is in position. Lower the rear arm between it and the following ball to lock in the follower. When ready release the target ball and then raise the barrier again. Then raise the rear servo arm to let the next ball roll forward into the target spot.
That way you have complete control of the procession of balls but never have to do any critical timing or worry about multiple balls in play while the gate is open.
Anything seems possible when you don't know what you're talking about.
@spaghetticallahan Yes, a light source and an LDR would be good.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
@spaghetticallahan That is very strange since there is one for it. But as you said it will not work.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
@will FYI @spaghetticallahan Good idea Will.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Thanks for the reply. At this point I am just trying to get the sensor to detect a ball, open gate 1 for 350ms, then close the gate. Then it would check for the presence of another ball, if no ball detected, then it would simply loop back (via the ELSE portion of the script) and repeat this checking until a ball arrives. However, through the other replies I believe that the IR sensor will not work in this application as one of the balls is black, which absorbs IR light. I believe the solution is to use a constant laser setup where when the beam is broken by an object, the gate is called to open. Unfortunately this means I have to do a little more machining on the tube to allow mounting of the laser receiver on the opposite side of the tube from the transmitter. I had originally considered this as an option but thought the Ir sensor would be a more simple solution. This would alleviate the problem of the presence of a black ball not being detected. Thoughts?
I like this idea. I think the simplest solution for the multiple ball problem is to move the gates closer together. So between the two gates, where the color is read... there is only room for one ball. In essence, when gate 1 opens, the balls move forward, but hit another closed gate (gate 2) before there is room enough for a 2nd ball to pass gate 1. This, in conjunction with the use of a laser rather than an IR sensor should alleviate the mechanical issues I'm facing. The script writing will still be a mystery for me but perhaps its best to solve all observable mechanical problems before embarking on that trip.