Gasverbrauch loggen - GELÖST!

Hallo zusammen,

ich möchte meinen Gasverbrauch loggen.
Reed_Kontakt o.ä. mit PullUp an Pin 2.
Uno, SD-Karte mit RTC ist vorhanden und funktioniert auch alles so weit.

Allerdings wird im Moment nach jeder Änderung des Eingangs (High, Low) die Variable mit Zeitstempel auf die SD-Karte geschrieben.

Folgendes möchte ich umsetzen:

Je 1x High / Low vom Eingang in eine Variable schreiben.
Also z.B. 3x High / 3x Low = Variable + 3
Dies soll ständig geschehen / abgefragt werden.

Alle 60 Sekunden soll der Inhalt der Variablen (zusammen mit dem Zeitstempel) auf die SD-Karte geschrieben und danach auf 0 gesetzt werden.

Für Tips wäre ich super dankbar.

Viele Grüße, Andreas.

Pin einlesen, entprellen und zählen, wie sieht Dein Vorschlag aus?

Laserman1974:
ich möchte …

Zeig am besten den Sketch, mit dem es nicht klappt. Fasse ihn in „Code-Tags“ (im Editor der Knopf ganz links, „</>“), damit er scrollbar und in einer Festbreitenschrift dargestellt wird. Alleine aus Deiner Beschreibung werde ich nicht richtig schlau.

Gruß

Gregor

@agmue
Den Pin kann ich schon einlesen und zählen und speichern, das klappt schon.

Ich will jetzt aber gleichzeitig, die Variable schreiben / erhöhen bei jeder Änderung des Eingangs, aber nur jede Minute die Variable auf die SD Karte schreiben (und dann wieder löschen).

Es kann also mal sein, daß in einer Minute eine 10 in der Variable steht.
Und dann wiederum z.B. nur eine 2.

Bis jetzt wird wie gesagt bei jeder Änderung des Eingangs auf SD Karte geschrieben.

// Einfügen der Libs die wir benötiegen.
// DS18S20

//SD
#include <SPI.h>
#include <SD.h>
//RTC
#include <Wire.h>
#include "RTClib.h"
#include <Math.h>

// Die DatenPins festlegen
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int chipSelect = 10; // Der SelectPin für die SD Karte liegt auf Pin 10
const int LEDPin = 7; // LED auf 7

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = LOW;         // current state of the button
int lastButtonState = LOW;     // previous state of the button

//SD Save
File dataFile;

//RTC
//#if defined(ARDUINO_ARCH_SAMD)
// for Zero, output on USB Serial console, remove line below if using programming port to program the Zero!
//#define Serial SerialUSB
//#endif

RTC_DS1307 rtc;

/*
   Setup function. Here we do the basics
*/
void setup(void)
{
    // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  pinMode(LEDPin, OUTPUT);
  
  // start serial port
  Serial.begin(9600);

delay(500);

  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);

  Serial.print("Initializing SD card...");
  
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
SDSTART:
  if (!SD.begin(chipSelect)) {

    Serial.println("Card failed, or not present");
    
    // don't do anything more:
    digitalWrite(3, LOW);
    goto SDSTART;
  } else {
    digitalWrite(3, HIGH);
  }
  
  Serial.println("card initialized.");

  // Open up the file we're going to log to!
SDWRITE:
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (! dataFile) {
    
    Serial.println("error opening datalog.txt");
    
    // Wait forever since we cant write data
    digitalWrite(3, LOW);
    goto SDWRITE;
  } else {
    digitalWrite(3, HIGH);
  }

  //RTC



  if (! rtc.begin()) {
    
    Serial.println("Couldn't find RTC");
    
    while (1);
  }

  if (! rtc.isrunning()) {
    
    Serial.println("RTC is NOT running!");
    
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

}


void loop(){
// read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

// Beim Wechsel des Eingangs von LOW zu HIGH:
  if (buttonState == HIGH && lastButtonState == LOW) {

    Serial.println("on");
    digitalWrite(LEDPin, LOW);
      
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // Delay a little bit to avoid bouncing
    delay(500);

 }
 
    // Beim Wechsel des Eingangs von HIGH zu LOW:
  if (buttonState == LOW && lastButtonState == HIGH) {

      buttonPushCounter++;
      
       Serial.println("off");
       digitalWrite(LEDPin, HIGH);
       Serial.print("Gasverbrauch: ");
       Serial.println(buttonPushCounter);

    DateTime now = rtc.now();
  
  String dataString = "";

  // Datum und Zeit stempeln und Verbrauchswert anhängen
  dataString += now.day(), DEC;
  dataString += ".";
  dataString += now.month(), DEC;
  dataString += ".";
  dataString += now.year(), DEC;
  dataString += " ";
  dataString += now.hour(), DEC;
  dataString += ":";
  dataString += now.minute(), DEC;
  dataString += ":";
  dataString += now.second(), DEC;
  dataString += ",";
  dataString += buttonPushCounter;

  dataFile.println(dataString);
  
  Serial.println("---Datensatz auf SD speichern---");
  Serial.println("Datum Zeit, Gasverbrauch in 0,01 m³");
  Serial.println(dataString);
  
  dataFile.flush();

  Serial.println("---Datensatz auf SD gespeichert---");
  
  digitalWrite(4, LOW);
  digitalWrite(3, HIGH);

  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

  // Delay a little bit to avoid bouncing
    delay(500);  
   
}
}

Was mir auffällt:

int buttonPushCounter = 0;   // kann nur positiv sein, also unsigned int
int buttonState = LOW;         // besser bool
int lastButtonState = LOW;     // besser bool
  pinMode(buttonPin, INPUT);
...
  pinMode(2, INPUT_PULLUP);

Das ist doppelt.

goto SDSTART;

Grummel ...

    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

Würde ich nicht jedesmal machen. Wenn die Uhr läuft, dann läuft sie.

  // Delay a little bit to avoid bouncing
    delay(500);

30 ms sollten reichen, sonst würde ich einen anderen Sensor nehmen.

  lastButtonState = buttonState;

Das würde ich an beiden Stellen löschen und hierhin verschieben:

  lastButtonState = buttonState;
  buttonState = digitalRead(buttonPin);

Zu Deiner eigentlichen Frage: Wenn now.second() nullt, dann schreibst Du was auf die SD-Karte und setzt den Zähler zurück.

Hallo zusammen,

ich konnte das Problem Dank Eurer Hilfe lösen. :slight_smile:

Vielen Dank dafür!

Für alle Interessierten hier der funktionierende Code:

// Einfügen der Libs die wir benötiegen.
// DS18S20

//SD
#include <SPI.h>
#include <SD.h>
//RTC
#include <Wire.h>
#include "RTClib.h"
#include <Math.h>

// Die DatenPins festlegen
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int chipSelect = 10; // Der SelectPin für die SD Karte liegt auf Pin 10
const int LEDPin = 7; // LED auf 7

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

//SD Save
File dataFile;

//RTC
RTC_DS1307 rtc;

/*
   Setup function. Here we do the basics
*/
void setup(void)
{
  pinMode(LEDPin, OUTPUT);
  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(buttonPin, INPUT_PULLUP);
  
  // start serial port
  Serial.begin(9600);

delay(500);

  Serial.print("Initializing SD card...");
  
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(10, OUTPUT);

  // see if the card is present and can be initialized:
SDSTART:
  if (!SD.begin(chipSelect)) {

    Serial.println("Card failed, or not present");
    
    // don't do anything more:
    digitalWrite(3, LOW);
    goto SDSTART;
  } else {
    digitalWrite(3, HIGH);
  }
  
  Serial.println("card initialized.");

  // Open up the file we're going to log to!
SDWRITE:
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (! dataFile) {
    
    Serial.println("error opening datalog.txt");
    
    // Wait forever since we cant write data
    digitalWrite(3, LOW);
    goto SDWRITE;
  } else {
    digitalWrite(3, HIGH);
  }
  Serial.println("logfile opened.");

  //RTC
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

}

void loop(){
  DateTime now = rtc.now();
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);
    
  // Beim Wechsel des Eingangs von LOW zu HIGH:
  if (buttonState == HIGH && lastButtonState == LOW) {
  lastButtonState = buttonState;
  // save the current state as the last state, for next time through the loop
    Serial.println("on");
    digitalWrite(LEDPin, LOW);
    // Delay a little bit to avoid bouncing
    delay(30);

 }
 
    // Beim Wechsel des Eingangs von HIGH zu LOW:
    if (buttonState == LOW && lastButtonState == HIGH) {
    lastButtonState = buttonState;
    // save the current state as the last state, for next time through the loop
      buttonPushCounter++;
       Serial.println("off");
       digitalWrite(LEDPin, HIGH);
       Serial.print("Gasverbrauch: ");
       Serial.println(buttonPushCounter);
    }
  Serial.println(now.second());
  if (now.second() == 0){
  String dataString = "";
  // Datum und Zeit stempeln und Verbrauchswert anhängen
  dataString += now.day(), DEC;
  dataString += ".";
  dataString += now.month(), DEC;
  dataString += ".";
  dataString += now.year(), DEC;
  dataString += " ";
  dataString += now.hour(), DEC;
  dataString += ":";
  dataString += now.minute(), DEC;
  dataString += ":";
  dataString += now.second(), DEC;
  dataString += ",";
  dataString += buttonPushCounter;
  dataFile.println(dataString);
  Serial.println("---Datensatz auf SD speichern---");
  Serial.println("Datum Zeit, Gasverbrauch in 0,01 m3");
  Serial.println(dataString);
  dataFile.flush();
  Serial.println("---Datensatz auf SD gespeichert---");
  digitalWrite(4, LOW);
  digitalWrite(3, HIGH);
  buttonPushCounter=0;
  delay(1000);
  }
  // Delay a little bit to avoid bouncing
    delay(30);  
   
}