Help Reqd. Delay Function

++ WOULD ANYONE BE INTERESTED IN QUOTING TO COMPLETE THIS PROJECT PLEASE? +++

Hi, hopefully I can get some help with this please. I'm rather new to Arduino and was generously provided with some code to control a stepper motor delay (and output that delay in seconds via an LCD display) for my project.

The code takes the value of a 1kohm potentiometer and uses that to set the delay to 1 whole second up to a maximum of 10 seconds.

However, ideally I would like the delay to be set in half seconds to give me a little more control. Is there a way that this code can be altered to achieve the same result, ie. a 1k potentiometer to control the delay in half seconds?

Many thanks in advance, Mick.

/* 
 Stepper Motor Control
 
 This program drives a unipolar or bipolar stepper motor.  

 Turning the rheostat changes delay timing
 
 The motor controller is attached to digital pins 8 + 9 of the Arduino.
 Rheostat analogue pin 2
 
 */

 
 #include <Stepper.h>                            // includes the stepper motor binaries
 const int stepsPerRevolution = 200;             // change this to fit the number of steps per revolution for your motor
 int val = 0;
 Stepper myStepper(stepsPerRevolution, 8,9);     // initialize the stepper library on pins 8 through 9
 

void setup() {
		myStepper.setSpeed(200);	// set the speed at 60 rpm:
		Serial.begin(9600);		// initialize the serial port:  
	    }

void loop() {
               Serial.println("Running");
               val = analogRead(2);              // read potentiometer data from analogue pin 2
               int pause = val*10;               // set the value of the pause variable by mulitiplying the pot value x 10 to increase time range
               Serial.println(pause/1000);       // 1000 is 1 second

                          myStepper.step(1280);
                          delay(pause);
                          
                          
            }

The analogue value is up to 1000 (round figures). To get .5 second increments you need 20 increments.

You require analogue / 50 to get the number of half seconds. (1000/50 = 20 half seconds).

When you have the number of increments you can use that to set your delay.

I would prefer to use a 10k pot as it reduces the current draw from the supply (just a little but it all counts).

Weedpharma

Would you rather have smooth control from 1 second to 10 seconds?

try this instead

int minDelay = 1000;
int maxDelay = 10000;

void loop() {
               Serial.println("Running");
               val = analogRead(2);              // read potentiometer data from analogue pin 2

               int pause = map(val, 0, 1023, minDelay, maxDelay);

               Serial.println(pause);       // 1000 is 1 second

               myStepper.step(1280);
                delay(pause);
                    
                         
            }

the map function 'stretches' a range of values.. and it only returns integer values.
The usage I showed remaps 'val' from being a value between 0 and 1023 (the valid range returned by analogRead, a 10 bit number) to the range defined by minDelay and maxDelay..
So when the pot is set to 0, your delay will be 1000, and when it's all the way, it'll be 10,000

Probably worth pointing out to OP that this approach is what's known as "blocking" and while it might not matter now it probably will one day.

Blocking means that while your code is sitting in delay(pause), the program is stopped and so nothing else can happen. Let's say (just for argument) that other things happen in the code like sensors being read and as a result of those reads, other actuators move. Using delay() means those sensors will not read and actuators not act, for the up to 10 seconds where your program is essentially stalled.

There are easy solutions: I won't clutter the thread with going into the how of that now, but bear it in mind....

Thank you all for your input, I'll try the smooth approach, as suggested, first.

Re: blocking - I have noticed that until the motor completes it's movement that the new value is not displayed on the LCD screen. Is this why? Is it caused by the 'blocking'.

A more immediate feedback would be preferable but, alas, it's easy beyond my programming abilities at the moment.

Thanks again, Mick.

Hmm, I posted the incorrect code at the top of this thread. The correct code is below:

/*-----( Import needed libraries )-----*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>                  // includes the LCD display binaries
#include <Stepper.h>                            // includes the stepper motor binaries

/*-----( Declare objects )-----*/

// LCD display
      // set the LCD address to 0x27 for a 16 chars 2 line display
      // Set the pins on the I2C chip used for LCD connections:
      //                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
      LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);       // Set the LCD I2C address to 0x27

// Stepper motor
      const int stepsPerRevolution = 200;                                 // change this to fit the number of steps per revolution for your motor
      Stepper myStepper(stepsPerRevolution, 8,9);                         // initialize the stepper library on pins 8 through 9

/*-----( End objects )-----*/



/*-----( Declare Variables )-----*/

    int val = 0;

/*-----( End Variables )-----*/



/*----( SETUP: RUNS ONCE )----*/
      void setup()
                    {
                myStepper.setSpeed(200);  // set the speed at 60 rpm:
                Serial.begin(9600);       // initialize the serial port:
                    
                      lcd.begin(16,2);          // initialize the lcd for 16 chars 2 lines and turn on backlight 
                      
                      // NOTE: Cursor Position: (CHAR, LINE) start at 0  
                      lcd.setCursor(4,0);      //Start at character 4 on line 0
                      lcd.print("Booting");
                      
                      lcd.setCursor(2,1);      //Start at character 4 on line 0
                      lcd.print("Please  Wait");
                      
                      delay(3000);
                      
                    
                    
                    }
/*--(end setup )---*/

/*----( LOOP: RUNS CONSTANTLY )----*/

      void loop()   
                    {
                     Serial.println("Running");
                     
                     val = analogRead(2);              // read potenttiometer data from analogue pin 2
                     Serial.println(val);              // print the resistor value to the serial window
                     
                     int pause = val*10;               // set the value of the pause variable by mulitiplying the pot value x 10 to increase time range
                     Serial.println(pause/1000);       // 1000 is 1 second
      
                     
                     lcd.clear();                      // clear lcd screen
                     
                     lcd.setCursor(1,0);               // set position of text displayed on the LCD pannel (location is cursor position, line) on top line
                     lcd.print("Time in flame:");      // top line text 
                     
                     lcd.setCursor(2,1);               // set position of variable text displayed on the LCD pannel bottom line
                     lcd.print(pause/1000);            // delay in seconds 
                     
                     lcd.setCursor(6,1);               // set position of text displayed on the LCD pannel bottom line after the variable
                     lcd.print("seconds");             // text after the delay variable on the bottom line
      
                     myStepper.step(1280);             // perform one step with motor
                     delay(pause);                     // pause motor for x number of seconds (from variable resistor read value)
                    
                    
                  }
                  
/* --(end main loop )-- */

/* ( THE END ) */

So.. if I wanted to achieve a smooth control I would use:

LCD connections:
GND - Ground
VCC - +5v
SDA - Analogue pin 4
SCL - Analogue pin 5

/*-----( Import needed libraries )-----*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>                  // includes the LCD display binaries
#include <Stepper.h>                            // includes the stepper motor binaries

/*-----( Declare objects )-----*/

// LCD display
      // set the LCD address to 0x27 for a 16 chars 2 line display
      // Set the pins on the I2C chip used for LCD connections:
      //                    addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
      LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);       // Set the LCD I2C address to 0x27

// Stepper motor
      const int stepsPerRevolution = 200;                                 // change this to fit the number of steps per revolution for your motor
      Stepper myStepper(stepsPerRevolution, 8,9);                         // initialize the stepper library on pins 8 through 9

/*-----( End objects )-----*/



/*-----( Declare Variables )-----*/

    int val = 0;

/*-----( End Variables )-----*/



/*----( SETUP: RUNS ONCE )----*/
      void setup()
                    {
        	      myStepper.setSpeed(200);	// set the speed at 60 rpm:
        	      Serial.begin(9600);       // initialize the serial port:
                    
                      lcd.begin(16,2);          // initialize the lcd for 16 chars 2 lines and turn on backlight 
                      
                      // NOTE: Cursor Position: (CHAR, LINE) start at 0  
                      lcd.setCursor(4,0);      //Start at character 4 on line 0
                      lcd.print("Booting");
                      
                      lcd.setCursor(2,1);      //Start at character 4 on line 0
                      lcd.print("Please  Wait");
                      
                      delay(3000);
                      
                    
                    
                    }
/*--(end setup )---*/

/*----( LOOP: RUNS CONSTANTLY )----*/
			int minDelay = 1000;
			int maxDelay = 10000;
      void loop()   
                    {
                     Serial.println("Running");
                     
                     val = analogRead(2);              // read potenttiometer data from analogue pin 2
                     Serial.println(val);              // print the resistor value to the serial window
                     
                     int pause = map(val, 0, 1023, minDelay, maxDelay);	// set the value of the pause variable

                     Serial.println(pause/1000);       // 1000 is 1 second
      
                     
                     lcd.clear();                      // clear lcd screen
                     
                     lcd.setCursor(1,0);               // set position of text displayed on the LCD pannel (location is cursor position, line) on top line
                     lcd.print("Time in flame:");      // top line text 
                     
                     lcd.setCursor(2,1);               // set position of variable text displayed on the LCD pannel bottom line
                     lcd.print(pause/1000);            // delay in seconds 
                     
                     lcd.setCursor(6,1);               // set position of text displayed on the LCD pannel bottom line after the variable
                     lcd.print("seconds");             // text after the delay variable on the bottom line
      
                     myStepper.step(1280);             // perform one step with motor
                     delay(pause);                     // pause motor for x number of seconds (from variable resistor read value)
                    
                    
                  }
                  
/* --(end main loop )-- */

/* ( THE END ) */

What would I need to change to create the half second steps as I originally wanted?

Mick-Miller:
Is it caused by the 'blocking'.

A more immediate feedback would be preferable but, alas, it's easy beyond my programming abilities at the moment.

Probably but I haven't looked closely.

Have a look at the BlinkWithOutDelay approach.... yep it takes a bit of getting one's mind around, but it's not as my son once put it, rocket surgery.

Have a look at the two examples in this Simple Stepper Code. The first example uses delay() and blocks because of that. The second example uses millis() and micros() to manage timing and does not block.

Only use delay() in simple test programs.

If you want to use the Stepper library you need to do things one step at a time if it is not to block. The AccelStepper library is much better and can operate without blocking.

...R
Stepper Motor Basics

Wow, lots there to read and digest. However, I wonder, as I need to get this project working as soon as possible, whether there is anywhere, anyhow I can hire someone to alter the code I already have to achieve what I need?

I've almost have my hands full designing the other parts of the project that need laser cutting and assembling.

as I need to get this project working as soon as possible, whether there is anywhere, anyhow I can hire someone to alter the code I already have to achieve what I need?

The Gigs and Collaborations section of the forum may be what you are looking for.

If you click the "Report to moderator" link on your original post you can ask a moderator to move this thread.

Thanks, well here we are. Can anyone help for a donation to charity, beer tokens, kindness of their heart?

I have a very rudimentary, but functioning bit of code to rotate a stepper motor in 36 degree increments and pause for a period of time that is set using a 1k potentiometer. Apparently the delay() function isn't the best choice and ideally I would like to have at least half second steps, or even quarter second pauses for more refinement.

It's almost there but just needs a little polish to get the right result. Would anyone be willing to help? Unfortunately I would like to get this project up and running as soon as possible.

95% done, 95% to go.

Yup, that about sums it up :slight_smile: hopefully someone will pm me with a cost to complete this.