ideas for troubleshooting...

I've got a sketch that uses the official ethernet shield to grab some data from the internet, parse some data from that, and occasionally forward it to another device via a (new software) serial port. It's not high throughput or anything. At very irregular intervals, it will lock up. I can tell this by virtue of the serial device showing old data. Sometimes it will work properly for an hour, and sometimes it will work for more than a day. But it just doesn't work properly.

I'm looking for some ideas for troubleshooting. I confess that I am spoiled by debugging on a PC where I can attach to a process with a debugger and see what's what. I know the usual technique here is to output strings to the serial port, but I don't really want to have a computer attached to the device for such long periods. Also, the sketch is definitely pushing the limits of RAM, although it doesn't seem to "go over the edge" and reboot (it used to, but I reduced its footprint some).

One thought I had was to sprinkle some other form of output through the code. I am sure I can find a max of 16 interesting spots in the code, and was thinking of hooking up a seven segment display to show a single hex digit. I began to research such things, and got a bit overwhelmed. So, I guess I have 3 thoughts at this point:

  1. perhaps someone can point me to a good tutorial on hooking up a 7-segment display via some form of driver IC where I can somehow send it the data and have it display. I don't really want to tie up 7 pins. Also, most drivers seem to be BCD, and I would really prefer hex. I think this should be cheap, but some hex drivers I've found are old and expensive. In my little imaginary world, I should be able to buy a $.95 digit, a $1.50 driver IC, and find a really tight library and go. I haven't found those pieces yet.

  2. I could just hook up 4 LED's and figure out how to drive them to represent a count.

  3. Maybe someone else has some other good ideas for very lightweight debugging aids.

Thanks for any assistance!

Also, most drivers seem to be BCD, and I would really prefer hex

Hey, it just needs another 42 bits! (48 at most)

Probably a 7 seg is not the best of ideas for a controller with so few spare I/Os.
Really, serial is the way to go, and if you can get your head around using program memory for your debug strings, it is unlikely that you’ll run out of storage.

Thanks, AWOL. I didn't really flesh out my plan here (with my daughter screaming at me to find her visor for her softball game :-/ ), but as a first step, I would just like to know where I'm getting hung up. So I'm thinking that in my loop, if I just output a digit (4 bits of info, regardless of how it's represented), then if it gets stuck, I'll know the last thing I was trying to call. There's just a handful of interesting interactions, either serial or network. And of course, it would also be very interesting to learn that I'm not in fact "hung" but looping without accomplishing anything useful.

I have all my strings in progmem already, so if anything I'm more concerned about stack usage, but also, serial takes a lot more time than flipping on a few bits.

There must be (?) cases where debugging via Serial.print is either impractical or undesirable, and I'm curious what people do in those cases. Maybe you don't think that applies in my case, but I'm interested to at least hear about other approaches.

I usually just hook up a 10-segment LED bar graph, or a bunch of LEDs, and use it to display binary data.

You’ll want to use digitalWriteFast for this, since you want it to take as little time as possible. Alternatively, use direct port access to simultaneously set bits (but you’ll need to make sure your wiring works out)

uint8_t pins[8]; // 8 LEDs

void showCounter(uint8_t ctr) {
  for (uint8_t i = 0; i < 8; i++) {
    digitalWriteFast(pins[i], (ctr & (1 << i)));
  }
}

void loop() {
  // ... something goes on
  showCounter(0);
   // something else goes on
  showCounter(1);
   // oh no something broke
  showCounter(2);
}

Some ideas:

  1. If you call pgm_read_byte (and friends) with a RAM address, the atmega might hang or reset. I once had this effect of random reboots, because i forgot to put one structure into PROGMEM. Review of the source might help.

2. I do not know the ethernet shield and it's software. It might use interrupts and so additional space on the stack might be required, especially if you execute some deeply nested procedures inside your code.

3. Using the internal watchdog might also help. But it is a little bit risky. Once activated it might be difficult to disable the watchdog without an additional programmer.

4. I am working a lot with displays (SPI interface). So for debugging i often output values on the this display. However, additional software is required (6K FlashROM)

Oliver

It sounds like you have some spare pins. Set 4 of them to output. Connect up 4 LEDs to them (and Gnd), with suitable resistors (eg. 1K). At your "interesting" points output a different pattern (eg. 0001, 0010, 0011 etc.). Then when the program hangs, the pattern on the LEDs will show which of the 16 points you hit. And with one more you can handle 32 points.

Thanks for the ideas, folks. @Nick- that's exactly what I was trying to outline as an alternative to the digit display. @Aeturnalus- I've been meaning to try direct port access -- this may be the opportunity. Alternatively the "fast" functions are new to me. A little googling shows some history, but couldn't find documentation on the arduino reference site. Did they ever get included in the core? Or are they in a .h file that I can simply include? Or do I first have to dl some library? @olikraus- I've thought about the watchdog as a means to recovering, but it scares me a little, and it seems like it would be a missed learning opportunity. I also have an LCD that I've thought about bringing in, but would like to try something very lightweight.

The *fast functions aren't part of the core - they're a header file you can download from here, which are essentially equivalent to direct port access for one pin, with a caveat: the pin number has to be known at compile time for the speed advantage.

Direct port access is still more efficient if you need to set multiple pins, as up to 8 pins in one port can be set at once, instead of in sequence.

Thanks. Will now have to figure out what pins are available :-)

So it looks like I’m not using any pins in the D0-7 bank, except that obviously 0-1 are in use as the serial port. I coded up the following function, that I can call to display where I am in the code via 6 LEDs connected via 560 ohm resistors to pins D2-7. I would welcome any (constructive :slight_smile: ) feedback:

void ShowLocation ( byte loc )
{
  byte temp = PORTD & 3; // preserve state of low two pins (serial port)
  loc <<= 2; // shift to make room for pins 0-1
  loc += temp; // put together the whole byte
  PORTD = loc; // GO!
}

That looks pretty good. Probably change the add to an or, because that is really the intention:

  loc |= temp; // put together the whole byte

True enough! Thanks, I had a feeling something wasn't quite right there.

So I finally got around to incorporating this into my sketch, and lo and behold, it did exactly what it was supposed to. Flashed for a while, then got stuck displaying ON OFF ON ON (lsb->msb), which is of course, unlucky number 13. Between 13 and 14 I have a 'while ( true )' loop with a conditional 'break' Guess my condition wasn't always being encountered! Success! (on the debugging front, anyway).