Go Down

Topic: Alternative to delay in loops? (Read 148 times) previous topic - next topic

JordanZaf

Hi all,

I have just ordered my first Arduino and have been playing around with simulators before it arrives. I have tried to make a circuit that pulses a motor depending on the input from a potentiometer (which works) ,  and continuously rotates the motor if a button is being pressed.


The issue i'm having is, when i set a delay to pulse the motor, the delay can't be overrun by the button being pressed down. Hopefully, that all makes sense.

Here is a link to simulation if you can help:   https://www.tinkercad.com/things/kRTUJ2yMAF6-epic/editel?sharecode=VTWz5YHhw_tZ4gUGxDJq8q2QF9Hi5WGvCerULrVS1i8=


Code for Reference,
Code: [Select]
/*
 Input Pullup Serial

 This example demonstrates the use of pinMode(INPUT_PULLUP). It reads a
 digital input on pin 2 and prints the results to the serial monitor.
 
 OPEN THE SERIAL MONITOR TO SEE THE OUTPUT FROM THE INPUT PIN >>

 The circuit:
 * Momentary switch attached from pin 2 to ground
 * Built-in LED on pin 13

 Unlike pinMode(INPUT), there is no pull-down resistor necessary. An internal
 20K-ohm resistor is pulled to 5V. This configuration causes the input to
 read HIGH when the switch is open, and LOW when it is closed.

 created 14 March 2012
 by Scott Fitzgerald

 http://www.arduino.cc/en/Tutorial/InputPullupSerial

 This example code is in the public domain

 */

void setup() {
  //start serial connection
  Serial.begin(9600);
  //configure pin2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  pinMode(A0, INPUT);
  pinMode(13, OUTPUT);
}

void loop() {
  //read the pushbutton value into a variable
  int fishON = digitalRead(2);
  int pulse = 0;
 
  //print out the value of the pushbutton
  //Serial.println(pulse);
  pulse = analogRead(A0);
 
  // Keep in mind the pullup means the pushbutton's
  // logic is inverted. It goes HIGH when it's open,
  // and LOW when it's pressed. Turn on pin 13 when the
  // button's pressed, and off when it's not:
  if(fishON == HIGH) {
    if (pulse <= 1000) {
      digitalWrite(13, HIGH);
      delay(2000);
      digitalWrite(13, LOW);
      delay(pulse * 20);
    }   
  else {
    digitalWrite(13, LOW);
  }
  }
   
  if (fishON == HIGH) {
    digitalWrite(13, LOW);
  } else {
    digitalWrite(13, HIGH);
  }
}


Kind Regards,
Jordan

vaj4088

Near the top of the "Introductory Tutorials" forum is a post "Using millis() for timing. A beginners guide" that you should learn.  Use micros() instead of millis() if you need shorter time intervals. delay(...) is convenient but one of its drawbacks is what you discovered.  millis() is slightly less convenient but MUCH better in the long run.  Somewhere there is an example BWOD Blink Without Delay that also demonstrates the technique.
Good Luck!

Power_Broker

1.) You need to wire the DC motor differently, google "control dc motor arduino" and look at some of the schematics
2.) You'll have more luck using analogWrite() instead of timing pulses with delay()
"The desire that guides me in all I do is the desire to harness the forces of nature to the service of mankind."
   - Nikola Tesla

Wardenoma

#3
Jan 16, 2020, 06:04 am Last Edit: Jan 16, 2020, 06:05 am by Wardenoma
As mentioned, take a look at "Blink Without Delay" example for non-blocking delay. You may also want to use "interrupt" CHANGE to handle push button logic.

JordanZaf

Thank you everyone for the help. I  will be sure to look into it all :)

Robin2

The demo Several Things at a Time is an extended example of BWoD and illustrates the use of millis() to manage timing without blocking. It may help with understanding the technique.

Have a look at Using millis() for timing. A beginners guide if you need more explanation.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

evanmars

As mentioned, take a look at "Blink Without Delay" example for non-blocking delay. You may also want to use "interrupt" CHANGE to handle push button logic.
There is no reason to use an interrupt to detect something that takes as long as a button push.

vaj4088

Interrupts are unnecessary for something as slow as a button pushed by a human, and Interrupt Service Routines can be difficult for a beginner to write and debug.

While I agree that interrupts are a way around the issues with delay(...), using millis() and avoiding interrupts would be even better.


UKHeliBob

Quote
I agree that interrupts are a way around the issues with delay(...),
Are they ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

vaj4088

Are they ?

Well, interrupts would catch a button press that might otherwise get missed with delay(...).  However, some processing of the button press might be delayed.


Go Up