[Solved] itoa() and HTML

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

WinAVR and using itoa() to insert int values into a table column in a HTML file in program memory in an ATmega32 webserver application.

Example 1:

adc_value = 12345;
   
// place adc_value, which is an INT into ADC_0
// and convert to ASCII characters
   itoa(adc_value, ADC_data_ptr->ADC_0, 10);

works as expected. I have defined maxlength as 5 and size as 5 at the top of the HTML file.

If I try to do:

adc_value = 900;

// place adc_value, which is an INT into ADC_4
// and convert to ASCII characters
   itoa(adc_value, ADC_data_ptr->ADC_4, 10);

I was a bit surprised to get

900��

in the web browser, but thought, "this is easy, just put in 2 spaces at buffer positions [4] and [3]". This works OK.

In the course of trying to fix this issue I tried:

adc_value = 900;

// place adc_value, which is an INT into ADC_3
// and convert to ASCII characters
   itoa(adc_value, ADC_data_ptr->ADC_3, 10);

   ADC_data_ptr->ADC_4[4] = ADC_data_ptr->ADC_4[2]; // shift the 9 two places to the right
   ADC_data_ptr->ADC_4[3] = ADC_data_ptr->ADC_4[1]; // shift the 0 two places to the right
   ADC_data_ptr->ADC_4[2] = ADC_data_ptr->ADC_4[0]; // shift the 0 two places to the right
   ADC_data_ptr->ADC_4[1] = ' '; // place a space
   ADC_data_ptr->ADC_4[0] = ' '; // place a space

which also works. So I concluded that it didn't matter which end of the value you placed the spaces at.

However, if I try to insert a decimal point between a 0 and the 5, as follows:

adc_value = 205;

// place adc_value, which is an INT into ADC_3
// and convert to ASCII characters
   itoa(adc_value, ADC_data_ptr->ADC_3, 10);
     
   ADC_data_ptr->ADC_3[3] = ADC_data_ptr->ADC_3[2]; // shift the 2 one place to the left
   ADC_data_ptr->ADC_3[2] = ADC_data_ptr->ADC_3[1]; // shift the 0 one place to the left
   ADC_data_ptr->ADC_3[1] = '.';

I get:

2.05�

I am now puzzled.

If I do:

adc_value = 205;

// place adc_value, which is an INT into ADC_3
// and convert to ASCII characters
   itoa(adc_value, ADC_data_ptr->ADC_3, 10);

   ADC_data_ptr->ADC_3[4] = ADC_data_ptr->ADC_3[2]; // shift the 5 two places to the right?
   ADC_data_ptr->ADC_3[3] = '.'; // insert a decimal point
   ADC_data_ptr->ADC_3[2] = ADC_data_ptr->ADC_3[1]; // shift the 0 one place to the right?
   ADC_data_ptr->ADC_3[1] = ADC_data_ptr->ADC_3[0]; // shift the 2 one place to the right?
   ADC_data_ptr->ADC_3[0] = ' '; // place a space, also overwrites the 2

I can get it to "work".

It appears the order for that HTML cell goes
0 1 2 3 4 , but that the lsd was in position [2].

This doesn't appear to be an endianness issue, but there is something fundamental I am missing here?

(Changing text-align: center; to left or right does not fix this problem.)

What I need is a function that will properly display 1, 2, 3, 4 or 5 characters of int values 0 to 32767 in an HTML cell.

Comments appreciated.

Thanks

Last Edited: Thu. May 7, 2009 - 07:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't suppose you can afford sprintf() can you? If so you could get it to do all the formatting, zero padding, spacing for you.

Cliff

BTW you haven't explained how the contents of ->ADC_n[] gets to your output and how that is being formatted in the above.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the contents of ->ADC-n . . .

The HTML file is stored in program memory. A routine increments through this file and when it gets to special character (%) it goes off to small routine which inserts characters out of ADC-n into the data stream headed off to the uip_appdata buffer in Adam Dunkel's uIP TCP/IP stack.

I will look at sprintf() to help with the padding issues, but I don't think it will help me shift characters around so I can insert a decimal point. I would like to be able to change ADC data to give one significant number to the right of the decimal point. Without resorting to floats.

The main problem is that I do not understand why I have to shift characters in this non-intuitive manner.

Thanks.

Edit. It looks like I added another requirement!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

For the case of making 205 in to 20.5 the following also works

ADC_data_ptr->ADC_3[3] = ADC_data_ptr->ADC_3[2]; // shift the 5 one place to the right
   ADC_data_ptr->ADC_3[2] = '.'; // insert a decimal point
   ADC_data_ptr->ADC_3[4] = ' ';

It appears that is does not matter which end of the "shorter than 5 character number to display" you place the space "filler" at.

It also appears that itoa() spits out the characters MSB first into buffer[0]. I'll be darn.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well there's no doubt about itoa()'s behaviour. Given:

char buffer[6];

itoa(1, buffer, 10)   gives buffer[0]='1', buffer[1]=0
itoa(12, buffer, 10)  gives buffer[0]='1', buffer[1]='2', buffer[2]=0
itoa(123, buffer, 10) gives buffer[0]='1', buffer[1]='2', buffer[2]='3', buffer[3]=0

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Didn't see anything in avr/include/stdlib.h, to that effect and my C reference book doesn't even mention itoa().

Appreciate you reading the rather long posting and your comments. Will have to limit C coding to less than 4 hours a night!