#include <EEPROM.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <PWM.h>
#include <ArduinoBoardManager.h> //https://stackoverflow.com/questions/13853109/determine-board-type-of-arduino
#include <SoftwareSerial.h>
/* Pin 2: Taster (interrupt)
Pin 3: Pir (interrupt)
Pin 4: DCF Eingang
Pin 5: Motor Klappe (PWM)
Pin 6: Endschalter Klappe Input
Pin 7: GSM TX
Pin 8: GSM RX
Pin 9: PWM out für Hochspannung
Pin 14 Nano /Pin 10 Pro Mini Einschalter HS DC
Pin 15 Nano /Pin 11 Pro Mini Lagesensor
Pin 16 Nano /Pin 12 Pro Mini LED Ansteuerung
Pin 18 Nano /Pin 14 Pro Mini Schalter am Nutella
Pin A7 Nano /Pin A3 Pro Mini Analoge Spannungsüberwachung
LED_BUILTIN ist beim ano und pro mini die 13
Bleiben noch 4 Aus/Eingänge übrig
*/
#define dcfpin 4
#define M_Klappe 5
#define Endschalter 6
String NR_Anlage = "123456";
String SWVERSION = "1.0";
String NR_Anlage_s ;
String dataString;
String SMSMESSAGE = "";
String timestamp;
byte Version_high;
byte Version_low;
const byte pintaster = 2;
const byte pirtaster = 3;
const byte HF_PIN = 9;
byte PIN_Einschalten_HS_DC;
byte PIN_Lagesensor;
byte PIN_LED;
byte PIN_Voltage;
byte PIN_Schalter;
ArduinoBoardManager arduino = ArduinoBoardManager(); // required if you want to know the board name and specific features
SoftwareSerial mySerial(7, 8);
int EEPROM_Size;
typedef struct {
byte delphi_time0;
byte delphi_time1;
byte delphi_time2;
byte delphi_time3;
byte delphi_time4;
byte delphi_time5;
byte delphi_time6;
byte delphi_time7;
} t_lesepuffer;
unsigned int v_uint;
unsigned int anzahl_log;
unsigned int counter_puffer = 0;
unsigned int Ratten_count;
int anzahl_log_max;
byte v_byte;
byte state = 10; //klappe beim starten zufahren
byte v_byte0;
byte v_byte1;
byte warte_Spannungsfehler;
byte befehl;
byte gprs_valid = 100;
byte Spannung;
unsigned long v_ulong;
unsigned long diff = 100; //das ist für blinken/blitzen
unsigned long last_change_blinken;
unsigned long last_change_blitzen;
unsigned long last_awake;
unsigned long warte_schlafen;
unsigned long warte_schlafen_taster = 24 * 60ul * 60ul * 1000ul; //einen Tag;
unsigned long warte_schlafen_pir = 30ul * 60ul * 1000ul; //30 Minuten
unsigned long Klappe_fahren;
unsigned long Timeout_Klappe = 10ul * 1000ul; // 10 Sekunden
unsigned long HS_Dauer;
unsigned long Pulsdauer = 60ul * 1000ul; //1 Minute
unsigned long Start_Tastendruck;
unsigned long start_anzeige;
unsigned long start_dauer = 0ul;
unsigned long gprs_dauer = 0ul;
bool dfc_debug = 0;
bool versendet =0;
int v_int;
bool first_serial = 0;
bool gruen_blinken = 0;
bool gruen_blitzen = 0 ;
bool blinken = true;
bool blitzen = true;
bool v_bool;
volatile bool int_taster = 1;
volatile bool int_pir = 0;
//bool agent;
byte dcf_index = 0;
bool dcf_signal = 1;
bool dcf_signal_neu;
unsigned long dcf_jetzt;
int dcf[59];
byte dcfjahr;
byte dcfmonat;
byte dcftag;
byte dcfminute;
byte dcfstunde;
byte dcf_byte1;
byte dcf_byte2;
byte dcf_byte3;
unsigned long dcf_valid = 0;
unsigned long dcf_diff;
unsigned long dcf_start;
word pwmWert;
float freq = 200.0; //in Hertz
float pulse = 40.0; //in microsekunden
char MESS_string[160];
t_lesepuffer lesepuffer;
void(* resetFunc) (void) = 0;//declare reset function at address 0
//Ende deklaration_________________________________________________________________
void schreibe_log() {
anzahl_log = EEPROM.read(9) * 256 + EEPROM.read(10);//Anzahl log_einträge
anzahl_log = anzahl_log + 1;
if (dfc_debug == 1) {
Serial.print("Log ");
Serial.println(anzahl_log);
};
if (anzahl_log > anzahl_log_max) { //maximal 335 von 0..334 anzahl_log_max = (EEPROM_Size-19)/3; // entweder 164 oder 335
anzahl_log = 1;
update_bit(13, 6, 1); //ist ja eigentlich kein fehler)
};
v_uint = anzahl_log;
schreibe_uint(9); // start vom log ist schon mal geschrieben, an die Position kommt der log-Eintrag
v_uint = v_uint - 1; //weil ich keine -1 darstellen kann
/* v_ulong = glob_millis;
v_byte0 = v_ulong >> 16;
v_byte1 = v_ulong >> 24;
v_byte = EEPROM.read(8);*/
EEPROM.update((v_uint * 3 + 19), dcf_byte1);
EEPROM.update((v_uint * 3 + 19 + 1), dcf_byte2);
EEPROM.update((v_uint * 3 + 19 + 2), dcf_byte3);
}
void lese_dataString() {
dataString = "";
gprs_valid++;
if (mySerial.available()) {
dataString = mySerial.readString();
Serial.println(dataString);
if (!((dataString.indexOf("OK") > 0 ) || (dataString.indexOf(">") > 0 ))) {
gprs_valid = 0;
}
}
else {
if (gprs_valid != 3) {
gprs_valid = 0;
Serial.println("Timeout");
}
}
Serial.println(dataString);
Serial.print("gprs ");
Serial.println(gprs_valid);
};
void mysend(String inst) {
v_byte = EEPROM.read(11);
if (bitRead(v_byte, 6) > 0) {
gprs_valid = 0;
SMSMESSAGE="";
if (dcf_valid!=0ul) {
SMSMESSAGE=timestamp;
}
SMSMESSAGE=SMSMESSAGE+NR_Anlage_s+" "+String(Spannung/10.0)+"V "+inst;
}
}
void sende_Message() {
switch (gprs_valid) {
case 0:
mySerial.write(27); // falls er im > stecken geblieben ist
gprs_valid++;
break;
case 1:
mydelay(100, 1);
break;
case 2:
lese_dataString();
break;
case 3:
Serial.println("Schreibe: AT+CSQ");
mySerial.println("AT+CSQ"); // Qualität
gprs_valid++;
break;
case 4:
mydelay(100, 1); //40ms
break;
case 5:
lese_dataString();
if (dataString.indexOf("+CSQ: 0,0") <= 0 ) {
Serial.println("nicht gefunde");
Serial.println(gprs_valid);
Serial.println(dataString.indexOf("+CSQ: 0,0"));
}
else {
Serial.println("gefunden");
gprs_valid = 0;
}
break;
case 6:
Serial.println("Schreibe: AT+CSMP=17,167,0,17");
mySerial.println("AT+CSMP=17,167,0,17"); // Einstellungen
gprs_valid++;
break;
case 7:
mydelay(100, 1); //20ms
break;
case 8:
lese_dataString();
break;
case 9:
Serial.println("Schreibe: AT+CMGF=1");
mySerial.println("AT+CMGF=1"); // SMS text mode
gprs_valid++;
break;
case 10:
mydelay(100, 1); //30ms
break;
case 11:
lese_dataString();
break;
case 12:
Serial.println("Schreibe: AT+CMGS=\"+491716981260\"");
mySerial.println("AT+CMGS=\"+491716981260\"");
gprs_valid++;
break;
case 13:
mydelay(2000, 1); //800ms
break;
case 14:
lese_dataString();
break;
case 15:
Serial.println(SMSMESSAGE);
mySerial.print(SMSMESSAGE);
mySerial.write(26);
mySerial.println("");
gprs_valid++;
break;
case 16:
mydelay(200, 1); //70ms
break;
case 17:
Serial.println("V11");
lese_dataString();
if (gprs_valid == 18) {
SMSMESSAGE = "";
gprs_valid++;
}
break;
default:
break;
}
}
void mydelay(unsigned long dauer, byte fall) { // 130 -> 140 oder 110 -> 115
switch (fall) {
case 0:
if (start_dauer == 0ul) {
start_dauer = millis();
}
else {
if ((millis() - start_dauer) > dauer) {
start_dauer = 0ul;
if (state == 130) {
state = 140;
}
else {
state = 115;
};
}
}
break;
case 1:
if (gprs_dauer == 0ul) {
gprs_dauer = millis();
}
else {
if ((millis() - gprs_dauer) > dauer) {
gprs_dauer = 0ul;
gprs_valid++;
}
else {
if (mySerial.available()) {
Serial.println("Daten vorhanden");
gprs_dauer = 0ul;
gprs_valid++;
}
}
}
break;
default:
break;
};
};
void DCF() {
// put your main code here, to run repeatedly:
dcf_signal_neu = digitalRead(dcfpin);
if ((dcf_signal_neu == 0) & (dcf_signal == 1)) {
//Zeitmessung starten bei abfallender Flanke
dcf_jetzt = millis();
};
if ((dcf_signal_neu == 1) & (dcf_signal == 0)) {
//Zeitmessung stoppt bei ansteigender Flanke
dcf_diff = millis() - dcf_jetzt;
if (dfc_debug == 1) {
Serial.print(dcf_index);
Serial.print(" ");
Serial.println(dcf_diff);
};
if (dcf_diff > 1500ul) {
if (dfc_debug == 1) {
Serial.println("Luecke");
}
dcf_diff = dcf_diff - 1000ul;
if (dcf_diff < 880ul) {
dcf_signal = 1;
}
else {
dcf_signal = 0;
}
dcf[dcf_index] = dcf_signal;
bool par_error = 0;
dcfjahr = dcf[50] + dcf[51] * 2 + dcf[52] * 4 + dcf[53] * 8 + (dcf[54] + dcf[55] * 2 + dcf[56] * 4 + dcf[57] * 8) * 10 - 24;
dcfmonat = dcf[45] + dcf[46] * 2 + dcf[47] * 4 + dcf[48] * 8 + dcf[49] * 10;
dcftag = dcf[36] + dcf[37] * 2 + dcf[38] * 4 + dcf[39] * 8 + (dcf[40] + dcf[41] * 2) * 10;
if (((dcf[36] + dcf[37] + dcf[38] + dcf[39] + dcf[40] + dcf[41] + dcf[42] + dcf[43] + dcf[44] + dcf[45] + dcf[46] + dcf[47] + dcf[48] + dcf[49] + dcf[50] + dcf[51] + dcf[52] + dcf[53] + dcf[54] + dcf[55] + dcf[56] + dcf[57]) % 2) != dcf[58]) {
par_error = 1;
};
dcfstunde = dcf[29] + dcf[30] * 2 + dcf[31] * 4 + dcf[32] * 8 + (dcf[33] + dcf[34] * 2) * 10;
if (((dcf[29] + dcf[30] + dcf[31] + dcf[32] + dcf[33] + dcf[34]) % 2) != dcf[35]) {
par_error = 1;
};
dcfminute = dcf[21] + dcf[22] * 2 + dcf[23] * 4 + dcf[24] * 8 + (dcf[25] + dcf[26] * 2 + dcf[27] * 4) * 10;
if (((dcf[21] + dcf[22] + dcf[23] + dcf[24] + dcf[25] + dcf[26] + dcf[27]) % 2) != dcf[28]) {
par_error = 1;
};
if ((par_error == 0) & (dcf_index == 58)) {
timestamp=String(dcftag)+"."+String(dcfmonat)+"."+String(dcfjahr)+" "+String(dcfstunde)+":"+String(dcfminute)+" ";
if (versendet==0) {
mysend(" Test zur Meldung");
versendet=1;
}
if (dfc_debug == 1) {
Serial.print("Jahr :"); Serial.println(dcfjahr);
Serial.print("Monat :"); Serial.println(dcfmonat);
Serial.print("tag :"); Serial.println(dcftag);
Serial.print("Stunde :"); Serial.println(dcfstunde);
Serial.print("Minute :"); Serial.println(dcfminute);
};
bitWrite(dcf_byte1, 7, bitRead(dcftag, 4));
bitWrite(dcf_byte1, 6, bitRead(dcftag, 3));
bitWrite(dcf_byte1, 5, bitRead(dcftag, 2));
bitWrite(dcf_byte1, 4, bitRead(dcftag, 1));
bitWrite(dcf_byte1, 3, bitRead(dcftag, 0));
bitWrite(dcf_byte1, 2, bitRead(dcfmonat, 3));
bitWrite(dcf_byte1, 1, bitRead(dcfmonat, 2));
bitWrite(dcf_byte1, 0, bitRead(dcfmonat, 1));
bitWrite(dcf_byte2, 7, bitRead(dcfmonat, 0));
bitWrite(dcf_byte2, 6, bitRead(dcfjahr, 5));
bitWrite(dcf_byte2, 5, bitRead(dcfjahr, 4));
bitWrite(dcf_byte2, 4, bitRead(dcfjahr, 3));
bitWrite(dcf_byte2, 3, bitRead(dcfjahr, 2));
bitWrite(dcf_byte2, 2, bitRead(dcfjahr, 1));
bitWrite(dcf_byte2, 1, bitRead(dcfjahr, 0));
bitWrite(dcf_byte2, 0, bitRead(dcfstunde, 4));
bitWrite(dcf_byte3, 7, bitRead(dcfstunde, 3));
bitWrite(dcf_byte3, 6, bitRead(dcfstunde, 2));
bitWrite(dcf_byte3, 5, bitRead(dcfstunde, 1));
bitWrite(dcf_byte3, 4, bitRead(dcfstunde, 0));
bitWrite(dcf_byte3, 3, bitRead(dcfminute, 5));
bitWrite(dcf_byte3, 2, bitRead(dcfminute, 4));
bitWrite(dcf_byte3, 1, bitRead(dcfminute, 3));
bitWrite(dcf_byte3, 0, bitRead(dcfminute, 2)); // 1 und 2 werden ignoriert
dcf_valid = millis();
update_bit(13, 4, 0);
digitalWrite(LED_BUILTIN, LOW);
//Serial.println("Valid");
while (counter_puffer != 0) {
schreibe_log();
counter_puffer--;
// Serial.println(counter_puffer);
}
}
dcf_index = 0;
}
else {
if (dcf_diff < 880ul) {
dcf_signal = 1;
}
else {
dcf_signal = 0;
}
dcf[dcf_index] = dcf_signal;
dcf_index++;
if (dcf_index == 59) {
dcf_index = 0;
}
};
};
dcf_signal = dcf_signal_neu;
if (dcf_valid!=0){
digitalWrite(LED_BUILTIN, 1);
}
else {
digitalWrite(LED_BUILTIN, blinken);
}
};
void set_blinken() {
gruen_blinken = 0;
gruen_blitzen = 0;
v_byte = EEPROM.read(13);
if (bitRead(v_byte, 6) > 0) { //überlauf log
gruen_blinken = 1;
};
if (bitRead(v_byte, 5) > 0) { //überlauf Rattenzahler
gruen_blinken = 1;
};
if (bitRead(v_byte, 4) > 0) { //DCF Invalid
gruen_blinken = 1;
};
if (bitRead(v_byte, 7) > 0) { //Spannungsfehler
gruen_blitzen = 1;
};
if (bitRead(v_byte, 3) > 0) { //Timeout bei beim Endschalter Klappe
gruen_blitzen = 1;
};
if (bitRead(v_byte, 2) > 0) { //Lagefehler
gruen_blitzen = 1;
};
if (gruen_blitzen) {
gruen_blinken = 0;
}
if (millis() - last_change_blinken > 500) { //blinken
blinken = not(blinken);
last_change_blinken = millis();
};
if (millis() - last_change_blitzen > diff) { //blitzen
if (diff == 100) {
blitzen = 0;
diff = 900;
last_change_blitzen = millis();
}
else {
blitzen = 1;
diff = 100;
last_change_blitzen = millis();
};
};
v_bool = digitalRead(pintaster);
v_bool = 1; //agent
if (v_bool == true) {
if (gruen_blinken) {
digitalWrite(PIN_LED, blinken);
}
else {
if (gruen_blitzen) {
digitalWrite(PIN_LED, blitzen);
}
else {
digitalWrite(PIN_LED, 1); //Wenn der Taster gedrückt ist und alles ok-> grün
}
};
}
else {
digitalWrite(PIN_LED, 0);
};
};
void update_bit(byte nr_byte, byte bitpos, byte wert) {
v_byte = EEPROM.read(nr_byte);
bitWrite(v_byte, bitpos, wert);
EEPROM.update(nr_byte, v_byte);
};
/*void set_tage() {
v_ulong = millis();
// diff_millis = v_ulong - old_millis;
// old_glob_millis = glob_millis;
// glob_millis = glob_millis + diff_millis;
// old_millis = v_ulong;
/* if (ueberlauf_tage == 1) {
glob_millis = 0;
EEPROM.update(8, 255);
};
if (glob_millis < old_glob_millis) {
v_byte = EEPROM.read(8); //tage50++ erhöhen
if (v_byte == 255) {
update_bit(13, 4, 1);
};
v_byte = v_byte + 1;
EEPROM.update(8, v_byte);
if (ueberlauf_tage == 1) {
ueberlauf_tage = 0;
};
};
};*/
void check_spannungsausfall() {
int PV = analogRead(PIN_Voltage);
Spannung = byte((PV * 5.0) * 3.0 / 1024.0); // die *3.0 kommt durch den Spannungsteiler
if (PV < 500) {
v_byte = EEPROM.read(13);
if (bitRead(v_byte, 7) == 0) { //Spannungsfehler neu aufgetreten
mysend(" Spannungsausfall");
update_bit(13, 7, 1);
state = 11;
};
if (PV > 600) {
v_byte = EEPROM.read(13);
if (bitRead(v_byte, 7) == 1) { //Spannungsfehler Wieder weg
mysend(" Spannungsausfall aufgehoben");
update_bit(13, 7, 0);
state = 12;
};
};
};
};
void schreibe_int(byte position, unsigned int wert) {
EEPROM.write(position, highByte(wert));
EEPROM.write(position + 1, lowByte(wert));
};
void schreibe_uint1(unsigned int position, unsigned int wert) {
EEPROM.write(position, highByte(wert));
EEPROM.write(position + 1, lowByte(wert));
};
void schreibe_uint(unsigned int position) {
EEPROM.write(position, highByte(v_uint));
EEPROM.write(position + 1, lowByte(v_uint));
};
void Ratte_hochzaehlen() {
v_uint = EEPROM.read(16) * 256 + EEPROM.read(17);
if (v_uint == 65535) { //Rattenzähler
update_bit(13, 5, 1);
};
v_uint = v_uint + 1;
EEPROM.write(16, highByte(v_uint));
EEPROM.write(17, lowByte(v_uint));
v_uint = EEPROM.read(16) * 256 + EEPROM.read(17);
if (dcf_valid != 0ul) { //update log
schreibe_log();
}
else {
counter_puffer++;
};
}
void check_command() {
if (Serial.available()) { // Daten liegen an
if (first_serial == 0) {
first_serial = 1;
};
last_awake = millis();
Serial.readBytes((byte*)&befehl, sizeof(befehl));
switch (befehl) {
case 49: // Uhrzeit setzen
/* Serial.readBytes((byte*)&lesepuffer, sizeof(lesepuffer));
EEPROM.update(0, lesepuffer.delphi_time0); // wenn die Uhr gesetzt ist, muss der eigene Timer auf Null gesetzt werden
EEPROM.update(1, lesepuffer.delphi_time1);
EEPROM.update(2, lesepuffer.delphi_time2);
EEPROM.update(3, lesepuffer.delphi_time3);
EEPROM.update(4, lesepuffer.delphi_time4);
EEPROM.update(5, lesepuffer.delphi_time5);
EEPROM.update(6, lesepuffer.delphi_time6);
EEPROM.update(7, lesepuffer.delphi_time7);
// glob_millis = 0;
// old_millis = millis();
EEPROM.update(8, 0); // überlauf (tage50) //wenn die Zeit gesetzt wird, muss der Log ebenfalls gelöscht werden*/
Serial.write(befehl);
break;
case 50: //log anfordern 2
v_byte = EEPROM_Size >> 8;
Serial.write(v_byte);
v_byte = EEPROM_Size;
Serial.write(v_byte);
int v_int1 = EEPROM_Size - 1;
for ( v_int = 0; v_int <= v_int1; v_int = v_int + 1) {
v_byte = EEPROM.read(v_int);
Serial.write(v_byte);
};
break;
case 51: // Diagnose anfordern 3
v_byte = EEPROM.read(13);
Serial.write(EEPROM.read(13));
break;
case 52: // log löschen 4
v_uint = 0;
schreibe_uint(9); //start schreiben
update_bit(13, 6, 0); // log Daten überlauf
update_bit(13, 4, 0); //Tage50 überlauf
Serial.write(befehl);
break;
case 53: // Diagnose löschen Überlauf log wird nicht gelöscht (ist das 6. Bit) 5
update_bit(13, 7, 0); // Spannung weg
update_bit(13, 5, 0); //Überlauf Rattenzäehler
update_bit(13, 4, 0); // Tage50 überlauf
v_byte = EEPROM.read(13);
Serial.write(befehl);
break;
case 54: // Ratte hochzählen, log schreiben das brauchen wir hinterher nicht mehr.. nur zum test gleich 6 in der Eingabe 6
Ratte_hochzaehlen();
Serial.write(befehl);
break;
case 55: // Ratten löschen 7
EEPROM.update(16, 0); EEPROM.update(17, 0);
update_bit(13, 5, 0); //Überlauf Rattenzäehler
Serial.write(befehl);
break;
case 56: // Rücklesen 8
// Serial.println("Rücklesen");
Serial.write(EEPROM.read(0));
Serial.write(EEPROM.read(1));
Serial.write(EEPROM.read(2));
Serial.write(EEPROM.read(3));
Serial.write(EEPROM.read(4));
Serial.write(EEPROM.read(5));
Serial.write(EEPROM.read(6));
Serial.write(EEPROM.read(7));
Serial.write(EEPROM.read(8));
Serial.write(EEPROM.read(9));
Serial.write(EEPROM.read(10));
Serial.write(EEPROM.read(11));
Serial.write(EEPROM.read(12));
Serial.write(EEPROM.read(13));
Serial.write(EEPROM.read(14));
Serial.write(EEPROM.read(15));
Serial.write(EEPROM.read(16));
Serial.write(EEPROM.read(17));
Serial.write(EEPROM.read(18));
break;
case 97: // Debug einschalten und Überlauf log_meldungen
EEPROM.update(9, 1); EEPROM.update(10, 79);
anzahl_log = EEPROM.read(9) * 256 + EEPROM.read(10);//Anzahl log_einträge
Serial.write(befehl);
break;
case 98: // Debug einschalten und Spannungsfehlermeldung
warte_Spannungsfehler = 1;
Serial.write(befehl);
break;
case 99: // Debug einschalten und Überlauf Anzahl Ratten
EEPROM.update(16, 255); EEPROM.update(17, 255);
Serial.write(befehl);
break;
case 100: // Debug einschalten und Überlauf Tage setzen
Serial.write(befehl);
break;
case 101: // Hochspannung abschalten
EEPROM.update(11, 128);
Serial.write(EEPROM.read(11));
break;
case 102: // Hochspannung einschalten
EEPROM.update(11, 0);
Serial.write(EEPROM.read(11));
default:
break;
};
};
};
void check_taste() {
if (Start_Tastendruck != 0ul) {
if (digitalRead(pintaster) == 0) { //hat wieder losgelassen
v_ulong = millis() - Start_Tastendruck;
if (v_ulong > 100ul) {
if (v_ulong < 5000ul) {
start_anzeige = millis();
Start_Tastendruck = 0ul;
}
else {
resetFunc();
}
}
}
}
if (start_anzeige != 0ul) {
if (gruen_blinken) {
digitalWrite(PIN_LED, blinken);
}
else {
if (gruen_blitzen) {
digitalWrite(PIN_LED, blitzen);
}
else {
digitalWrite(PIN_LED, 1); //Wenn der Taster gedrückt ist und alles ok-> grün
}
};
if ((millis() - start_anzeige) > 10000ul) {
digitalWrite(PIN_LED, 0); //Wenn der Taster gedrückt ist und alles ok-> grün
start_anzeige = 0ul;
}
}
}
void check_sleep() {
if ((millis() - last_awake) > warte_schlafen) {
int_taster = 0;
int_pir = 0;
if (counter_puffer > 0) {
update_bit(13, 4, 1);
dcf_byte1 = 0;
dcf_byte2 = 0;
dcf_byte3 = 0;
}
while (counter_puffer != 0) { //da hat er leider kein dcf-Signal bekommen
schreibe_log();
counter_puffer--;
};
sleep_enable();
sleep_mode();
dcf_valid = 0;
update_bit(13, 4, 1);
sleep_disable();
if (int_taster == 1) {
warte_schlafen = warte_schlafen_taster; //
Start_Tastendruck = millis();
}
else {
warte_schlafen = warte_schlafen_pir;
};
last_awake = millis();
};
};
void taster_gedrueckt()
{
int_taster = 1;
};
void pir_gedrueckt()
{
int_pir = 1;
}
void fahre_klappe_zu() { //state=10 (initial) 12 (Spannungsfehler wieder weg) oder 130 (letzter)
if (digitalRead(Endschalter) == 1) { //Endschalter offen, muss geschlossen sein, also auf 0
if (Klappe_fahren == 0ul) {
Klappe_fahren = millis();
digitalWrite(M_Klappe, HIGH);
}
if ((millis() - Klappe_fahren) > Timeout_Klappe) {
digitalWrite(M_Klappe, LOW);
update_bit(13, 3, 1);
Klappe_fahren = 0ul;
state = 0;
}
}
else {
digitalWrite(M_Klappe, LOW);
state = 100;
}
};
void fahre_klappe_auf() { // 11 (Spannungsfehler aufgetreten) oder 120
if (digitalRead(Endschalter) == 0) { //Endschalter geschlossen, muss offen sein, also auf 0
if (Klappe_fahren == 0ul) {
Klappe_fahren = millis();
digitalWrite(M_Klappe, HIGH);
}
if ((millis() - Klappe_fahren) > Timeout_Klappe) {
digitalWrite(M_Klappe, LOW);
update_bit(13, 3, 1);
state = 0;
Klappe_fahren = 0ul;
}
}
else {
digitalWrite(M_Klappe, LOW);
if (state == 120) {
state = 130;
}
else {
state = 100;
}
}
};
void check_lage() {
if (PIN_Lagesensor == HIGH) {
v_byte = EEPROM.read(13);
if (bitRead(v_byte, 2) == 0) { //Lagefehler neu aufgetreten
mysend(" umgefallen");
update_bit(13, 2, 1);
};
if (PIN_Lagesensor == LOW) {
v_byte = EEPROM.read(13);
if (bitRead(v_byte, 2) == 1) { //Lagefehler Wieder weg
mysend(" Wieder aufgerichtet");
update_bit(13, 2, 0);
};
};
};
};
//Hier das Setup_______________________________________________________________________________________
void setup() {
/*
Pin 14 Nano /Pin 10 Pro Mini Einschalter HS DC
Pin 15 Nano /Pin 11 Pro Mini Lagesensor
Pin 16 Nano /Pin 12 Pro Mini LED Ansteuerung
Pin A7 Nano /Pin A3 Pro Mini Analoge Spannungsüberwachung
*/
if (arduino.BOARD_NAME == "nano") {
PIN_Einschalten_HS_DC = 14;
PIN_Lagesensor = 15;
PIN_LED = 16;
PIN_Voltage = A7;
PIN_Schalter = 18;
}
else {
PIN_Einschalten_HS_DC = 10;
PIN_Lagesensor = 11;
PIN_LED = 12;
PIN_Voltage = A3;
PIN_Schalter = 14;
}
EEPROM_Size = EEPROM.length(); //entweder 512 oder 1024
EEPROM_Size = 512; //debug
anzahl_log_max = (EEPROM_Size - 19) / 3; // entweder 164 oder 335
attachInterrupt(digitalPinToInterrupt(2), taster_gedrueckt, CHANGE);
attachInterrupt(digitalPinToInterrupt(3), pir_gedrueckt, CHANGE);
set_sleep_mode(SLEEP_MODE_IDLE);
// SLEEP_MODE_IDLE - the lowest power saving mode
// SLEEP_MODE_ADC
// SLEEP_MODE_PWR_SAVE + legt millis lahm
// SLEEP_MODE_STANDBY -legt millis lahm
// SLEEP_MODE_PWR_DOWN - legt millis lahm
warte_schlafen = warte_schlafen_taster; //debug
InitTimersSafe();
pinMode(HF_PIN, OUTPUT);
pwmWert = round(0.065536 * freq * pulse);
SetPinFrequencySafe(HF_PIN, word(freq) ); //200 = Frequenz
pinMode(pintaster, INPUT_PULLUP);
pinMode(pirtaster, INPUT_PULLUP);
pinMode(PIN_Lagesensor, INPUT_PULLUP);
pinMode(PIN_LED, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(dcfpin, INPUT);
pinMode(Endschalter, INPUT_PULLUP);
pinMode(PIN_Schalter, INPUT_PULLUP);
pinMode(M_Klappe, OUTPUT);
Serial.setTimeout(1000);
Serial.begin(115200);
mySerial.begin(57600);
EEPROM.update(13, 0); //Fehlerbyte
dcf_valid = 0;
update_bit(13, 4, 1);
digitalWrite(LED_BUILTIN, HIGH);
last_change_blinken = millis();
last_change_blitzen = millis();
last_awake = millis();
NR_Anlage_s = NR_Anlage;
while (NR_Anlage_s.substring(0, 1) == "0") {
NR_Anlage_s = NR_Anlage_s.substring(1);
};
v_byte1 = EEPROM.length() >> 8;
v_byte0 = EEPROM.length();
Serial.print("ROGER");
Serial.print(NR_Anlage);//fehler?
Version_high = SWVERSION.substring(0, v_byte).toInt();
Version_low = SWVERSION.substring(v_byte + 1, 100).toInt();
Serial.write(Version_high);
Serial.write(Version_low);
};
void loop() {
check_spannungsausfall(); //
// set_tage(); //falls es im glob_millis einen überlauf gibt wird das hier mitgezählt
check_command(); // verarbeiten
check_sleep();
check_lage();
DCF();
check_taste();
set_blinken();
sende_Message();
switch (state) { // hier kommt die State Maschine rein...
case 0: // //hier landet man, wenn die Klappe nicht gefahren werden konnte. Nur durch einen Reset zu verlassen
break;
case 10: //
fahre_klappe_zu(); // initial, falls vorher ein Spannungsfehler warte_schlafen
break;
case 11: //
fahre_klappe_auf(); //da ist das erste mal ein Spannungsfehler aufgetreten
break;
case 12: //
fahre_klappe_zu(); // da ist der Spannungsfehler wieder weg
break;
case 100: // hier wird gewartet, bis der kontakt ausgelöst wird.
if (gruen_blitzen == 0) {
if (digitalRead(PIN_Schalter) == 0) {
v_byte = EEPROM.read(11);
if (bitRead(v_byte, 7) == 0) { // kein Hochspannnung?
state = 105;
}
else {
state = 120;
}
}
}
break;
case 105: //
digitalWrite(PIN_Einschalten_HS_DC, HIGH);
pwmWriteHR(HF_PIN, pwmWert); // 5000 =0,5 ms; 20000=1,5ms;40000=3ms; 10000=1ms;
state = 110;
break;
case 110: //
mydelay(Pulsdauer, 0);
break;
case 115: //
digitalWrite(PIN_Einschalten_HS_DC, LOW);
pwmWriteHR(HF_PIN, 0); // 5000 =0,5 ms; 20000=1,5ms;40000=3ms; 10000=1ms;
state = 120;
break;
case 120: //
fahre_klappe_auf();
break;
case 130: //
mydelay(1000, 0);
break;
case (140):
fahre_klappe_zu();
Ratte_hochzaehlen();
mysend(" Ratte getoetet, insgesamt " + String( Ratten_count));
break;
default:
break;
};
}
// void(* resetFunc) (void) = 0; //declare reset function @adress 0 aus https://www.instructables.com/two-ways-to-reset-arduino-in-software/
/*
//2+ log holen = Zeitstempel, aktuelle millisekunden
//wieviele Sekunden hat der Tag: 86400 das passt nur in eine long variable bis 2147483647, dann sind bis millisekunden möglich, datum ebenso..auch in eine Long-Variable
EEPROM.update(0, );
EEPROM.update(1, );
EEPROM.update(2, );
EEPROM.update(3, );
EEPROM.update(4, );
EEPROM.update(5, );
EEPROM.update(6, );
EEPROM.update(7, ); //delphi Datum
EEPROM.update(8, 7); // überlauf (tage50) braucht man das hier überhaupt?????
EEPROM.update(9, 8); // start_pos logmeldung, bit1
EEPROM.update(10, 8); // start_pos logmeldung, bit2
EEPROM.update(11, 64); // bi7=1 Hochspannung abgeschaltet, bit7=0 Hochspannung eingeschaltet.
//bit6=1 SMS wird versendet, bit6=0, kein SMS-Versand default:11=8
EEPROM.update(12, 8); // frei
EEPROM.update(13, 8); //Diagnosebytebyte z.b. bit7 Spannungsausfall,
bit 6 überlauf log
bit 5 überlauf Rattenzahler
bit4 tage50 hatte überlauf
EEPROM.update(14, 8); // frei
EEPROM.update(15, 8); // frei
EEPROM.update(16, 8); //counter_ratte1
EEPROM.update(17, 8); //counter_ratte2
EEPROM.update(18,0 ); //frei
DCF77 ohne Interrupt-PIN:
https://wolles-elektronikkiste.de/dcf77-funkuhr
*/