Akvarielys

Kildekode
#include <Bridge.h>
#include <FileIO.h>
#include <Process.h>

Process date;
const byte
  on =1, off = 2, op = 3, ned=4, nat=5,
  PWMPin[] = {3,5,6,9,10,11,13},
  PWRPin[] = {4,7,8,12,A0,A1,A2};
const int MinutterIUge = 7*24*60;
String FileName = "/mnt/sda1/akvarielys.txt";
struct lysskifttype {
  int tid; // minutter siden mandag kl 00:00
  byte funktion;
  byte kanal=0; //kanalnummer 1-7
};
lysskifttype lysskifttabel [196];
int Minutter,
  AntalSkift=0; // antal records i lysskiftetabel;
byte index,
  NextEntry,
  Kanaler,
  ugedag=255,
  Solopgang=30,
  Solnedgang=30,
  Dagslys[]={255,255,155,200,255,255,255},
  Skumring[]={0,100,25,100,255,0,20};   //brg grb
int KanalRecord [7];
boolean DefaultTider=true;

void setup() {
  Bridge.begin();
  Console.begin();
  FileSystem.begin ();
  boolean LinuxDown=true;
  for (index = 0; index <7; index++) {
    pinMode(PWMPin[index],OUTPUT);
    analogWrite(PWMPin[index],0);
    pinMode(PWRPin[index],OUTPUT);
    digitalWrite(PWRPin[index],HIGH);
  }
  while (LinuxDown) {
    File hosts = FileSystem.open("/etc/hosts", FILE_READ);
    if (hosts) {
      hosts.close();
      LinuxDown=false;
    }
  }
  ReadParamFile ();
}
int HentTid () {
    byte ugedag;
    if (!date.running()) {
    date.begin("date");
    date.run();
  }
  while (date.available() > 0) {
    // Hent resultattet for kaldet af Date
    String DateTxt = date.readString();
    Console.print (DateTxt);
    String UgeTxt = DateTxt.substring(0,3);
    if (UgeTxt=="Mon")
      ugedag = 0;
    else if (UgeTxt=="Tue") ugedag = 1;
    else if (UgeTxt=="Wed") ugedag = 2;
    else if (UgeTxt=="Thu") ugedag = 3;
    else if (UgeTxt=="Fri") ugedag = 4;
    else if (UgeTxt=="Sat") ugedag = 5;
    else if (UgeTxt=="Sun") ugedag = 6;
    else ugedag =255;
    // find tiden:
    int firstColon = DateTxt.indexOf(":");
    int secondColon = DateTxt.lastIndexOf(":");
    // udtræk timer og minutter
    String TimeTxt = DateTxt.substring(firstColon-2, firstColon);
    String MinutTxt = DateTxt.substring(firstColon + 1, secondColon);
    // returner antal minutter siden mandag kl 00:00
    return MinutTxt.toInt() + 60 * (TimeTxt.toInt() + 24 * ugedag);
  }
}
String ReadParamLine ( File& Pfile) {
  String line;
  byte nextbyte;
  boolean readon = true;
  while (Pfile.available() && readon) {
    nextbyte = Pfile.read();
    switch (nextbyte) {
      case ' ': //mellemrum springes over
      break;
      case 10: // line feed
      case 13: // carriage return
        if (line.length() > 0) readon = false;
      break;
      case 11: // TAB
        line += ',';
      break;
      default:
        if ((nextbyte >= 'a') && (nextbyte <= 'z')) {
          line += char(nextbyte + ('A' - 'a'));
        }
        else {
          line += char(nextbyte);
          }
      break;
    }
    }
  Console.print(F("Indl\346st: \""));
  Console.print(line);
  Console.println("\"");
  return line;
}
void ReadParamFile (){
  int str_len=FileName.length()+1;
  char filnavn[str_len];
  FileName.toCharArray(filnavn, str_len);
  AntalSkift=0;
  Kanaler=0;
  File ParamFile = FileSystem.open(filnavn, FILE_READ);
  if (!ParamFile) {
    Console.print(FileName);
  Console.println (F(" findes ikke"));
    SetDefault ();
  }
  else {
    Console.print(FileName);
    Console.println (F(" \345bnet"));
    String text = ReadParamLine(ParamFile);
    while (text.length() > 0) {
      if (text.startsWith ("OP")) {
        // tidslængde solopgang
        Solopgang = min (255,text.substring(3).toInt());
      }
      else if (text.startsWith ("NED")) {
        // tidslængde solnegang
        Solnedgang = min (255,text.substring(4).toInt());
      }
      else if (text.startsWith ("DAG")) {
        // Værdier for dagslys
        byte startPos=text.indexOf('=');
    Console.print(F("Dagslys:"));
    for (byte index=0; index<7; index++) {
    startPos ++;
    Dagslys [index]= text.substring(startPos).toInt();
    startPos = text.indexOf(',',startPos);
    Console.print (Dagslys[index]);
    Console.print (",");
    }
    Console.println();
      }
      else if (text.startsWith ("NAT")) {
        // Værdier for skumring
        byte startPos=text.indexOf('=');
        Console.print(F("Skumring:"));
        for (byte index=0; index<7; index++) {
          startPos ++;
          Skumring [index]= text.substring(startPos).toInt();
          startPos = text.indexOf(',',startPos);
          Console.print (Skumring[index]);
          Console.print (",");
        }
      Console.println();
      }
      else {
        // Skifterecord
        byte ugedag=7;
        byte TimePos = text.indexOf(",")+1;
        byte FunktionPos = text.indexOf(",",TimePos)+1;
        byte KanalPos = text.indexOf(",",FunktionPos)+1;
        byte MinutPos = text.indexOf(":")+1;
        if (text.startsWith (",")) {
          for (ugedag=0; ugedag<7; ugedag++) {
            GemRecord(ugedag,text.substring(TimePos).toInt(), // timer
                            text.substring(MinutPos).toInt(), // minutter
                            text.substring(FunktionPos).toInt(), // funktion
                            text.substring(KanalPos).toInt()); // kanal
          }
        }
        else if (text.startsWith ("1-4")) {
          for (ugedag=0; ugedag<4; ugedag++) {
            GemRecord(ugedag,text.substring(TimePos).toInt(), // timer
                            text.substring(MinutPos).toInt(),   // minutter
                            text.substring(FunktionPos).toInt(), // funktion
                            text.substring(KanalPos).toInt()); // kanal
          }
        }
        else if (text.startsWith ("1-5")) {
          for (ugedag=0; ugedag<5; ugedag++) {
            GemRecord(ugedag,text.substring(TimePos).toInt(), // timer
                            text.substring(MinutPos).toInt(),   // minutter
                            text.substring(FunktionPos).toInt(), // funktion
                            text.substring(KanalPos).toInt()); // kanal
          }
        }
        else {
          // find ugedag
          if (text.startsWith ("M")) ugedag=0;
          else if (text.startsWith ("TI")) ugedag=1;
          else if (text.startsWith ("O")) ugedag=2;
          else if (text.startsWith ("TO")) ugedag=3;
          else if (text.startsWith ("F")) ugedag=4;
          else if (text.startsWith ("L")) ugedag=5;
          else if (text.startsWith ("S")) ugedag=6;
          else {
            ugedag=text.toInt();
            if (ugedag>0) {
              ugedag--;
              Console.println (ugedag);
              if (ugedag<7) {
                GemRecord(ugedag,text.substring(TimePos).toInt(), // timer
                                text.substring(MinutPos).toInt(), // minutter
                                text.substring(FunktionPos).toInt(), // funktion
                                text.substring(KanalPos).toInt()); // kanal
              }
            }
          }
        }
      }
      text = ReadParamLine(ParamFile);
    }
    ParamFile.close();
    if (AntalSkift == 0) SetDefault(); else DefaultTider=false;
  }
}
void GemRecord (byte ugedag, byte hour, byte minut, byte funktion, byte kanal) {
  lysskifttabel [AntalSkift].tid = 60 *(24 * ugedag + hour) + minut;
  lysskifttabel [AntalSkift].funktion = funktion;
  lysskifttabel [AntalSkift].kanal=kanal;
  Console.print(AntalSkift);
  Console.print(F(": Tid: "));
  Console.print(lysskifttabel[AntalSkift].tid);
  Console.print(F(": Funktion: "));
  Console.print(lysskifttabel[AntalSkift].funktion);
  Console.print(F(": Kanal: "));
  Console.println(lysskifttabel[AntalSkift].kanal);
  AntalSkift ++;
  if (kanal > Kanaler) Kanaler = kanal;
}
void SetDefault () {
  AntalSkift = 0;
  for (byte ugedag = 0; ugedag < 7; ugedag++) {
    for (byte kanal = 0; kanal < 6; kanal++) {
      GemRecord (ugedag, 8, 0, nat,kanal);
      GemRecord (ugedag, 11, 0, op,kanal);
      GemRecord (ugedag, 22, 0, ned,kanal);
      GemRecord (ugedag, 23, 59, off,kanal);
    }
  }
  DefaultTider=true;
}

void loop() {
  String ConsLine;
  Minutter = HentTid ( );
  // Indlæs parametre fra Console
  while (Console.available () > 0) {
  ConsLine += char(Console.read ());
  }
  ConsLine.trim();
  Console.print("*");
  Console.print(ConsLine);
  Console.println("*");
  if (ConsLine.startsWith("fil")) {
    if (ConsLine.length()>4) {
      FileName = ConsLine.substring(4);
      FileName.trim();
  if (!(FileName.startsWith("/mnt"))) FileName="/mnt/sda1/" + FileName;
  }
  ReadParamFile ();
  }
  if (DefaultTider) ReadParamFile ();
  //find sidste skift før nuværende klokke for hver kanal
  for (byte Kanal=0; Kanal < Kanaler; Kanal++) {
    KanalRecord [Kanal] = -1;
  }
  for (index=0; index <AntalSkift; index++) {
    if (lysskifttabel [index].tid > Minutter) {
      lysskifttabel [index].tid -= MinutterIUge;
    };
    if ((lysskifttabel [index].tid + MinutterIUge) <= Minutter) {
    lysskifttabel [index].tid += MinutterIUge;
    }
    if (KanalRecord[lysskifttabel[index].kanal] ==-1){
        KanalRecord [lysskifttabel[index].kanal] = index;
    }
    else if (lysskifttabel[index].tid >= lysskifttabel [KanalRecord[lysskifttabel[index].kanal]].tid) {
      KanalRecord [lysskifttabel[index].kanal] = index;
    }
  }

  byte PWM;
  for (byte Kanal = 0; Kanal <= Kanaler; Kanal++) {
    if ((0 <= KanalRecord[Kanal]) && (KanalRecord[Kanal]< AntalSkift) ) {
    Console.print (KanalRecord[Kanal]);
      Console.print ( F(" Tid: "));
      Console.print (lysskifttabel[KanalRecord[Kanal]].tid);
      Console.print ( F(" Funktion: "));
      Console.print (lysskifttabel[KanalRecord[Kanal]].funktion);
      Console.print ( F(" Kanal: "));
      Console.print (lysskifttabel[KanalRecord[Kanal]].kanal);
      switch (lysskifttabel[KanalRecord[Kanal]].funktion) {
      case on:
        PWM = Dagslys [Kanal];
        digitalWrite (PWRPin [Kanal], LOW);
      break;
      case off:
        PWM = 0;
        digitalWrite (PWRPin [Kanal], HIGH);
      break;
      case op:
        if ((lysskifttabel[KanalRecord[Kanal]].tid + Solopgang ) <= Minutter) {
          PWM = Dagslys [Kanal];
        }
        else {
          PWM = Skumring [Kanal]
            + int (
            float(Dagslys [Kanal]-Skumring [Kanal])
            * float(Minutter-lysskifttabel[KanalRecord[Kanal]].tid)
            / float(Solopgang));
        }
        digitalWrite (PWRPin [Kanal], LOW);
      break;
      case ned:
        if ((lysskifttabel[KanalRecord[Kanal]].tid + Solnedgang ) <= Minutter) {
          PWM = Skumring [Kanal];
        }
        else {
        PWM = Dagslys [Kanal]
            - int (
            float (Dagslys [Kanal]-Skumring [Kanal])
            * float (Minutter-lysskifttabel[KanalRecord[Kanal]].tid)
            / float (Solnedgang));
        }
        digitalWrite (PWRPin [Kanal], LOW);
      break;
      case nat:
        PWM = Skumring [Kanal];
        digitalWrite (PWRPin [Kanal], LOW);
      break;
  }
  analogWrite (PWMPin [Kanal], PWM);
  Console.print ( F(" PWM: "));
  Console.println (PWM);
    }
    else {
      analogWrite (PWMPin [Kanal], 0);
      digitalWrite (PWRPin [Kanal], HIGH);
    }
  }
  delay (10000);
}