Convert __FlashStringHelper to String type

Hi there Arduino professionals

I wonder if anyone can tell me how to assign the contents of a __FlashStringHelper parameter to a String variable?

Thanks in advance

I wonder if anyone can tell me how to assign the contents of a __FlashStringHelper parameter to a String variable?

Why do you want to? The reason for using the F() macro is to move a non-mutable String out of SRAM. Dragging it back to SRAM then defeats the purpose. If you need the String to be mutable, don't put it in Flash in the first place.

PaulS:

I wonder if anyone can tell me how to assign the contents of a __FlashStringHelper parameter to a String variable?

Why do you want to? The reason for using the F() macro is to move a non-mutable String out of SRAM. Dragging it back to SRAM then defeats the purpose. If you need the String to be mutable, don’t put it in Flash in the first place.

Thanks for a very helpful and enlightening answer Paul. Much appreciated.

In the hope of actually getting an answer I will attempt to explain why I wish to do this.

Simply so that my overloaded method need not duplicate code but convert to string and call my original method.

See this post if you need more details.

Sorry if I appear angry but some of the holier than though type of posts on this forum in response to simple questions sucks.

These answer are given because a conversion is not that easy and in almost any case not desired. A String object is a structure in RAM which can be read and written as the user (or better: the code) likes. A constant string defined by the F() macro is stored in the program flash memory where it cannot be accessed directly but by a special routine byte by byte. This explains why the code in the Stream class (the base class for the ones you use) differentiate between the two uses. The compiler decides (at compile time) which implementation is to be used. Although your code looks identical, the produced binary code is different as it calls different implementations.

One possibility to "convert" from __FlashStringHelper to String would be to call pgm_read_byte for every character in the string and append it to a String object. As PaulS already pointed out, this does not make sense as the intention of using F() to have a __FlashStringHelper object is reduced to absurdity.

Hi Pylon

Thanks for giving me a direction to look into.

--more info behind my reasoning....

My debugwrite method will sometimes output input from sensors (distance, servo angle, compass readings) and at other times it will output hard strings declaring which process is active such as scanWhileDriving or hardTurnLeft etc. These hard strings will be stored in PROGMEM using the F() macro to prevent me running out of memory.

I believe my requirement is valid as an approach which does not convert the __FlashStringHelper to String would require duplicate code, which everytime I wish to modify will require modifying multiple methods rather than a single method..

Which is the worse approach... duplicate code or writing PROGMEM values to a variable is debatable but to be honest I am not interested in debating finer points of coding right now. I just want to get my robot working with a method of human readable output with minimal code duplication.

If you don't wanna support identical looking code, why not defining a macro that contains it and calling that macro inside the two function bodies?

Hmm… not quite clear what you mean by this? If you could elaborate…

What I currently have is

void debugWrite(String data) {
  if ( debugWriteFlag == 1 || debugWriteFlag == 3 ) {
    lcd.print(data);
  }
  if ( debugWriteFlag == 2 || debugWriteFlag == 3 ) {
    Serial.println(data);
  }
}

void debugWrite( __FlashStringHelper* data) {
  if ( debugWriteFlag == 1 || debugWriteFlag == 3 ) {
    lcd.print(data);
  }
  if ( debugWriteFlag == 2 || debugWriteFlag == 3 ) {
    Serial.println(data);
  }
}

and then the following calls will write the output to serial, lcd or both depending on my configuration of debugWriteFlag…

debugWrite(F("hardTurnLeft"));
do some stuff...
debugWrite("angle:"+currentAngle+" dist:"+distanceRead);

This would be what I described:

#define __debugWrite(data)  \
  if ( debugWriteFlag == 1 || debugWriteFlag == 3 ) {\
    lcd.print(data);\
  }\
  if ( debugWriteFlag == 2 || debugWriteFlag == 3 ) {\
    Serial.println(data);\
  }

void debugWrite(String data) {
  __debugWrite(data);
}

void debugWrite( __FlashStringHelper* data) {
  __debugWrite(data);
}

Ahh... now that is interesting.

I did not really understand the use of the word macro. I thought it was just another word for a method :)

So am I right in understanding that one could declare a parameter without type in a macro but one has to define the parameter type in a method (procedure/function)?

I have not done much with Arduino at all, and know nothing of C.

What you have done there Pylon does seem to do what I need. Is there any resource you can point me to which will improve my understanding of macros?

Cheers

To be correct, macros are not part of the C language but are handled by the C preprocessor. You get more information about that here:

and in much greater detail here

http://gcc.gnu.org/onlinedocs/cpp/

Enjoy!

Magic

I will read up on that later.

Thanks for your help Pylon. Much appreciated.