¿Cómo depuro un bosquejo de Arduino?

11

Comencé a codificar para Arduino muy recientemente. Y estos errores en el código me están matando. Como no hay un depurador de hardware en el Arduino, serial.print () es mi único recurso. ¿Cuáles son los métodos / prácticas que implementas para depurar el código Arduino?

    
pregunta 0xakhil

8 respuestas

9

La modularidad es tu amiga. Escriba su bucle principal para hacer su función llamando a las funciones, a las que llama a las funciones, ..., hasta el nivel en el que sus funciones serían simples. Comience con el bucle principal y el siguiente nivel hacia abajo, haga funciones de código auxiliar; o bien vacío:

function foo(){
    ;
}

o falso:

function read_temperature(){
    return(95);
}

, que no hace nada más que devolver lo que sea necesario para que el nivel de llamada pueda continuar. Cuando ese nivel funcione, baje un nivel y comience a completar un código simple que también llama funciones de código auxiliar. Desmarque gradualmente una función a la vez hasta que tenga una aplicación que funcione.

Para depurar una función que devuelve un valor incorrecto, o para crear una sin ninguna influencia del resto de la aplicación, puede crear andamios, un simple boceto que solo alimenta la función con algunos valores de ejemplo y, dentro de la función, imprimir los valores de los parámetros y algunos valores intermedios, hasta que obtenga una idea de qué parte de la función está fallando. Incluso he creado funciones falsas que me piden que en el terminal me devuelva un valor. (Obviamente, esta técnica solo puede funcionar si el sistema puede tolerar la velocidad relativamente glacial de los humanos. Otro uso para los andamios).

Stubbing funciona especialmente bien para ser compatible con funciones que se interconectan con el hardware, lo que le permite comenzar a abrir la aplicación antes de que tenga que sumergirse en hojas de datos, problemas de tiempo y otros detalles (como, ¡no tener las partes!) que de lo contrario podría detener su progreso.

Hablando de problemas de tiempo, alternar un pin de salida en un punto particular de tu programa, como entrar y salir de un ISR, te da una onda cuadrada en el pin Arduino cuya frecuencia o ciclo de trabajo te pueden dar una idea de El tiempo interno de su programa. El formulario directo de E / S del puerto, por ejemplo,

PORTC ^= 0x01;

, distorsionará el tiempo menos que llamando a digitalWrite() . Útil si tiene un 'alcance' o uno de los DMM con la capacidad de medir la frecuencia y / o el ciclo de trabajo.

De manera similar, puede usar un pin de salida analógica para enviar un valor numérico a su medidor desde el interior del programa sin alterar demasiado el tiempo ni hacer que el código se agote con las funciones de E / S en serie. Utilice los formularios de E / S directa aquí también.

    
respondido por el JRobert
6

Uso Serial.print () y hago que los LED se enciendan.

Eso es todo lo que puedes hacer.

Además, me aseguro de que el código sea legible y fácil de entender. Divida las cosas en pasos simples y cree funciones para cada paso, de modo que pueda ver la secuencia exacta de eventos.

    
respondido por el Majenko
5

3 otras técnicas:

  • Construya la funcionalidad de un programa probando lentamente en cada etapa, de esa manera usted enfrenta solo un pequeño conjunto de errores a la vez.

  • Cree el programa alrededor de un intérprete de comandos para que pueda trabajar con las secciones a la vez, como en aquí .

  • Desplázate en momentos significativos y usa un alcance.

respondido por el russ_hensel
2

Partiendo de herramientas de lujo como ARM u otras plataformas (AVR, PIC con herramientas decentes), estoy de acuerdo en que las instalaciones de depuración de Arduino son demasiado limitadas. Pero es una herramienta de inicio con baja entrada.

Serial.print () es tu amigo. Para mi proyecto particular (universidad), no tenía ningún LED conectado, por lo que Serial.print () lo es. Si quiero probar si el código se ejecuta correctamente a través de las declaraciones, generalmente coloco Serial.print ("A"); , luego yendo a B, C, etc. o algo a través de la sección de depuración. Comparo las letras de depuración con lo que espero que haga.

Aparte de eso, no hay puntos de interrupción o pasos de código. Arduino no es más que una placa con un AVR atmega chip, un entorno de desarrollo de bootloader + y una tonelada de bibliotecas de software. Desafortunadamente, trabajar con un cargador de arranque limita las capacidades de depuración.

    
respondido por el Hans
1

Mejor que directamente serial.print, usa macros. Ejemplo:

#ifdef TRACE1
#define trace1(s) serial.print(s)
#define traceln1(s) serial.println(s)
#else
#define trace1(s)
#define traceln1(s)
#endif

Úsalo así:

function doIt(param1, param2) {
    trace1("->doIt("); trace1("param1: "); trace1(param1); trace1(" param2: "); trace1(param2); traceln1(")");

    ...

    traceln1("<-doIt");
}

Es posible que tenga diferentes niveles de rastreo (#ifdef TRACE2 ...) con más detalles.

Y puedes usar la macro "F", (trace1(F("param1"));) . La macro "F" impide que la cadena utilice una cantidad extremadamente limitada de SRAM.

    
respondido por el Mangar
0

Para hacer que el uso de serial.print sea más controlado, puede definir una variable booleana global para activar y desactivar la depuración. Cualquier línea de serial.print se ajustará dentro de una declaración if que se ejecutará solo si el indicador de depuración está activado. De esta manera, puedes dejar las líneas de depuración en el código incluso cuando hayas terminado, pero asegúrate de desactivar el indicador de depuración más adelante.

    
respondido por el Gabby
0

Parpadea los LED, imprime cosas en el puerto serie y escribe y depura pequeñas secciones de código a la vez, a veces solo unas pocas líneas.

Hay momentos en que puedes modularizar. Si en C, por ejemplo, puede desarrollar y probar una función de cálculo, por ejemplo, que no toca hardware en una computadora host, otro procesador, envuelva la función con un banco de pruebas para alimentar las entradas y verificar las salidas, etc. / p>

Otra forma similar podría ser usar un simulador de conjuntos de instrucciones si tiene acceso a uno (si no, es un proyecto muy educativo y gratificante, después de haber hecho algunos de ellos, puede golpear uno en un fin de semana o dos). Aún mejor si alguien tiene un clon de Verilog o VHDL del procesador ( OpenCores por ejemplo) puede probar GHDL, Verilator , o Icarus Verilog . Puede ser lo suficientemente cerca para incluir los periféricos en los que está interesado, y puede obtener una visibilidad de nivel de señal de lo que está sucediendo dentro.

Por supuesto, probablemente no sea un clon perfecto, pero podría ser lo suficientemente bueno. Verilator hace que sea realmente fácil crear periféricos en C / C ++ para que pueda simular lo que tenga conectado a su dispositivo AVR.

Salida UART y LED parpadeantes y / o líneas GPIO parpadeantes y utilizando un osciloscopio o voltímetro. La clave para no volverse loco es escribir y depurar pequeñas secciones de código. Es mejor escribir 10 líneas a la vez y realizar 100 pruebas en lugar de 1000 líneas e intentar depurarlas todas de una vez. Especialmente cuando descubre que la mayoría de las hojas de datos y los manuales de referencia para el hardware de los programadores no siempre son correctos. Siempre se requiere algo de piratería.

    
respondido por el old_timer

Lea otras preguntas en las etiquetas