Click here to Skip to main content
15,887,027 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,
I am stuck to shorten a function in Arduino, can anyone help me with this?
I have not been working in Arduino for very long.
I currently have 5 outputs controlled by 6 program steps = 30 program steps
This is the code I am using now:
C++
if (prog0 != "000000000000" || prog0 != "1000000000") {
    // Program at I/O1 != empty
    if (String(prog0[i - 1]) == "1" && String(hourNow) == String(setHour) && String(minNow) == String(setMin)) {
      if (String(onOff) == "1") {
        // output high
        Serial.println("Output on");
      } else {
        // output low
        Serial.println("Output off");
      }
    }
  }
 if (prog1 != "000000000000" || prog1 != "1000000000") {
    // Program at I/O1 != empty
    if (String(prog1[i - 1]) == "1" && String(hourNow) == String(setHour) && String(minNow) == String(setMin)) {
      if (String(onOff) == "1") {
        // output high
        Serial.println("Output prog1 on");
      } else {
        // output low
        Serial.println("Output prog1 off");
      }
    }
  }


I now repeat this until I get to prog29, how can I shorten this code?

What I have tried:

I thought by a class or a function but something is wrong here:
C++
int d = 0;
char inputString[13];
char destin[13];
char charRead;
void readFromFile() {
  byte i = 0;

  if (!SD.exists("/programm.txt"))
    Serial.println("programm.txt doesn't exist.");
  Serial.println("Reading from programm.txt:");
  myFile = SD.open("/programm.txt");
  while (myFile.available()) {
    char inputChar = myFile.read();
    if (inputChar == '\n')  //end of line (or 10)
    {
      if (d < 30) {
        switch (d) {
          case 0:
            destin = prog0;
            break;
          case 1:
            destin = prog1;
            break;
            // and so on
        }
        changeDest(inputString, destin, 0, 11);
        d++;
        i = 0;
      } else {
        inputString[i] = inputChar;
        i++;
      }
      if (i > sizeOf(inputString)) {
        while (1)
          ;
      }
    }
  }
}
void changeDest(char source[], char destination[], byte startAt, byte length) {
  for (int pos = 0; pos < length; pos++) {
    destination[startAt + pos] = source[pos];
  }
}
Posted
Updated 30-Jul-23 10:13am
v3
Comments
Richard MacCutchan 28-Jul-23 6:31am    
You have not explained what values are different for progs 2 to 29. You should be able to write a single function and then call it with the appropriate parameters for each setting. Also there does not seem to be any connection between your two code samples.

Concentrating on your 1st block of code, you can create a function that takes the 'prog' string, the index 'i', and the 'onOff' values as parameters -
C++
#include <iostream>
#include <string>

//Function based on your input parameters...
void checkProgram(const std::string& prog, int i, bool onOff, int hourNow, int minNow, int setHour, int setMin) {
    if (prog != "000000000000" && prog != "1000000000") {
        //Program at I/O1 != empty
        if (prog[i - 1] == '1' && hourNow == setHour && minNow == setMin) {
            if (onOff) {
                //The high output...
                std::cout << "Output " << prog << " on\n";
            } else {
                //The low output...
                std::cout << "Output " << prog << " off\n";
            }
        }
    }
}

int main() {
    //You can call the function i.e...
    std::string prog0 = "110000000000";
    std::string prog1 = "101000000000";
    bool onOff = true;
    int hourNow = 12;
    int minNow = 30;
    int setHour = 12;
    int setMin = 30;
    int i = 1;

    //Call your function for each prog value prog0, 1 to 29...
    checkProgram(prog0, i, onOff, hourNow, minNow, setHour, setMin);
    checkProgram(prog1, i, onOff, hourNow, minNow, setHour, setMin);

    return 0;
}


Output -
Output 110000000000 on
Output 101000000000 on
 
Share this answer
 
v2
@Andre Oosthuizen Thank you for your help, I have made a little changes, but you gave me the base to start with.
So I paste the whole sketch below, I use 30 programsteps and 5 outputs, so every output has 6 programsteps, I only have used 4 to make the sketch a little shorter.

C++
// Code for Arduino environment
// Using ESP32 Dev Module ESP32 WROOM 32 from AZ delivery https://www.az-delivery.de/en
/* Include libraries */
#include <iostream>
#include <string>
#include <FS.h>   // File system library
#include <SPI.h>  // Esp8266/Esp32 core library for Arduino environment
#include <SD.h>   // SD card library
#include "time.h"  /*C:\Users\User\AppData\Local\Arduino..\packages\ esp32\hardware\esp32\2.0.9\tools\ sdk\esp32\include\newlib\platform_include\*/
#include <WiFi.h>  // This library allows an Arduino board to connect to the internet
#include <Wire.h>  // Wiring library
/*
 * Connect the µSD card module to the following pins:
 *
 * µSD Card module    | ESP32
 *
 * CS                   SD D0/GPIO2
 * MOSI                 MOSI/GPIO23
 * VSS/GND              GND
 * VDD/VCC              5V
 * CLK/SCK              SCK/GPIO18
 * MISO                 MISO/GPIO19
 *
 * TFT SPI             | Resistor      | ESP32
 *
 * VCC                   -               5V
 * GND                   -               GND
 * CS                    1KΩ             SS/GPIO5
 * RESET/RST             1KΩ             GPIO22 OR 3.3V
 * D/C                   1KΩ             GPIO4
 * SDI/MOSI              1KΩ             MOSI/GPIO23
 * SCK                   1KΩ             SCK/GPIO18
 * LED                   -               3.3V or GPIO15 (if used to save screen)
 * SDO/MISO              1KΩ             MISO/GPIO19
 *
 * SD CARD (if used)   | ESP32
 * 9 D2                  -
 * 1 D3                  GPIO2
 * 2 CMD                 MOSI/GPIO23
 * 3 VSS                 GND
 * 4 VDD                 3.3V
 * 5 CLK                 SCK/GPIO18
 * 6 VSS                 GND
 * 7 DO                  MISO/GPIO19
 * 8 D1                  -
 *
 */
/*
Connect following pins from the DHT to the ESP32
*   DHT      Resistor           ESP32
*    1          -               3.3V
*    2         10KΩ             3.3V
*    2          -               12
*    3          -               -
*    4          -               GND
*/

// Disconnect GPIO22 and wire the tft pin RESET to 3.3V
// BMP 280 connection           ESP32
/* VCC                          3.3V
 *  GND                          GND
 *  SCL                          21
 *  SDA                          22
 */

/*Change the data with your internet settings*/
// Identification and password needed to connect to your router
const char *ssid = "your ssid";
const char *password = "password";

const char *ntpServerName = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
struct tm timeinfo;
// The data will be stored as follow: Mo,Tu,We,Th,Fr,Sa,Su,H,H,M,M,O;7 Days, Time & O stands for output
char prog0[13] = { "111000009001" };  // For example set the output on monday, tuesday, wednesday high at 09:00, the last digit 1 = pinMode high
char prog1[13] = { "111111109010" };  // Every day we set the output off at 09:01, the last digit = 0, so pinMode low
char prog2[13] = { "100000018101" };  // Monday set output on at 18:10
char prog3[13] = { "100000018150" };  // Monday set output off at 18:15
char *myString = "111000115001";
File myFile;
char fileName[] = "/programm.txt";
const int chipSelect = 2;
char charRead;
char inputString[13];  //string to hold read string
int c50 = 0;
void setup() {
  Serial.begin(115200);
  pinMode(0, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(24, OUTPUT);
  pinMode(25, OUTPUT);
  // connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  int i = 0;
  while (i < 15 && WiFi.status() != WL_CONNECTED) {
    i++;
    Serial.print(".");
    if (i == 15) {
      // disconnect WiFi as it's no longer needed
      WiFi.disconnect(true);
      WiFi.mode(WIFI_OFF);
      Serial.println("WIFI disconnected");
      break;
    }
    delay(500);
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println(" CONNECTED");
  }
  // init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServerName);

  Serial.println("Initializing System");
  /* Setup the sd-card and test the type, send the information to the serial monitor */
  if (!SD.begin(2)) {  // Select chip, use SD_CS GPIO 2
    Serial.println("Card Mount Failed");
    return;
  }
  uint8_t cardType = SD.cardType();

  if (cardType == CARD_NONE) {
    Serial.println("No SD card attached");
    return;
  }

  Serial.print("SD Card Type: ");
  if (cardType == CARD_MMC) {
    Serial.println("MMC");
  } else if (cardType == CARD_SD) {
    Serial.println("SDSC");
  } else if (cardType == CARD_SDHC) {
    Serial.println("SDHC");
  } else {
    Serial.println("UNKNOWN");
  }

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);
  Serial.println("initialisation done.");
  writeToFile();
  delay(2000);
  readFromFile();
  printFile();
}

void loop() {
  loadProgramm();
  delay(20000);
}

void writeToFile() {
  myFile = SD.open("/programm.txt", FILE_WRITE);
  if (myFile)  // it opened OK
  {
    myFile.println(prog0);
    myFile.println(prog1);
    myFile.println(prog2);
    myFile.println(prog3);
    // close the file:
    myFile.close();
    Serial.println("Done writing to programm.txt");
  } else
    Serial.println("Error opening programm.txt");  // programm.txt does not exist
  // re-open the file for reading:
  myFile = SD.open("/programm.txt");
  if (myFile) {
    Serial.println("Writing to programm.txt");
    myFile.println(prog0);
    myFile.println(prog1);
    myFile.println(prog2);
    myFile.println(prog3);
    Serial.println("programm.txt created");
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening the text file");
  }
}
void readFromFile() {
  int d = 0;
  byte i = 0;  //counter
  //now read it back and show on Serial monitor
  // Check to see if the file exists:
  if (!SD.exists("/programm.txt"))
    Serial.println("programm.txt doesn't exist.");
  Serial.println("Reading from programm.txt:");
  myFile = SD.open("/programm.txt");

  while (myFile.available()) {
    char inputChar = myFile.read();  // Gets one byte from serial buffer
    if (inputChar == '\n')           //end of line
    {
      inputString[i] = 0;  //terminate the string correctly
      Serial.println(inputString);
      if (d == 0) {
        substituteChars(inputString, prog0, 0, 11);
      }
      if (d == 1) {
        substituteChars(inputString, prog1, 0, 11);
      }
      if (d == 2) {
        substituteChars(inputString, prog2, 0, 11);
      }
      if (d == 3) {
        substituteChars(inputString, prog3, 0, 11);
      }
      d++;
      i = 0;
    } else {
      inputString[i] = inputChar;  // Store it
      i++;
    }
    if (i > sizeof(inputString)) {
      Serial.println("Incoming string longer than array allows");
      Serial.println(sizeof(inputString));
      while (1)
        ;
    }
  }
  // close the file:
  myFile.close();
  Serial.println("Done reading file");
}
void printFile() {
  Serial.print("programma 0 = ");
  Serial.println(prog0);
  Serial.print("programma 1 = ");
  Serial.println(prog1);
  Serial.print("programma 2 = ");
  Serial.println(prog2);
  Serial.print("programma 3 = ");
  Serial.println(prog3);
}
void substituteChars(char source[], char destination[], byte startAt, byte length) {
  for (int pos = 0; pos < length; pos++) {
    destination[startAt + pos] = source[pos];
  }
}
// So far everything goes fine
void loadProgramm() {
  struct tm timeInfo;
  if (!getLocalTime(&timeInfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  bool onOff = false;
  bool daySet = false;
  String setHour;
  String setMin;
  char setOn = prog0[11];
  int hourNow = timeInfo.tm_hour;
  int minNow = timeInfo.tm_min;
  int b = timeInfo.tm_wday;
  int c = b - 1;
  if (c == -1) {
    c = 6;
    Serial.println("Sunday");
  }
  int IO = 0;
  //std::string prog5 = myString;
  int d = 0;
  do {
    switch (d) {
      case 0:
        myString = prog0;
        IO = 0;
        break;
      case 1:
        myString = prog1;
        IO = 0;
        break;
      case 2:
        myString = prog2;
        IO = 0;
        break;
      case 3:
        myString = prog3;
        IO = 0;
        break;
    }
    setOn = myString[11];
    if (String(setOn) == "1") {
      onOff = true;
    } else {
      onOff = false;
    }
    daySet = false;
    if (String(myString[c]) == "1") {
      daySet = true;
    }
    if (minNow < 10) {
      setMin = String(myString[10]);
    } else {
      setMin = String(myString[9]);
      setMin += String(myString[10]);
    }
    if (hourNow < 10) {
      setHour = String(myString[8]);
    } else {
      setHour = String(myString[7]);
      setHour += String(myString[8]);
    }
    checkProgram(myString, c, daySet, hourNow, minNow, setHour, setMin, onOff, IO);
    d++;
  } while (d < 4);
  Serial.println("Done checking file");
}
void checkProgram(const std::string &prog, int wDay, bool daySet, int hourNow, int minNow, String setHour, String setMin, bool onOff, int progNum) {
  /* Used outputs
  pinMode(0, OUTPUT);
  pinMode(13, OUTPUT);
  pinMode(14, OUTPUT);
  pinMode(24, OUTPUT);
  pinMode(25, OUTPUT);
  */
  
  if (prog != "000000000000" && prog != "1000000000") {
    //Program at I/O1 != empty
    if (prog[wDay] == '1' && daySet && String(hourNow) == setHour && String(minNow) == setMin) {
      if (onOff) {
        //The high output...
        std::cout << "Output " << prog << " on\n";
        std::cout << "Output " << progNum << " set high\n";
        if (progNum == 1) {
          setOutput1();
        }
      } else {
        //The low output...
        std::cout << "Output " << prog << " off\n";
        std::cout << "Output " << progNum << " set low\n";
        if (progNum == 0) {
          clearOutput1();
        }
      }
    } else {
      // output ! empty but data changing from time or day now
      std::cout << "Output " << prog << " skipped\n";
    }
  } else {
    std::cout << "Data not set yet\n";
  }
}
void setOutput1() {
  // eg: set output 1
  pinMode(0, HIGH);
}
void clearOutput1() {
  // eg: clear output 1
  pinMode(0, LOW);
}

Everyone can use the sketch and change it to his needs.
 
Share this answer
 
Use arrays and integer variables.
 
Share this answer
 
1. You should breakdown the code in smaller functions, so the two "prog" comparison can refactored in a function with some parameters.
2. Comparing String is a bad idea because of CPU performance, so try to compare the values as integers or cast them to int.
3. Create an output string insted if/else with output.
4.
if (!SD.exists("/programm.txt"))
is bad style. Use an else to. Start with positive case and else the warning.

Shorten the code isnt as important as writing high performing and quality code. ;-)
 
Share this answer
 
Comments
Member 14175816 30-Jul-23 16:27pm    
I'm new to Arduino and this code I've copied from the examples, but thank you for the reply, can you take a look at the last sketch to see if I can make some changes, but I will clean-up the coding later.
I was not able to test the following other than parts to check the logic of compiling and uncompiling the programs and whether the logic to turn a pin on or off works. My tests indicate that logic is working however I'm not sure of the file reading and writing.

I also tried to make it "do the appropriate thing" in the face of data errors. There were a few places where I was unsure as to what you were trying to accomplish so I just made a guess.

I did add to the program to include a pin number on the end. So the format is now:
Mon, Tues, Wed, Thur, Fri, Sat, Sun, H, H, M, M, on/off, pin number

By changing the program storage from a character string to the binary data structure, memory usage was reduced. If you increase the number of programs, the amount of memory used increases by less using the binary data structure over the character string storage.

This compiled with the Arduino IDE however Microsoft Visual Studio 2019 displayed errors which required that I use #defines for the day of week constants so that const uint8_t SundayDOW = 0x01; became #define SundayDOW 0x01, etc.

C++
// Code for Arduino environment
// Using ESP32 Dev Module ESP32 WROOM 32 from AZ delivery https://www.az-delivery.de/en
/* Include libraries */
#include <iostream>
#include <string>
#include <FS.h>   // File system library
#include <SPI.h>  // Esp8266/Esp32 core library for Arduino environment
#include <SD.h>   // SD card library
#include "time.h"  /*C:\Users\User\AppData\Local\Arduino..\packages\ esp32\hardware\esp32\2.0.9\tools\ sdk\esp32\include\newlib\platform_include\*/
#include <WiFi.h>  // This library allows an Arduino board to connect to the internet
#include <Wire.h>  // Wiring library
/*
 * Connect the µSD card module to the following pins:
 *
 * µSD Card module    | ESP32
 *
 * CS                   SD D0/GPIO2
 * MOSI                 MOSI/GPIO23
 * VSS/GND              GND
 * VDD/VCC              5V
 * CLK/SCK              SCK/GPIO18
 * MISO                 MISO/GPIO19
 *
 * TFT SPI             | Resistor      | ESP32
 *
 * VCC                   -               5V
 * GND                   -               GND
 * CS                    1KΩ             SS/GPIO5
 * RESET/RST             1KΩ             GPIO22 OR 3.3V
 * D/C                   1KΩ             GPIO4
 * SDI/MOSI              1KΩ             MOSI/GPIO23
 * SCK                   1KΩ             SCK/GPIO18
 * LED                   -               3.3V or GPIO15 (if used to save screen)
 * SDO/MISO              1KΩ             MISO/GPIO19
 *
 * SD CARD (if used)   | ESP32
 * 9 D2                  -
 * 1 D3                  GPIO2
 * 2 CMD                 MOSI/GPIO23
 * 3 VSS                 GND
 * 4 VDD                 3.3V
 * 5 CLK                 SCK/GPIO18
 * 6 VSS                 GND
 * 7 DO                  MISO/GPIO19
 * 8 D1                  -
 *
 */
/*
Connect following pins from the DHT to the ESP32
*   DHT      Resistor           ESP32
*    1          -               3.3V
*    2         10KΩ             3.3V
*    2          -               12
*    3          -               -
*    4          -               GND
*/

// Disconnect GPIO22 and wire the tft pin RESET to 3.3V
// BMP 280 connection           ESP32
/* VCC                          3.3V
 *  GND                          GND
 *  SCL                          21
 *  SDA                          22
 */

/*Change the data with your internet settings*/
// Identification and password needed to connect to your router
const char *ssid = "your ssid";
const char *password = "password";

const char *ntpServerName = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;

// following days of week are in the same sequence as member tm_wday of struct tm
const uint8_t  SundayDOW = 0x01;
const uint8_t  MondayDOW = 0x02;
const uint8_t  TuesdayDOW = 0x04;
const uint8_t  WednesdayDOW = 0x08;
const uint8_t  ThursdayDOW = 0x10;
const uint8_t  FridayDOW = 0x20;
const uint8_t  SaturdayDOW = 0x40;
const uint8_t  WeekEndDOW = SundayDOW | SaturdayDOW;
const uint8_t  WeekWorkDOW = MondayDOW | TuesdayDOW | WednesdayDOW | ThursdayDOW | FridayDOW;
const uint8_t  WeekEntireDOW = WeekWorkDOW | WeekEndDOW;

struct s_prog {
  uint8_t   daysofweek;    // days of week as bitmap 0x01, 0x02, 0x04, ... 0x40 -> Sunday through Saturday
  uint8_t   hourofday;     // hour of day to do operation
  uint8_t   minuteofhour;   // minute of hour to do operaton
  uint8_t   pinno;          // pin number of pin to manipulate
  uint8_t   pinoutput;     // 0 is low and 1 is high
} progs[] = {
  {MondayDOW | TuesdayDOW | WednesdayDOW, 9, 0, 0, 1},  // For example set the output on monday, tuesday, wednesday high at 09:00, the last digit 1 = pinMode high
  {WeekEntireDOW, 9, 1, 0, 0},                          // Every day we set the output off at 09:01, the last digit = 0, so pinMode low
  {MondayDOW, 18, 10, 0, 1},                            // Monday set output on at 18:10
  {MondayDOW, 18, 15, 0, 0}                             // Monday set output off at 18:15
};

int dcount = sizeof(progs)/sizeof(progs[0]);      // figure out number of programs stored.

const uint8_t usablepins[] = {0, 13, 14, 24, 25};

File myFile;
char fileName[] = "/programm.txt";

void setup() {
  Serial.begin(115200);

  for (int i = 0; i < sizeof(usablepins)/sizeof(usablepins[0]); i++) pinMode(usablepins[i], OUTPUT);

  // connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  int i = 0;
  while (i < 15 && WiFi.status() != WL_CONNECTED) {
    i++;
    Serial.print(".");
    if (i == 15) {
      // disconnect WiFi as it's no longer needed
      WiFi.disconnect(true);
      WiFi.mode(WIFI_OFF);
      Serial.println("WIFI disconnected");
      break;
    }
    delay(500);
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println(" CONNECTED");
  }
  // init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServerName);

  Serial.println("Initializing System");
  /* Setup the sd-card and test the type, send the information to the serial monitor */
  if (!SD.begin(2)) {  // Select chip, use SD_CS GPIO 2
    Serial.println("Card Mount Failed");
    return;
  }

  char  cardtype[16] = {0};
  switch(SD.cardType()) {
  case CARD_NONE:
    Serial.println("No SD card attached");
    return;
    break;
  case CARD_MMC:
    strcpy(cardtype, "MMC");
    break;
  case CARD_SD:
    strcpy(cardtype, "SDSC");
    break;
  case CARD_SDHC:
    strcpy(cardtype, "SDHC");
    break;
  default:
    strcpy(cardtype, "UNKNOWN");
    break;
  }

  Serial.print("SD Card Type: ");
  Serial.println(cardtype);

  uint64_t cardSize = SD.cardSize() / (1024 * 1024);
  Serial.printf("SD Card Size: %lluMB\n", cardSize);
  Serial.println("initialisation done.");
  writeToFile();
  delay(2000);
  readFromFile();
  printFile();
}

void loop() {
  loadProgramm();
  delay(20000);
}

// The data will be stored as follow: Mo,Tu,We,Th,Fr,Sa,Su,H,H,M,M,O;7 Days, Time & O stands for output
int compileprogram (const char program[16], struct s_prog *pgm) {
  const uint8_t days[] = {MondayDOW, TuesdayDOW, WednesdayDOW, ThursdayDOW, FridayDOW, SaturdayDOW, SundayDOW};
  uint8_t finish = 0;
  struct s_prog jj = {0};
  *pgm = jj;
  for (int i = 0; program[i]; i++) {
    switch (i) {
      case 0:       // indicates Monday
      case 1:       // indicates Tuesday
      case 2:       // indicates Wednesday
      case 3:       // indicates Thursday
      case 4:       // indicates Friday
      case 5:       // indicates Saturday
      case 6:       // indicates Sunday
        (program[i] == '1' && (pgm->daysofweek |= days[i]));
        break;
      case 7:     // indicates hour of day, first digit
      case 8:     // indicates hour of day, second digit
        pgm->hourofday = pgm->hourofday * 10 + program[i] - '0';
        break;
      case 9:     // indicates minute of hour, first digit
      case 10:     // indicates minute of hour, second digit
        pgm->minuteofhour = pgm->minuteofhour * 10 + program[i] - '0';
        break;
      case 11:     // indicates pin output
        (program[i] == '1' && (pgm->pinoutput = 1));
         break;
      case 12:     // indicates hour of day, first digit
        pgm->pinno = pgm->pinno * 10 + program[i] - '0';
        break;
      case 13:     // indicates hour of day, second digit
        pgm->pinno = pgm->pinno * 10 + program[i] - '0';
        finish = 1;
        break;
    }
  }

  return finish;
}

char * uncompileprogram (char program[16], const struct s_prog pgm) {
  const uint8_t days[] = {MondayDOW, TuesdayDOW, WednesdayDOW, ThursdayDOW, FridayDOW, SaturdayDOW, SundayDOW};

 for (int i = 0; i < 14; i++) {
    program[i] = '0';
    switch (i) {
      case 0:       // indicates Monday
      case 1:       // indicates Tuesday
      case 2:       // indicates Wednesday
      case 3:       // indicates Thursday
      case 4:       // indicates Friday
      case 5:       // indicates Saturday
      case 6:       // indicates Sunday
        ((pgm.daysofweek & days[i]) && (program[i] = '1'));
        break;
      case 7:     // indicates hour of day, first digit
        program[i] = (pgm.hourofday / 10) + '0';
        break;
      case 8:     // indicates hour of day, second digit
        program[i] = (pgm.hourofday % 10) + '0';
        break;
      case 9:     // indicates minute of hour, first digit
        program[i] = (pgm.minuteofhour / 10) + '0';
        break;
      case 10:     // indicates minute of hour, second digit
         program[i] = (pgm.minuteofhour % 10) + '0';
        break;
      case 11:     // indicates pin output
        ((pgm.pinoutput == 1) && (program[i] = '1'));
        break;
      case 12:     // indicates pin number, first digit
        program[i] = (pgm.pinno / 10) + '0';
        break;
      case 13:     // indicates pin number, second digit
        program[i] = (pgm.pinno % 10) + '0';
        program[i+1] = 0;    // ensure string is properly terminated.
        break;
    }
  }

  return program;
}

void writeToFile() {
  myFile = SD.open("/programm.txt", FILE_WRITE);
  if (myFile)  // it opened OK
  {
    char prog[16];
    myFile.println(uncompileprogram (prog, progs[0]));
    myFile.println(uncompileprogram (prog, progs[1]));
    myFile.println(uncompileprogram (prog, progs[2]));
    myFile.println(uncompileprogram (prog, progs[3]));
    // close the file:
    myFile.close();
    Serial.println("Done writing to programm.txt");
  } else {
    Serial.println("Error opening programm.txt");  // programm.txt does not exist
  }
}

void readFromFile() {
  //now read it back and show on Serial monitor
  // Check to see if the file exists:
  if (!SD.exists("/programm.txt"))
    Serial.println("programm.txt doesn't exist.");

  Serial.println("Reading from programm.txt:");
  myFile = SD.open("/programm.txt");

  char inputString[16];  //string to hold read string

  for (uint8_t d = 0, i = 0; myFile.available() && d < dcount; ) {
    char inputChar = myFile.read();  // Gets one byte from serial buffer
    if (inputChar == '\n')           //end of line
    {
      inputString[i] = 0;  //terminate the string correctly
      Serial.println(inputString);
      compileprogram (inputString, progs + d);
      if (i > 13) {
        Serial.println("Incoming string longer than array allows");
        Serial.print("  String No. "); Serial.print(d); Serial.print(" length ");
        Serial.println(i);
      }
      d++;
      i = 0;
    } else if (i < 13) {
      inputString[i] = inputChar;  // Store it
      i++;
    }
  }
  // close the file:
  myFile.close();
  Serial.println("Done reading file");
}
void printFile() {
  char prog[16];  //string to hold read string

  Serial.print("programma 0 = ");
  Serial.println(uncompileprogram (prog, progs[0]));
  Serial.print("programma 1 = ");
  Serial.println(uncompileprogram (prog, progs[1]));
  Serial.print("programma 2 = ");
  Serial.println(uncompileprogram (prog, progs[2]));
  Serial.print("programma 3 = ");
  Serial.println(uncompileprogram (prog, progs[3]));
}

int checkpinok (uint8_t pinno) {
  int i = 0;
  for (i = 0; i < sizeof(usablepins)/sizeof(usablepins[0]); i++) {
    if (pinno == usablepins[i]) break;
  }

  return i < sizeof(usablepins)/sizeof(usablepins[0]);
}

void checkProgram(const struct s_prog prog, struct tm timeInfo, int progNum) {
  uint8_t thisday = (0x01 << timeInfo.tm_wday);

  //Program at I/O1 != empty
  if ((prog.daysofweek & thisday) && prog.hourofday == timeInfo.tm_hour && prog.minuteofhour == timeInfo.tm_min && checkpinok(prog.pinno)) {
    char progstr[16];  //string to hold read string
      std::cout << "Output " << uncompileprogram(progstr, prog) << (prog.pinoutput ? " on\n" : " off\n");
      std::cout << "Output " << progNum << (prog.pinoutput ? " set high\n" : " set low\n");
      pinMode(prog.pinno, (prog.pinoutput ? HIGH : LOW));
  } else {
    // output ! empty but data changing from time or day now
    std::cout << "Output " << progNum << " skipped\n";
  }
}

// So far everything goes fine
void loadProgramm() {
  struct tm timeInfo;
  if (!getLocalTime(&timeInfo)) {
    Serial.println("Failed to obtain time");
    return;
  }

  //std::string prog5 = myString;
  for (int d = 0; d < dcount; d++) {
    checkProgram(progs[d], timeInfo, d);
  } 
  Serial.println("Done checking file");
}
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900