PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATtiny85 Speicher knapp, was tun?



spunky9003
07.12.2017, 23:43
Hallo, ich mache grad mit dem ATtiny85 rum, der hat ja nur 6.012 Byte freien Programmspeicher, ich habe jetzt schon 5.938 Byte belegt. Was passiert, wenn ich während der Laufzeit einen String aufbaue der 100 Byte lang ist? Wird der immer irgendwo abgeschnitten? Haben Variablen einen extra Speicherbereich oder geht das auf Kosten des Programmspeichers? Hängt sich das Programm auf? Darum besser auf den nächst größeren ATtiny167 umsteigen?


ATtiny85: https://www.ebay.de/itm/292349477939

ATtiny167: http://www.ebay.de/itm/192209426699


Wie viel Zeichen kann man mit Serial.read bzw. Serial.println in einem String senden bzw. empfangen, ist das begrenz oder kann man das irgendwo deklarieren? Ist ein String von 150 Zeichen ein Problem bei 9600 Baud?

MfG.

Ceos
08.12.2017, 07:00
ist der flash voll, meckert dein flash tool
ist der ram schon reichlich voll wirds dramatisch

variablen die du in methoden verwendest werden vom linker meist hochgradig optimiert (z.b. doppelnutzung bei code pfaden die nie gleichzeitig ausgeführt werden) und an den anfang des RAM gelegt
globale variablen werden dahinter angelegt
methodenaufrufe und deren parameter und die register die zum rechnen verwendet werden werden auf den sog. stack gelegt
der stack wird vom ende des ram nach vorne geschrieben (rückwärts) und wenn er groß genug ist überschreibt er ohne vorwarnung deine globalen variablen (sog. stackobverflow) aber der tiny is dumm und merkt das nicht!

wenn also deine globalen variablen rum spinnen oder der controller nach dem beenden einer methode plötzlich ins nirvana springt und mist ausführt wird dir wohl der ram ausgegenagen sein

konstanten die du definierst kannst du zwar mit PROGMEM (PROGMEM uint8_t someTextConstant="Hello";) in den flasch schreiben um RAM zu sparen aber der zugriff auf sog. progmem variablen ist tückisch, du kannst sie als einzelne variablen kopieren aber wenn du ein array kopieren willst must du memcpy_P benutzen statt memcpy ... es gibt diverse methoden die mit _P enden extra für ROM konstanten

kontanten in den RAM zu laden bringt rein garnichts für mehr ROM, der inhalt der variablen steht trotzdem im flash, denn die variablen müssen erstmal erzeugt werden, das bringt dir ausschließlich geschwindigkeitsvorteile weil ROM konstanten mehrere takte brauchen um sie für die operation zu laden

versuch mal deine optimierungsstufe zu ändern, mit dem aktuellen avr gcc der mit atmel studio 7 kommt habe ich BESTE erfahreungen mit "-oS" gemacht (es gibt noch -o1 für standard optimierung, -o2 für kompakteren code und kleinen RAM, -o3 für maximal schnellen code und -oS für minimale flash größe)

spunky9003
08.12.2017, 07:38
kann ich mit atmel studio 7 auch die oben genannten USB-Board benutzen oder brauch ich einen bestimmten Programmer?

Ceos
08.12.2017, 07:45
du kannst die hex files compilieren udn dann mit einem tool deiner wahl flashen (arduino bietet sowas auch soweit ich mich entsinne)

aber versuch doch die optionen bei deinem compiler erstmal, müsste die gleiche wirkung haben, effekt kann cih nicht vorhersagen :)

HaWe
08.12.2017, 09:07
Hallo, ich mache grad mit dem ATtiny85 rum, der hat ja nur 6.012 Byte freien Programmspeicher, ich habe jetzt schon 5.938 Byte belegt. Was passiert, wenn ich während der Laufzeit einen String aufbaue der 100 Byte lang ist? Wird der immer irgendwo abgeschnitten? Haben Variablen einen extra Speicherbereich oder geht das auf Kosten des Programmspeichers? Hängt sich das Programm auf? Darum besser auf den nächst größeren ATtiny167 umsteigen?


ATtiny85: https://www.ebay.de/itm/292349477939

ATtiny167: http://www.ebay.de/itm/192209426699


Wie viel Zeichen kann man mit Serial.read bzw. Serial.println in einem String senden bzw. empfangen, ist das begrenz oder kann man das irgendwo deklarieren? Ist ein String von 150 Zeichen ein Problem bei 9600 Baud?

MfG.

du kannst auf einen zeitgemäßen Prozessor (z.B. Arduinos mit ARM Cortex M0, M3, ESP oder STM) umsteigen, die haben mindestes 32 KB RAM aufwärts - und es gibt sie auch mit Breadboard-kompatiblen Pin-outs. 8)

Ceos
08.12.2017, 09:58
das mit arduino war nur vermutet, aber vielleicht bruacht er den chip wegen pinout und größe oder gar stromverbrauch

spunky9003
08.12.2017, 10:32
ja, das Board wurde auf Grund der Größe gewählt, ich brauche auch nur wenige Pins. Auch der Preis spielte hier eine Rolle, es sollen 48 Stück seriell miteinander verbunden werden, jeder soll einen Sensor überwachen.

Aber ich werde meinen Code überarbeiten, bisher gibt jedes Board seine Sensordaten an das nächste Board weiter, das wiederum hängt seine Daten dran usw. bis am Ende eine sehr lange Datenkette ausgewertet wird.

Ich werde es jetzt so versuchen, das jedes Board nur fehlerhafte Sensordaten weiterleitet.

Ceos
08.12.2017, 11:17
mach es doch einfacher, statt die daten entgegen zu nehmen, zwischen zu speichern und dann verändert weiter zu senden

nimm das daisy chain verfahren, dafür brauchst du aber noch eine zusätzliche leitung!

wenn der erste sensor senden möchte, zieht er eine signalleitung auf LOW (am empfänger hat die leitung einen pull up widerstand) und sendet seine daten, solange die leitung am nächsten sensor low ist, plaudert er die daten munter zum nächsten sensor weiter und zieht auch seine eigene leitung auf LOW

wenn die leitung von LOW auf HIGH wechselt (also der erste sensor seine daten fertig gesendet hat) fängt der zweite sensor an zu senden und lässt anschließend die signalleitung zum dritten sensor los, der hat inzwischen die daten vom ersten udn zweiten sensor weitererzählt während er seine signalleitung zu nr. 4 auf low hält und hängt dann seine daten mit an .... usw. usw. usw.

als empfänger bekommst du dann also nach dem stille post prinzip (daisy chain kommt von daisy duck die alles weiterschnattert) mehrere datenpäckchen aneinander gereiht auf die dann eine längere pause kommt

wenn du jetzt die signalleitung vom letzten sensor an den ersten hängst hast du sogar eine endlosreihe von paketen oder deni empfänger toggelt einfach de signalleitung des ersten sensor kurz HIGH LOW HIGH und er fängt an zu senden

spunky9003
08.12.2017, 23:17
ok, ich konnte den Code optimieren, er macht jetzt was er soll.

Danke.

spunky9003
12.12.2017, 20:09
so, noch mal...

ich habe hier zwei Code Schnipsel:

wird der erste Code compiliert, brauche ich 5.900 byte (Program size: 5.900 bytes (used 98% of a 6.012 byte maximum) (0,62 secs)):

.
.
.
// wenn eingang <> "!" und fehler = 1, dann ausgang = (eingang(!*) + 1) & "!" & (eingang(!*) + 1)
else if (inString.indexOf("!") == 0 && analogRead(1) > 1000) {
mySerial.println(inp + "!" + out);
}
// wenn eingang <> "!" und fehler = 0, dann ausgang = (eingang(!*) + 1)
// else if (inString.indexOf("!") == 0 && analogRead(1) < 1000) {
// mySerial.println(out);
// }


wird der zweite Code compiliert, brauche ich 6.400 byte (Program too big. The size is 6400 bytes (of a 6012 byte maximum).):

.
.
.
// wenn eingang <> "!" und fehler = 1, dann ausgang = (eingang(!*) + 1) & "!" & (eingang(!*) + 1)
// else if (inString.indexOf("!") == 0 && analogRead(1) > 1000) {
// mySerial.println(inp + "!" + out);
// }
// wenn eingang <> "!" und fehler = 0, dann ausgang = (eingang(!*) + 1)
else if (inString.indexOf("!") == 0 && analogRead(1) < 1000) {
mySerial.println(out);
}


Im 2. Abschnitt wird weniger Code benutzt, doch ich brauch 500 byte mehr! Kann mir das mal jemand erklären? Ich benutze Visual Micro (Arduino), bei Atmel Studio 7 blick ich leider nicht durch und habe es wieder deinstalliert.

HaWe
12.12.2017, 20:24
so, noch mal...

ich habe hier zwei Code Schnipsel:

wird der erste Code compiliert, brauche ich 5.900 byte (Program size: 5.900 bytes (used 98% of a 6.012 byte maximum) (0,62 secs)):

.
.
.
// wenn eingang <> "!" und fehler = 1, dann ausgang = (eingang(!*) + 1) & "!" & (eingang(!*) + 1)
else if (inString.indexOf("!") == 0 && analogRead(1) > 1000) {
mySerial.println(inp + "!" + out);
}
// wenn eingang <> "!" und fehler = 0, dann ausgang = (eingang(!*) + 1)
// else if (inString.indexOf("!") == 0 && analogRead(1) < 1000) {
// mySerial.println(out);
// }


wird der zweite Code compiliert, brauche ich 6.400 byte (Program too big. The size is 6400 bytes (of a 6012 byte maximum).):

.
.
.
// wenn eingang <> "!" und fehler = 1, dann ausgang = (eingang(!*) + 1) & "!" & (eingang(!*) + 1)
// else if (inString.indexOf("!") == 0 && analogRead(1) > 1000) {
// mySerial.println(inp + "!" + out);
// }
// wenn eingang <> "!" und fehler = 0, dann ausgang = (eingang(!*) + 1)
else if (inString.indexOf("!") == 0 && analogRead(1) < 1000) {
mySerial.println(out);
}


Im 2. Abschnitt wird weniger Code benutzt, doch ich brauch 500 byte mehr! Kann mir das mal jemand erklären? Ich benutze Visual Micro (Arduino), bei Atmel Studio 7 blick ich leider nicht durch und habe es wieder deinstalliert.

hallo,
wo ist da der Unterschied zwischen den beiden Codes?
500 bytes Unterschied bei sonst gleichem Code klingt nach Verwendung anderer Libs - aber was genau wurde denn jetzt anders gemacht?
Evtl. brauchen wir sonst hier sicher den kompletten, ungekürzten Code.

spunky9003
12.12.2017, 20:43
es ist jeweils der gleiche Code, nur wurde nur einmal der obere, dann der untere Teil auskommentiert und compiliert, alles andere ist 100% identisch.

habe den Code nochmal farblich hervorgehoben. https://www.roboternetz.de/community/threads/71424-ATtiny85-Speicher-knapp-was-tun?p=641058&viewfull=1#post641058

HaWe
12.12.2017, 21:09
ah, alles klar, hier wird in der Serial-Class erst die auszugebende Zeichenkette quasi per String-class-Methoden verlängert.
Versuche mal, den Ausgabe-string mit normalen ANSI-strcat-Methoden außerhalb von Serial zusammenzusetzen und dann erst in der kompletten neuen Variante per Serial auszugeben!

Testweise:
was macht das hier:

mySerial.print(inp);
mySerial.print("!");
mySerial.println(out);


Falls möglich, verwende auch keine String Class, sondern ANSI-C-strings, also char[] bzw. char *, das spart mächtig Speicher.

spunky9003
16.12.2017, 16:51
ich habe den Code nochmal überarbeitet, ich konnte ihn noch ein wenig optimieren. Leider noch immer ca. 100 Byte zu viel für den ATtiny85. Ich bin leider nicht so der Profi, sieht jemand eine Möglichkeit den Code noch weiter zu optimieren, bei den wenigen Zeilen wahrscheinlich nicht so einfach.


/*
Name: Sketch1.ino (speziell für IR Reflexlichtschranke, TCRT 5000)
Created: 06.12.2017 14:10:36
*/

#include <SoftSerial.h>

SoftSerial mySerial(4, 0); // RX, TX
const int LED_out = 1; // onboard LED auf Model A
//const int DIST_in = 2; // Sharp Distance Sensor
const int IR_in = 2; // IR Modul, Empfänger
const int IR_out = 3; // IR Modul, Sender
long lasttime;
//String err = "";
String out_l = "";
String out_r = "1";
//String outString = "1";
String inString = "";

void setup() {
mySerial.begin(9600);
//pinMode(DIST_in, INPUT); // Sharp Distance Sensor
pinMode(LED_out, OUTPUT); // LED Fehlermeldung
pinMode(IR_out, OUTPUT); // IR Modul, Sender
pinMode(IR_in, INPUT); // IR Modul, Empfänger
}

void loop() {

if (millis() - lasttime > 500) {

digitalWrite(IR_out, HIGH); // IR Modul, Sender ein
digitalWrite(LED_out, LOW); // LED Fehlermeldung aus

while (mySerial.available() > 0) { // sind Daten vorhanden, dann
inString += (char)mySerial.read(); // Daten von anderen Modul einlesen
}

if (inString != "") { // wurden Daten eingelesen, dann
out_r = inString.substring(inString.indexOf("!") + 1, inString.indexOf("\n") - 1).toInt() + 1; // eigene Modul-Nummer berechnen
}


if (analogRead(1) < 300 || analogRead(1) > 900) { // IR Modul, Empfänger abfragen, dann
digitalWrite(LED_out, HIGH); // LED Fehlermeldung ein
out_l = out_r; // eigene Modul-Nummer für Fehlermeldung merken
}
else { // keine Fehlermeldung
out_l = "";
}

if (inString.indexOf("!") > 0 && out_l == "") { // Fehlermeldung von anderen Modul und keine Fehlermeldung vom eigenen Modul, dann
out_l = inString.substring(0, inString.indexOf("!")); // Fehlermeldung von anderen Modul weiterleiten
}
else if (inString.indexOf("!") > 0 && out_l != "") { // Fehlermeldung von anderen Modul und Fehlermeldung vom eigenen Modul, dann
out_l = inString.substring(0, inString.indexOf("!")) + "," + out_r; // Fehlermeldung von anderen Modul und Fehlermeldung vom eigenen Modul weiterleiten
}


mySerial.println(out_l + "!" + out_r); // Daten zum nächsten Modul schicken, Fehlermeldung(en) + "!" + eigene Modul-Nummer

inString = ""; // Eingangsdaten löschen

digitalWrite(IR_out, LOW); // IR Modul, Sender aus

lasttime = millis();
}

}

HaWe
16.12.2017, 18:58
ich habe den Code nochmal überarbeitet, ich konnte ihn noch ein wenig optimieren. Leider noch immer ca. 100 Byte zu viel für den ATtiny85. Ich bin leider nicht so der Profi, sieht jemand eine Möglichkeit den Code noch weiter zu optimieren, bei den wenigen Zeilen wahrscheinlich nicht so einfach.


/*
Name: Sketch1.ino (speziell für IR Reflexlichtschranke, TCRT 5000)
Created: 06.12.2017 14:10:36
*/

#include <SoftSerial.h>

SoftSerial mySerial(4, 0); // RX, TX
const int LED_out = 1; // onboard LED auf Model A
//const int DIST_in = 2; // Sharp Distance Sensor
const int IR_in = 2; // IR Modul, Empfänger
const int IR_out = 3; // IR Modul, Sender
long lasttime;
//String err = "";
String out_l = "";
String out_r = "1";
//String outString = "1";
String inString = "";

void setup() {
mySerial.begin(9600);
//pinMode(DIST_in, INPUT); // Sharp Distance Sensor
pinMode(LED_out, OUTPUT); // LED Fehlermeldung
pinMode(IR_out, OUTPUT); // IR Modul, Sender
pinMode(IR_in, INPUT); // IR Modul, Empfänger
}

void loop() {

if (millis() - lasttime > 500) {

digitalWrite(IR_out, HIGH); // IR Modul, Sender ein
digitalWrite(LED_out, LOW); // LED Fehlermeldung aus

while (mySerial.available() > 0) { // sind Daten vorhanden, dann
inString += (char)mySerial.read(); // Daten von anderen Modul einlesen
}

if (inString != "") { // wurden Daten eingelesen, dann
out_r = inString.substring(inString.indexOf("!") + 1, inString.indexOf("\n") - 1).toInt() + 1; // eigene Modul-Nummer berechnen
}


if (analogRead(1) < 300 || analogRead(1) > 900) { // IR Modul, Empfänger abfragen, dann
digitalWrite(LED_out, HIGH); // LED Fehlermeldung ein
out_l = out_r; // eigene Modul-Nummer für Fehlermeldung merken
}
else { // keine Fehlermeldung
out_l = "";
}

if (inString.indexOf("!") > 0 && out_l == "") { // Fehlermeldung von anderen Modul und keine Fehlermeldung vom eigenen Modul, dann
out_l = inString.substring(0, inString.indexOf("!")); // Fehlermeldung von anderen Modul weiterleiten
}
else if (inString.indexOf("!") > 0 && out_l != "") { // Fehlermeldung von anderen Modul und Fehlermeldung vom eigenen Modul, dann
out_l = inString.substring(0, inString.indexOf("!")) + "," + out_r; // Fehlermeldung von anderen Modul und Fehlermeldung vom eigenen Modul weiterleiten
}


mySerial.println(out_l + "!" + out_r); // Daten zum nächsten Modul schicken, Fehlermeldung(en) + "!" + eigene Modul-Nummer

inString = ""; // Eingangsdaten löschen

digitalWrite(IR_out, LOW); // IR Modul, Sender aus

lasttime = millis();
}

}


mein Tipp ging in die Richtung, die String Klasse so weit wie möglich weg zu lassen.
Also:
statt String out_l = ""; // <<< das ist dei Arduinoo String Class String. Braucht viel Speicher mit seinen ganzen String Class Methoden im Programmspeicher
also jetzt stattdessen:
char out_l[50]=""; // <<< das ist ein C string, also ein char array mit deutlich weniger Memory-Bedarf im Programmspeicher.

ich habe hier willkürlich 50 char Länge gewählt, du musst es ntl auf deinen Bedarf hin optimieren.
Entsprechend sind dann auch die anderen Arduino Strings durch C strings zu ersetzen.

C strings kann man nicht addieren, dazu werden hingegen die folgenden weniger Speicher-hungrigen C Funktionen verwendet:
strcpy()
strncpy()
strcat()
strncat()
memcpy()

char out_l[50]="";
geht auch nur beim 1. Initialisieren, danach muss es heißen
strcpy(out_l[50], "");

Achte darauf, dass deine C strings immer mit einer Null terminiert sind (Zahl Null = '\0', nicht Zeichen '0'). Manche C-Funktionen ergänzen den automatisch, manche nicht.
http://www.cplusplus.com/reference/cstring/strcat/
http://www.cplusplus.com/reference/cstring/strcpy/

Ceos
16.12.2017, 19:15
je nachdem wie gut der compiler schjon optimiert könntest du aus deinen kontanten ROM konstanten machen und so ein paar byte init code sparen (geht aber minimal zu lasten der geschwindigkeit)

const int -> const PROGMEM short .... je nachdem wie dein compiler arbeitet kann dein int 16 oder 32bit groß sein udn short ist nur 8bit

WARNUNG: wenn er PROGMEM nicht compilieren kann liegt es daran dass es eine instruktion ist die nur ein AVR compiler kann

spunky9003
17.12.2017, 10:29
ok, ich probiere das mal...

...hab dann noch überlegt, alle Daten bit-weise zu übertragen, es sollen ja mehrere Module seriell verbunden werden, könnte dann bei 8 Modulen so aussehen, das erste Byte gibt eine Fehlermeldung weiter, das zweite Byte gibt die aktuelle Modul-Nummer ans nächste Modul:

Modul 1 sendet: 00000000 00000001 (Modul 1 ok)
Modul 2 sendet: 00000000 00000010 (Modul 1+2 ok)
Modul 3 sendet: 00100000 00000011 (Modul 1+2 ok, Modul 3 Fehler)
Modul 4 sendet: 00100000 00000100 (Modul 1+2+4 ok, Modul 3 Fehler)
Modul 5 sendet: 00100000 00000101 (Modul 1+2+4+5 ok, Modul 3 Fehler)
Modul 6 sendet: 00100000 00000110 (Modul 1+2+4+5+6 ok, Modul 3 Fehler)
Modul 7 sendet: 00100010 00000111 (Modul 1+2+4+5+6 ok, Modul 3+7 Fehler)
Modul 8 sendet: 00100010 00001000 (Modul 1+2+4+5+6+8 ok, Modul 3+7 Fehler)

Auf dem Modul brauch keine Auswertung erfolgen, es muss nur die empfange Modul-Nummer um 1 erhöht werden und bei einem Fehler muss ein bit an der richtigen Stelle auf 1 gesetzt werden.

---

Edit: mit der binären Übertragung brauche ich nur 3 kByte Programmspeicher, da spare ich mir das ganze String-Geraffel, warum nicht gleich so... :p

Ceos
18.12.2017, 16:31
netter ansatz ;)

HaWe
18.12.2017, 22:14
ok, ich probiere das mal...

...hab dann noch überlegt, alle Daten bit-weise zu übertragen, es sollen ja mehrere Module seriell verbunden werden, könnte dann bei 8 Modulen so aussehen, das erste Byte gibt eine Fehlermeldung weiter, das zweite Byte gibt die aktuelle Modul-Nummer ans nächste Modul:

Modul 1 sendet: 00000000 00000001 (Modul 1 ok)
Modul 2 sendet: 00000000 00000010 (Modul 1+2 ok)
Modul 3 sendet: 00100000 00000011 (Modul 1+2 ok, Modul 3 Fehler)
Modul 4 sendet: 00100000 00000100 (Modul 1+2+4 ok, Modul 3 Fehler)
Modul 5 sendet: 00100000 00000101 (Modul 1+2+4+5 ok, Modul 3 Fehler)
Modul 6 sendet: 00100000 00000110 (Modul 1+2+4+5+6 ok, Modul 3 Fehler)
Modul 7 sendet: 00100010 00000111 (Modul 1+2+4+5+6 ok, Modul 3+7 Fehler)
Modul 8 sendet: 00100010 00001000 (Modul 1+2+4+5+6+8 ok, Modul 3+7 Fehler)

Auf dem Modul brauch keine Auswertung erfolgen, es muss nur die empfange Modul-Nummer um 1 erhöht werden und bei einem Fehler muss ein bit an der richtigen Stelle auf 1 gesetzt werden.

---

Edit: mit der binären Übertragung brauche ich nur 3 kByte Programmspeicher, da spare ich mir das ganze String-Geraffel, warum nicht gleich so... :p

schön zu sehen, dass der Verzicht auf die String Klasse, wie ich vermutet habe, tatsächlich so viel Speicher-Ersparnis bringt.
Jetzt spiel doch mal ein bisschen mit den ANSI C strings rum, und sei es nur, um klassisches C zu lernen: ich bin sicher, dass der Speicherbedarf selbst dann nicht wieder ins Monströse anwachsen wird.

Ceos
19.12.2017, 15:02
dass der Verzicht auf die String Klasse, wie ich vermutet habe, tatsächlich so viel Speicher-Ersparnis bringt

Dinge wie strings, modulo rechnung oder floating point berechungen kosten MASSIV speicher, da immer gleich die ganze bibliothek eingebunden wird, ohne das auszukommen ist aber definitiv nicht einfach

ich hätte es zwar auch gerne empfohlen aber da mir eine hinreichende alternative fehlte hab ich mich da lieber rausgehalten :)

HaWe
19.12.2017, 17:17
Dinge wie strings, modulo rechnung oder floating point berechungen kosten MASSIV speicher, da immer gleich die ganze bibliothek eingebunden wird, ohne das auszukommen ist aber definitiv nicht einfach
ich hätte es zwar auch gerne empfohlen aber da mir eine hinreichende alternative fehlte hab ich mich da lieber rausgehalten :)

wie ich es meinte, war:
der einfache ANSI C-string (klein geschrieben) Datentyp char * wird ja immer eingebunden,
C++ std::string (klein geschrieben) gibt es bei Arduino überhaupt nicht,
die C++ String Klasse (groß geschrieben) samt ihrer Klassen-Methoden wird aber, soweit ich weiß, nur eingebunden, sobald man sie tatsächlich benutzt;
dass die C++ String Klasse viel Zusatz-Speicher braucht, sobald man sie benutzt, deckt sich aber mit den Beobachtungen des OP.

Ob und wie weit das mit dem Zusatz-Speicherbedarf aber für die ANSI C string library Funktionen (string.h, klein geschrieben, mit strcpy und strcat) in der Arduino IDE ebenfalls gilt, wäre echt mal auszutesten - auch diese lib muss ja nicht explizit #included werden, denn die Arduino IDE macht das automatisch, implizit.

Ceos
19.12.2017, 19:52
auch was die math lib und die string lib angeht, kann man in den compiler einstellungen rumspielen, sodass er nicht immer die komplette lib benutzt sondern nur einen teil davon, aber das geht zu tief in die materie "wie konfiguriere ich meinen compiler"

ich kann nur wärmstens empfehlen sich entweder ein buch für den ansi-c compiler zu holen und sich mit den compiler flags auseinander zu setzen und zusätzlich im Inet schlau zu machen wie man den compiler von arduino "justieren" kann ... oder lass den buch opart weg und such dir eine online referenz (warnung, fast nur in englisch zu haben)

da fällt mir noch was wichtiges ein, wenn man den GANZEN printf kram weg lässt spart man ebenfalls UNMENGEN speicher, leider ist aber die arduino lib schon damit zugepflastert und man kann es nicht wirklich umgehen

HaWe
19.12.2017, 20:42
auch was die math lib und die string lib angeht, kann man in den compiler einstellungen rumspielen, sodass er nicht immer die komplette lib benutzt sondern nur einen teil davon, aber das geht zu tief in die materie "wie konfiguriere ich meinen compiler"

ich kann nur wärmstens empfehlen sich entweder ein buch für den ansi-c compiler zu holen und sich mit den compiler flags auseinander zu setzen und zusätzlich im Inet schlau zu machen wie man den compiler von arduino "justieren" kann ... oder lass den buch opart weg und such dir eine online referenz (warnung, fast nur in englisch zu haben)

da fällt mir noch was wichtiges ein, wenn man den GANZEN printf kram weg lässt spart man ebenfalls UNMENGEN speicher, leider ist aber die arduino lib schon damit zugepflastert und man kann es nicht wirklich umgehen

wie es grundsätzlich geht, weiß ich von gcc auf dem Pi.
Ich spreche hier also nur über die Arduino-IDE mit den default-Einstellungen, so wie sie jeder normale Arduino-Nutzer verwendet, und wie es die Arduino IDE eben dann automatisch macht: Da wird normalerweise nichts an Compile- oder Build-Flags oder Makefile herummanipuliert.

Es geht also nur darum, inwiefern sich allein dadurch etwas ändert, dass man vollständig ohne die String-Klasse im eigenen Sourcecode auskommt, sondern stattdessen alleine char* oder char[] verwendet (d.h. nullterminierte C-strings), und dann entweder mit oder ohne Verwendung von zusätzlichen cstring-lib-Funktionen wie strcat oder strcpy arbeitet: was ändert das am Speicherbedarf für ansonsten identische Programme?
Das war die Frage an den OP.

Tido
21.12.2017, 20:46
ok, ich probiere das mal...

...hab dann noch überlegt, alle Daten bit-weise zu übertragen, es sollen ja mehrere Module seriell verbunden werden, könnte dann bei 8 Modulen so aussehen, das erste Byte gibt eine Fehlermeldung weiter, das zweite Byte gibt die aktuelle Modul-Nummer ans nächste Modul:

Modul 1 sendet: 00000000 00000001 (Modul 1 ok)
Modul 2 sendet: 00000000 00000010 (Modul 1+2 ok)
Modul 3 sendet: 00100000 00000011 (Modul 1+2 ok, Modul 3 Fehler)
Modul 4 sendet: 00100000 00000100 (Modul 1+2+4 ok, Modul 3 Fehler)
Modul 5 sendet: 00100000 00000101 (Modul 1+2+4+5 ok, Modul 3 Fehler)
Modul 6 sendet: 00100000 00000110 (Modul 1+2+4+5+6 ok, Modul 3 Fehler)
Modul 7 sendet: 00100010 00000111 (Modul 1+2+4+5+6 ok, Modul 3+7 Fehler)
Modul 8 sendet: 00100010 00001000 (Modul 1+2+4+5+6+8 ok, Modul 3+7 Fehler)

Auf dem Modul brauch keine Auswertung erfolgen, es muss nur die empfange Modul-Nummer um 1 erhöht werden und bei einem Fehler muss ein bit an der richtigen Stelle auf 1 gesetzt werden.

---

Edit: mit der binären Übertragung brauche ich nur 3 kByte Programmspeicher, da spare ich mir das ganze String-Geraffel, warum nicht gleich so... :p



Das zweite Byte kann man sich sparen, denn wenn Modul x etwas empfängt kann der Sender ja nur Modul x-1 sein.
Oder habe ich was übersehen?

Edit: Es sei denn, die Module werden nicht fortlaufend bzw. zufällig zusammengesteckt...