¿Cómo depuro un boceto de Arduino?

10

Empecé 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 Arduino, serial.print () es mi único recurso. ¿Cuáles son los métodos / prácticas que implementa para depurar el código Arduino?

0xakhil
fuente
eche un vistazo a playground.arduino.cc/Main/DevelopmentTools para IDE y herramientas de depuración
Dallo

Respuestas:

8

La modularidad es tu amiga. Escriba su bucle principal para hacer lo suyo llamando a funciones, que llaman funciones, ..., hasta el nivel en el que sus funciones serían simples. Comience con el bucle principal y el siguiente nivel hacia abajo, realice funciones de código auxiliar; ya sea vacío:

function foo(){
    ;
}

o falso:

function read_temperature(){
    return(95);
}

, que no hacen nada más que devolver lo que el nivel de llamada necesita para que pueda continuar. Cuando ese nivel funcione, baje un nivel y comience a completar el código simple que también llama a las funciones de código auxiliar. Gradualmente, anule la función de 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 su aplicación, puede construir un andamiaje, un boceto simple que solo alimenta a la función algunos valores de ejemplo y, dentro de la función, imprime valores de 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 solicitan en el terminal que 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 andamios).

Stubbing funciona especialmente bien para sustituir las funciones que interactúan con el hardware, lo que le permite comenzar a abrir la aplicación antes de tener que sumergirse en hojas de datos, problemas de tiempo y otras minucias (como no tener las piezas) que de otro modo podrían detenerse su progreso.

Hablando de problemas de temporización, alternar un pin de salida en un punto particular de su programa, como la entrada y salida de un ISR, le da una onda cuadrada en el pin Arduino cuya frecuencia o ciclo de trabajo puede darle una idea del tiempo interno de tu programa. La forma directa de E / S de puerto, por ejemplo,

PORTC ^= 0x01;

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

Del mismo modo, puede usar un pin de salida analógica para emitir un valor numérico a su medidor desde el interior del programa sin alterar demasiado el tiempo o inflar el código con las funciones de E / S en serie. Utilice los formularios de E / S directa aquí también.

JRobert
fuente
6

Uso Serial.print () y hago que los LED parpadeen.

Eso es prácticamente 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, para que pueda ver la secuencia exacta de eventos.

Majenko
fuente
5

3 Otras técnicas:

  • Desarrolle la funcionalidad de un programa probando lentamente en cada etapa, de esa manera enfrentará solo un pequeño conjunto de errores a la vez.

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

  • Pulse en momentos significativos y use un alcance.

russ_hensel
fuente
3

El complemento Visual Micro para Visual Studio proporciona Arduino Debug . Incluye el código fuente trace and break también permite que las expresiones y variables sean "observadas" y / o modificadas.

ingrese la descripción de la imagen aquí

Micro visual
fuente
1
Tenga en cuenta que esto se realiza mediante impresiones en serie generadas automáticamente insertadas en su código.
por1234
Así es, ¡excepto que las impresiones y lecturas en serie o wifi se insertan en una copia temporal del código, no en el código real! Todo se explica claramente en los documentos de visualmicro.com y para aquellos pocos que tienen depuradores de hardware (generalmente no para Uno, etc.) también son compatibles. Cada método tiene sus propias ventajas y desventajas.
Visual Micro
De Debugger for Arduino : "No admitía pasar por el código y se basaba en el código oculto insertado en su programa antes de la compilación para comunicarse con el depurador".
Peter Mortensen
Así es. Evita la necesidad de que los usuarios agreguen impresiones en serie, permite actualizar vars con nombre mientras se ejecuta la CPU, muestra gráficos y pines digitales, etc. Es diferente de un depurador de hardware pero es rápido y fácil y tiene otros beneficios. Todo esto está bien documentado en visualmicro.com, así que lea. Si su placa soporta gdb o usa atmel studio, hay otras opciones de depuración, por supuesto. Todo depende de su experiencia y del hardware que tenga. Si tiene Arduino genuino, en Atmel studio puede combinar arduino con atmel debug o sim.
Visual Micro
2

Al pasar 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 que estoy depurando. 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 chip AVR atmega, un entorno de desarrollo bootloader + y una tonelada de bibliotecas de software. Desafortunadamente, trabajar con un gestor de arranque limita las capacidades de depuración.

Hans
fuente
0

Para hacer un uso serial.printmás controlado, puede definir una variable booleana global para activar y desactivar la depuración. Cualquier línea de serial.printse envolverá dentro de una ifdeclaración que se ejecutará solo si el indicador de depuración está activado. De esta manera, puede dejar las líneas de depuración en el código incluso cuando haya terminado, pero asegúrese de establecer el indicador de depuración en OFF más adelante.

Hablador
fuente
0

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

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

Úselo 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 es posible utilizar la macro "F", (trace1(F("param1"));). La macro "F" evita que la cadena use la cantidad extremadamente limitada de SRAM.

Mangar
fuente
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 los que puedes modularizar. Si en C, por ejemplo, puede desarrollar y probar una función de cálculo, por ejemplo, que no toca el hardware en una computadora host, otro procesador, envuelve la función con un banco de pruebas para alimentar las entradas y verificar las salidas, etc.

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

Es cierto que 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 sea que tenga conectado su dispositivo AVR.

Salida UART y LED parpadeantes y / o líneas GPIO parpadeantes y utilizando un osciloscopio o un 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 que 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 de los programadores para el hardware no siempre son correctos. Siempre se requiere algún pirateo.

viejo contador de tiempo
fuente