Hallo,
ich hab grad ein Programm für meinen Arduino geschrieben, dass das
Netzwerk nach Geräten abscannt und in einer Datei auf der MicroSD-Karte
das ganze speichert. Das funktioniert auch, aber der Arduino bleibt
immer nach einer gewissen Zeit (bis jetzt nach max. 5 min) hängen und
gibt ab da in der Konsole entweder gar nichts mehr, ein paar komische
Zeichen und dann gar nichts mehr oder nur noch unendlich viele komische
Zeichen aus. Das Programm bleibt da einfach hängen. Woran kann das
liegen?
Danke im Vorraus
burgerohnealles
Ups. Logisch, dass es irgendwann hängen bleibt. Aber kann mir jemand
erklären, was genau im ATmega328P vorgeht, dass es dann gar nichts mehr
oder nur Quatsch macht?
geändert. Aber wie gesagt, es bleibt wieder hängen. Was ist da noch
falsch, bzw. wie gehe ich bei so einem Fall richtig vor, um das Problem
zu lösen?
Hier nich die letzten Zeilen, die bei mir am Läppi ankamen:
1
74: load data ... ok ... connect data ... ok ... send data ... ok ... free memory ... ok ... wait for reply ... timeout, no reply
2
75: load data ... ok ... connect data ... ok ... send data ... ok ... free memory ... ok ... wait for reply ... timeout, no reply
3
76: load data ... ok ... connect data ... ok ... send data ... ok ... free memory ... ok ... wait for reply ... free memo
Lies mal in einem Tutorial wie man ein Array verwendet. Das 1. Element
im Array wird mit 0 angesprochen. Du initialisierts i mit 1. Wie soll
dann bitte das 1. Element einen Wert bekommen.
Aber das wird nicht das Problem sein.
>was genau im ATmega328P vorgeht, dass es dann gar nichts mehr>oder nur Quatsch macht?
Wenn dein Array auf 8 ist dann greifst du auf Specher zu, der nicht zum
Array gehört, sondern zu irgendetwas anderem. Somit versaust dir deine
anderen Variablen. Wenn du glück hast, dann ist dort nichts abgelegt.
Dann merkst du nichts. Beim Computer würde das Betriebsystem dies
verhindern und dein Programm würde mit einer Fehlermeldung stehen
bleiben. Bei Windows würde dann kommen Program xyz funktioniert nicht
mehr....
Beim uc fehlt diesr Schutz und dann macht es halt irgendetwas.
Ich vermute mal, dass du das meiste zusammenkopiert hast und jetzt
versuchst es abzuändern, ohne wircklich zu verstehen was da passiert und
wie man arrays verwendet. Ich würde dir ein C Tutorial empfehlen, da dir
Grundkentnisse zu Arrays fehlen.
Hallo,
das was Gusti empfohlen hat stimmt leider :-(
Hab das selbst erfahren - da hat mann praktische erfahrung von mehr als
15 Jahren mit der Elektronik - sowohl Analog als auch Digital kennt die
kleinen Gemeinheiten und (scheinbaren) selbstverständlichkeiten und
möchte dann endlich in die µC Nutzung einsteigen- Aufbau, elektrische
Ansteuerung, nutzung von Transistoren und MOSFET usw. - halt die ganze
Hardware kein Problem.
Andererseits nie interesse an der Programmierung eines Computers gehabt
- es gibt ja alles fertig ;-) und somit kaum Erfahrung mit
Programmiersprachen.
Da sollte es doch möglich sein das Programmieren speziell für den µC
(hier AVR und Sprache C) lernen zu können...
Und festgestellt => es geht nicht - die Tipps welche immer wieder
gegeben werden (und die mir auch zuerst nicht gefallen haben) erstmal
die Grundlagen am Computer zu erlernen sind (leider) richtig.
Ja da fängt mann mit der "Hallo world" Textausgabe auf den Monitor an,
schafft ja nach Zeit und Lust dann nach einigen Wochen bis Monaten eine
einfache Datenbank zu programmieren (welche aber Lichtjahre von
Anwendungen wie Open Office entfernt ist) und fragt sich warum das Ganze
?- Ich will doch nur einen µC Programmieren können um meine
....steuerung endlich realisieren zu können.
Wenn es dann aber doch endlich mit den µC losgeht und mann sich die
Beispiele, Datenblätter und Tutorials entschaut und aufeinmal versteht
was gemeint ist, die Gedankengänge nochvollziehen kann dann wird einen
auf einmal klar wieso der scheinbare Umweg nötig war.
Gerade Arduino verleitet erstmal dazu sich das Programm (Sketch)
zusammen zu kopieren - das kann sogar funktionieren allerdings lehrnt
mann dabei sehr wenig und mann wird niemals selbst etwas anpassen oder
entwickeln können und wird auch immer auf teuere fertige Hardware
(shields) angewiesen bleiben
Den seltenen Sensor, der preiswerte Restposten, das neuste Display usw.
auch mit ausfühlichen Datenblatt wird mann so nicht selbstständig zu
laufen bringen und mann muss immer warten bis das ein anderer das
gemacht hat (was eventeull nie passieren wird).
Aber auch mit Arduino kann mann auf sehr hohen Niveau arbeiten dafür
sind aber die tiefergehenden Kenntnisse leider notwendig.
mfg
µC_Starter
Genau
Wobei Datenbankenprgrammieren und Objektorientierte Programmierung musst
du nicht lernen für den uc, sofern du nur bei C bleibst.
Ich habe eine abgeschlossene Lehre als Elektroniker. Im 1. Jahr hatten
wir in der Schule 4 Lektionen pro Woche uc programmieren. Im 1. Halbjahr
haben wir nur auf der Konsole am Computer programmiert. So lernst du am
einfachsten die Grundlagen. Wie z.B. wie verwende ich ein Array oder ein
Switch case, und, oder, xor operationen etc.
Wann verwende ich ein for, while oder do while schleife.
Ausserdem haben wir so auch gelernt, wie man x for schleifen ineinander
verschachtelt. Mit Übungen wie einen Tannenbaum an den Konsole ausgeben.
Dies funktioniert recht einfach mit verschachtelten for Schleifen. Die
Struktur der Verschachtelung ist sehr komplex und solche Übungen, auch
wenn sie mühsam sind helfen sehr beim Verständnis. Was dir dann später
auf dem uc zu gute kommt.
Vorallem auch wenn du 2 oder 3D Arrays verwendest.
Gusti schrieb:> Ich vermute mal, dass du das meiste zusammenkopiert hast
Das stimmt nicht. Ich hab alles selbst geschrieben (bis auf den Teil, wo
die Zeit ausgelesen wird)!
Gusti schrieb:> Lies mal in einem Tutorial wie man ein Array verwendet. Das 1. Element> im Array wird mit 0 angesprochen. Du initialisierts i mit 1. Wie soll> dann bitte das 1. Element einen Wert bekommen.> Aber das wird nicht das Problem sein.
Dirket nach dem Array steht die funktion
1
memset(devices,0x00,32)
. Dadurch werden doch alle Werte auf 0 gesetzt. Oder verstehe ich das
falsch? Und dass ich bei 1 anfange hat auch einen Grunde, denn es gibt
nun mal in einem Netzwerk keinen Rechner mit der IP-Adresse
192.168.178.0 !
µC_Starter schrieb:> Gerade Arduino verleitet erstmal dazu sich das Programm (Sketch)> zusammen zu kopieren - das kann sogar funktionieren allerdings lehrnt> mann dabei sehr wenig und mann wird niemals selbst etwas anpassen oder> entwickeln können und wird auch immer auf teuere fertige Hardware> (shields) angewiesen bleiben
Das masg auch sein, aber wie gesagt, ich habe alles (bis auf den Teil,
wo die Zeit ausgelesen wird) selbst geschrieben.
Nur jetzt verstehe ich immer noch nicht, warum das Programm hängen
bleibt? Ich hab ja die Größe des Array auf 32 erweitert!? Und was ich
oben vergessen hab dazuzuschreiben, logischer Weise auch die Funktion
memset. Das hab auch den dritten Paramter von 8 auf 32 geändert! Aber
warum funktioniert es immer noch nicht!?
Uwe schrieb:> Weil nen Array was 32 groß ist nur von 0 bis 31 geht und nicht von 1 bis> 32.
Ja das ist mir auch klar, aber wo greif ich z.B. auf das 32. Element zu?
Hab aber noch was gelesen (http://stackoverflow.com/a/7202857), und zwar
man soll ein Array nicht mit memset() initialisieren, sonder mit einer
Schleife die Werte einzeln setzt, aber warum?
if(rbuf_size<(2+SIZE_ETHERNET+SIZE_ARP)){// min length for arp packet
6
...
7
free(rbuf);
8
}
9
..
10
memcpy(ðernet,rbuf+2,SIZE_ETHERNET);
11
..
12
free(rbuf);
Zweimal denselben Speicher freigeben (rbuf, einmal bedingt im if{} und
einmal zwangsweise danach) und auch noch den evtl. schon freigegeben
Speicher verwenden ist nicht schön.
if(rbuf_size<(2+SIZE_ETHERNET+SIZE_ARP)){// min length for arp packet
2
...
3
free(rbuf);
4
continue;
5
}
, was heißt, dass dann die Schleife hier abgebrochen wird und wieder von
vorne weiter läuft. Oder steh ich grad aufm Schlauch und verstehe das
ganz falsch !?
Ja trotzdem danke, bin froh über jeden Tipp, der mein Problem lösen
könnte. Ich versuchs mal, wie schon oben gesagt, das Array mit einer
Schleife, anstatt mit memset() zu initialisieren, aber was ist daran
falsch, es mit memset() zu machen?
Lokale Variable werden fast immer auf dem Stack abgelegt.
Die Rücksprungadressen von Unterfunktionen ebenfalls.
Wenn jetzt eine Variable "Amok" läuft, ist es nur eine Frage der Zeit,
wenn diese eine Rücksprungadresse überschreibt.
amateur schrieb:> Lokale Variable werden fast immer auf dem Stack abgelegt.> Die Rücksprungadressen von Unterfunktionen ebenfalls.>> Wenn jetzt eine Variable "Amok" läuft, ist es nur eine Frage der Zeit,> wenn diese eine Rücksprungadresse überschreibt.
Ok, dann weiß ich ja jetzt, warum diese komischen Ausgaben kommen, aber
was meinst du mit "wenn eine Variable 'Amok' läuft"? Meinst du damit
z.B. das:
1
uint8_tarr[8];
2
arr[10]=26;
? Oder was ? Und wann passiert das in meinem Code? Nach den
Verbesserungen, müsste es ja eigtl funktionieren. Ich habe auch noch
1
memset(devices,0x00,32);
durch
1
for(uint8_ti=0;i<32;i++)
2
devices[i]=0x00;
ersetzt. Das
1
memset arbeitet auf Bytes. Da ein "int" aber i.d.R. aus ein paar Bytes besteht, werden alle Bytes des 'int's auf den Wert (hier 1) gesetzt.
2
Die binärdarstellung der 1 in einem 4-bytigen int wäre aber 0x00000001 und nicht 0x01010101.
würde erklären, warum man memset nicht benutzen sollte, aber in meinem
Fall geht das, weil ich ja alle Werte auf 0x00 setzen möchte. Was ist
dann an dem Code noch falsch?
Fehler gefunden ^^ des war ein ziemlich mieser Fehler. Mir ist
aufgefallen, dass es immer in dem Bereich bei " ok ... send data ... ok
." zu Fehlern kommt. Also hab ich mal diesen Teil wegkommentiert. Also
und alles, wo auf buf zugegriffen wird. Dann kam beim Kompilieren ein
Fehler. Und zwar hier:
1
uint16_trbuf_size=W5100.getRXReceivedSize(s);
2
if(rbuf_size<=0)continue;
3
uint8_t*rbuf=(uint8_t*)malloc(rbuf_size);
4
if(rbuf==NULL){
5
debug_print(F("error allocating memory\n"));
6
return;
7
}
! Da stand nämlich vorher noch "... if (buf == NULL) ...". Wenn ich
jetzt das ganz starte, kommt dieser Fehler "error allocating memory". Da
wurde dann anscheinend, wenn rbuf NULL war, auf irgendwas zugeriffen,
und es hat sich aufgehangen. Was so ein kleiner Buchstabe für Ärger
machen kann .. Habt ihr Tipps, wie man solche Fehler schneller findet?
Sichher hätte es auch was gebracht, nach jedem Aufruf von free() den
Zeiger auf NULL zu setzen. Sonst danke für die Hilfe und wenn ihr Tipps
habt, her damit ! :D
Jonathan K. schrieb:> Sonst danke für die Hilfe und wenn ihr Tipps> habt, her damit ! :D
Keine dynamische Speicherverwaltung verwenden. Bringt nichts und macht
es komplizierter und fehleranfälliger.
avr schrieb:> Jonathan K. schrieb:>> Sonst danke für die Hilfe und wenn ihr Tipps>> habt, her damit ! :D>> Keine dynamische Speicherverwaltung verwenden. Bringt nichts und macht> es komplizierter und fehleranfälliger.
(Y) Wer ich mir merken! Ansonsten, war das Problem, dann immer noch da.
Also hab ich meine umständlichste Methode genommen, nämlich, mehr oder
weniger alles wegkommentieren. Dann Schritt für Schritt wieder einen
Teil dazumachen und gucken wann der Fehler kommt. Diesmal hat der Aufruf
der Funktion [c]W5100.recv_data_processing()[c] probleme, gemacht. Wenn
das mir jemand erklären kannt, bitte! Gelöst habe ich es, in dem ich mir
zuerst das Datenblatt und alle Dateien aus dem Orderner
Arduino/libraries/Ethernet/utilitys nochmal angeguckt habe. Dann war ich
in der Lage, diese "Problemfunktion" rauszulassen und den Code dieser
Funktion direkt in den Code aufgeteilt einzufügen, und es GEHT! :D Wenn
jmd den Code haben möchte, kann er mich fragen.