Hi there, I'm having a small yet annoying issue with my code here. I have a DC motor running here along with the HC-SR04 sensor, It's meant to act as a belt that counts parts passing through the sensor, everything I have works , it counts the parts , sensor working correctly, LED flashing after every part counted. Having to stop the motor after 3 parts passing through with the switch not pressed and then turning it back on, and also with the switch pressed and 6 parts counted do the same. My problem is after it counts the 3 parts, it stops and delays the 3 seconds and then just sends impulses to the motor and not running through the code again? any idea as to why?
// We initialize our Pins here to what pin on the board they're used at
int switchPin = 2; // Setting the switch to pin 2
int motorPin = 4; // Setting the motor pin to pin 4
int LedDetection = 10; // Setting the led pin to pin 10
const int out = 12; // Setting the constants of pin 12 and 13
const int in = 13;
int partCounter = 0; // Counter for Box / Phone
boolean detection = false; // Detection of our Box / Phone
int switchState = 0; // Initializing switch state
void setup() {
Serial.begin(9600); // Serial Monitor for data transmission
pinMode(in, INPUT);
pinMode(out, OUTPUT);
pinMode(switchPin, INPUT); // Switch pin reading our input , to control the LED / Motor
pinMode(LedDetection, OUTPUT); // Led pin reading as output
pinMode(motorPin, OUTPUT); // Motor pin reading as output
}
void loop() {
digitalWrite(motorPin,HIGH);
/////////////////////////////// Sensor Loop for distance //////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
long duration;
long tocm;
digitalWrite(out,LOW);
delayMicroseconds(2);
digitalWrite(out,HIGH);
delayMicroseconds(10);
digitalWrite(out,LOW);
duration = pulseIn(in,HIGH);
tocm = microsecondsToCentimeters(duration);
Serial.print("Distance from conveyor in cm : "); // Here we print out the distance from the conveyor / wall by the sensor.
Serial.println(String(tocm));
delay(100); // Reading sensor every 100ms
Serial.print("Parts detected this run : "); // We print here how many parts have been detected.
Serial.println(partCounter);
delay(100); // Updating the counter every 100ms also
//////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// Reading the input from the Switch///////////////////////////////////
switchState = digitalRead(switchPin);
if(switchState == LOW && partCounter == 3){
digitalWrite(motorPin,LOW);
delay(3000);
digitalWrite(motorPin,HIGH);
}
if (switchState == HIGH && partCounter == 6){
digitalWrite(motorPin,LOW);
delay(3000);
digitalWrite(motorPin,HIGH);
}
////////////////////////////// Counter for parts going through the conveyor belt /////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
if(tocm <= 5)
{
detection = true;
}
else if (tocm > 10 && detection == true)
{
partCounter++;
detection = false;
digitalWrite(LedDetection, HIGH); // After part detection the LED will flash
delay(100);
digitalWrite(LedDetection, LOW);
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29 / 2;
}
Not really, but the first thing I notice is that partCounter does not seem to be reset to 0 at all. So once your loop goes through its motions once, after that the parts counter will still be 'stuck' at a higher value than you may anticipate.
Other than that, there's a lot to be said about your code, but I'll leave it to others to suggest eliminating reliance on delays and the benefits of using functions or even objects to do some stuff.
Also, where does 'duration' get its value from? You define it at the start of loop, never assign a value to it and then use it to calculate distance. Looks odd.
But there's quite a few things not entirely in order with your code, so I don't think this is going to solve your problem. Like I said, I only took a quick glance and spotted 2 potential issues apart from a pretty fundamental lack of effective structure to your code.
Well, your application seems like one that could benefit from the implementation of a simple state machine. Many wise things have been written on this, but here's a page that covers the essentials in a concise manner and also gives an example: State Machines and Arduino Implementation – Norwegian Creations
That worked it reset the parts back to 0, but the problem was still there. Basically stops the program until I press and hold the switch and count it to 6, then it works normal again
void loop() {
Serial.println( "I'm not stopped" );
After adding the code above does the program stop printing?
You see a program stopping is a different issue than the program not doing the thing you want it to do. So now we got to prove is it a stop or is it a not do?
Please add the serial print, run your program and let us know if it actually stops printing.
Yes it stops printing anything after it counts to 3 parts. Last message i get is parts detected this run : 2. Even though I did 3 and the motor stopped for 3 seconds and turned back on
Serial.print("Distance from conveyor in cm : "); // Here we print out the distance from the conveyor / wall by the sensor.
Serial.println(String(tocm));
delay(100); // Reading sensor every 100ms
Serial.print("Parts detected this run : "); // We print here how many parts have been detected.
Serial.println(partCounter);
delay(100); // Updating the counter every 100ms also
Serial.println(switchState); // Here we print out our switch state 0 being off, and 1 being on.`
Ultimately the problem you're running into is unanticipated problems with multiple if statements. Hence my earlier suggestion to look into state machines. While such an approach doesn't make you immune against this kind of problem, it does in practice make it easier to spot & solve these kinds of issues. Give it a thought.
You should not be running motor power from an Arduino. Please stop trying to run the motor using the Arduino as a power supply.
A breadboard cannot supply the proper current to run a motor. Supplying power to the motor from an Arduino may be the reason why things stop.
What happens when you disconnect the motor from the project, does the printing stop?
After you have made a code change, post the changed code. Don't go back and edit a previous code posting, that is very confusing. Just post the new changed code, Arduino has plenty of storage space to store your code. Why posting your code often on this site is a good way to back up your code.
Welll...in general I'd agree with you, but with this specific motor the problem isn't the breadboard. A breadboard will easily pass even the stall current of this small motor.
I do very much agree with you on not powering any motor from the Arduino. Although that is also probably not the issue here.