Controlling the duration of motors. How do I do it?

Hello all,

I'm currently working on a project where I use two distance sensors to create an autonomous obstacle avoidance robot that drives two motors. I am using a motor driver module and I am controlling the speed of each motor through a PWM signal with a value between 0 and 255.


I am trying to write a case where if the distance of both sensors is below a threshold, the robot turns left (this is to avoid colliding with a wall). However, no matter how many times I have tried I cannot manage to keep the robot turning left for a select duration.

Does anyone have any ideas of how to control how long each motor runs?

Below is my code for that case:

 if (distanceL < THRESHOLD_DISTANCE && distanceR < THRESHOLD_DISTANCE){
 
  rightMotorSpeed = 200;
 
  leftMotorSpeed = 0;
 
  analogWrite(PWMR, 200);
 
  analogWrite(PWML, 0);
 
  //Add something here to prolong the duration of the driving motors?
 
}

Hello! The easiest way for this is to use the delay(); function. The value you put inside the brackets is in milliseconds this means that delay(1000); will let the motor spin for 1 second delay(2000); for 2 seconds. If you have any other questions let me know

Not being totaly sure if it is neede but to be safe I would write:

if ((distanceL < THRESHOLD_DISTANCE) && (distanceR < THRESHOLD_DISTANCE){

Always supply the entire code. I already think of possible mistakes outside the snippet You sent.

nikolas550:
Hello! The easiest way for this is to use the delay(); function. The value you put inside the brackets is in milliseconds this means that delay(1000); will let the motor spin for 1 second delay(2000); for 2 seconds. If you have any other questions let me know

Delay() in a real time application? Come on!

nikolas550:
Hello! The easiest way for this is to use the delay(); function. The value you put inside the brackets is in milliseconds this means that delay(1000); will let the motor spin for 1 second delay(2000); for 2 seconds. If you have any other questions let me know

Ya know what, that actually works! I did try a delay function before but I only changed it marginally (I tried delay(200) and then delay(500)). I suppose the small adjustments are not enough to notice a change lol.

Thanks for your help!

1 Like

Condition the wall sensing through a bit of state change code and use the state change to set a boolean variable true when a wall is present. Use the boolean to run a timer to drive the motors for enough milliseconds to make a sufficient turn to the left. When the timer runs out reset the boolean to false.

If you're going to use delay(), understand that the processor does NOTHING else until the delay is finished.

DELAY is fine to check the idea, but having seen it CAN work, look at this example Blink without Delay to see a better way.

Be aware your code should then not use Delay ANYWHERE or the millis() strtaegy will be compromised.

johnerrington:
Be aware your code should then not use Delay ANYWHERE.

I do wish people would stop saying that. There are many cases where delay() is entirely appropriate and using any other technique just adds more code and makes it more difficult to understand what is going on.

It is necessary to understand what delay() does but provided you do understand that then you should feel free to use it wherever it is appropriate. Getting a simple device to run motors for a fixed time and only then continue processing is one such case.

Steve

Yes perhaps I was a bit dictatorial; of course many programs work fine with delay(); however it needs to be treated with some caution as it prevents the program from responding to changes - such as in this case if the obstacle was removed.

Similarly (as I recently discovered) a state machine using millis() timing breaks down if a delay or other blocking code (eg a wait for switch closure) is introduced.

Sorry I do get a bit argumentative about this because so many people round here insist that delay() is the very devil and any program with it in is guaranteed to be useless.

The reality is that you should to know both timing methods and when they are appropriate. It's interesting that people aren't so ready to condemn for loops even though they're also blocking code. Perhaps it's because it's a real pain coding the equivalent of a for loop using millis().

Steve

Not wanting to hijack the thread but this may interest the OP;

Delay() blocks any other process from executing (except for interrupts)

but using the "blink without delay" scatters timing tests throughout your code & gets messy.

There IS another way; the arduino chips have timers that can be used for activating bits of code.

This library (my next bit of experimentation is to try it out) seems to make easy work of some time-related taks and a LOT less messy than the millis() strategy.