0

In my recent project, I'm working with the motor. I have to drive the motor for the specific time like for 2 minutes, 3 minutes, 4 minutes and 5 minutes. I already created functions for that. And motor drive based on readings taken from the sensor.

My code is below:

#define PIN_OUTPUT 6

const int kPinIN1 = 4;
const int kPinIN2 = 5;

void setup()
{
  Serial.begin(9600);

  pinMode(kPinIN1, OUTPUT);
  pinMode(kPinIN2, OUTPUT);
}

void loop() 
{
  Serial.println(analogRead(A0));

  if(analogRead(A0) > 100 && analogRead(A0) < 200)
  {
    motorDriveFor2Min();
  }
  else if(analogRead(A0) > 200 && analogRead(A0) < 300)
  {
    motorDriveFor3Min();
  }
  else if(analogRead(A0) > 300 && analogRead(A0) < 400)
  {
    motorDriveFor4Min();
  }
  else if(analogRead(A0) > 400 && analogRead(A0) < 500)
  {
    motorDriveFor5Min();
  }      
}

void motorDriveFor2Min()
{
  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);            

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(64000);  
}


void motorDriveFor3Min()
{
  motorDriveFor2Min();

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(32000);  
}

void motorDriveFor4Min()
{
  motorDriveFor3Min();

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(46000);   
}

void motorDriveFor5Min()
{
  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(120000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, HIGH);
  digitalWrite(kPinIN2, LOW);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(7000);

  digitalWrite(kPinIN1, LOW);
  digitalWrite(kPinIN2, HIGH);

  analogWrite(PIN_OUTPUT, 255);

  verboseDelay(120000);
}

void verboseDelay(unsigned long ms)
{
  unsigned long now = millis();
  unsigned long start = now;

  do
  {
    now = millis();
  }
  while (now - start < ms);
}

Here, I have four functions named motorDriveFor2Min(), motorDriveFor3Min(), motorDriveFor4Min() and motorDriveFor5Min() for my specific time means for 2 minutes, 3 minutes, 4 minutes and 5 minutes respectively.

So, suppose If I want to drive motor for 4 min then I have to call function motorDriveFor4Min() and for that, I have to set my reading between 300 & 400. But I can't able to do that because when my reading reaches at 100 then it starts executing another function means motorDriveFor2Min() and then continuously run that functionality. During that time I try to change the reading but nothing happens. After restating Arduino it run according to the reading.

So, I thought maybe delay() function block everything. So I replace inbuilt delay function with custom delay function. But that can't solve my problem. Then I google it out and I found out that analogRead may cause this problem. Any suggestion for this.

  • 1
    That is clearly a design fault. What does your analog reading represent? Are there discrete values for stopping the motor? Like <100 and >500? You could simply keep running until the reading reaches those. – mystery Mar 29 '18 at 11:58
  • In essence, all your program does is run the motor all the time. Because as soon as it has run to motor for X minutes, it immediately goes through your code again, and run for Y minutes. I think you benefit from adding a button. So that only when you press the button, the motor will run for X minutes, where X is dependent on the position of your potentiometer. – Gerben Mar 29 '18 at 14:43
  • If you want to determine the length of time to drive the motor before the motor starts (as it sounds like you want to) what you probably need is a "go" button. If you can alter your goal and instead keep reading the analog to make an ongoing decision if you want to keep driving it, that would probably be wiser - the time taken to do even a blocking analog read is short in motor terms. Keep in mind that your system should have a non-software "emergency stop" and that you really shouldn't be using an Arduino to control anything where mis-operation would be hazardous. – Chris Stratton Mar 29 '18 at 15:40
  • In effect, right now, you have the reset button or power switch functioning as a "go" button that causes it to evaluate the (hopefully desired) analog input value you have set. – Chris Stratton Mar 29 '18 at 15:43
  • Also you should call analog read only once for your printout and decision tree and save the result in a variable. Otherwise every check may see a different value and you could fall through satisfying none. And change some of your comparisons to include the equals case, so that the boundary numbers like 200, 300 etc don't fall through satisfying nothing. – Chris Stratton Mar 29 '18 at 15:45
3

It's not analogRead. It's not (just) delay. It's the whole method of your program.

The way it's written you can do nothing else while driving a motor for X minutes.

You need to rethink your whole program so that it's not "run for X minutes" each time, but instead "Run the motor until the time is up" and constantly re-evaluate what the time should be.

That means:

  • No "run for X" functions.
  • No delay() functions (of any form - yours is as bad as the normal one).
  • A state machine to determine what should be happening when.
  • Constantly referencing both millis() and analogRead() to determine what state the state machine should be in or progress to and when.
| improve this answer | |
  • Actually, that's not quite the problem. They want to do nothing but drive the motor for several minutes. The problem is that while they are adjusting the pot (or before they get a chance to) it takes off on an undesired reading. It's possible the task could be re-organized to drive the motor for some period of time, and then read the analog input to decide if driving should continue - and that might be smarter, but it's not the goal that was stated. – Chris Stratton Mar 29 '18 at 15:38
  • 1
    @ChrisStratton For something like this there are many many ways of achieving the same thing. None are wrong. Either way, the underlying methodology of their existing program prevents any proper control and they need to re-think how to better do what they want. – Majenko Mar 29 '18 at 15:45
  • @Majenko Thank you for clearing my misunderstanding about the delay() and analogRead(). I just find out a better way for my logic. – Hasan Apr 2 '18 at 12:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.