SVP not running program

I’m having a problem where periodically my SVP 1284 doesn’t run a program after it’s been loaded. As long as I have the programmer plugged in the program runs fine. When I remove the cable and start it again I get “1” printed on the LCD and nothing else happens.

I loaded the demo program, which says my battery is putting out a little over 10V, so I think that’s ok. I don’t see anything in the user guide that gives me a clue, I’d appreciate some help.

Here’s the code, if that matters since it runs fine with the cable attached. It pokes a Ping range finder and prints the result. I added some debug output to see where it was hanging, I only see “1”.

#include <pololu/orangutan.h>
#include <pololu/lcd.h>
#include <stdint.h>

unsigned long microsecondsToCentimeters(unsigned long microseconds)
{
    return (microseconds / 29 / 2);
}

// ------------------------------------------------------------------------

static uint8_t readPing()
{
    lcd_goto_xy(0,0);
    print("1");
    unsigned long x = 0;

    // Bring the line low to get a clean start of the pulse
    set_digital_output(IO_D0, LOW);
    delay_us(10);

    // Send a pulse to tell it to do a measurement
    set_digital_output(IO_D0, HIGH);
    delay_us(3);
    
    // Stop the pulse so it will send us one
    set_digital_output(IO_D0, LOW);
    delay_us(1);

    // set the line to input and read the measurement pulse
    set_digital_input(IO_D0, HIGH_IMPEDANCE);
    while(! is_digital_input_high(IO_D0))
	;

    while(is_digital_input_high(IO_D0))
    {
	delay_us(1);
	x += 1;
    }

     return microsecondsToCentimeters(x);
}


int main()
{
    clear();

    long i;
    while(1)
    {
	i = readPing();
	clear();
	lcd_goto_xy(0,0);
	print_long(i);
	delay_ms(100);
    }
}

Thanks

Joe

I forgot to mention that I’m using the Pololu USB programmer with avrdude under linux.

Joe

Hello goober. Are you really using the Pololu USB AVR Programmer instead of the Orangutan SVP’s built-in programmer?

The reason you only see “1” on the screen might be because your readPing function is never returning. readPing has two infinite loops that might cause it to never return. You should figure out what part of your program is being executed using the user LEDs with the red_led(…) and green_led(…) functions; those functions are much faster than printing to the LCD.

If those suggestions don’t lead you to a solution, please simplify your code further and post it here. By simple, I mean:

  • All code refactored to be inside main()
  • Get rid of microsecondsToCentimeters() and any other code that isn’t needed to demonstrate the problem.
  • Either get rid of your infinite loops or (put some code that causes your loop to definitely exit after a reasonable time, like 500ms) or use LEDs to prove that the infinite loops are not being executed.

–David

Yes

Yes, I knew it wasn’t returning because of what I saw on the LCD. My question wasn’t if there was something wrong with the program, but why it ran fine with the programmer attached but not without it. Since it ran fine in one circumstance I’m at a loss to explain why it wouldn’t in the other.

I see it timing out now from the green led, here’s the code now:

#include <pololu/orangutan.h>
#include <pololu/lcd.h>
#include <stdint.h>

int main()
{
    while(1)
    {
	unsigned long x = 0;
	unsigned long t = 0;

	set_digital_output(IO_D0, LOW);
	delay_us(10);

	set_digital_output(IO_D0, HIGH);
	delay_us(3);

	set_digital_output(IO_D0, LOW);
	delay_us(1);

	red_led(1);
	set_digital_input(IO_D0, HIGH_IMPEDANCE);
	while(! is_digital_input_high(IO_D0))
	{
	    t++;
	    if (t > 1000000)
		break;
	}
	
	green_led(1);
	while(is_digital_input_high(IO_D0))
	{
	    delay_us(1);
	    x += 1;
	    if (x > 1000)
		break;
	}

	green_led(0);
	red_led(0);
    }
}

The code below has no long delays in it, so it might actually be working even though it appears like the green LED is on solid (is that what meant was happening?).

I recommend that you add a little beep and a human-perceivable delay to the top of your main loop so that you know how often your main loop is running. Also, a different kind of beep at the beginning of your program would be nice so you can tell if the AVR is resetting:

delay_ms(500);
play("f64");
delay_ms(500);
while(1)
{
    play("c64");
    delay_ms(500);
    //... rest of code ...
}

If you do that, what kind of beeps do you hear when the program is running?

When the Pololu USB AVR Programmer (item #1300) is not programming your device, all the pins on it are inputs except GND. Does your program run properly if you disconnect the programmer but connect the SVP’s GND to the programmer’s GND?

–David

No, the green led was blinking periodically.

Adding the code you sent makes it act very differently. There’s a beep at program startup, and then a series of lower pitched beeps about every half second. The Ping is being triggered now each time (it has an led that lights up when it’s triggered). Previously it wasn’t getting triggered at all.

I don’t see any difference when doing that. I’m plugging a wire into a ground connector on the SVP, with the other end in contact with the ground pin on the programmer.

I’m starting to think this has something to do with timing. The sensor wants at least a 2 us pulse to trigger it, and I was giving it 3, maybe something I was doing was making that erratic?

It works the same now whether or not I have the programmer plugged in. I’d like to know what made it work with the programmer but not without it before so I can avoid it in the future, but maybe that will be one of life’s little mysteries. For now I’ll experiment with the timing, maybe it’s just pickier than I thought it was.

Thanks

Joe

Cool, I’m glad everything is working for you now. Maybe the added delays give the ping sensor time to reset itself or something. I don’t know. Hopefully the delay doesn’t need to be 500 ms; you can experiment to make it shorter if you need to.

–David

Hello Joe.

In the situation where it was failing, how were you resetting the SVP? Were you using the reset button or the power button? If it was the latter, it’s possible your first pulse to the sensor was sent before the sensor was fully powered up, which caused your infinite loop to never return. You wouldn’t have had this problem immediately after programming because the programmer uses the reset line to restart the microcontroller but doesn’t interrupt power to the sensor (so it’s ready for your first pulse).

- Ben

That must have been it. I went back to the original code, and added a 20 ms delay at the top of main(), and now it works like a champ.

I brought this code over from an Arduino setup, in which it worked as expected. I hadn’t considered until now that the SVP isn’t going to have the delay at startup due to the bootloader that the Arduino has.

Anyway, thanks very much for pointing that out. I appreciate the help from you guys.

Joe