Followers

Recent Posts

Monday, November 30, 2009

Debugging robots for fun and profit

More astute readers who followed the procedure in my last post may have noticed that it didn't actually work.

That's not to say that the instructions were wrong - those are still the steps to build the robobuilder C source files and upload them to the RBC. The problem was that the code which I linked doesn't actually do what it says on the side of the box, so to speak.

The execution of the code posted on the robosavvy forum (which is primarily an english adaptation of the official code) should result in the robot performing the RIGHTPUNCH action when the PF1 button is pressed. However, when the files are built and installed on the robot, no amount of button pressing will elicit a response from the robot.

I'm working on producing an updated version of the code which is nice and flexible, which I will upload here when I'm satisfied with it. In the meantime, for those of you playing along at home, I thought I would share a quick debugging procedure known only to a secluded group of embedded systems programmers.

There are on-chip debuggers available for the AVR family of microcontrollers, however I don't have one. There are also situations when the debugger causes more problems than it solves - ie, by hogging certain pins on the board, or restricting the flow of real-time interrupts. The poor mans solution to this is to set up a quick method of stepping through your program and seeing where it gets to and where it gets stuck. The easiest way of allowing your program to communicate back to you is using the onboard LEDs.

#include "macro.h"
#include "main.h"

WORD gDebugMode = 1;

void Debug(BYTE code)
{
if(gDebugMode)
{
CHK_BIT7(code)? RUN_LED2_ON : RUN_LED2_OFF; //Green
CHK_BIT6(code)? PF1_LED2_ON : PF1_LED2_OFF; //Red
CHK_BIT5(code)? PWR_LED2_ON : PWR_LED2_OFF; //Green
CHK_BIT4(code)? PWR_LED1_ON : PWR_LED1_OFF; //Red
CHK_BIT3(code)? PF1_LED1_ON : PF1_LED1_OFF; //Blue
CHK_BIT2(code)? RUN_LED1_ON : RUN_LED1_OFF; //Blue
CHK_BIT1(code)? PF2_LED_ON : PF2_LED_OFF; //Yellow
CHK_BIT0(code)? ERR_LED_ON : ERR_LED_OFF; //Red
}
return;
}

The input to this function is just a number you can assign to a particular error/state code: ie, Debug(3) would have the error and PF1 LEDs lit, while DEBUG(0) turns all the LEDs off. Combined with the use of the _delay_ms(1000) command, you can sprinkle these throughout problem areas and observe how your code branches or if it gets stuck anywhere.


The ordering of the LEDs may seem arbitrary, and it can be a little hard because the ordering zig-zags upwards from LSB (error) to MSB (power), and then zigs back down again. The reasoning behind this is because I wanted to make the lower numbers easier to read, since three of the LEDs have two possible colours. Hence, it's just normal binary for error values up to 2^5 = 32, and only mildly more complicated for bigger numbers.

No comments:

Post a Comment