Ich verwende einen Schleifenzähler, der in einem Header deklariert ist:
int loop_counter = 0;
Ich benutze diesen Zähler, um von Zeit zu Zeit ein Ereignis auszulösen. Früher habe ich ein Modulo für dieselbe Art von Verhalten verwendet, aber ich habe es vereinfacht, damit es einfacher ist, damit zu arbeiten (es führt immer noch zu demselben Verhalten).
void loop() {
if(loop_counter > 100) loop_counter = 0;
else loop_counter++;
//Serial.println("hey");
if(loop_counter == 0) {
//do_something_important();
}
}
Alles ist gut und schön, bis ich versuche, mit dem zu kommunizieren, Serial
indem ich das auskommentiere //Serial.println("hey");
( "hey"
in diesem Beispiel, weil dieses Verhalten für mich absurd ist).
Dies führt dazu, dass der Codeabschnitt loop_counter
niemals ausgelöst wird do_something_important();
. Ich versuchte zu erklären , loop_counter
wie volatile
, dass nichts geändert hat. Ich habe versucht , Serial.print
ing loop_counter
, und ich war auch seltsames Verhalten bekommen (es würde die Schleife einfrieren). Serial.println("hey");
funktioniert in dem Sinne, dass ich im seriellen Monitor viel "hey" bekomme (dh schnell viel mehr als 100 "heys", die Anzahl der Iterationen, bei denen der andere Codeabschnitt ausgelöst werden soll).
Was könnte möglicherweise die Verwendung von Serial
Daten verursachen, die nicht (soweit ich das beurteilen kann) gebunden sind, loop_counter
um die ordnungsgemäße Funktion vollständig zu verhindern?
BEARBEITEN : Hier ist der Teil der Hauptdatei, der das Problem aufwirft (nun, am meisten dazu beiträgt (mit zu viel Speicher)):
void display_state() {
int i,j,index=0;
short alive[256][2];
for(i=0;i<num_rows;i++) {
for(j=0;j<num_cols;j++) {
if(led_matrix[i][j]==1) {
alive[index][0]=i;
alive[index][1]=j;
index++;
}
}
}
alive[index][0]=NULL; //Null-terminate.
alive[index][1]=NULL;
//383 is a great number
for(int idx=0;idx < index; idx++) {
display(alive[idx][0],alive[idx][1]);
delayMicroseconds(283);
}
}
Hier ist "letter.h":
#ifndef _MY_LETTERS_H #define _MY_LETTERS_H
#define nrows 4 #define ncols 4 #define num_rows 16 #define num_cols 16 #define MAX_WORD_LENGTH 16 #define NUMBER_OF_CHARACTERS 26 #include <stdlib.h>
int loop_counter = 0;loop_counter = 0 ; kurze led_matrix [num_rows] [num_cols];kurze led_matrix [ num_rows ] [ num_cols ];
const short letter_a [nrows] [ncols] = {{0,1,1,0}, kurzer Buchstabe_a [ nrows ] [ ncols ] = {{ 0 , 1 , 1 , 0 }, {1,0,0,1},{ 1 , 0 , 0 , 1 }, {1,1,1,1},{ 1 , 1 , 1 , 1 }, {1,0,0,1}};{ 1 , 0 , 0 , 1 }}; const short letter_b [nrows] [ncols] = {{1,0,0,0}, {1,1,1,0}, {1,0,1,0}, {1,1,1,0} };const short letter_b [ nrows ] [ ncols ] = {{ 1 , 0 , 0 , 0 }, { 1 , 1 , 1 , 0 }, { 1 , 0 , 1 , 0 }, { 1 , 1 , 1 , 0 } }; const short letter_c [nrows] [ncols] = {{0,1,1,1}, {1,0,0,0}, {1,0,0,0}, {0,1,1,1} };const short letter_c [ nrows ] [ ncols ] = {{ 0 , 1 , 1 , 1 }, { 1 , 0 , 0 , 0 }, { 1 , 0 , 0 , 0 }, { 0 , 1 , 1 , 1 } }; const short letter_t [nrows] [ncols] = {{1,1,1,1}, {0,1,0,0}, {0,1,0,0}, {0,1,0,0} };const short letter_t [ nrows ] [ ncols ] = {{ 1 , 1 , 1 , 1 }, { 0 , 1 , 0 , 0 }, { 0 , 1 , 0 , 0 }, { 0 , 1 , 0 , 0 } };
typedef struct letter_node { struct letter_node { const short * data;const short * data ; letter_node * next;* weiter ; int x;int x ; int y;int y ; } letter_node;} letter_node ;
letter_node aa = {& letter_a [0] [0], NULL, 1,1};= {& letter_a [ 0 ] [ 0 ], NULL , 1 , 1 }; letter_node bb = {& letter_b [0] [0], NULL, 1,1};= {& letter_b [ 0 ] [ 0 ], NULL , 1 , 1 }; letter_node cc = {& letter_c [0] [0], NULL, 1,1};= {& letter_c [ 0 ] [ 0 ], NULL , 1 , 1 }; letter_node tt = {& letter_t [0] [0], NULL, 1,1};= {& letter_t [ 0 ] [ 0 ], NULL , 1 , 1 };
letter_node letter_map [NUMBER_OF_CHARACTERS];[ NUMBER_OF_CHARACTERS ]; #endif#endif
Weitere Informationen: - Ich verwende ein Uno (ATMega328)
loop()
Funktion. Wie soll ich meinen Stapel malen, wenn die einzige Ausgabemethode, die ich habe (Serial.print()
), darin besteht, dass ich versage?Antworten:
Ich hatte auch ein ähnliches Problem wie dieses und bin mir sehr sicher, dass Ihr Problem auch nicht mit dem Stapelspeicher zusammenhängt. Versuchen Sie, den Code so weit wie möglich zu verkleinern.
In meinem Fall wurde der Code manchmal ausgeführt, wenn ich eine serielle Nachricht darin hatte, aber dann schien er nicht ausgeführt zu werden, wenn ich dies nicht tat. Ich hatte auch einen Fall, in dem das Senden von seriellen Nachrichten dazu führen würde, dass das Arduino endlos zurückgesetzt wird.
Ich habe auch ein Arduino328 verwendet. Wahrscheinlich sollten Sie die Größe Ihres Arrays reduzieren, wenn Sie eine auf die kleinste akzeptable Größe haben.
quelle
Initialisiert Ihr Code die serielle Schnittstelle? Z.B.
Andernfalls kann es bei der ersten Verwendung der Seriennummer zu einem Absturz kommen.
quelle
Vielleicht geht Ihnen der Speicher aus? Alle Zeichenfolgen, die Sie mit Serial.print ("etwas") drucken, finden im SRAM statt, entsprechend der Anzahl der Zeichen dieser Zeichenfolge + 1 für den Terminator \ 0. Es ist möglich, dass der Speicher knapp wird, selbst wenn die kompilierte Größe Ihrer Skizze viel kleiner als der Arduino-Flash-Speicher ist, da SRAM nur 2048 Byte für Atmega328 und 1024 Byte für Atmega 168 beträgt. Ich hatte ein ähnliches Problem, das ich durch Verkürzen aller gelöst habe Texte und Entfernen unnötiger Debug-Meldungen.
quelle
display_state()
Funktion überarbeitet, um diese zusätzliche Zuordnung nicht zu benötigen. Ich mache selten eingebettete Verarbeitung, ich nehme an, wir müssen alle irgendwann auf die Speicherwand stoßen!Sie haben den Code, der die Variable "loop_counter" initialisiert, nicht angezeigt. Liegt das außerhalb der loop () -Routine?
Haben Sie das möglicherweise so deklariert, dass es an einen anderen Speicherbereich angrenzt, der außerhalb seiner deklarierten Größe arbeitet, und dieses Tromping auf die Variable loop_counter?
quelle
loop()
usw. Wollen Sie damit sagen, dass dieSerial.print()
Methode sie möglicherweise irgendwie überschreibt?Ich sehe in Ihrem Code nicht, wo Sie anrufen
loop()
. Es sieht auch nicht , wie Sie verwenden sindloop_counter
diese Funktion außerhalb. Gibt es einen Grund, warum Sie es für global erklären? Ich gehe davon aus, dass Sie möchten, dass der Wert zwischen den Anrufen erhalten bleibt. Sie können dies stattdessen mit einer statischen lokalen Variablen tun .Das sollte sicherstellen, dass keine anderen externen Funktionen darauf stampfen können. Sie sollten Ihre Variablen immer im kleinstmöglichen Bereich deklarieren, um unerwünschtes Verhalten zu vermeiden.
Wenn dies nicht funktioniert, müssen Sie Ihre Speichernutzung wirklich analysieren. In diesen EE.SE-Fragen und Antworten finden Sie verschiedene Beispielcodes, um dies in einem Arduino zu tun.
quelle
setup()
undloop()
sind Funktionen, die Arduino standardmäßig ausführt,setup()
erstens,loop()
zweitens.loop()
ist im Wesentlichen wiemain()
, außer es wird wiederholt aufgerufen. Referenz: arduino.cc/en/Reference/loop Ich werde diesen Link überprüfen.Serial.print()
. Es sieht so ausprocessing
, alsSerial.print()
das funktioniert gut, da es viel "hey" druckt . Es ist dasloop_counter
, was dir ein Problem gibt. Versuchen Sie, denif(loop_counter == 0)
Code zu entfernen, den Code einzugebenget_free_memory()
(dasloop_counter
Inkrement zu belassen) und auszuführen . Dies wird Ihnen zumindest sagen, ob Sie größere Probleme mit Ihrer Speicherzuordnung haben.Die serielle Bibliothek der Arduino-Software verwendet Interrupts. (siehe "softwareSerial.cpp, .h"). Möglicherweise haben Sie ein Problem, bei dem der ISR auf den Hauptcode "tritt" (oder umgekehrt). Versuchen Sie, Interlock-Flags zu verwenden, damit der Code wartet, während die Druckvorgänge abgeschlossen sind.
quelle
Vor einiger Zeit hatte ich den Eindruck, das gleiche Problem zu haben. Damals habe ich es gelöst, indem ich eine Verzögerung (1) vor oder nach der serial.println hinzugefügt habe. Das war mit Arduino 0022 unter Linux. Ich bin mir nicht sicher, um welches Board es sich handelt, wahrscheinlich um eine Boarduino-Serie. Kann es auch nicht reproduzieren.
Derzeit funktioniert es für mich auf einem Boarduino USB mit Arduino 1.01 unter Windows:
quelle