Print_long() displays garbage?

I decided to restore the demo program in an Orangutan SV328 w/LCD.

I found this project:

libpololu-avr\examples\atmega328p\SV-xx8_demo_program\SV-xx8_demo_program.aps

It appears to work on LEDs and beeps (not tested on motors), but the millivolt display routines are displaying garbage. For example:

// Displays the battery voltage.
void bat_test()
{
	int bat = read_battery_millivolts_sv();

	print_long(bat);
	print("mV");

	delay_ms(100);
}

The pot demo also displays garbage, as does the VBAT display in the quick demo mode.

My instincts tell me that print_long() should not be passed an int, but there seems to be no other way to convert a number to a string in the lib, and it’s done consistently throughout the demo code. I have tried printing ints with values I have assigned, and they display correctly.

I’ve tried quite a few variations on the analog read functions, but all the print_long() statements result in garbage (e.g., “1?] 4V”).

Any insight into what I’m doing wrong would be much appreciated. Or perhaps a link to the latest demo source that’s preloaded into the controllers.

Thanks in advance,

Allen

Allen,

This is a bug that started occurring in the latest version of the library. I don’t know what causes it, but I fixed it the other day by changing the variable named “digit” in print(unsigned long value) from an unsigned long to and unsigned char. We’ll post a new version of the library that includes this fix soon, but until then you can try pasting the code below in to your project and using “my_print_long” instead:

void my_print_unsigned_long(unsigned long value)
{
	unsigned char str[10];
	unsigned char i = 10;
	unsigned char digit;

	do
	{
		digit = value;
		value /= 10;
		digit -= value * 10;
		str[--i] = '0' + (unsigned char)digit;
	}
	while (value != 0);

	for(; i < 10; i++)
		print_character(str[i]);
}

void my_print_long(long value)
{
	if (value < 0)
	{
		value = -value;
		print_character('-');
	}
	my_print_unsigned_long((unsigned long)value);
}

This code is basically a copy of what’s in the library right now, so it should work, but I haven’t tested it so there might be a typo or two.

-David

Thanks, David. I much appreciate your quick response.

I’m working with your code, and the garbage seems to be gone. But I’m still not getting what the factory-flashed code used to display.

In the demo source, bat_test() calls read_battery_millivolts_sv168() and displays “165mV”.

The “hold key while powering on” battery test calls analog_read_average(6, 10), and then to_millivolts(), and displays " VBAT ", “495 mV m”.

With the original shipping code, both displayed approximately “5998 mV” for the 6V supply I’m using.

So there are a couple of things going on. I thought the trailing " m" is due to the uninitialized char array, but it is consistent from build to build. I removed the trailing space from print(" mV ") to see if more garbage would appear, but then the display read “-9115 mV”.

I’ll take a closer look at the source and try to improve my understanding of the different analog read facilities. Since I’m using a sv328, I’m wondering if bat_test() is calling the wrong lib routine.

Also, I should mention that this is my first exploration of AVR Studio, etc., and the Orang line. So I may be doing something supremely stupid…

Is there any way to obtain the actual code that’s flashed in the current batch of sv328’s? Comparing that code with what I’ve taken from the demo folder would be very informative.

Thanks,

Allen

Hello, Allen.

Don’t worry that the function name has an sv168 at the end of it: the boards for the SV-168 and SV-328 are identical except for the processor on them so that function will work on both boards.

The original HEX file that was programmed on to your SV-328 was compiled with the older version of the library, version 090605. You can download the older version from here:

pololu.com/docs/0J20/3

The library ZIP file contains the compiled hex file (SV-xx8_demo_program.hex) which I just programmed on my SV-328, and verified that the battery voltage display is correct.

Since the current version of the library is giving you problems, I recommend you use the older version until we can get a new version up.

(Alternatively, you can use the newest version but try recompiling the .a files. I believe the problems you are experiencing are a problem with avr-gcc version 4.3.0 in Linux which compiled the .a files in the release, and so if you recompiled using the latest version of avr-gcc the problem might go away.)

-David

Hi David,

Thanks, I’ll try your suggestions. Good to know there’s a rational explanation for this weirdness. Getting up to speed with a new mpu and new tools is always filled with suprises, and I’m glad it’s not just me doing something dumb.

Allen

Hi David,

Just to follow up, I downloaded the previous lib (090605) and recompiled the demo app. It still displays the weird voltages.

Then I just loaded the saved hex file for the demo app, and it displayed correct voltages in both modes.

I tried compiling from the previous lib (090420), but still got weird voltages.

Oh, and the precompiled hex file from 090605 also works.

Allen

ashtangakasha,

We just released a new version of the Pololu Library (091201) which is very similar to the last one (091125) except that it was compiled with the latest avr-gcc (4.3.3). The print_long and print_unsigned_long bugs should be gone. You can read the announcement and download the library.

The precompiled hex file for the SV 328 demo program in the new library should work for you. If you use the new library and still have trouble compiling your own program that uses print_long, then tell me what version of avr-gcc you are using (run “avr-gcc --version”).

-David

Hello DavidEGrayson

I test lib version 091201 and it still has this bag. I tested precompiled .hex from hex_files folder.
I use avr-gcc 4.3.3.
:frowning:

Hello, andrey0628.

The precompiled hex files in libpololu-avr-091201.zip should not have the print_long() garbage bug in them.

Can you tell me:

  1. The path of the pre-compiled hex file you used (including the device folder).
  2. The model of Orangutan you programmed it on (SV-168, SV-328, etc.)
  3. Your Orangutan’s expected behavior.
  4. Your Orangutan’s actual behavior.

-David