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
#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){
}
}
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?
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.
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
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!