Liebes Forum,
ich habe hier ein kleines Datenloggerprogramm, bei dem ich die Lade- und Entladekurve meines Rasenmäherakkus aufzeichnen möchte. Der Aufbau mit Stromsensor ACS712, LCD 16x2 und SD Karte (levelshifted) funktioniert. Erstmal... Die Daten werden gemessen, erfasst und als jeweiliger Datensatz auf die SD Karte geschrieben. Allerdings bei so ca. 150- 180 Datensätzen ist dann Schluss. Die SD Karte schreibt nicht mehr, die Messungen laufen aber unauffällig weiter und ich kann den Fortschritt am LCD sehen. Was ich einzig bei der SD Karte feststelle, ist dass bei anscheinend funktionierenden Schreibvorgang die LED auf dem Modul kurz aufblinkt, während nachdem das Schreiben scheinbar nicht mehr funktioniert diese LED wesentlich länger leuchtet.
Alles mit Arduino NANO realisiert. Kompilermeldungen für mich unauffällig: Der Sketch verwendet 17104 Bytes (55%) des Programmspeicherplatzes. Das Maximum sind 30720 Bytes.
Globale Variablen verwenden 1522 Bytes (74%) des dynamischen Speichers, 526 Bytes für lokale Variablen verbleiben.
Vielleicht wieder einmal ein Kapazitätsproblem? Aber warum schreibt er dann die 150 Datensätze???
Ich hoffe auf eure Hilfe.
```
#include <Arduino.h>
#include <SD.h>
#include <SPI.h>
#define chipSelect 10
File StromXX;
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display
bool measuring = false;
unsigned int zaehler = 0;
const int PinLED = 7; //Gruene LED
const int PinLED_Stop = 8; //blaue LED
//Messdatenermittlung mit ACS712
const int ACS712_Pin = A0;
const float vRef = 4.99; //Spannung mit DMM Multimeter (Aref zu GND) gemessen. vRef = 5.0 bei 12V Spannungsquelle
float rawVoltage = 0;
float current = 0;
const float zeroCurrentValue = 510.8;
static unsigned long zeitgeber = 0; //globale Variable, wird nur einmal angelegt , verhält sich wie eine lokale Variable
unsigned long zeitgeberCount = 0;
const int button1Pin = 5; // Pin für Taster 1
const int button2Pin = 6; // Pin für Taster 2 //hier nur fuer diesen Taster
int button1State = HIGH; // Aktueller Zustand von Taster 1
int button2State = HIGH; // Aktueller Zustand von Taster 2
int button1PreviousState = HIGH; // Vorheriger Zustand von Taster 1
int button2PreviousState = HIGH; // Vorheriger Zustand von Taster 2
unsigned long button1PressStartTime = 0; // Startzeit des Taster-Drucks von Taster 1
unsigned long button2PressStartTime = 0; // Startzeit des Taster-Drucks von Taster 2
const unsigned long debounceDelay = 50; // Entprellungsverzögerung (in Millisekunden)
const unsigned long longPressDelay = 1000; // Zeit für langen Tasterdruck (in Millisekunden)
int counter = 0; // Variable zum Hoch- und Herunterzählen
bool button2LongPressDetected = false; // Flag für erkannten Long-Press von Taster 2
bool freigabe = true;
void header() {
StromXX = SD.open("Strom_2.csv", FILE_WRITE); //Schreiben der HeaderZeile
if (StromXX) {
StromXX.print("Strommessung mit ACS712 (5-Ampere) Sensor");
StromXX.print("Messung");
StromXX.print(",");
StromXX.print(" Volt[RAW]");
StromXX.print(",");
StromXX.print(" Volt[V]");
StromXX.print(",");
StromXX.print("Strom[mA]");
StromXX.print(",");
StromXX.print("Messdauer[ms]");
StromXX.print(",");
StromXX.println();
StromXX.close();
}
lcd.setCursor(0, 1);
lcd.print(" Header geschr.");
delay(1000);
lcd.setCursor(0, 0);
lcd.print("Header angelegt");
lcd.setCursor(0, 1);
lcd.print(" Start->short ");
}
void loopblink(void) {
if (millis() - zeitgeber > 5000) {
zeitgeberCount = millis() - zeitgeber;
zeitgeber = millis();
zaehler += 1;
//arbeitsteil:
lcd.setCursor(9, 0);
lcd.print(" ");
startMeasurement(); //Beginne die Messung
lcd.setCursor(2, 0);
lcd.print(zaehler);
lcd.setCursor(9, 0);
lcd.print(current, 1);
datenlogger(); //Aufzeichnung der Messung
//digitalWrite(PinLED, !digitalRead(PinLED)); //Arbeitsteil
}
}
void startMeasurement() {
digitalWrite(PinLED, !digitalRead(PinLED)); //Arbeitsteil LED Statusaenderung, Zeigt Messintervalle an
long rawValue = 0;
for (int i = 0; i < 500; i++) { //fuehre 1000 Messungen durch (Messschwankungen des ACS712) ACHTUNG: dauert 2 Sekunden
rawValue += analogRead(ACS712_Pin);
delay(2);
}
rawVoltage = rawValue / 500.0;
current = (rawVoltage - zeroCurrentValue) * vRef / 1.024 / 0.185;
}
void stopMeasurement() {
if (measuring) {
measuring = false; //Beende das Messprogramm und schiesst sicher die SD Karte
StromXX = SD.open("Strom_2.csv", FILE_WRITE);
if (StromXX) {
StromXX.println("Messung beendet");
StromXX.print("Insgesamt : ");
StromXX.print(zaehler);
StromXX.println(" Messungen durchgefuehrt");
StromXX.println("***** NEUE MESSUNG *****");
}
StromXX.close();
// Serial.println("CARD Close");
digitalWrite (PinLED, LOW);
digitalWrite (PinLED_Stop, HIGH);
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("SD-Card closed");
lcd.setCursor(0, 1);
lcd.print("Anz: ");
lcd.print(zaehler);
lcd.setCursor(11, 1);
lcd.print(" Mes.");
}
}
void datenlogger() {
StromXX = SD.open("Strom_2.csv", FILE_WRITE); //schreibt die Messdaten in die EXCEL Datei Strom_1.xls
if (StromXX) {
StromXX.print(zaehler);
StromXX.print(" ), ");
StromXX.print(rawVoltage);
StromXX.print(", ");
StromXX.print(rawVoltage * vRef / 1024);
StromXX.print(", ");
StromXX.print(current);
StromXX.print(", ");
StromXX.print(zeitgeberCount);
StromXX.println(", ");
delay(50);
StromXX.close();
}
}
void setup() {
// Serial.begin(115200);
pinMode(button1Pin, INPUT_PULLUP); // Taster 1 als Eingang mit Pull-Up-Widerstand
pinMode(button2Pin, INPUT_PULLUP); // Taster 2 als Eingang mit Pull-Up-Widerstand
// Serial.println("Initialisierung");
pinMode(chipSelect, OUTPUT);
pinMode(PinLED, OUTPUT);
pinMode(PinLED_Stop, OUTPUT);
digitalWrite (PinLED, LOW);
digitalWrite (PinLED_Stop, LOW);
lcd.init(); // initialize the lcd
// Print a message to the LCD.
lcd.backlight();
lcd.setCursor(0, 0); ////an Pos 3 in Zeile 0
lcd.print("Initialisierung");
// Initialisiere die SD-Karte
if (!SD.begin(chipSelect)) {
// Serial.println("SD-Kartenfehler");
lcd.setCursor(0, 1);
lcd.print("SD-Kartenfehler");
while (true) { //Kartenfehler: abwechselndes Blinken der beiden LEDs
digitalWrite(PinLED, !digitalRead(PinLED));
delay(200);
digitalWrite(PinLED_Stop, !digitalRead(PinLED_Stop));
delay(200);
}
}
else {
lcd.clear();
// Serial.println("Karte Initialisiert");
lcd.setCursor(1, 0);
lcd.print("Initialisiert");
lcd.setCursor(2, 1);
lcd.print("Start->short");
}
}
void loop() {
if (measuring == true) loopblink(); //wenn der Taster 2 kurz gedrueckt, Starte das Messprogramm.
int button1Reading = digitalRead(button1Pin);
int button2Reading = digitalRead(button2Pin);
// Entprellen von Taster 1; Taster hat in diesem Programm keine Funktion!
if (button1Reading != button1PreviousState) {
button1PressStartTime = millis();
}
if (millis() - button1PressStartTime > debounceDelay) {
if (button1Reading != button1State) {
button1State = button1Reading;
// Kurzer Tasterdruck auf Taster 1
if (button1State == LOW) {
counter++;
Serial.print("Counter+: "); Serial.println (counter);
}
}
}
// Entprellen von Taster 2
if (button2Reading != button2PreviousState) {
button2PressStartTime = millis();
}
if (millis() - button2PressStartTime > debounceDelay) { //pruefe ob Taster kurz gedrueckt wurde
if (button2Reading != button2State) {
button2State = button2Reading;
// Taster 2 gedrückt bei PULL UP ist LOW gedrueckt und HIGH losgelassen
if (button2State == LOW) {
button2LongPressDetected = false; // Setze Long-Press-Flag zurück
} else {
// Taster 2 losgelassen
if (!button2LongPressDetected) { // Kurzer Tasterdruck auf Taster 2
// Starte Messung
digitalWrite (PinLED_Stop, LOW);
zaehler = 0;
header();
//Serial.println("Start Messung");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Z:");
lcd.setCursor(6, 0);
lcd.print("mA: ");
lcd.setCursor(0, 1);
lcd.print(" Stop -> long");
measuring = true; // Starte Messung
}
}
}
}
// Prüfe auf Long-Press von Taster 2
if (button2State == LOW && !button2LongPressDetected && millis() - button2PressStartTime >= longPressDelay) {
button2LongPressDetected = true;
// Ergebnis der Variable verwenden
// Hier kannst du den gewünschten Code für das weitere Programm einfügen
// Serial.println("Stop Messung");
stopMeasurement(); //Stoppe Messung (Taster 2 wurde lange gedrueckt)
}
// Speichere den aktuellen Zustand der Taster für den nächsten Schleifendurchlauf
button1PreviousState = button1Reading;
button2PreviousState = button2Reading;
}
```