Arduino Uno zu wenig Arbeitsspeicher?

Hallo,

ich bekomme folgende Meldung bei meinem Sketch:

“Der Sketch verwendet 24886 Bytes (77%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 1546 Bytes (75%) des dynamischen Speichers, 502 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.
Wenig Arbeitsspeicher verfügbar, es können Stabilitätsprobleme auftreten.”

Das ist der dazugehörige Sketch:

//Black = Ground
//Yellow = Data
//Red = +5V
//DS18B20 one wire bus pin 2; resistor between DATA and +5V
//2 x BME280 and BH1750 (..., SDA, SCL, GND, 5V) I2C pin SDA and pin SCL
//HC06 pin 6 (TX) and pin 7 (RX)
//DS3231 pin A4 (SDA) and pin A5 (SCL)

#include <Wire.h>
#include "RTClib.h"
#include <OneWire.h>           
#include <DallasTemperature.h>
#include <SPI.h>
#include <SD.h>
#include "cactus_io_BME280_I2C.h" ///BME280
BME280_I2C bme1(0x77); // I2C using address 0x77 
BME280_I2C bme2(0x76); // I2C using address 0x76 
#include <BH1750.h> ///BH1750
BH1750 lightMeter; ///BH1750
#include <SoftwareSerial.h> ///HC06
SoftwareSerial BT(6, 7); ///TX 6 RX 7, BT=Bluetooth, HC06

#define ONE_WIRE_BUS_PIN 2              //DS18B20 OneWire

byte lastMinute = 0xFF; //Initialize to an impossible value, for sampling every minute

OneWire oneWire(ONE_WIRE_BUS_PIN);     // Setup oneWire
DallasTemperature sensors(&oneWire);   //  oneWire to Dallas Temperature.
RTC_DS1307 RTC;                        // define the Real Time Clock object

const int chipSelect = 4;              //CS pin of your data logger shield.Maybe not yours!!
File Logfile;                          //Name of the file

DeviceAddress Probe01 = { 0x28, 0xAA, 0x21, 0x9E, 0x13, 0x13, 0x02, 0xE7 }; //DS18B20 serial adresses
DeviceAddress Probe02 = { 0x28, 0xAA, 0x5E, 0xA8, 0x13, 0x13, 0x02, 0xA4 };
DeviceAddress Probe03 = { 0x28, 0xFF, 0x1A, 0x1B, 0x93, 0x16, 0x05, 0x90 };
DeviceAddress Probe04 = { 0x28, 0xAA, 0xA9, 0xA5, 0x13, 0x13, 0x02, 0xCE };
DeviceAddress Probe05 = { 0x28, 0x7E, 0xA5, 0x77, 0x91, 0x08, 0x02, 0x13 };


void setup()
{
SD.begin(chipSelect);
Wire.begin();
RTC.begin();
sensors.begin();
lightMeter.begin(); ///BH1750
bme1.begin(); ///BME280
bme2.begin(); ///BME280
BT.begin(9600); ///HC06
  
  // set the resolution to 9 bit (Can be 9 to 12 bits .. lower is faster)
  sensors.setResolution(Probe01, 9);
  sensors.setResolution(Probe02, 9);
  sensors.setResolution(Probe03, 9);
  sensors.setResolution(Probe04, 9);
  sensors.setResolution(Probe05, 9);
  
Logfile=SD.open("Logfile.csv",FILE_WRITE);               //Open and write once, just for headers
//Logfile.println(" Date/Time         Temp1   Temp2   Temp3    Temp4    Temp5   Hum5");    //Print headers(not saved yet) //////////
Logfile.close();                                        //Print saved

}
void loop()
{
Serial.begin(9600); ///SERIAL MONITOR

 DateTime now = RTC.now();        // Clock call
 now = RTC.now();                 

//if(now.second()==00){          //Sample every minute
if(now.minute() != lastMinute) {
lastMinute = now.minute();
 
 Logfile=SD.open("Logfile.csv",FILE_WRITE);  // Print date and time    

Logfile.println();
Logfile.print(now.year(), DEC);
Logfile.print("/");
Logfile.print(now.month(), DEC);
Logfile.print("/");
Logfile.print(now.day(), DEC);
Logfile.print(" ");
Logfile.print(now.hour(), DEC);
Logfile.print(":");
Logfile.print(now.minute(), DEC);
Logfile.print(":");
Logfile.print(now.second(), DEC);
Logfile.print(";  ");
Logfile.close();
Serial.println();
Serial.print(now.year(), DEC);
Serial.print("/");
Serial.print(now.month(), DEC);
Serial.print("/");
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(":");
Serial.print(now.minute(), DEC);
Serial.print(":");
Serial.print(now.second(), DEC);
Serial.print(";  ");
BT.println();
BT.print(now.year(), DEC);
BT.print("/");
BT.print(now.month(), DEC);
BT.print("/");
BT.print(now.day(), DEC);
BT.print(" ");
BT.print(now.hour(), DEC);
BT.print(":");
BT.print(now.minute(), DEC);
BT.print(":");
BT.print(now.second(), DEC);
BT.print(";  ");       

sensors.requestTemperatures(); // Command all devices on bus to read temperature 
Logfile=SD.open("Logfile.csv",FILE_WRITE); 
  
 Serial.print(" Temp1: ");
 BT.print(" Temp1: ");
 Serial.print(sensors.getTempC(Probe01));
 BT.print(sensors.getTempC(Probe01));
 Logfile.print(sensors.getTempC(Probe01));
 Logfile.print(";");
 Serial.print(" C ");
 BT.print(" C ");
 Serial.print(" Temp2: ");
 BT.print(" Temp2: ");
 Serial.print(sensors.getTempC(Probe02));
 BT.print(sensors.getTempC(Probe02));
 Logfile.print(sensors.getTempC(Probe02));
 Logfile.print(";");
 Serial.print(" C ");
 BT.print(" C ");
 Serial.print(" Temp3: ");
 BT.print(" Temp3: ");
 Serial.print(sensors.getTempC(Probe03));
 BT.print(sensors.getTempC(Probe03));
 Logfile.print(sensors.getTempC(Probe03));
 Logfile.print(";");
 Serial.print(" C ");
 BT.print(" C ");
 Serial.print(" Temp4: ");
 BT.print(" Temp4: ");
 Serial.print(sensors.getTempC(Probe04));
 BT.print(sensors.getTempC(Probe04));
 Logfile.print(sensors.getTempC(Probe04));
 Logfile.print(";");
 Serial.print(" C ");
 BT.print(" C ");
 Serial.print(" Temp5: ");
 BT.print(" Temp5: ");
 Serial.print(sensors.getTempC(Probe05));
 BT.print(sensors.getTempC(Probe05));
 Logfile.print(sensors.getTempC(Probe05));
 Logfile.print(";");
 Serial.print(" C ");
 BT.print(" C ");

  

    uint16_t lux = lightMeter.readLightLevel(); ///BH1750
  Logfile.print(lux);
  Logfile.print(";");
  Serial.print(" Light: ");
  Serial.print(lux);
  Serial.print(" lx;");
  BT.print(" Light: ");
  BT.print(lux);
  BT.print(" lx;"); ///BH1750

    bme1.readSensor(); ///BME280_1
    Logfile.print(bme1.getTemperature_C());
    Logfile.print(";");
    Logfile.print(bme1.getPressure_MB());
    Logfile.print(";");
    Logfile.print(bme1.getHumidity());
    Logfile.println(";");
    Serial.print(" Temp6: ");
    Serial.print(bme1.getTemperature_C());
    Serial.print(" C;");
    Serial.print(" Pr6: ");
    Serial.print(bme1.getPressure_MB());
    Serial.print(" hPa;");
    Serial.print(" Hum6: ");
    Serial.print(bme1.getHumidity());
    Serial.println(" %;");
    BT.print(" Temp6: ");
    BT.print(bme1.getTemperature_C());
    BT.print(" C;");
    BT.print(" Pr6: ");
    BT.print(bme1.getPressure_MB());
    BT.print(" hPa;");
    BT.print(" Hum6: ");
    BT.print(bme1.getHumidity());
    BT.println(" %;"); ///BME280_1

    bme2.readSensor(); ///BME280_2
    Logfile.print(bme2.getTemperature_C());
    Logfile.print(";");
    Logfile.print(bme2.getPressure_MB());
    Logfile.print(";");
    Logfile.print(bme2.getHumidity());
    Logfile.println(";");
    Serial.print(" Temp7: ");
    Serial.print(bme2.getTemperature_C());
    Serial.print(" C;");
    Serial.print(" Pr7: ");
    Serial.print(bme2.getPressure_MB());
    Serial.print(" hPa;");
    Serial.print(" Hum7: ");
    Serial.print(bme2.getHumidity());
    Serial.println(" %;");
    BT.print(" Temp7: ");
    BT.print(bme2.getTemperature_C());
    BT.print(" C;");
    BT.print(" Pr7: ");
    BT.print(bme2.getPressure_MB());
    BT.print(" hPa;");
    BT.print(" Hum7: ");
    BT.print(bme2.getHumidity());
    BT.println(" %;"); ///BME280_2

 Logfile.close();                //Print saved
 }
 
delay(1000);                        //One data per second
}

Kann ich am Sketch etwas ändern, um den Arbeitsspeicher zu schonen?

phytopia:
......
Kann ich am Sketch etwas ändern, um den Arbeitsspeicher zu schonen?

Ja, indem du für deine Texte das "F-Makro" verwendest.

Serial.print(F("dein Text"));

Das kannst du für alle "print-Ausgaben" einsetzen.

Ob das reicht, kann ich nicht sagen.

Generell ist auch die SD-Library sehr ressourcenhungrig.

Edit:

Serial.begin(9600);
solltest du lieber in das Setup einsetzen.

Hallo,

also das überfordert den UNO jetzt nu wirklich. Habe ich in ähnlicher Konstellation auch mal probiert. Schlussendlich habe ich dann das hier bebaut. arduino-uno-with-8-times-more-memory . Oder du musst halt einen Grösseren Arduino benutzen.

Gruss Temucin

Oder du versuchst es mal mit einer anderen Library, z.B. die "SdFat.h"

HotSystems:
Ja, indem du für deine Texte das “F-Makro” verwendest.

Serial.print(F("dein Text"));

Das kannst du für alle “print-Ausgaben” einsetzen.

Sobald ich das in einer Zeile ändere, bekomme ich schon diese Fehlermeldung:
“exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno.”

Muss ich das bei allen print-Befehlen gleichzeitig umschreiben oder was ist das Problem hier?

phytopia:
Sobald ich das in einer Zeile ändere, bekomme ich schon diese Fehlermeldung:
"exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno."

Muss ich das bei allen print-Befehlen gleichzeitig umschreiben oder was ist das Problem hier?

Was bei dir falsch ist, kann ich nicht sehen.
Dann musst du schon den Sketch zeigen.

Du kannst es nur bei Texteingaben machen, nicht bei Variablen.

phytopia:
Muss ich das bei allen print-Befehlen gleichzeitig umschreiben oder was ist das Problem hier?

Das Problem ist, dass Du uns die genaue Fehlermeldung verschweigst.

Gruß Tommy

von

Logfile.println();

zu

Logfile.println(F());

ergibt

Arduino: 1.8.7 (Windows 10), Board: "Arduino/Genuino Uno"

In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:28:0,

                 from sketch\Sketch_working.ino.cpp:1:

C:\Users\User\Downloads\Sketch_working\Sketch_working.ino: In function 'void loop()':

C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/WString.h:38:74: error: expected primary-expression before ')' token

 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))

                                                                          ^

C:\Users\User\Downloads\Sketch_working\Sketch_working.ino:78:17: note: in expansion of macro 'F'

 Logfile.println(F());

                 ^

exit status 1
Fehler beim Kompilieren für das Board Arduino/Genuino Uno.

Dieser Bericht wäre detaillierter, wenn die Option
"Ausführliche Ausgabe während der Kompilierung"
in Datei -> Voreinstellungen aktiviert wäre.

Der detaillierte Bericht passt hier leider nicht rein, aber falls nötig, kann ich ihn in mehreren Stückchen posten.

Da kann ich den Compiler verstehen. Wo kein konstanter Text ist, kann auch keiner in einem Makro eingeschlossen werden.

Gruß Tommy

Die Fehlermeldung sagt:

bei F() fehlt was vor der schliessenden Klammer.

Logfile.println(F());

Falsch!
Das F() darf nur auf Zeichenketten angewendet werden.

also
Logfile.println(F("Ausgabe"));

So wurde es dir gezeigt, und so ist es auch richtig.

combie:
Falsch!
Das F() darf nur auf Zeichenketten angewendet werden.

also
Logfile.println(F(“Ausgabe”));

So wurde es dir gezeigt, und so ist es auch richtig.

Ok, ich habe das jetzt auf alle Ausgaben angewendet und die Warnung ist tatsächlich verschwunden. Jetzt steht da nur noch:
“Der Sketch verwendet 25158 Bytes (77%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 1412 Bytes (68%) des dynamischen Speichers, 636 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.”

Danke!!

phytopia:
Ok, ich habe das jetzt auf alle Ausgaben angewendet und die Warnung ist tatsächlich verschwunden. Jetzt steht da nur noch:
“Der Sketch verwendet 25158 Bytes (77%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 1412 Bytes (68%) des dynamischen Speichers, 636 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.”

Danke!!

Prima und danke für die Rückmeldung.

Das mit dem "Es können Stabilitätsprobleme auftreten" ist übrigens nur geraten.
Bei dir sollte nach 1 Minute klar sein, ob der RAM ausreicht oder nicht.

Aber den F-Makro solltest du auf jeden Fall kennen. Also hat sich die Aktion gelohnt.