Probleme mit Variablen?

Hallöchen,

da ich noch Anfänger bin, weiß ich gerade nicht weiter.

Mein Programm habe ich aus zwei Teilen zusammenkopiert.
Zum einen aus einem Datenlogger und zum anderen aus einem Wägeprogramm.
Zusammen soll das Programm alle 5min die Daten der Waage auslesen und

Beide Programme funktionieren eigenständig, gemeinsam funktioniert aber keines von beiden.
Der Datenlogger-Teil schafft es nicht, Daten auf die SD-Karte zu speichern und der Waagen-Teil wiegt immer 0kg, obwohl die Waage belastet ist.

Ich habe zwei Vermutungen, woran es hierbei scheitern könnte:

  1. entweder behindern sich die Bibliotheken gegenseitig oder
  2. mein Arduino Uno hat zu wenig Arbeitsspeicher dafür

Denn beim Hochladen erhalte ich folgende Meldung von der Arduino-Software:

Der Sketch verwendet 20238 Bytes (62%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 1744 Bytes (85%) des dynamischen Speichers, 304 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
Wenig Arbeitsspeicher verfügbar, es können Stabilitätsprobleme auftreten.

Kannst Du mir sagen, woran es wirklich scheitert?
Oder was ich ändern muss, damit es funktioniert?
Schon einmal vielen Dank für Deine Tipps!

Hier noch das Programm dazu:

#include <SD.h>
#include <Wire.h>
#include <RTClib.h>
#include <string.h>
#include <LiquidCrystal.h>
#include <HX711_ADC.h>

const float CellFactor = -25500.0;  //Waagenfaktor

int chipSelect = 10;  //SD-Karte

const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;  //LCD
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const int Display = 9;           //Stromversorgung fürs Display

//const String dt = A5, sck = A4;  //Waage
HX711_ADC LoadCell(A3, A2);

const int LED = 8;  //LED

int fehler = 0;


RTC_DS1307 RTC;
Sd2Card card;
SdVolume volume;

File myFile;
String line;
DateTime now;

char datestr[20];
char timestr[20];
char *ptr;
int  idx;
char c;

String Name;
String Dateiname;

byte ok[8] = {
  B00000,
  B00001,
  B00001,
  B00010,
  B10010,
  B01100,
  B00000,
};

void setup() {
  Serial.begin(9600);
  pinMode (LED, OUTPUT);
  pinMode (Display, OUTPUT);
  lcd.createChar(0, ok);

  String Name = "Bienenwaage0.2";
  
  lcd.begin(16, 2);          //LCD
  lcd.print(Name);
  digitalWrite (Display, HIGH);
  String Dateiname = String(Name + ".csv");
  delay(3000);
  lcd.clear();
  lcd.print("Starte...");
  lcd.setCursor(0, 1);
  lcd.print("starte SD...");

  Serial.println("Initialisiere SD-Karte...");    //SD und Zeit
  Serial.println("");
  delay(200);
  Wire.begin();
  RTC.begin();
    
  if (! RTC.isrunning()) {
    Serial.println("RTC läuft nicht!");
    delay(200);
  } 
  else {
    Serial.println("Test 1 von 4 ok");
    lcd.setCursor(10, 0);
    lcd.print("1");
    fehler = fehler + 10000;
    delay(200);
    }
      
  pinMode(chipSelect, OUTPUT);
    
  if (!SD.begin(chipSelect)) {
  Serial.println("SD-slot initialization failed");
  delay(200);
    }
  else {
    Serial.println("Test 2 von 4 ok");
    lcd.setCursor(11, 0);
    lcd.print("2");
    fehler = fehler + 2000;
    delay(200);
    }
    
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
  Serial.println("SD-hardware initialization failed");
  delay(200);
    } 
  else {
    Serial.println("Test 3 von 4 ok");
    lcd.setCursor(12, 0);
    lcd.print("3");
    fehler = fehler + 300;
    delay(200);
    }
    
  if (!volume.init(card)) {
  Serial.println("Could not find FAT16/FAT32 partition");
  delay(200);
    }
  else {
    Serial.println("Test 4 von 4 ok");
    lcd.setCursor(13, 0);
    lcd.print("4");
    fehler = fehler + 40;
    delay(200);
    }
  Serial.println("");  
  DateTime now = RTC.now();  

  SD.begin(chipSelect);
  myFile = SD.open(Dateiname, FILE_WRITE); //##
  if (myFile) {
    myFile.println(Name); //##
    myFile.print('"');
    myFile.print("Datum");
    myFile.print('"');
    myFile.print(';');
    myFile.print('"');
    myFile.print("Gewicht");
    myFile.print('"');
    myFile.println();
    if (now.day() < 10){
      myFile.print('0');
    }
    myFile.print(now.day(), DEC);
    myFile.print('.');
    if (now.month() < 10){
      myFile.print('0');
    }
    myFile.print(now.month(), DEC);
    myFile.print('.');
    myFile.print(now.year(), DEC);
    myFile.print(' ');
    if (now.hour() < 10){
      myFile.print('0');
    }
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    if (now.minute() < 10){
      myFile.print('0');
    }
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    if (now.second() < 10){
      myFile.print('0');
    }
    myFile.print(now.second(), DEC);
    myFile.print(';');
    myFile.print("power up");
    myFile.println();
    myFile.close();
    Serial.println("Titel wurde geschrieben");
    Serial.println("");
    lcd.setCursor(14, 0);
    lcd.print("5");
    fehler = fehler + 5;
    delay(200);
  } else {
    digitalWrite(LED, HIGH);
    delay(3000);
    Serial.println("kann nicht schreiben");
    delay(200);
    digitalWrite(LED, LOW);
  }

  if (fehler == 12345){
    lcd.setCursor(15, 0);
    lcd.write(byte(0));
  }
  else {
    lcd.setCursor(15, 0);
    lcd.print("X");
    delay(3000);
  }

  lcd.setCursor(0, 1);
  lcd.print ("Tariere Waage...");
  
  digitalWrite(LED, HIGH);    
  Serial.println("3...");
  lcd.setCursor(15, 1);
  lcd.print("3");
  delay(1000);
  digitalWrite(LED, LOW);
  Serial.println("2...");
  lcd.setCursor(15, 1);
  lcd.print("2");
  delay(1000);
  digitalWrite(LED, HIGH);
  Serial.println("1...");
  lcd.setCursor(15, 1);
  lcd.print("1");
  delay(1000);
  digitalWrite(LED, LOW);
  lcd.setCursor(15, 1);
  lcd.print(".");

  Serial.println("Wait...");           //Kalibrierung der Waage
  LoadCell.begin();
  long stabilisingtime = 3000;   // tare preciscion
  LoadCell.start(stabilisingtime);
  LoadCell.setCalFactor(CellFactor);
  digitalWrite(LED, HIGH);
  Serial.println("Waage ist bereit und tariert");
  Serial.println("");
  
  lcd.clear();
  lcd.print("Starte in");
  lcd.setCursor(10, 0);
  lcd.print("3...");
  delay(1000);
  lcd.setCursor(10, 0);
  lcd.print("2...");
  delay(1000);
  lcd.setCursor(10, 0);
  lcd.print("1...");
  delay(1000);
  digitalWrite(LED, LOW);
  digitalWrite(Display, LOW);
  lcd.clear();
}

void loop() {
  DateTime now = RTC.now();
  if (now.minute() % 5 == 0){  
    float i = LoadCell.getData();
    digitalWrite (Display, HIGH);
    Serial.print("Gewicht: ");
    Serial.print(i);
    Serial.println("kg");
    lcd.print(i);
    lcd.print("kg");
    
    myFile = SD.open(Dateiname, FILE_WRITE);
    if (now.day() < 10){
      myFile.print('0');
    }
    myFile.print(now.day(), DEC);
    myFile.print('.');
    if (now.month() < 10){
      myFile.print('0');
    }
    myFile.print(now.month(), DEC);
    myFile.print('.');
    myFile.print(now.year(), DEC);
    myFile.print(' ');
    if (now.hour() < 10){
      myFile.print('0');
    }
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    if (now.minute() < 10){
      myFile.print('0');
    }
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    if (now.second() < 10){
      myFile.print('0');
    }
    myFile.print(now.second(), DEC);
    myFile.print(';');

    myFile.print(i);
    myFile.println();
    myFile.close();
    delay(5000);
    digitalWrite(Display, LOW);
    lcd.clear();
    delay(85000);
  }
  else{
    delay(30000);
  }
  }

Und das Protokoll des Seriellen Monitors:

Initialisiere SD-Karte...

Test 1 von 4 ok
Test 2 von 4 ok
Test 3 von 4 ok
Test 4 von 4 ok

kann nicht schreiben
3...
2...
1...
Wait...
Waage ist bereit und tariert

Gewicht: 0.00kg
Gewicht: 0.00kg

Test 4 von 4 ok

kann nicht schreiben
3...

Habe gerade deinen Code überflogen da scheint an der Stelle etwas nicht zu funktionieren.
Das hat nichts mit der Meldung am Anfang zu tun. Diese Meldung ist nur eine Warnung, dass falls die Variablen zu groß werden, der Speicher voll laufen könnte.

Dein Fehler ist also hier:

 SD.begin(chipSelect);
  myFile = SD.open(Dateiname, FILE_WRITE); //##
  if (myFile) {
    ...
  } else {
    ...
    Serial.println("kann nicht schreiben");
  }
  1. Warum wiederholst du SD.begin() ?
  2. Warum verwendest du String Objekte ?

@michael_x:

  1. Ich wiederhole SD.Begin(), da es in meiner Vorlage auch so gemacht wurde.
  2. Ich verwende String Objekte um die Dateinamen schneller ändern zu können, ohne das ganze Programm zu durchsuchen.

Zum Test habe ich gerade das zweite SD.begin() weggelassen und einen festen Dateinamen eingefügt:

  // SD.begin(10);
  myFile = SD.open("Bienenwaage0.2.csv", FILE_WRITE); //##
  if (myFile) {
    ...
  } else {
    ...
    Serial.println("kann nicht schreiben");
  }

Leider ändert das nichts an den Problemen.
Sämtliche Ausgaben bleiben gleich (falsch).

Zusätzlich das F-Macro benutzen:

Serial.println(F("kann nicht schreiben"));

Der ganze Sketch wäre sinnvoller.

Gruß Tommy

Tommy56:
Zusätzlich das F-Macro benutzen:

Serial.println(F("kann nicht schreiben"));

Vielen Dank für den Tipp!
Damit verbraucht das Programm nun 20% weniger dynamischen Speicher.

Aber die Probleme bleiben leider erhalten...

Bist Du sicher, dass Deine SD-Lib lange Dateinamen unterstützt? Probiere mal einen im 8.3-Format.

Gruß Tommy

Tommy56:
Bist Du sicher, dass Deine SD-Lib lange Dateinamen unterstützt? Probiere mal einen im 8.3-Format.

Vielen lieben Dank für den Tipp!
Du bist der beste!
Mit dem Dateinamen "asdf.txt" schreibt das Ding nun auf die SD-Karte!

Jetzt ist nur noch die Frage, wieso die Waage immer 0kg ausgibt...

Du sagst, einzeln gehen alle 3 Teile (Messen, LCD, SD Logging) Dann mach es doch zum Test mal anders rum: Erst Messung, dann SD initialisieren. (Nicht dass sich beim Kalibrieren oder so ein Fehler eingeschlichen hat.)

Evtl. auch gleich in setup() die erste Messung durchführen.

Mir ist gerade aufgefallen, dass ich "LoadCell.update();" vergessen hatte. :-X
Dadurch hat das Programm immer den gleichen Wert gespeichert...
Jetzt funktioniert auf jeden Fall alles.
Vielen Dank für eure Mithilfe!