problem Stopping Dc motors of wheeled robot

Hi ,

I'm working on a closed loop code , and in a certain part of my code i need to stop my Dc motor after only 0.25 revolution
by calling a function to do that so i decided to use the rotary encoder but the problem is all the codes i found is for tracking and monitoring and the function i'm trying to edit seems very poor and totally wrong ! .

1 - i'm asking if there is any way to stop the motor after this 0.25 revolution only by calling a function like that i tried to edit ?
2 - can i use the delay instead of the rotary encoder, as after calculations i will need 125 ms only and after that the motor must stop?
3 - should i put an encoder for the right motor and another one for the left ? or using one encoder on anyone of them will do what i need ?

// call this function to perform 0.25 Motor revolution == 10 CM 
 
long positionLeft  = -999;      // the left encoder initial value 
long positionRight = -999;      // the right encoder initial value

void Encoder_Function(int pulsecounts )
 {
  long newLeft, newRight;
  newLeft = knobLeft.read();
  newRight = knobRight.read();
  if (pulsecounts == 20)
   {
 
    MotorControl(1, 1);
   delay (125);
   MotorControl(0, 0);
    
   Serial.print(" 20 Counts Done " );  

  }
   

}

An object in motion tends to remain in motion. There is no way to turn a dc motor only 1/4 revolution unless it is a closed loop servo motor. An RC servo is an example of a closed loop dc servo. Having an encoder will tell you where the motor is but without a closed loop servo system you would have no way of controlling the rotation. You can turn it on or turn it off, but that doesn't guarantee it will stop rotating when you turn it off unless the dampening (load) is so great that it stops instantly when the power is removed.
If that is the case , then you still have to control the speed. If you reduce the speed to a very slow rpm just prior to removing power AND sense position with an encoder, it may do what you want, but what you describe is the kind of application a servo motor was designed for. If it doesn't stop EXACTLY where you want, were you planning on reversing direction to the target position ?

Point being, it is pointless to work with closed loop code without closed loop hardware. That means a PID servo control system, in addition to the encoder. The encoder without the PID is NOT a closed loop system, closed loop code or not.

And ditch using delay(). Check out Blink Without Delay in the examples of the Arduino IDE.

An RC servo is an example of a closed loop dc servo.

Hmmmmm..... That's debatable.

Might be closed loop inside, but the important loop- the one back to the human- is not usually closed. Most servos don't have feedback to the world outside the servo, so unless you have something like this you don't actually know that the servo got to where you sent it.

Discuss. I'm off to work.... 0520 and a 0600 start gets me to work while the roads are empty.

I was actually considering mentioning that servo since it has come up in other posts (usually at your hand)....

Having an encoder will tell you where the motor is but without a closed loop servo system you would have no way of controlling the rotation.

is that means the encoder is for monitoring only , and i can't take a decision depends on the motor position it reads if i'm using dc motor ?

@polymorph
I've just checked the example, but in the description ..

Returns the number of milliseconds since the Arduino board began running the current program. This number will overflow (go back to zero), after approximately 50 days.

i can't determine if that means the function would work since the arduino board began or since i called the function includes it ?
i think u have a problem using delay() , can u tell me why :smiley: ?

  • The encoder is for monitoring yes, and you then make a decision based on what you read. But inertia means nothing is instant: it's too late to stop the motor if it already got where you want. That's where PID control comes in, maybe with just the P= proportional part implemented. So you speed/slow the motor proportionally compared to where it is. So as you approach the stopping point, you slow down, just like when you park your car. It's too late to hit the brake once you hit the wall. Idea being that when you get to 0 speed, you're in the right place.

  • millis() starts when the sketch starts.

  • The big problem with delay() is that it stops everything else. So if you are supposed (say) to read a sensor while you have a delay() going to speed up a motor, you can't.

Amen.

Yes. Everything (nearly) else stops during the delay() function. There are some ways around it, interrupts I think, but it is much simpler using something like Blink Without Delay.

I've actually put the link to a discussion of using millis() or micros() to do multiple things at once in my signature block. Here it is:

http://forum.arduino.cc/index.php?topic=223286.0

When done correctly, as shown, it won't matter when it rolls over unless you've set the time between events longer than the rollover time.

Hi All,
Not sure if this will help! But I have just finnished a bit of code and breadboard tested it. I have 2 bots one being a Pololu Zumo (Tracked) the other using the same Pololu wheels, but with tyres on, the wheels have 12 teeth/notches! I am using a Vishay TCRT1000 this is a IR Led and photo-trans set side by side, this detects and counts the teeth, the idea being I say turn left until count =24 that's 2 revs of the wheel, then it stops or does something else.

I also did a spreadsheet to calc, circumference, turning circle, pulse count, etc.

Here's my code:

Hope it helps.

Regrds

Mel.

/* Simple Counter  MS12/10/2014
 * This is a simple counter that takes a digital input
 */
int ledPin = 13; // choose the pin for the LED
int InPin =2; // choose the input pin  
int val = 0; // variable for reading the pin status
int counter = 0;
int currentState = 0;
int previousState = 0;

void setup()
{
	pinMode(ledPin, OUTPUT); // declare LED as output
	pinMode(InPin, INPUT); // declare InputPin as input
	Serial.begin(9600);
}
void loop()
{
	while(counter<36) // This will be X from calling function.
	{
		val = digitalRead(InPin); // read input value
		if (val == HIGH) // check if the input is HIGH  
		{
			digitalWrite(ledPin, HIGH); // turn LED on
			currentState = 1;
		}
		else
		{
			digitalWrite(ledPin, LOW); // turn LED off
			currentState = 0;
		}
		if(currentState != previousState)
		{
			if(currentState == 1)
			{
				counter = counter + 1;
				Serial.println(counter);
			}
		}
		previousState = currentState;
	}
	end();
}
void end()
{
	digitalWrite(ledPin,LOW);
	delay(5000);
}