Timing to change motor direction

Hello, I'm learning all this stuff and need some help.
I have a 12v drill motor that is controlled with a Uno and a BTS7960 bridge driver, it is wired and works.
What I would like to do is have the motor run forwards for 10sec stop for 2sec and reverse for 10sec, stop for 3min then repeat the loop endlessly.
This is the working code I have with the pins.

int r_en = 2;

int l_en = 3;

int r_pwm = 5;

int l_pwm = 6;

void setup() {

// put your setup code here, to run once:

pinMode(2, OUTPUT);

pinMode(3, OUTPUT);

pinMode(5, OUTPUT);

pinMode(6, OUTPUT);

}

void loop() {

// put your main code here, to run repeatedly:

digitalWrite(r_en, HIGH);

digitalWrite(l_en, HIGH);

analogWrite(r_pwm, 150);

analogWrite(l_pwm, 0);

Something is missing... probably just the close brace.

Try this...

// run forwards for 10sec
// stop for 2sec
// reverse for 10sec,
// stop for 3min
// repeat the loop endlessly.

int r_en = 2;
int l_en = 3;
int r_pwm = 5;
int l_pwm = 6;

int seconds_2   = 2;
int seconds_10  = 10;
int seconds_180 = 180; // three minutes

void setup() {
  pinMode(r_en, OUTPUT);
  pinMode(l_en, OUTPUT);
  pinMode(r_pwm, OUTPUT);
  pinMode(l_pwm, OUTPUT);
}
void loop() {
  forward();
  delay(10 * 1000); // 10 seconds
  stop();
  delay(2 * 1000); // 2 seconds
  reverse();
  delay (10 * 1000);
  stop();
  delay (180 * 1000); // 180 seconds = 3 minutes
}

void stop() {
  analogWrite(r_pwm, 0);
  analogWrite(l_pwm, 0);
  digitalWrite(r_en, LOW); // disable r motor
  digitalWrite(l_en, LOW); // disable l motor
}

void forward() {
  analogWrite(r_pwm, 150);
  analogWrite(l_pwm, 0);
  digitalWrite(r_en, HIGH); // enable motor r
  digitalWrite(l_en, HIGH); // enable motor l
}

void reverse() {
  analogWrite(r_pwm, 0);
  analogWrite(l_pwm, 150);
  digitalWrite(r_en, HIGH); // enable motor r
  digitalWrite(l_en, HIGH); // enable motor l
}
2 Likes

I may be wrong, but due to integer overflow this delay lasts about 49 days. To fix this change 1000 to 1000L or 1000UL.

1 Like

Thank you. I wondered if that would go badly at 180,000 things... but did not check (which ends up as -16608). Sorry for leaving it in.

Thanks for the code, now what if I wanted it to start at 9:00am and stop at 4:30pm every day?

When you search "arduino pet feeder"... you will find many ideas to set alarms to do things. This example only shows the time and date, so you will want to write code to decide "if the time of day is nine or half-past four, do things."

The code seems to be very random, the 10sec on, 2sec off, 10sec on works but the 180 is very random, I have tested with the U the UL as well as without.
The 180 delays anywhere from 50 sec to 100 sec.

Post your latest code.

Ugly, but, you could do six loops of (30 * 1000) (stays below short INT maximum)

// run forwards for 10sec
// stop for 2sec
// reverse for 10sec,
// stop for 3min
// repeat the loop endlessly.

int r_en = 2;
int l_en = 3;
int r_pwm = 5;
int l_pwm = 6;

int seconds_2 = 2;
int seconds_10 = 10;
int seconds_180 = 180; // three minutes

void setup() {
pinMode(r_en, OUTPUT);
pinMode(l_en, OUTPUT);
pinMode(r_pwm, OUTPUT);
pinMode(l_pwm, OUTPUT);
}
void loop() {
forward();
delay(10 * 1000); // 10 seconds
stop();
delay(2 * 1000); // 2 seconds
reverse();
delay (10 * 1000);
stop();
delay (180 * 1000); // 180 seconds = 3 minutes
}

void stop() {
analogWrite(r_pwm, 0);
analogWrite(l_pwm, 0);
digitalWrite(r_en, LOW); // disable r motor
digitalWrite(l_en, LOW); // disable l motor
}

void forward() {
analogWrite(r_pwm, 150);
analogWrite(l_pwm, 0);
digitalWrite(r_en, HIGH); // enable motor r
digitalWrite(l_en, HIGH); // enable motor l
}

void reverse() {
analogWrite(r_pwm, 0);
analogWrite(l_pwm, 150);
digitalWrite(r_en, HIGH); // enable motor r
digitalWrite(l_en, HIGH); // enable motor l
}Use code tags to format code for the forum

Change that to:

unsigned long seconds_180 = 180; // three minutes

And:
delay (180 * 1000); // 180 seconds = 3 minutes
To;

delay (180UL * 1000); // 180 seconds = 3 minutes

And try it.

2 Likes

No didn't work, still random as random can be.

The 180*1000 still does something you do not expect:

void setup() {
  Serial.begin(115200);
  Serial.println(180*1000); // -16608
  Serial.println((unsigned long)(180*1000)); // 4294950688
  Serial.println(180*1000UL); // 180000
}
void loop() {}

gives:

-16608
4294950688
180000

int - Arduino Reference says:

When signed variables are made to exceed their maximum or minimum capacity they overflow . The result of an overflow is unpredictable so this should be avoided. A typical symptom of an overflow is the variable "rolling over" from its maximum capacity to its minimum or vice versa, but this is not always the case.

Try an explicit 180000 or 180*1000UL.

// run forwards for 10sec
// stop for 2sec
// reverse for 10sec,
// stop for 3min
// repeat the loop endlessly.

int r_en = 2;
int l_en = 3;
int r_pwm = 5;
int l_pwm = 6;

int seconds_2 = 2;
int seconds_10 = 10;
int seconds_180 = 180; // three minutes

void setup() {
  pinMode(r_en, OUTPUT);
  pinMode(l_en, OUTPUT);
  pinMode(r_pwm, OUTPUT);
  pinMode(l_pwm, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  forward();
  Serial.print("F(delaying:");Serial.print(10*1000);Serial.print(")");
  delay(10 * 1000); // 10 seconds
  stop();
  Serial.print("S1(delaying:");Serial.print(2*1000);Serial.print(")");
  delay(2 * 1000); // 2 seconds
  reverse();
  Serial.print("R(delaying:");Serial.print(20*1000);Serial.print(")");
  delay (10 * 1000);
  stop();
  Serial.print("S2(delaying:");Serial.print(180*1000);Serial.print(")");
  delay (180 * 1000); // 180 seconds = 3 minutes
}

void stop() {
  analogWrite(r_pwm, 0);
  analogWrite(l_pwm, 0);
  digitalWrite(r_en, LOW); // disable r motor
  digitalWrite(l_en, LOW); // disable l motor
}

void forward() {
  analogWrite(r_pwm, 150);
  analogWrite(l_pwm, 0);
  digitalWrite(r_en, HIGH); // enable motor r
  digitalWrite(l_en, HIGH); // enable motor l
}

void reverse() {
  analogWrite(r_pwm, 0);
  analogWrite(l_pwm, 150);
  digitalWrite(r_en, HIGH); // enable motor r
  digitalWrite(l_en, HIGH); // enable motor l
}

prints:

F(delaying:10000)S1(delaying:2000)R(delaying:20000)S2(delaying:-16608)

I am new to this coding but I find it crazy that a simple code like this is so hard.
In the following code the delay (3 * 60 * 1000); is anywhere from 45sec to 1.5 minutes. It should be 3 min.

// run forwards for 10sec
// stop for 2sec
// reverse for 10sec,
// stop for 3min
// repeat the loop endlessly.

int r_en = 2;
int l_en = 3;
int r_pwm = 5;
int l_pwm = 6;



void setup() {
pinMode(r_en, OUTPUT);
pinMode(l_en, OUTPUT);
pinMode(r_pwm, OUTPUT);
pinMode(l_pwm, OUTPUT);
}
void loop() {
forward();
delay(10000);
stop();
delay(2000); 
reverse();
delay (10000);
stop();
delay (3 * 60 * 1000); 
}

void stop() {
analogWrite(r_pwm, 0);
analogWrite(l_pwm, 0);
digitalWrite(r_en, LOW); // disable r motor
digitalWrite(l_en, LOW); // disable l motor
}

void forward() {
analogWrite(r_pwm, 150);
analogWrite(l_pwm, 0);
digitalWrite(r_en, HIGH); // enable motor r
digitalWrite(l_en, HIGH); // enable motor l
}

void reverse() {
analogWrite(r_pwm, 0);
analogWrite(l_pwm, 150);
digitalWrite(r_en, HIGH); // enable motor r
digitalWrite(l_en, HIGH); // enable motor l
}

The tricky part is that default integer math can overflow strangely, so you need to be careful with it.

One easy way to be careful is to express that you want it to do math with large integers that don't wrap around into negative numbers:

 delay( 30UL * 60 * 1000);

or you can do the math yourself:

 delay(1800000);

Is it possible to control the number of rotations in a 12v Drill motor with coding?

Yes, it is possible to control the number of rotations if you have a way of detecting when the drill motor has made a rotation. Some sort of encoder disc and reader will be required.

What is your drill motor turning, and how is it connected? With inertia in the system, can the motor stop turning exactly when you want it without a brake?

So the timing is so random on this that I need to change something.
This motor is turning a tilt bed on a 1940's X-ray machine but with the random timing it wants to run the bed off the rails. I would like to add limit switches so that when the bed goes to far one way it will stop and reverse. Or I guess I could run it till it hits one limit reverses till it hit the next one and stops for 3 min.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.