- LiFePO4 Speicher Test         
Ergebnis 1 bis 10 von 24

Thema: ATtiny85 Speicher knapp, was tun?

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Benutzer Stammmitglied Avatar von spunky9003
    Registriert seit
    14.09.2014
    Beiträge
    36

    Reden

    ok, ich konnte den Code optimieren, er macht jetzt was er soll.

    Danke.

  2. #2
    Benutzer Stammmitglied Avatar von spunky9003
    Registriert seit
    14.09.2014
    Beiträge
    36

    Frage

    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)):
    Code:
    		.
    		.
    		.
    //		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).):
    Code:
    		.
    		.
    		.
    //		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.
    Geändert von spunky9003 (12.12.2017 um 20:45 Uhr)

  3. #3
    HaWe
    Gast
    Zitat Zitat von spunky9003 Beitrag anzeigen
    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)):
    Code:
    		.
    		.
    		.
    //		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).):
    Code:
    		.
    		.
    		.
    //		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.

  4. #4
    Benutzer Stammmitglied Avatar von spunky9003
    Registriert seit
    14.09.2014
    Beiträge
    36
    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...l=1#post641058

  5. #5
    HaWe
    Gast
    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.

  6. #6
    Benutzer Stammmitglied Avatar von spunky9003
    Registriert seit
    14.09.2014
    Beiträge
    36

    Frage

    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.

    Code:
    /*
    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();
    	}
    
    }

  7. #7
    HaWe
    Gast
    Zitat Zitat von spunky9003 Beitrag anzeigen
    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.

    Code:
    /*
    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/

  8. #8
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    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
    Es gibt 10 Sorten von Menschen: Die einen können binär zählen, die anderen
    nicht.

  9. #9
    Benutzer Stammmitglied Avatar von spunky9003
    Registriert seit
    14.09.2014
    Beiträge
    36
    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...
    Geändert von spunky9003 (18.12.2017 um 20:38 Uhr)

  10. #10
    HaWe
    Gast
    Zitat Zitat von Ceos Beitrag anzeigen
    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.

Ähnliche Themen

  1. Weltrekord: Kleiner Quadrocopter steigt in knapp 4 Sekunden um 100 Meter
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 25.02.2016, 07:10
  2. BMW: Neuer i3 soll knapp 240 km elektrisch fahren
    Von Roboternetz-News im Forum Neuigkeiten / Technik-News / Nachrichten / Aktuelles
    Antworten: 0
    Letzter Beitrag: 19.01.2016, 10:50
  3. Antworten: 8
    Letzter Beitrag: 21.10.2014, 09:18
  4. Suche Attiny85 im DIP-Gehäuse
    Von RAM im Forum Kaufen, Verkaufen, Tauschen, Suchen
    Antworten: 2
    Letzter Beitrag: 16.10.2011, 14:43
  5. Suche einen OPV der bis knapp unter die Versorgungsspannung ausgesteuern kann
    Von alex91 im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 4
    Letzter Beitrag: 20.05.2011, 19:04

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen