Forum: Mikrocontroller und Digitale Elektronik Arduino China-ProMini stürzt ab


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Manfred (Gast)


Lesenswert?

Ich habe einen Aufbau mit einem Pro-Mini (Mega328 @ 8 MHz), der erstmal 
unauffällig losläuft: Meine LEDs blinken, der ADS1115 wird abgefragt, 
die Spannungen stehen auf dem Display, Tasten sind abfragbar ..., aber 
es ist noch nicht alles programmiert.

Compiliert wird mit Arduino 1.89.

Wenn ich nun erweitere, dreht das Ding einen Absturz - alle Ports auf 
high, keine serielle Ausgabe mehr, tot. Ich habe Stunden zugebracht, die 
Logik zu erkennen.

Ich hatte eine Funktion in Verdacht, aber es ist viel simpler:
Sobald mein Programm etwa 83% des Programmspeicherplatzes belegt, das 
sind ca. 25.000 Bytes, kommt der Absturz. Es genügt bereits, im Setup 25 
mal das Display mit verschiedenen Texten zu beschreiben, ohne weitere 
Dinge zu tun.

Einen Überlauf des dynamischen Speichers schließe ich aus, der bewegt 
sich lt. A*-IDE um 66..68% - da war ich auf dem Nano schon höher 
unterwegs und habe auf Nano auch Software mit 98% Programmspeicher 
sauber laufen.

Testweise habe ich mal einen anderen 16MHz-ProMini reingesteckt, das 
Problem bleibt.

Aktuell kommt mir in den Sinn, den ProMini neu zu flashen und dabei den 
Optiboot zu nutzen - aber eigentlich bin ich ja noch 5k vom Ende weg.

Ideen dazu?

von ... (Gast)


Lesenswert?

Manfred schrieb:
> Es genügt bereits, im Setup 25
> mal das Display mit verschiedenen Texten zu beschreiben, ohne weitere
> Dinge zu tun.

klingt aber nach stack problem

von Einer K. (Gast)


Lesenswert?

Manfred schrieb:
> Compiliert wird mit Arduino 1.89.
Die Version kenne ich nicht.
"Wir" sind bei 1.8.13

Aber, ich befürchte, dass du einen Fehler im Programm hast.
Bootloader austauschen, wird da gar nichts bringen.
Das dürfte eine Nebelkerze sein, um dich selber von der Ursache 
abzulenken.

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Einen Überlauf des dynamischen Speichers schließe ich aus, der bewegt
> sich lt. A*-IDE um 66..68%

Die Arduino IDE kann nur den statisch belegten Speicher abschätzen. 
Der Rest ist für Stack und Heap frei.

von MWS (Gast)


Lesenswert?

Manfred schrieb:
> Sobald mein Programm etwa 83% des Programmspeicherplatzes belegt, das
> sind ca. 25.000 Bytes, kommt der Absturz.

> Es genügt bereits, im Setup 25
> mal das Display mit verschiedenen Texten zu beschreiben, ohne weitere
> Dinge zu tun.

Was nun? Das Erste betrifft Flash, Probleme entstehen z.B. dann, wenn 
der Compiler Sprungweiten falsch berechnet, bzw. falsche Befehle dafür 
verwendet. Das ist unwahrscheinlich, da die Kombination Compiler/ATM328 
häufig anzutreffen und damit gut untersucht ist. Unausgereifte Libs, 
z.B. für das Display können dagegen ein Problem erzeugen.

Das Zweite betrifft SRam, also dynamischen Speicher. Bei ausreichend 
vielen, sich selbst aufrufenden Funktionen oder durch 
Programmiererfehler kann der ausgehen.

Ich finde die Fehlerbeschreibung zu ungenau, erzeugt jede der Optionen 
für sich allein einen Fehler, oder nur Option eins in Verbindung mit 
Option zwei?

von Ingo E. (ogni42)


Lesenswert?

Bei 68% statischem RAM Verbrauch ist die Wahrscheinlichkeit groß, dass 
Du Dir mit Heap den Stack oder umgekehrt kaputt schreibst.

Aber ohne Code wird es schwer Dir da weiter zu helfen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Arduino Fanboy D. schrieb:
> ich befürchte, dass du einen Fehler im Programm hast.
Das ist in gefühlt >99,9% der Fälle so, wenn es "vorher" läuft und dann 
nach einer kleinen Änderung "auf einemal" nicht mehr.

Manfred schrieb:
> aber eigentlich bin ich ja noch 5k vom Ende weg.
Du schaust auf das falsche Ende des falschen Speichers. Weil dein 
Problem erst zur Laufzeit auftritt, bringt es nichts, wenn du auf das 
schaust, was der PC beim Compilieren ausrechnen kann. Du musst deinen 
Stackpointer kontrollieren.

> Sobald mein Programm etwa 83% des Programmspeicherplatzes belegt
... und trotzdem "noch nicht alles programmiert" ist, hast du sowieso 
ein Problem und solltest mal nach den "Speicherfressern" suchen und die 
beheben. Oft sind solche Programme nämlich erstaunlich ineffizient und 
ressourcenfressend implementiert.

von Joachim B. (jar)


Lesenswert?

Lothar M. schrieb:
> Das ist in gefühlt >99,9% der Fälle so, wenn es "vorher" läuft und dann
> nach einer kleinen Änderung "auf einemal" nicht mehr.

das dürfte jeder Programmier schon mal erfahren haben :)
Ich 2 Tage vor einer Typmusterprüfeung an einem Testautomaten.

Jedenfalls sind rekursive Aufrufe Mist wenn:

Ingo E. schrieb:
> Du Dir mit Heap den Stack oder umgekehrt kaputt schreibst

ich bin da eher doch ein Freund von globalen Variablen die konstant 
Speicher verbrauchen.

von Einer K. (Gast)


Lesenswert?

Joachim B. schrieb:
> Jedenfalls sind rekursive Aufrufe Mist wenn:
>
> Ingo E. schrieb:
>> Du Dir mit Heap den Stack oder umgekehrt kaputt schreibst
>
> ich bin da eher doch ein Freund von globalen Variablen die konstant
> Speicher verbrauchen.

Ich verstehe nicht, was Rekursion mit globalen Variablen zu tun hat.
Aber auch egal....
Rekursion, zu Laufzeit, auf kleinen µC ist bedenklich. Klar.
Aber hier sehe ich keine Rekursion.
Weit und breit nicht.
Eigentlich sehe ich gar nix.

Auch kann man das(Rekursion) oft zur Compilezeit erledigen.
Der PC hat mehr Speicher, dem tut das nicht so weh.
Und der schreit auch, wenns zuviel wird.

von Joachim B. (jar)


Lesenswert?

Arduino Fanboy D. schrieb:
> Ich verstehe nicht, was Rekursion mit globalen Variablen zu tun hat.
> Aber auch egal....

man soll ja globale Variablen eher vermeiden also werden oft Variablen 
in der SUB angelegt und die sind dann nach Verlassen der SUB wieder weg, 
nur was ist wenn der Speicher ausgeht?

Voher kann der Compiler nicht wissen wieviele Variablen auf dem Stack 
liegen.

Kann sein das ich die Worte falsch benutze, aber das Problem ist so alt 
wie PCs.

Am PET2001 gab es noch die garbadge collection die den löcherigen 
Speicher aufräumte, heute vermisse ich das irgendwie.
Selbst mein Qnap NAS auf Linux Basis meckert mich an das ich lange kein 
reboot mehr gemacht habe, mein Raspberry bleibt auch immer irgendwann 
stehen wenn der swap voll ist, niemand scheint heute gerne mehr den Müll 
rauszubringen, ist fast wie "zu Hause" :)

Ich habe eine Zeitlang auch mit malloc und free gearbeitet, hilft aber 
auch nicht viel und jeder Routine ein free ram vorzuschalten
1
int freeRAM()
2
{
3
  extern int __heap_start, *__brkval;
4
  int v;
5
  return (int) &v - (__brkval == 0 ? (int) &__heap_start: (int) __brkval;
6
}

ist machbar aber aufwändig und vor Lücken im Speicher schützt es auch 
nicht.

Was nutzt es wenn ich 100 Byte im Stück brauche aber zusammenhängend nur 
50 Byte verfügbar sind und nur über alles 200 Byte frei sind?

Ich bin aber kein guter Programmierer, vielleicht gibt es Lösungen die 
ich nicht kenne.

von Einer K. (Gast)


Lesenswert?

Joachim B. schrieb:
> man soll ja globale Variablen eher vermeiden also werden oft Variablen
> in der SUB angelegt und die sind dann nach Verlassen der SUB wieder weg,
> nur was ist wenn der Speicher ausgeht?

Merksätze:
A: Jede vermiedene "globale Variable" ist eine gute Variable.
B: Jede vermeidbare "globale Variable", ist ein böse Variable.

In den Sätzen a und b kannst du "globale Variable" durch jegliches 
andere Sprachmittel ersetzen.
Z.B. if, goto, Funktionsaufruf, Schleife, new, usw....

Heißt das jetzt, dass man alles vermeiden sollte?
Natürlich nicht!
Zwischen den beiden Sätzen gibt es eine Hysterese. Den Bereich wo die 
Notwendigkeiten ihren Platz finden, aus denen dann letztendlich das 
fertige Programm besteht. Ein unvermeidbares new, z.B., geschickt 
eingefädelt, dann kann der Compiler die Instanz in den Speicherverbrauch 
einrechnen und schon beim Compilieren anzeigen. Das ist dann ein in die 
Hysterese hinein gezwungenes new.

Joachim B. schrieb:
> Ich bin aber kein guter Programmierer, vielleicht gibt es Lösungen die
> ich nicht kenne.
Weiß ich nicht.....
Aber wie gut man ist, zeigt sich genau in dieser eben genannten 
Hysterese.

von Manfred (Gast)


Lesenswert?

... schrieb:
> klingt aber nach stack problem
Du könntest richtig liegen!

Lothar M. schrieb:
>> ich befürchte, dass du einen Fehler im Programm hast.
> Das ist in gefühlt >99,9% der Fälle so, wenn es "vorher" läuft und dann
> nach einer kleinen Änderung "auf einemal" nicht mehr.

So ist das - wobei die Änderungen nicht klein sind. Ich gehe 
schrittweise vor: Erstmal die LEDs blinken lassen, dann per Display 
guten Tag sagen, den ADC abfragen, meine Schalter abfragen. Schreibe ich 
alles komplett und es rennt nicht, weiß ich garnicht, wo ich anfangen 
soll.

Ich habe das Programm auf einen Nano-Old geladen und genau das gleiche 
Problem, damit scheidet ein fehlerhaft geflashter Bootloader incl. Fuses 
am ProMini aus.

>> Sobald mein Programm etwa 83% des Programmspeicherplatzes belegt
> ... und trotzdem "noch nicht alles programmiert" ist, hast du sowieso
> ein Problem und solltest mal nach den "Speicherfressern" suchen

Das ist die Adafruit_SSD1306.h :-(

Ich habe meine Displayansteuerung entfernt und gebe
mit Serial.println(F("Die Pins ..."));
jede Menge sinnlosen Text aus, so dass die IDE 98% Programmspeicherplatz 
/ 61% dynamischen Speicher meldet -
da passiert kein Absturz. Ich kann meine SD-Karte ansprechen, bekomme 
sinnvolle Spannungswerte vom ADS1115 ...

Damit ist bewiesen:
Die Adafruit Adafruit_SSD1306.h für mein 128x64 OLED bringt das System 
um. Jetzt also suchen, welche Alternativen sparsamer sind.

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Die Adafruit Adafruit_SSD1306.h für mein 128x64 OLED bringt das System
> um.

Oder irgend etwas anderes in deinem Code, der für die Adafruit 
Bibliothek nicht genug Speicher übrig lässt.

Da ist eine kleinere Alternative drin, geht auch auch AVR: 
http://stefanfrings.de/esp8266/WIFI-Kit-8-OLED.zip

von Sven K. (quotschmacher)


Lesenswert?

Manfred schrieb:
> Damit ist bewiesen

das ist aber eine einfache beweisführung... vielleicht nutzt du sie auch 
nicht ganz korrekt. es wurde ja schon des öfteren nach code gefragt... 
aber egal. ES IST BEWIESEN!

von Manfred (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Da ist eine kleinere Alternative drin, geht auch auch AVR:
> http://stefanfrings.de/esp8266/WIFI-Kit-8-OLED.zip

Fabriziert einen blockierten µC :-(
(In meinem Aufbau habe ich an 16 einen Pieper und an 14 eine LED)

Ich habe ein paar serial.print eingebaut:
Zeile 33 display.init(); wird angelaufen, dann ist Schluß,
serial.print in Zeile 34 kommt nicht mehr.

Gucke ich in Deine oled.cpp, müsste bei OLED display=OLED(4,5,16) doch 
noch mehr übergeben werden, aber auch da führen Änderungen nicht zum 
Erfolg.

---------

In einem anderen Thread 
Beitrag "Re: SSD1306/1309 Library zum Darstellen von Text auf OLED Displays" gibt es eine 
OLED-Library, aus der ich zumindest main_display_test zur Funktion 
bringe - aber leider keine größere Schrift.

---------

Bei Beiden ist mir unklar, ob das I2C-Handling mir Ärger machen könnte, 
ich habe einen ADS1115 im System, der wohl eher die wire.h als Basis 
braucht.

Mit der Adafruit_1306 läuft das Display und auch der ADS1115 liefert 
plausible Werte, leider werde ich deren Absturz nicht Herr.

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Gucke ich in Deine oled.cpp, müsste bei OLED display=OLED(4,5,16) doch
> noch mehr übergeben werden, aber auch da führen Änderungen nicht zum
> Erfolg.

Du hast doch ein 128x64 display. Die Default Werte des Konstruktors sind 
aber 128x32:
1
OLED(uint8_t sda_pin, uint8_t scl_pin, uint8_t reset_pin=NO_RESET_PIN, 
2
    uint8_t i2c_address=0x3C, uint_fast8_t width=128, 
3
    uint_fast8_t height=32, bool isSH1106=false);

Also ja, da musst du mehr Parameter angeben. Sind denn die Pin Nummern 4 
und 5 richtig? Es wäre interessant zu erfahren, wo genau die init() 
Methode hängen bleibt. Eine I²C Kommunikation kann eigentlich nur dann 
hängen, wenn der Bus blockiert ist, also wenn die Leitungen SDA und SCL 
nicht beide auf High gehen. Da wäre dann die Frage, wer die gestörte 
Leitung auf Low zieht.

Manfred schrieb:
> Bei Beiden ist mir unklar, ob das I2C-Handling mir Ärger machen könnte,
> ich habe einen ADS1115 im System, der wohl eher die wire.h als Basis
> braucht.

Auf den gleichen Pins? Ja, dann hast du wohl einen Konflikt, denn meine 
OLED Library macht Bit-Banging. Aber du kannst sie leicht auf wire.h 
umschreiben.

von Manfred (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Manfred schrieb:
>> Gucke ich in Deine oled.cpp, müsste bei OLED display=OLED(4,5,16) doch
>> noch mehr übergeben werden, aber auch da führen Änderungen nicht zum
>> Erfolg.
>
> Du hast doch ein 128x64 display. Die Default Werte des Konstruktors sind
> aber 128x32:
> OLED(uint8_t sda_pin, uint8_t scl_pin, uint8_t reset_pin=NO_RESET_PIN,
>     uint8_t i2c_address=0x3C, uint_fast8_t width=128,
>     uint_fast8_t height=32, bool isSH1106=false);
>
> Also ja, da musst du mehr Parameter angeben.

Aber wie?
1
static OLED display=OLED(4,5,255,0x3C,128,64,false);
oder
1
static OLED display=OLED(4,5,255,60,128,64,false);
hat keinen Erfolg gebracht.

> Sind denn die Pin Nummern 4 und 5 richtig?
A4-SDA / A5-SCL sind Arduino-Standard und so beschaltet.

> Es wäre interessant zu erfahren, wo genau die init()
> Methode hängen bleibt.

Ich habe keine Idee, wie ich das ermittlen kann.

> Eine I²C Kommunikation kann eigentlich nur dann
> hängen, wenn der Bus blockiert ist, also wenn die Leitungen SDA und SCL
> nicht beide auf High gehen. Da wäre dann die Frage, wer die gestörte
> Leitung auf Low zieht.

Da das Ding von  M. K. (sylaina) Anzeigen liefert, gehe ich nicht von 
einer Blockade durch den ADS1115 aus.

>> Bei Beiden ist mir unklar, ob das I2C-Handling mir Ärger machen könnte,
>> ich habe einen ADS1115 im System, der wohl eher die wire.h als Basis
>> braucht.
>
> Auf den gleichen Pins?

Selbstverständlich, das ist doch der Sinn von I2C, mehrere Komponenten 
parallel zu haben. In einer anderen, sauber laufenden Anwendung, habe 
ich 2 A/D, 2 D/A und das Display parallel dran.

> Ja, dann hast du wohl einen Konflikt, denn meine
> OLED Library macht Bit-Banging. Aber du kannst sie leicht auf wire.h
> umschreiben.

Ich habe keine Idee, wo ich da anfassen soll und wie ich das machen 
könnte.

von Stefan F. (Gast)


Lesenswert?

Ich denke, dass das hier deinen Kenntnisstand überfordert. Zu viele 
Baustellen gleichzeitig. Das kann man nicht im Rahmen einer Diskussion 
überwinden.

Bleibe mal bei der Adafruit Bibliothek und wechsle auf einen anderen AVR 
mit mehr Speicher. Z.B. dem ATmega2560.

von Manfred (Gast)


Lesenswert?

Sven K. schrieb:
> das ist aber eine einfache beweisführung... vielleicht nutzt du sie auch
> nicht ganz korrekt. es wurde ja schon des öfteren nach code gefragt...
> aber egal.

Würdest Du wirklich den Code übersetzen und den Fehler suchen, wenn ich 
ihn hier reinstelle?

Es ist verfahren: Ich habe mehrere Geräte, wo Meßdaten auf die SD-Karte 
geschrieben werden und der Programmspeicherplatz sehr hoch ist, bei 
einem 98% - laufen seit Jahren stabil.

Wenn ich auf das OLED verzichte und sinnlose serielle Textausgaben 
fabriziere (96% Speicher), funktioniert mein SD-Zugriff.

Klammere ich SD aus und mache den Speicher voll, funktioniert die 
Anzeige auf dem OLED klaglos.

Erst, wenn ich beide in Betrieb nehme, gibt es einen Runtime-Absturz!
Der Absturz klappt auch mit einem Nano ohne jegliche Hardware dran.
Das bedeutet, dass die beiden sich nicht vertragen - aber erst, wenn die 
Programmspeicherauslastung hoch ist.

Ich sehe als meine einzige Chance, eine andere OLED-Library zu finden.

Die Meßwerte liefert ein ADS1115 mit der Lib von Lygte-info.dk, weshalb 
die OLED-Lib der I2C nicht an sich reißen darf, sondern wire.h nutzen 
soll.

--------

Stefan ⛄ F. schrieb:
> Ich denke, dass das hier deinen Kenntnisstand überfordert. Zu viele
> Baustellen gleichzeitig. Das kann man nicht im Rahmen einer Diskussion
> überwinden.

Diese Antwort finde ich sehr unfreundlich!
Stefan ⛄ F. schrieb:
> Aber du kannst sie leicht auf wire.h umschreiben.

Wenn das so leicht ist, warum nicht ein paar erklärende Worte von Dir 
dazu?

> Bleibe mal bei der Adafruit Bibliothek und wechsle auf einen
> anderen AVR mit mehr Speicher. Z.B. dem ATmega2560.

Das ist keine greifbare Option.

von c-hater (Gast)


Lesenswert?

Manfred schrieb:

> Das bedeutet, dass die beiden sich nicht vertragen - aber erst, wenn die
> Programmspeicherauslastung hoch ist.

Die Programmspeicherauslastung ist ganz sicher nicht direkt das Problem. 
Die kann problemlos 100% erreichen, ohne das irgendwelcher Scheiß 
passiert. Das schicke am Programmspeicher ist nämlich: dessen Belegung 
steht schon zur Compilezeit (genauer: zur Linkzeit) vollständig fest und 
der Compiler oder spätestens der Linker würden schon beim Build meckern, 
falls da irgendwas nicht passt, also gaaaanz laaaange vor der 
allerersten Laufzeit des Programms...
(Für die Oberschlauen: ja, ich weiß auch, dass man zur Laufzeit auch im 
Programmspeicher schreiben kann, aber das dürfte beim TO wohl ganz 
sicher nicht das Problem sein...)

Aber indirekt hat die Größe des Programmspeichers schon Einfluß. Mehr 
Programmspeicher benötigt bedeutet nämlich dass da entweder mehr Code 
übersetzt wurde und/oder dass das Programm mehr initialisierte Daten 
enthält. Beides sorgt typisch dafür, dass zur Laufzeit mehr RAM 
benötigt wird. Insbesondere ist das so bei lausiger 
C&P-"Programmierung", wenn also der "Programmierer" keine Ahnung hat, 
was er da eigentlich tut...

Da gibt es nur zwei Auswege: Entweder der Programmierer lernt, wie man 
selber (und effizienter) programmiert oder er weicht auf eine Hardware 
mit mehr RAM aus.

Also: beherzige den Tip von unserem seligen Samariter der Arduidioten, 
dem hl. Stefanus: nimm einfach einfach einen größeren, wenn deiner so 
klein ist, dass er immer steht...

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Wenn das so leicht ist, warum nicht ein paar erklärende Worte von Dir
> dazu?

Weil ich mir abgewöhnt habe, ellenlange Sätze vorab zu schreiben. 
Meistens kann die Zielperson damit nämlich nichts anfangen, mangels 
Know-How. Und dann ist das für alle Beteiligten reine Zeitverschwendung.

Deine Weigerung, den gesamten Quelltext zu zeigen, nimmt uns die Chance, 
zielsicher zu helfen. Jeder ist seine eigenen Glückes Schmied.

von Manfred (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Deine Weigerung, den gesamten Quelltext zu zeigen,
> nimmt uns die Chance, zielsicher zu helfen.

Siehe Anhang, in der Hoffnung, dass sich das wirklich jemand ernsthaft 
anschaut. Das sind noch ein paar Dinge nicht benutzt bzw. noch nicht 
fertig, kommt erst, wenn die Grundfunktion läuft.

Wird hier mit der IDE 1.89 unter XP übersetzt.
Auch ohne externe Hardware gibt es serielle Ausgaben,
nach 3x "card.init failed" jede Sekunde zwei Meßwerte.
(Mit SD-Karte wird auf dieser die Datei angelegt).

Jetzt in Zeile 154 "/// StartDisplay();" freigeben
oder
in 330..333 die "///" entfernen, stürzt der Kram ab.

Wie ich schrieb: Entweder OLED bedienen oder SD bedienen,
beide gemeinsam vertragen sich nicht.

von Stefan F. (Gast)


Lesenswert?

Soweit ich sehen kann benutzt dieser Sketch nur minimal dynamischen 
Speicher. Vermutlich liegt die Problemursache doch woanders. Trotzdem 
sollte man es überprüfen. Das ist der Punkt wo ein Debugger sehr 
hilfreich wäre, wenn Arduino einen hätte. Du könntest zwischendurch 
seriell ausgeben, wie viel Bytes RAM frei sind. Bei weniger als 100 wird 
es kritisch.

von Wolfgang (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Das ist der Punkt wo ein Debugger sehr hilfreich wäre, wenn
> Arduino einen hätte.

Die Arduino IDE für Visual Studio hat einen
https://www.visualmicro.com/

von CE (criminal engineer®) (Gast)


Lesenswert?

Manfred schrieb:
> Ich habe einen Aufbau mit einem Pro-Mini (Mega328 @ 8 MHz), der
..
> Ideen dazu?

Nicht überall wo Mega328 drauf steht, ist ein AVR ATMega328 drin..

von Manfred (Gast)


Angehängte Dateien:

Lesenswert?

Stefan ⛄ F. schrieb:
> Soweit ich sehen kann benutzt dieser Sketch nur minimal dynamischen
> Speicher. Vermutlich liegt die Problemursache doch woanders. Trotzdem
> sollte man es überprüfen. Das ist der Punkt wo ein Debugger sehr
> hilfreich wäre, wenn Arduino einen hätte. Du könntest zwischendurch
> seriell ausgeben, wie viel Bytes RAM frei sind.

Gefunden habe ich freeMem von 
https://playground.arduino.cc/Code/AvailableMemory/ und es eingebunden.

Aber: Ich komme garnicht soweit, wenn ich Display und SD freigebe, 
knallt das Programm bereits in setup() weg, sobald ich display.begin 
aufrufe.

Ein simples Testprogramm, was nur irgendwas ins Display schreibt, 
startet mit etwa 1400 Byte frei (Unterschiedlich, welche IDE ich 
verwende) und zeigt nach Aufruf des Displays um 900, macht 514 Bytes.

Den Bedarf der SD.h kann ich nicht ermitteln, weil ich vor deren 
Initialisierung keine Mem-Ausabe machen kann.

Hattest Du Zeit, das mal auf einen Arduino aufzuspielen? Ob ProMini oder 
Nano, Bootloader alt oder neu macht keinen Unterschied.

Magst Du mir doch noch verraten, wie ich Deine OLED-Lib anstatt der 
Adafruit eingebunden bekomme?

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Ein simples Testprogramm, was nur irgendwas ins Display schreibt,
> startet mit etwa 1400 Byte frei (Unterschiedlich, welche IDE ich
> verwende) und zeigt nach Aufruf des Displays um 900, macht 514 Bytes.

Das ist ein sehr guter Hinweis. Für SD Karten braucht man mindestens 512 
Bytes Pufferspeicher, weil das die kleinste übertragbare Blockgröße ist.

Diese SD Library belegt Speicher für den Puffer tatsächlich dynamisch 
auf dem Heap, damit hatte ich nicht gerechnet.

Du brauchst einen Mikrocontroller mit mehr RAM, oder eine andere Library 
für das Display, die ohne Puffer auskommt, also direkt ins RAM des 
Displays schreibt. Ich fürchte, das musst du dir selbst entwickeln.

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Magst Du mir doch noch verraten, wie ich Deine OLED-Lib anstatt der
> Adafruit eingebunden bekomme?

Da ist doch ein Beispielprogramm dabei, und die Header-Datei ist 
umfangreich kommentiert. Aber ich denke, das nützt dir nichts, weil auch 
meine Bibliothek mit Pufferspeicher arbeitet.

von Stefan F. (Gast)


Lesenswert?

Manfred,

ich habe meine OLED Klasse anlässlich deiner Reklamation nochmal auf
einem Arduino Nano geprüft. Sie funktioniert. Auf der Seite
http://stefanfrings.de/arduino_oled/index.html siehst du ein Foto vom
Aufbau und da kannst du auch den exakten Quelltext von meinem Test
downloaden.

Dein Speicherproblem wird damit wohl nicht gelöst. Ich wollte nur zurück
melden, dass der Code funktionsfähig ist.

von Einer K. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Sie funktioniert.
Habe das mal kurz untersucht...

Aufgefallen ist mir, dass du Soft I2C verwendest.
Der TE wird für den ADS1115 sicherlich Wire (Hardware I2C) verwenden
Damit gehen die beiden nicht auf einem Bus.
Zumindest nicht ohne "Extra Klimmzüge".

von Manfred (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> ich habe meine OLED Klasse anlässlich deiner Reklamation nochmal auf
> einem Arduino Nano geprüft. Sie funktioniert.

Habe ich wirklich in Frage gestellt, ob sie funktioniert - ich erinnere 
mich nicht daran. Aber, da war etwas mit I2C:

Manfred schrieb:
> Die Meßwerte liefert ein ADS1115 mit der Lib von Lygte-info.dk, weshalb
> die OLED-Lib der I2C nicht an sich reißen darf, sondern wire.h nutzen
> soll.

Solange Du I2C selbst machst, brauche ich sie nicht zu testen - sie 
blockiert den Zugriff auf den A/D-Wandler.

von Stefan F. (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> Aufgefallen ist mir, dass du Soft I2C verwendest.

Ja, weil der Code primär für den ESP8266 gedacht war.

> Damit gehen die beiden nicht auf einem Bus.

Korrekt, guter Hinweis.

von Stefan F. (Gast)


Lesenswert?

Manfred schrieb:
> Habe ich wirklich in Frage gestellt, ob sie funktioniert - ich erinnere
> mich nicht daran.

Alles OK. Du hast geschrieben, dass es bei dir nicht geklappt hat. Da 
ich selbst den Code schon ein paar Jahre nicht mehr genutzt habe, nahm 
ich das zum Anlass, ihn zu überprüfen.

von Manfred (Gast)


Angehängte Dateien:

Lesenswert?

Hier kam nichts, was mir wirklich geholfen hätte, aber zumindest war es 
der Selbstdarstellung eines ... dienlich. Eine Änderung der Hardware war 
nicht realistisch, die Mechanik war fertig, bevor ich zuende 
Programmiert hatte.

Auch mir drängt sich die Frage auf, siehe andere Threads, ob im µC-net 
mehr geht als über den Betrieb einer LED zu palawern :-(

Nach längerer Pause habe ich mal wieder gestochert und eine OLED-Library 
gefunden, die zwar ein paar Wünsche offen lässt, aber sehr wenig 
Ressourcen braucht: https://github.com/greiman/SSD1306Ascii

Seit ein paar Tagen ist nun der Deckel zu und das Ding auch ein paar 
Stunden im PKW-Motorraum mitgefahren.

Hardware: Vom ProMini habe ich die beiden LEDs und den Spannungsregler 
entfernt, der Spannungsregler vom SD-Modul musste ebenfalls weichen. Die 
Aufteilung auf zwei MCP1702-33 hätte ich mir wohl sparen dürfen, aber so 
wie es ist, habe ich bis 3,25V am LiIon noch 3,20V auf den 3V3-Schienen.

Der Akku wird über ein China-Modul geladen, durch den Schlitz der 
Rückwand ist der Programmieranschluss des ProMini erreichbar, ohne 
aufschrauben zu müssen.

Das Gehäuse ist vom Max, die bekloppten Rastnasen habe ich abgefeilt und 
Gewinde M2.5 geschnitten:
https://www.pollin.de/p/donau-elektronik-kunststoffgehaeuse-kgb12-blau-460282

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.