Running a Stepper motor NEMA 17 for 1 hour and stop it for 5 hours

Hi, I want run my stepper motor back and forth at a frequency of 0.1Hz continuously for an hour. After an hour, I want it to stop for five hours and I want this to repeat indefinitely. I am using an SD card module to log data on start and stop times using millis().
The issue I am facing is two fold:
*Data is not getting logged after large intervals of time.
*The motor is not starting back on after five hours.
Please find the code below.
Thank you :slight_smile:

#include<SPI.h>
#include<SD.h>

const int dirPin  = 8;
const int stepPin = 9; 
const int enPin   = 10;
int stepsPerRot = 16;

unsigned long period = 18000000;
unsigned long time_now = 0;

int counter = 0;

File dataFile;

void setup() {
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);

  SD.begin(7);
}

void loop() {
  counter = 0;
  dataFile = SD.open("log.csv", FILE_WRITE);
  if(dataFile) {
    dataFile.print(millis());
    dataFile.print(",");
    dataFile.println("On");
    dataFile.close();
  }
  while (counter<360){
    digitalWrite(dirPin,LOW);
    for(int x = 0; x < 4800; x++){ //2mm 
      digitalWrite(stepPin,HIGH); 
      delayMicroseconds(520); 
      digitalWrite(stepPin,LOW); 
      delayMicroseconds(520);
    }
    delay(100);
    digitalWrite(dirPin,HIGH);
    for(int x = 0; x < 4800; x++){
      digitalWrite(stepPin,HIGH); 
      delayMicroseconds(520); 
      digitalWrite(stepPin,LOW); 
      delayMicroseconds(520);
    }
    delay(100);
    counter=counter+1;
  }
  dataFile = SD.open("log.csv", FILE_WRITE);
  if (dataFile) {
    dataFile.print(millis());
    dataFile.print(",");
    dataFile.println("Off");
    dataFile.close();
  }
  time_now = millis();
  while(millis() < time_now + period){

  }
}

Should be

  time_now = millis();
  while(millis() - time_now < period){

  }
}

to avoid the overflow problem. However, this only occurs once every ~50 days, so does not explain why your motor does not start after 5 hours.

This is the same as a delay of 18,000,000 milliseconds (or 5 hours).

Can you be any more specific?

The motor was running as expected when did not include the logger code. Is there any chance the logger code is holding up the motor from running again after 5 hours?

I guess so, but I do not know why.

What about my question?

I was unable to get the logs of the second cycle. So, could be anywhere between the first and the sixth hour.

It's worth noting that the SD library uses malloc, and it appears you are calling SD.open() multiple times. I suggest you only need to call it once.

At least, call SD.close () before re-opening.

OP actually does call it.

Oh yes, my bad. However, I would still suspect a heap problem.

Otherwise there is not much to go wrong, although it could be a faulty SD card, or problem with SD card hangup which some people have encountered.

Ok assuming it is an SD card problem, why would that stop the stepper motor from running?

Without studying the SD library in detail, I don't know specifically. In theory though, the SD library may have a loop waiting for an event that never happens (e.g. a response from the SD card), and hangs.

Don't assume. Remove the SD card code and see if the problem goes away.

The OP already did that.

I agree this is worth trying. Problem is that the writes get buffered, so if you reset or power off the Arduino or upload code, the buffer contents are lost and I think you can even corrupt the file system on the card by doing that. That's why @vizros is closing and opening the file for each write, I guess. But there is another way around that problem:

#include<SPI.h>
#include<SD.h>

const int dirPin  = 8;
const int stepPin = 9; 
const int enPin   = 10;
int stepsPerRot = 16;

unsigned long period = 18000000;
unsigned long time_now = 0;

int counter = 0;

File dataFile;

void setup() {
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);

  SD.begin(7);
  dataFile = SD.open("log.csv", FILE_WRITE);

}

void loop() {
  counter = 0;
  dataFile.print(millis());
  dataFile.print(",");
  dataFile.println("On");
  dataFile.flush();
  }
  while (counter<360){
    digitalWrite(dirPin,LOW);
    for(int x = 0; x < 4800; x++){ //2mm 
      digitalWrite(stepPin,HIGH); 
      delayMicroseconds(520); 
      digitalWrite(stepPin,LOW); 
      delayMicroseconds(520);
    }
    delay(100);
    digitalWrite(dirPin,HIGH);
    for(int x = 0; x < 4800; x++){
      digitalWrite(stepPin,HIGH); 
      delayMicroseconds(520); 
      digitalWrite(stepPin,LOW); 
      delayMicroseconds(520);
    }
    delay(100);
    counter=counter+1;
  }
  dataFile.print(millis());
  dataFile.print(",");
  dataFile.println("Off");
  dataFile.flush();
  }
  time_now = millis();
  while(millis() < time_now + period){

  }
}

I would use a real time clock , eg DS3231- then you can just read the hours and decide what to do. Times will be accurate and you can log actual real times .
I would collect the data and save it when the motor is not running

Add some serial prints to find out where it crashes.

Which Arduino is it? It looks like the stepper enable pin you're using is the default SD chip select. How did you wire it up?

Yes, it is working without the SD card code.

Thank you @PaulRB! I will try this and get back to you.

Not keen on adding another component to this project. Printing millis is should suffice. Thank you for the tip though, I will keep it in mind for future projects!