Reading data from sd card file to set multiple alarms using ds3231 module

I'm working on a project which consists of an android app and a pet feeding device.
The android app is used to send various commands via bluetooth such as: send "add," "delete," " play," and send time.

The sent time values (or whichever command/value received are named as String incomingString variable) are defined by the user, read and saved inside a .txt file named "time.txt" each time the "SEND TIME" button in the app is pressed and have this format:
12:49
17:30
7:15
6:45

I need a way to retrieve each line that contain a time value and set an alarm to move a servo motor (for opening and closing the bottom part of the feeder).
The board I am using for this project is Arduino Mega for the extra internal memory, pins, and processing power.

I'm aware that my code needs optimization, I am new to Arduino and every bit of your help is appreciated to complete this project.

Here's where I'm at with the code. Thanks in advance for your feedback!

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SD.h>
#include <NewPing.h>
#include <SoftwareSerial.h>
#include <pcmConfig.h>
#include <pcmRF.h>
#include <TMRpcm.h>
#include <SPI.h>
#include <PWMServo.h>

#include <string.h>

//#define SD_ChipSelectPin 4
#define trigPin 3
#define echoPin 2
#define MAX_DISTANCE 350
#define rxPin 0
#define txPin 1

const int DS1307 = 0x68; // Address of DS1307 see data sheets
const char* days[] =
{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const char* months[] =
{"January", "February", "March", "April", "May", "June", "July", "August","September", "October", "November", "December"};

// Initializes all values: 
byte second = 0;
byte minute = 0;
byte hour = 0;
byte weekday = 0;
byte monthday = 0;
byte month = 0;
byte year = 0;

NewPing sonar(trigPin, echoPin, MAX_DISTANCE);
TMRpcm audio;
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial HC06(rxPin, txPin);
PWMServo servo_test;

File myFile1;
File myFile2;
File myFile11;
File myFile21;
uint32_t ugStart;
uint32_t ugStops;
float fgProcessTime;
float fgSEM;
char cgCmd;
unsigned long lgUpdateTime;

float duration, distance;

int count = 0;
char t[32];
int file_number = 0;
char fileSlNum[10] = "";
char filePrefixname[3] = "fd";
char exten[5] = ".wav";
const int cs_pin = 53;
//const int mic_pin = A0;
//const int sample_rate = 16000;

void setup() {
  ugStart = millis();
  lgUpdateTime = millis();  
  Wire.begin();
  servo_test.attach(9);
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(12,OUTPUT);  //Pin pairs: 9,10 Mega: 5-2,6-7,11-12,46-45
  //pinMode(A0, INPUT);  //pinMode(mic_pin, INPUT);
  pinMode(cs_pin, OUTPUT);

  HC06.begin(9600);
  Serial.begin(9600);
  delay(2000); // This delay allows the MCU to read the current date and time.
  printTime();
  
  lcd.init();  
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("Automated");
  lcd.setCursor(2, 1);
  lcd.print("Pet Feeding");
  audio.speakerPin = 11;
  audio.setVolume(6);
  
  Serial.print("Initializing SD card...");
  if (!SD.begin(cs_pin)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  audio.CSPin = cs_pin;

  servo_test.write(60);
  delay(500);
  servo_test.write(0);
  //myFile1 = SD.open("record.txt", FILE_WRITE);
  //myFile2 = SD.open("time.txt", FILE_WRITE);
}

void loop() {
  /*lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Time:");
  lcd.setCursor(0, 1);
  lcd.print(String(hour) + String(":") + String(minute) + String(":") + String(second));
  printTime();*/
  wait_sec(1);
  String SD_Read ="";
  String SD_ReadTime ="";
  String incomingString = "";
  
  while(Serial.available()){
    delay(3);
    char c = Serial.read();
    incomingString += c;
  }
  if (incomingString.length() > 0) {
    if (incomingString == "add") {      
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Do:");
      lcd.setCursor(2, 1);
      lcd.print("Add Recording");
      char file_name[10] = "";      
      itoa(file_number, fileSlNum, 10);
      strcat(file_name, filePrefixname);
      strcat(file_name, fileSlNum);
      strcat(file_name, exten);
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Recording:");
      lcd.setCursor(0, 1);
      lcd.print(file_name);
      audio.startRecording(file_name,16000,A0);
      Serial.println("startRecording");
      wait_sec(5);
      audio.stopRecording(file_name);
      Serial.println("stopRecording");
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Recording Done:");
      lcd.setCursor(0, 1);
      SD.remove("record.txt");   
      if (SD.exists("record.txt")) {
        Serial.println("The record.txt exists.");
      } else {
      }      
      myFile1 = SD.open("record.txt", FILE_WRITE);
      if (myFile1) {
        myFile1.println(file_name); 
        myFile1.close();
      } else {
        Serial.println("error opening record.txt");
      }
      myFile11 = SD.open("record.txt");
      if (myFile11) {
        Serial.println("record.txt  content:");
        while (myFile11.available()) {
          Serial.write(myFile11.read());
        }
        myFile11.close();
      } else {
        Serial.println("error opening record.txt");
      }
      lcd.print(file_name);
      file_number++;
      Serial.println("=====================================");
    } else if (incomingString == "play") {
      char inputCharString[8];
      char inputChar;
      int stringIndex = 0;
      myFile11 = SD.open("record.txt");
      if (myFile11) {
        Serial.println("record.txt  content:");
        while (myFile11.available()) {
          Serial.write(myFile11.read());
        }
        myFile11.close();
      } else {
        Serial.println("error opening record.txt");
      }
      if (myFile11) {
        while (myFile11.available()) {
          inputChar = myFile11.read();
          inputCharString[stringIndex] = inputChar;
          stringIndex++;
        }
        myFile11.close();
      } else {
      }
      SD_Read = String(inputCharString);
      Serial.println("play: " + String(SD_Read));
      audio.setVolume(6);      
      //audio.play(SD_Read.c_str());
      audio.play("test.wav");
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Do:");
      lcd.setCursor(2, 1);
      lcd.print("Play");
      lcd.setCursor(7, 1);
      lcd.print(SD_Read.c_str());
      wait_sec(6);
      audio.stopPlayback();      
      Serial.println("=====================================");
    } else if (incomingString == "delete") {
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Do:");
      lcd.setCursor(2, 1);
      lcd.print("Delete");
      Serial.println("Removing record.txt...");
      SD.remove("record.txt");  
      if (SD.exists("record.txt")) {
        Serial.println("The record.txt exists.");
      } else {
        Serial.println("record.txt has been removed.");
      }
      Serial.println("Removing time.txt...");
      SD.remove("time.txt");   
      if (SD.exists("time.txt")) {
        Serial.println("The time.txt exists.");
      } else {
        Serial.println("time.txt has been removed.");
      }
      Serial.println("=====================================");      
    } else if (incomingString.indexOf(":") > 0) {
      char inputCharStrings[50];
      char inputChars;
      int stringIndexes = 0;
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Time:");
      lcd.setCursor(2, 1);
      lcd.print("" + incomingString);
      myFile2 = SD.open("time.txt", FILE_WRITE);
      if (myFile2) {
        myFile2.println(incomingString);
        myFile2.close();
      } else {
        Serial.println("error opening time.txt");
      }
      myFile21 = SD.open("time.txt");
      if (myFile21) {
        Serial.println("time.txt  content:");
        while (myFile21.available()) {
          Serial.write(myFile21.read());
        }
        myFile21.close();
      } else {
        Serial.println("error opening time.txt");
      }
      if (myFile21) {
        while (myFile11.available()) {
          inputChars = myFile21.read();
          inputCharStrings[stringIndexes] = inputChars;
          stringIndexes++;
        }
        myFile21.close();
      } else {
      }
      SD_ReadTime = String(inputCharStrings);
      Serial.println("new time set: " + incomingString);
      //Serial.print(incomingString);
      Serial.println("=====================================");
    }
  }
  /*String finput = "";
  int lines = 0;
  String times[100];
  myFile21 = SD.open("time.txt");
  if (myFile21) {
    Serial.println("time.txt  content:");
    while (myFile21.available()) {
      //Serial.write(myFile21.read());
      times[lines] = finput;
      Serial.println("line ");
      Serial.print(lines+1);
      Serial.print(": ");
      Serial.print(finput);      
      lines++;
    }      
    myFile21.close();
  } else {
    Serial.println("error opening time.txt");
  }
  for(int i=0; i < lines; i++){
    //times[i];
    if(times[i]=0){

    }
  }
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration * 0.034 / 2; // Speed of sound wave divided by 2 (go and back)
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  if (distance <= 5){
    if((String(hour) == "7") && (String(minute) == "0") && (String(second) == "0")){
      char inputCharString[8];
      char inputChar;
      int stringIndex = 0;
      myFile11 = SD.open("record.txt");
      if (myFile11) {
        Serial.println("record.txt  content:");
        while (myFile11.available()) {
          Serial.write(myFile11.read());
        }
        myFile11.close();
      } else {
        Serial.println("error opening record.txt");
      }
      if (myFile11) {
        while (myFile11.available()) {
          inputChar = myFile11.read();
          inputCharString[stringIndex] = inputChar;
          stringIndex++;
        }
        myFile11.close();
      } else {
      }
      SD_Read = String(inputCharString);
      Serial.println("play: " + String(SD_Read));
      audio.setVolume(6);      
      audio.play(SD_Read.c_str());
      //audio.play("fd0.wav");
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Do:");
      lcd.setCursor(2, 1);
      lcd.print("Play");
      lcd.setCursor(7, 1);
      lcd.print(SD_Read.c_str());
      
      servo_test.write(60);
      delay(500);
      servo_test.write(0);
    }else if((String(hour) == "12") && (String(minute) == "0") && (String(second) == "0")){
      char inputCharString[8];
      char inputChar;
      int stringIndex = 0;
      myFile11 = SD.open("record.txt");
      if (myFile11) {
        Serial.println("record.txt  content:");
        while (myFile11.available()) {
          Serial.write(myFile11.read());
        }
        myFile11.close();
      } else {
        Serial.println("error opening record.txt");
      }
      if (myFile11) {
        while (myFile11.available()) {
          inputChar = myFile11.read();
          inputCharString[stringIndex] = inputChar;
          stringIndex++;
        }
        myFile11.close();
      } else {
      }
      SD_Read = String(inputCharString);
      Serial.println("play: " + String(SD_Read));
      audio.setVolume(6);      
      audio.play(SD_Read.c_str());
      //audio.play("fd0.wav");
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Do:");
      lcd.setCursor(2, 1);
      lcd.print("Play");
      lcd.setCursor(7, 1);
      lcd.print(SD_Read.c_str());
  
      servo_test.write(60);
      delay(500);
      servo_test.write(0);
    }else if((String(hour) == "17") && (String(minute) == "0") && (String(second) == "0")){
      char inputCharString[8];
      char inputChar;
      int stringIndex = 0;
      myFile11 = SD.open("record.txt");
      if (myFile11) {
        Serial.println("record.txt  content:");
        while (myFile11.available()) {
          Serial.write(myFile11.read());
        }
        myFile11.close();
      } else {
        Serial.println("error opening record.txt");
      }
      if (myFile11) {
        while (myFile11.available()) {
          inputChar = myFile11.read();
          inputCharString[stringIndex] = inputChar;
          stringIndex++;
        }
        myFile11.close();
      } else {
      }
      SD_Read = String(inputCharString);
      Serial.println("play: " + String(SD_Read));
      audio.setVolume(6);      
      audio.play(SD_Read.c_str());
      //audio.play("fd0.wav");
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print("Do:");
      lcd.setCursor(2, 1);
      lcd.print("Play");
      lcd.setCursor(7, 1);
      lcd.print(SD_Read.c_str());
  
      servo_test.write(60);
      delay(500);
      servo_test.write(0);
    }       
  }else if (distance > 15){
    audio.play("refill.wav");
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Refill");
    lcd.setCursor(0,1);
    lcd.print("Container");
  }*/
}

// Continuous function for converting bytes to decimals and vice versa
byte decToBcd(byte val) {
  return ((val/10*16) + (val%10));
}
byte bcdToDec(byte val) {
  return ((val/16*10) + (val%16));
}

byte readByte() {
  while (!Serial.available()) delay(10);
  byte reading = 0;
  byte incomingByte = Serial.read();
  while (incomingByte != '\n') {
    if (incomingByte >= '0' && incomingByte <= '9')
      reading = reading * 10 + (incomingByte - '0');
    else;
    incomingByte = Serial.read();
  }
  Serial.flush();
  return reading;
}

void wait_sec(int secs) {
  int kawnt = 0;
  int mil = secs * 10;
  while (1) {
    delay(100);
    kawnt++;
    if (kawnt == mil) {
      count = 0;
      break;
    }
  }
  return ;
}

void printTime() {
  char buffer[3];
  char buffer1[3];
  const char* AMPM = 0;
  readTime();
  Serial.print(days[weekday-1]);
  Serial.print(" ");
  Serial.print(months[month-1]);
  Serial.print(" ");
  Serial.print(monthday);
  Serial.print(", 20");
  Serial.print(year);
  Serial.print(" ");
  if (hour > 12) {
    hour -= 12;
    AMPM = " PM";
  }
  else AMPM = " AM";
  Serial.print(hour);
  Serial.print(":");
  sprintf(buffer, "%02d", minute);
  Serial.print(buffer);
  Serial.print(":");
  sprintf(buffer1, "%02d", second);
  Serial.print(buffer1);
  Serial.println(AMPM);
}

void readTime() {
  Wire.beginTransmission(DS1307);
  Wire.write(byte(0));
  Wire.endTransmission();
  Wire.requestFrom(DS1307, 7);
  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read());
  weekday = bcdToDec(Wire.read());
  monthday = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}

Sounds like example 5 of serial input basics would help you. You could get the android app to send the "send time" string and a 32-bit unix time stamp in a single transmission.

This same tutorial can help in retrieving ascii data from the SD card.

1 Like

Not sure I quite understand the full functionality, but here's a couple of observations...

You do not handle the serial input very well... at 9600 baud data arrives fairly slowly... the micro-controller is much faster... it will read everything available and try and process it before it has all arrived. There are a number of tutorials on how to receive serial data... for example...

Consider reading the serial data into a simple C char array rather than using Strings.

Consider sending times with a leading zero for anything less than 10 hours... it will make it easier to process if all the times are the exact same format. So 07:15 for 7:15 am.

This is not a good way to do timing ... this code is "blocking" ... while it runs nothing else can. There are better techniques to use.

Don't try and get all this code working at once. Get one thing working then add the next bit. That way you can focus on a small piece of code at a time.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.