Setting steppermotor to an exact speed (28BYJ-48)

Hi,
I trying to use my Arduino to get my 28BYJ-48 steppermotor to run at an exact speed. I thought i had written a code that does just that, but when i try to make it run at exactly 1rpm it keeps turning a bit too fast. Can you help me figure out what I'm doing wrong? I would like to keep the code as simple as possible since i have no programming experience and kind of understand this code.
Thanks!
Douwey

/*
Code om een BYJ48 stappenmotor per tijdseenheid een andere snelheid te laten draaien
*/

//sluit de stappenmotor als voglt aan
#define IN1 2
#define IN2 3
#define IN3 4
#define IN4 5
//beginwaarde voor de array
int i=0;
//beginwaarde voor verschilbepaling voor intervalberekening
long previousMillis = 0;
//bepaald interval waarmee de snelheid veranderd. LET OP! interval moet groter zijn dan 8x de hoogste waarde in lut!
int interval = 60000;
//array met delays tussen stappen
float lut[] = {
14.72,
14.72,
14.72,
14.72
};

void setup()
{
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
}

void loop()
{
// bepaald de tijd dat de arduino aanstaat in miliseconden
unsigned long currentMillis = millis();
//check of er meer dan de intervaltijd is verstreken
if(currentMillis - previousMillis > interval)
{
//zet de tijd vanwaar gemeten wordt weer op nul
previousMillis = currentMillis;
//gaat één waarde vErder in lut
i++;
}

//maakt de waarde in lut de delay tussen de stappen
float value = lut[i%3];

//beschrijft de stappen en de delay ertussen
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
delay(value);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
delay(value);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
delay(value);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, HIGH);
delay(value);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
delay(value);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
delay(value);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
delay(value);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
delay(value);

}

The delay() function does not take a float value. However you should not use delay() at all. Use millis() for all your timing.

This line

previousMillis = currentMillis;

can cause an accumulation of small errors. It is better to use

previousMillis += interval;

The reason is extensively discussed in several things at a time.

...R

I'm not really following your code, but maybe that's just me.

I see one problem- Type int can't hold a value of 60,000. A regular signed integer holds values between -32,768 to 32,767. If you try setting it to 60,000 the sign bit (the MSB) will be set and it will be seen by the Arduino as a negative number. Use type long for Interval. It's good practice not to mix-and-match types in an expression anyway. (I don't understand why you need a 60 second interval...)

delay() is supposed to use a type int.

If your stepper is 200 steps per revolution, 300mS per step should be 1 RPM.

Thanks for your replies. The 60,000 value is in order to change the speed every minute. For testing if the code worked i tried to make it turn at exactly 1RPM but in the end I want to increase the speed a little every minute . I'll now read the link Robin2 sent me. If there more suggestions they are more than welcome as I find programming quite a challenge.
Douwey

Instead of using float delays in milliseconds you could use integer delays in microseconds:

unsigned long lut[] = {
14720,
14720,
14720,
14720
};

  
  //maakt de waarde in lut de delay tussen de stappen
  unsigned long value = lut[i%3];

  //beschrijft de stappen en de delay ertussen
   digitalWrite(IN1, LOW); 
   digitalWrite(IN2, HIGH);
   digitalWrite(IN3, LOW);
   digitalWrite(IN4, LOW);
     delayMicroseconds(value);
   digitalWrite(IN1, LOW); 
   digitalWrite(IN2, HIGH);
   digitalWrite(IN3, HIGH);
   digitalWrite(IN4, LOW);
     delayMicroseconds(value);
   digitalWrite(IN1, LOW); 
   digitalWrite(IN2, LOW);
   digitalWrite(IN3, HIGH);
   digitalWrite(IN4, LOW);
     delayMicroseconds(value);
   digitalWrite(IN1, LOW);

a bit late, but thanks for all the help! changing millis to micros and getting rid of the delay() worked!