Arduino La impresión en serie cambia el comportamiento del programa de forma no deseada

9

Estoy usando un contador de bucles, declarado en un encabezado:

int loop_counter = 0;

Utilizo este contador para activar un evento de vez en cuando. Solía usar un módulo para este mismo tipo de comportamiento, pero lo simplifiqué para que sea más fácil trabajar con él (aún resulta en el mismo comportamiento)

void loop() {
    if(loop_counter > 100) loop_counter = 0;
    else loop_counter++;

    //Serial.println("hey");

    if(loop_counter == 0) {
         //do_something_important();
    }      
}

Todo está muy bien, hasta que trato de comunicarme con Serial descomentando el //Serial.println("hey"); ( "hey" en este ejemplo porque, para mí, este comportamiento es absurdo).

Esto da como resultado que loop_counter nunca active la sección do_something_important(); del código. Intenté declarar loop_counter como volatile , eso no cambió nada. Intenté Serial.print ing loop_counter , y también estaba teniendo un comportamiento extraño (congelaría el ciclo). Serial.println("hey"); funciona en el sentido de que en el monitor Serial obtengo un montón de "hey", (es decir, mucho más de 100 "heys", el número de iteraciones a las que se debe activar la otra sección de código)

¿Qué podría estar causando el uso de Serial , con datos que no están vinculados a loop_counter (por lo que puedo decir) relacionados con %code% ?

EDIT : Aquí está la parte del archivo principal que terminó planteando el problema (bueno, contribuyendo más a él (usando demasiada memoria)):



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);
 }
}

Aquí está "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; short led_matrix [num_rows] [num_cols];

const short letter_a [nrows] [ncols] = {{0,1,1,0},                     {1,0,0,1},                     {1,1,1,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_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} };

typedef struct letter_node {   const corta * datos;   letter_node * next;   int x;   int y } letter_node;

letter_node aa = {& letter_a [0] [0], NULL, 1,1}; letter_node bb = {& letter_b [0] [0], NULL, 1,1}; letter_node cc = {& letter_c [0] [0], NULL, 1,1}; letter_node tt = {& letter_t [0] [0], NULL, 1,1};

letter_node letter_map [NUMBER_OF_CHARACTERS];     #endif

Un poco más de información: - Estoy usando un Uno (ATMega328)

    
pregunta eqzx

7 respuestas

2

También tuve un problema similar a este, y estoy muy seguro de que el tuyo tampoco está relacionado con el espacio de pila. Intente reducir el código tanto como sea posible.

En mi caso, el código a veces se ejecutaba cuando tenía un mensaje serial, pero parece que no se ejecuta cuando no lo hice. También tuve un caso en el que enviar mensajes en serie causaría que el arduino se reiniciara sin cesar.

También estaba usando un arduino328. Probablemente debería reducir el tamaño de su matriz si tiene alguno al tamaño más pequeño que sea aceptable.

    
respondido por el Reza Hussain
4

¿Tu código inicializa el puerto serie? Por ejemplo.

void setup()
{
    Serial.begin(9600);
}

Si no lo hace, podría producirse un bloqueo al utilizar por primera vez la serie.

    
respondido por el Toby Jaffey
3

¿Quizás te estás quedando sin memoria? Todas las cadenas que imprime con Serial.print ("algo") tienen lugar en la SRAM, igual al número de caracteres de esa cadena + 1 para el terminador \ 0. Es posible que se quede sin memoria incluso si el tamaño compilado de su boceto es mucho más pequeño que la memoria flash de Arduino, ya que SRAM solo tiene 2048 bytes para Atmega328 y 1024 bytes para Atmega 168. Tuve un problema similar, que resolví acortando todo Textos y eliminación de mensajes de depuración innecesarios.

    
respondido por el Erion
1

No ha mostrado el código que inicializa la variable "loop_counter". ¿Está eso fuera de la rutina loop () ?

¿Es posible que haya declarado eso de manera que sea adyacente a otra área de almacenamiento de memoria que esté operando fuera de su tamaño declarado y que esté pisando la variable loop_counter?

    
respondido por el Michael Karas
1

No veo en tu código a dónde llamas loop() . Tampoco parece que estés usando loop_counter fuera de esa función. ¿Hay alguna razón por la que lo declaras global? Supongo que es porque quiere que retenga su valor entre llamadas. Podría hacer esto con una variable local estática .

void loop() {
    static int loop_counter = 0;

    if(loop_counter > 100)
    {
        loop_counter = 0;
    }
    else
    {
        loop_counter++;
    }

    Serial.println("hey");

    if(loop_counter == 0)
    {
         //do_something_important();
    }      
}

Eso debería asegurar que ninguna otra función externa pueda pisotearlo. Siempre debe declarar sus variables en el ámbito más pequeño posible para evitar comportamientos no deseados.

Si eso no funciona, tendrá que analizar realmente el uso de la memoria. Verifique este EE.SE Q & A para varios ejemplos de código para hacer esto dentro de un Arduino.

    
respondido por el embedded.kyle
1

La biblioteca serial del software Arduino usa interrupciones. (vea "softwareSerial.cpp, .h"). Es posible que tenga un problema en el que el ISR esté "pisando" el código principal (o viceversa). Intente usar indicadores de bloqueo, de modo que el código espere mientras se completan las operaciones de impresión.

    
respondido por el Bob Kugler
0

Hace un tiempo, hace un tiempo tuve la impresión de tener el mismo problema. En aquel entonces, lo resolví agregando un retraso (1) delante o después del serial.println. Eso fue con Arduino 0022 en Linux. No estoy seguro de qué placa era, probablemente una serie de Boarduino. Tampoco puedo reproducirlo.

Actualmente, me funciona en un dispositivo USB con Arduino 1.01 en Windows:

int loop_counter = 0;
int led = 13;

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);}

void loop() {
    if(loop_counter > 100) {
      loop_counter = 0;
    }
    else {
      loop_counter++;
    }

    Serial.println(loop_counter);

    if(loop_counter == 0) {
      Serial.println("hey hey orange, hey hey!");
    }      
}
    
respondido por el posipiet

Lea otras preguntas en las etiquetas