Zu wenig Ram/ Wie programmiere ich effizienter (DHT,SIM900,Thingspeak, Etherne,)

Das Programm leuft super, bisher mehrere Durchläufe ohne Probleme. Nur das Sim900 scheint durch das F() auch nichts mehr zu verschicken. An welchen Stellen sollte ich das weglassen?

void SMSsend()                                                            //SMS Funktion falls Temperatur zu hoch ist , \r steht für Enter (CR)     
{    
  serialSIM900.write(F("AT+CMGF=1\r\n"));
  delay(1000);
  serialSIM900.write(F("AT+CMGS=\"+49"));
  delay(1000);
  serialSIM900.write(Handynummer);
  delay(1000);
  serialSIM900.write(F("\"\r\n")); 
  delay(2000);
  serialSIM900.write(Zeile1);
  serialSIM900.write(F("*\n\r"));
  delay(1000);
  serialSIM900.write(Zeile2);
  serialSIM900.write(F("*\n\r"));
  delay(1000);
  serialSIM900.write(Zeile3);
  serialSIM900.write(F("*\n\r"));
  delay(1000);
  serialSIM900.write(Zeile4);
  serialSIM900.write(F("*\n\r"));
  delay(1000);
  serialSIM900.write(Zeile5);
  serialSIM900.write(F("*"));
  delay(1000);
  serialSIM900.write((char)26);
  Serial.println(F("gesendet"));
}

Warum hast du solange delays in der void SMSsend() ?

Serial.print("text") ; // hat einen festen Platz im RAM 


String x="";

x += "text"; // belegt dynamisch zusätzlichen RAM der bei jedem Aufruf neu (und woanders) belegt wird.

michael_x:

x += "text"; // belegt dynamisch zusätzlichen RAM der bei jedem Aufruf neu (und woanders) belegt wird.

und deswegen u.U. Absturz, unvorhersehbar und schlecht zu debuggen

Und du bist sicher, zu wissen, was

serialSIM900.write(Handynummer);

so genau macht?

ode wieso nimmst du write? Kennst du den Unterschied zu print?
Gut, in diesem Fall, wird es nicht viel ausmachen.

Gibt einen Compilierfehler, zumindest als Serial.write(F("AT+CMGF=1\r\n")
Die SoftwareSerial schluckt es aber. Bug or Feature?

serialSIM900.write(F("AT+CMGF=1\r\n"));
Sollte einen Fehler beim Kompilieren geben...

Das F Makro ist eigentlich für print gedacht, nicht für write.
(Lerne den Unterschied zwischen write und print).

Wenn es keinen Kompilierfehler gibt, (und trotzdem nicht geht), ist das ein Fehler in der Library :wink:

OOPS, wo ist den der Beitrag hin?

OOPS, wo ist den der Beitrag hin?

Den hatte ich

  1. geschrieben,
  2. ausprobiert
  3. mich gewundert
  4. da sich noch niemand drauf bezogen hat, wieder gelöscht.

Hab es auch gemerkt: HardwareSerial liefert:

   call of overloaded 'write(const __FlashStringHelper*)' is ambiguous

Aber SoftwareSerial schluckt es. Da es - wie beobachtet - nicht geht, ist es meiner Meinung nach ein Bug in SoftwareSerial.h, den falschen Datentyp nicht anzumeckern.


Ist aber off-topic hier :slight_smile:
serialSIM900.print(F("AT+CMGF=1\r\n")); // sollte funktionieren.

Ja Compiler Fehler gab es keine , ist es denn "Problematisch" die SMS Funktion von dem F() zu befreien. Denn ich habe meinen Code jetzt aufgeräumt und komme auf um die 60% ohne Thingspeak und 70% mit thingspeak . Bei diesen 70% gibt es schon wieder schneller Fehler (logisch).

Zu dem was "handynummer" macht , ich fange den AT befehl zum sms senden an :
serialSIM900.write(("AT+CMGS="+49"));
und füge die Nummer an
serialSIM900.write(Handynummer);
, hänge mit
serialSIM900.write((""\r\n"));
noch ein " dran und schicke es los, funktioniert super.

Wie deklariere ich denn Arrays ohne feste Größe richtig? Ich dachte eigentlich immer das char name[] = "";
der richtige weg sei aber bin ja noch recht neu hier.

Danke für die Antworten durch euch leuft mein Sketch wieder, damits fertig wird muss es nur noch n bissl flotter laufen :slight_smile:

Wie deklariere ich denn Arrays ohne feste Größe richtig?

Gar nicht. Arrays brauchen eine feste Größe

Ich dachte eigentlich immer das char name[] = ""

Das ist ein Array der Größe 1. Wegen dem Null-Terminator. Wenn du da drüber hinaus schreibst passieren schlimme Dinge

Und wieso geht das nicht?

serialSIM900.print(F("AT+CMGS=\"+49"));

Sowas ist auch unsinnig:

String Sensorenauswahl[] = {"0","0","0","0","0"};

Wenn du einzelne Ziffern als char Speichern willst, tut es ein Array aus char:

char Sensorenauswahl[] = { '0', '0', '0', '0', '0' };

Das geht für Ziffern von 0-9. Oder nehme ein Array aus Byte:

byte Sensorenauswahl[] = { 0, 0, 0, 0, 0 };

Ok ok fange ich mal an gut, das mit den Arrays wusste ich nicht das ich dann praktisch ins nichts schreibe, werde ich ändern habe ich wie man sieht zu viel verwendet.

Das mit dem AT command "funktioniert" in dem Sinne das der Compiler nichts aussspuckt aber ich keine SMS mehr bekomme (müsste mich mehr mit Beschäftigen und schauen was das SIM900 antwortet bzw wie das auf F() reagiert)

Das mit der Sensorenauswahl hatte ich vorher auch als Char gehabt doch da ich früher Probleme mit Umrechnungen hatte und es bei dem damaligen Code einfacher war hatte ich mich für die String Variante entschieden werde das aber gleich ändern.

Danke für die hilfreichen Antworten!

Außerdem habe ich wie vorhin vorgeschlagen die Streaming.h Library eingebaut und die Serielle Ausgabe der DHT Werte damit in eine Zeile gefasst.

Serial << F("**********************************") << F("\r\n") << F("Temperatursensor 1 : ") << dht1value << F("\r\n") << F("Temperatursensor 2 : ") << dht2value << F("\r\n") << F("Temperatursensor 3 : ") << dht3value << F("\r\n") << F("Temperatursensor 4 : ") << dht4value << F("\r\n") << F("Temperatursensor 5 : ") << dht5value << F("\r\n") << F("**********************************") << F("\r\n");

Außerdem , wie lange müssen die Delays zwischen den GSM Befehlen sein? Gibt es einen guten Richtwert?
Habe bisher überall 1000 ms gesehen...

(müsste mich mehr mit Beschäftigen und schauen was das SIM900 antwortet bzw wie das auf F() reagiert)

Das SIM900 interessiert gar nicht ob das F() oder nicht F() ist. Das bekommt davon gar nichts mit. Das Problem besteht in der Bibliothek und welche der Methoden darin aufgerufen wird. Die Methoden sind überladen (d.h. der gleiche Methodenname für unterschiedliche Datentypen) und manchmal ist es nicht klar welche aufgerufen werden soll.

write() sollte mit F() eigentlich nicht gehen, da es keine Version davon mit einem FlashStringHelper als Parameter gibt.

Tip: Warnungen aktivieren! Fehler sind nicht alles

doch da ich früher Probleme mit Umrechnungen hatte und es bei dem damaligen Code einfacher war hatte ich mich für die String Variante entschieden

Dann sorge dafür dass es korrekt umgerechnet wird wenn du was damit machst. Irgendwas + '0' geht genauso. Die String Klasse ist auf Grund ihres riesigen Overheads (6 Byte! Für einen Zeiger auf das interne Array, die Länge des Strings und die Größe des Arrays) keine Lösung

Lerne den Unterschied zwischen write und print

serialSIM900.print(F("AT+CMGF=1\r\n")); // sollte funktionieren.

Du kannst in C auch eine Anweisung in meherere Zeilen trennen.
Dem Compiler und dem Arduino ist es vollkommen egal, uns Menschen nicht.

Serial << F("**********************************") << F("\r\n") 
         << F("Temperatursensor 1 : ") << dht1value << F("\r\n") 
         << F("Temperatursensor 2 : ") << dht2value << F("\r\n") 
         << F("Temperatursensor 3 : ") << dht3value << F("\r\n") 
         << F("Temperatursensor 4 : ") << dht4value << F("\r\n") 
         << F("Temperatursensor 5 : ") << dht5value << F("\r\n") 
         << F("**********************************") << F("\r\n");

AlexArduinoP:
Ok ok fange ich mal an gut, das mit den Arrays wusste ich nicht das ich dann praktisch ins nichts schreibe, werde ich ändern habe ich wie man sieht zu viel verwendet.

Du schreibst nicht ins nichts; Du überschreibst den darauffolgenden RAM-Speicher. Dadurch werden die inhalte verändert und der Sketch macht komische Sachen.

Grüße Uwe

Serial << F("**********************************") << F("\r\n") ;

eleganter und vielleicht(?) Flash sparender:

Serial << F("**********************************") << endl) ;

michael_x:
Du kannst in C auch eine Anweisung in meherere Zeilen trennen.
Dem Compiler und dem Arduino ist es vollkommen egal, uns Menschen nicht.

Serial << F("**********************************") << F("\r\n") 

<< F("Temperatursensor 1 : ") << dht1value << F("\r\n")
        << F("Temperatursensor 2 : ") << dht2value << F("\r\n")
        << F("Temperatursensor 3 : ") << dht3value << F("\r\n")
        << F("Temperatursensor 4 : ") << dht4value << F("\r\n")
        << F("Temperatursensor 5 : ") << dht5value << F("\r\n")
        << F("**********************************") << F("\r\n");

Gut , mache ich dann so sieht schöner aus ^^

ElEspanol:
Serial << F("**********************************") << F("\r\n") ;

eleganter und vielleicht(?) Flash sparender:

Serial << F("**********************************") << endl) ;

Gute Idee mache ich auch , sieht nochmal besser aus.

uwefed:
Du schreibst nicht ins nichts; Du überschreibst den darauffolgenden RAM-Speicher. Dadurch werden die inhalte verändert und der Sketch macht komische Sachen.

Gut ich werde dann jetzt versuchen alle Arrays eine feste größe zuzuweisen um zu verhindern das mein Sketch irgendwann einfach stehen bleibt richtig?

Weisse den array jeweils die max. zu erwartende Grösse + 1 (für die 0-Terminierung) zu.
Benutze nur EINEN Puffer, auch hier die max. zu erwartende Grösse + 1
Beim Reinschreiben kannst du noch einen Fehler abfangen in dem du den Schreibindex auf

if (Schreibindex  >sizeof(buffer)-1 ){
Serial.println(F"Pufferueberlauf in xxx");
Schreibindex = Schreibindex  -1;  // oder Schreibindex  =0; je nach Anwendung
}

Puffer sind, wie der name schon sagt, zum Puffern bzw. zum zusammensetzen von verschiedenen Daten, also nur temporär. Vor erneuter Benutzung sollte man ihn mit
memset (buffer,0,sizeof(buffer));
zurücksetzen. Somit ist auch gewährt, dass der buffer immer terminiert ist.

Jup das hatte ich auch schon in meinem Code gehabt (das mit dem Buffer leeren) nur ich hatte es wieder entfernt gehabt da es mir keinen Vorteil bei dem Ram Problem was ich vorher hatte gegeben hatte. Der Programmcode den ich mithilfe dieses Threads verbessert habe funktioniert mittlerweile und ich habe ihn probeweise über Nacht laufen gelassen und er hat sich nicht aufgehangen oder irgendwelche komischen Sachen gemacht.

Danke für die hilfreichen Antworten hat mir in meinem ersten Projekt echt weitergeholfen.

hier noch einmal der fertige code falls es noch jemanden interessiert, Verbesserungsvorschläge um Fehler vorzubeugen oder kreative Ideen werden immernoch gerne angenommen!

code dieses mal leider auf pastebin weil ich sonst 3 posts hintereinander machen müsste.

https://pastebin.com/PP2MjtyT

Ich habe den Code mal kurz überflogen. wenn keine Fehler drin sind, bzw. Alles läuft wie es soll, ändere besser nichts mehr dran.

Kreative Ideen braucht es für die Problemstellung nicht wirklich.

Optimierung von Speicherverbrauch und Programmierstil, da ist noch viel Luft nach oben.
Falls du beim Arduino Hobby bleibst und weiter lernen willst, können wir den Sketch gerne darauf durchgehen.