Go Down

Topic: printing variables in formated text? (Read 1 time) previous topic - next topic

2660

I am working with a Ethernet shield and want to add some variables to lines of text and HTML / Java Code.

This is what I am doing and it works but...
Code: [Select]
client.println("<p>The phone number of John Smith is ");
client.println(phone_number);
client.println("</p>");


In PHP I would do this like so... So how do I do it with Arduino?
Code: [Select]
client.println("<p>The phone number of John Smith is ".$phone_number."</p> ");

Can it be done?

James C4S

you need to use sprintf() and a pre-defined character buffer.

However, keep in mind the limited amount of RAM of the arduino makes strings like you suggest problematic.  Large char const* like those get copied into RAM and cause problems.
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

2660

So I should stick with what I have sine I have  LOT more other lines of code also?

I don't mind doing it like I show in the first example but it does make editing the HTML code a PITA.  :smiley-roll-blue:

James C4S

That's not at all what I'm saying.

Having a lot of lines like:
Code: [Select]
client.println("<p>The phone number of John Smith is ");

Consumes RAM, unless you are very careful.  That line is 40 bytes of the 2048 of RAM you have available...
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

2660

I under stand what you are saying about the RAM, does it free it back up after it prints the line or save it till it does the entire code.  If it does the entire code I will not be able to do it since the HTML code is several hundred lines and most of them will have variables. 

ajofscott

Any label you generate occupies memory, it could be forced into the program space using PROGMEM then read out of the program memoryspace.

ajofscott

I too have had to get used to the thimble sized memory here that I had in masses in windows

2660

Ok I will keep the memory problem in mind, but my issue at the moment is how to stick a variable in line wit the other code. As shown above, Anyone got any way to do that?

James C4S


Ok I will keep the memory problem in mind, but my issue at the moment is how to stick a variable in line wit the other code. As shown above, Anyone got any way to do that?


uh?  I already told you.  sprintf()
Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Nick Gammon

I could tell you that (and James already did) but bear in mind you probably need to print literals differently from variables for the memory reasons discussed.

Quote
... does it free it back up after it prints the line or save it till it does the entire code ...


String literals (like "foo") are copied from the program memory into RAM. They are never freed.

However if you use the PROGMEM library, you can copy them a byte at a time, and only therefore use a total of one byte of RAM to hold them.
Please post technical questions on the forum, not by personal message. Thanks!

More info:
http://www.gammon.com.au/electronics

2660

Ok,  I get it now  8)
Now I understand why you were bringing up the RAM problem, I did not look into how sprintf() solved the problem till after my last post.  Once I did I see why it will not work for what I need (in total)

Thanks!

Morris Dovey

One viable approach might be to do something like the following:

Code: [Select]
void putline(unsigned fmt,...)
{  static char format[MAXFMT];
   static char buffer[MAXLIN];

   /* Retrieve format string fmt from FLASH into 'format' */

   /* Assemble print line in 'buffer' */

   Serial.println(buffer);
}


if you made '#' the substitution character, fmt == 0 corresponds to
"<p>The phone number of # is #</p>", name = "John Smith", and phone = "123-456-7890", then the call

   putline(0,name,phone);

would result in retrieving the appropriate format string, performing the two substitutions, and outputting the text line you want, ie:

<p>The phone number of John Smith is 123-456-7890</p>
There's always a better way!

Or you could just set up printf, and use the normal idioms!

Code: [Select]

int serial_putc( char c, FILE * )
{
  Serial.write( c );
  return c;
}

void setup(void)
{
  Serial.begin(57600);
  fdevopen( &serial_putc, 0 );
  printf("Lots of %u numbers %u everywhere %S!",1,2,PSTR("And strings too!"));
}


Easy to extend this to printing out to the Ethernet client too.

Morris Dovey

#13
Jan 23, 2012, 09:26 am Last Edit: Jan 23, 2012, 09:21 pm by Morris Dovey Reason: 1
I took a couple of minutes to play with 02660's problem and wrote this test code to run on my desktop:

(non-working code deleted)

I thought I was being more helpful than I was. I got help with the problems I was having (in a separate thread: Compiling data into program memory...) and posted the working version of the deleted code there.
There's always a better way!

Go Up