J'utilise un compteur de boucles, déclaré dans un en-tête:
int loop_counter = 0;
J'utilise ce compteur pour déclencher un événement de temps en temps. J'avais l'habitude d'utiliser un modulo pour ce même type de comportement, mais je l'ai simplifié pour qu'il soit plus facile de travailler avec (il en résulte toujours le même comportement)
void loop() {
if(loop_counter > 100) loop_counter = 0;
else loop_counter++;
//Serial.println("hey");
if(loop_counter == 0) {
//do_something_important();
}
}
Tout va bien, jusqu'à ce que j'essaie de communiquer avec Serial
en décommentant le //Serial.println("hey");
( "hey"
dans cet exemple parce que, pour moi, ce comportement est absurde).
Cela se traduit par loop_counter
ne jamais déclencher la do_something_important();
section de code. J'ai essayé de déclarer loop_counter
que volatile
cela ne changeait rien. J'ai essayé Serial.print
ing loop_counter
, et j'obtenais aussi un comportement étrange (cela gèlerait la boucle). Serial.println("hey");
fonctionne en ce sens que dans le moniteur série, j'obtiens beaucoup de "hey", (c'est-à-dire rapidement beaucoup plus de 100 "heys", le nombre d'itérations auxquelles l'autre section de code devrait se déclencher)
Qu'est-ce qui pourrait éventuellement causer l'utilisation de Serial
, avec des données qui ne sont pas (pour autant que je sache) liées à l' loop_counter
empêcher complètement de fonctionner correctement?
EDIT : Voici la partie du fichier principal qui a fini par poser le problème (enfin, y contribuer le plus (utiliser trop de mémoire)):
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);
}
}
Voici "letters.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 ; short led_matrix [num_rows] [num_cols];short led_matrix [ num_rows ] [ num_cols ];
const short letter_a [nrows] [ncols] = {{0,1,1,0}, short letter_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 * suivant;* suivant ; 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 ]; #fin si#fin si
Quelques informations supplémentaires: - J'utilise un Uno (ATMega328)
la source
loop()
fonction. Comment dois-je peindre ma pile si la seule méthode de sortie que j'ai (Serial.print()
) échoue?Réponses:
J'ai également eu un problème similaire à cela, et je suis très sûr que le vôtre est également hors de l'espace de pile. Essayez de réduire le code autant que possible.
Dans mon cas, le code s'exécutait parfois lorsque j'avais un message série, mais il semblait alors ne pas fonctionner lorsque je ne le faisais pas. J'ai également eu un cas où l'envoi de messages série entraînerait la réinitialisation sans fin de l'arduino.
J'utilisais également un arduino328. Vous devriez probablement réduire la taille de votre baie si vous en avez une à la plus petite taille acceptable.
la source
Votre code initialise-t-il le port série? Par exemple.
Ne pas le faire pourrait entraîner un crash lors de la première utilisation de la série.
la source
Peut-être que vous manquez de mémoire? Toutes les chaînes que vous imprimez avec Serial.print ("quelque chose") ont lieu dans SRAM, égal au nombre de caractères de cette chaîne + 1 pour le terminateur \ 0. Il est possible de manquer de mémoire même si la taille compilée de votre croquis est beaucoup plus petite que la mémoire flash Arduino, car SRAM n'est que de 2048 octets pour Atmega328 et 1024 octets pour Atmega 168. J'ai eu un problème similaire, que j'ai résolu en raccourcissant tout textes et supprimer les messages de débogage inutiles.
la source
display_state()
fonction pour ne pas avoir besoin de cette allocation supplémentaire. Je fais rarement du traitement intégré, je suppose que nous devons tous frapper le mur de la mémoire à un moment donné!Vous n'avez pas montré le code qui initialise la variable "loop_counter". Est-ce en dehors de la routine loop () ?
Avez-vous éventuellement déclaré cela de manière à ce qu'il soit adjacent à une autre zone de stockage de mémoire qui fonctionne en dehors de sa taille déclarée et ce trompe sur la variable loop_counter?
la source
loop()
- dessus , etc. Êtes-vous en train de dire que laSerial.print()
méthode pourrait l'écraser d'une manière ou d'une autre?Je ne vois pas dans votre code où vous appelez
loop()
. Il ne semble pas non plus que vous utilisiez enloop_counter
dehors de cette fonction. Y a-t-il une raison pour laquelle vous le déclarez mondial? Je suppose que c'est parce que vous voulez qu'il conserve sa valeur entre les appels. Vous pouvez le faire avec une variable locale statique à la place.Cela devrait garantir qu'aucune autre fonction externe ne puisse y piétiner. Vous devez toujours déclarer vos variables dans la plus petite étendue possible pour éviter tout comportement indésirable.
Si cela ne fonctionne pas, vous devrez vraiment analyser votre utilisation de la mémoire. Consultez ce Q&A EE.SE pour divers exemples de code pour le faire dans un Arduino.
la source
setup()
etloop()
sont des fonctions qu'arduino exécute par défaut, ensetup()
premier, enloop()
second.loop()
est essentiellement similairemain()
, sauf qu'il est appelé à plusieurs reprises. référence: arduino.cc/en/Reference/loop Je vais vérifier ce lien.Serial.print()
. Il semble que je devrai sortir de l'processing
IDE normal si je veux pouvoir utiliser GDBSerial.print()
fonctionnait bien dans la mesure où cela imprimait beaucoup "hé". C'estloop_counter
cela qui vous pose un problème. Essayez de supprimer leif(loop_counter == 0)
code et de mettre leget_free_memory()
code (laissez l'loop_counter
incrément) et de l'exécuter. Cela vous indiquera au moins si vous avez des problèmes majeurs avec votre allocation de mémoire.La bibliothèque série du logiciel Arduino utilise des interruptions. (voir "softwareSerial.cpp, .h"). Vous pouvez avoir un problème où l'ISR "marche" sur le code principal (ou vice versa). Essayez d'utiliser des drapeaux de verrouillage, de sorte que le code attend pendant la fin des opérations d'impression.
la source
Il y a quelque temps, j'ai eu l'impression d'avoir le même problème. À l'époque, je l'ai résolu en ajoutant un délai (1) devant ou après le serial.println. C'était avec Arduino 0022 sous Linux. Je ne sais pas de quelle carte il s'agissait, probablement une série Boarduino. Je ne peux pas non plus le reproduire.
Actuellement, cela fonctionne pour moi sur un boarduino USB avec Arduino 1.01 sous Windows:
la source