Go Down

Topic: How to use the F() macro on a parameter? (Read 1 time) previous topic - next topic

berds

I'm working on a new project (diagnostic tool) that can be operated with a desktop (verbose mode) or with a portable power supply (output only mode).

Thing is, I won't be needing the verbose Serial.print lines if I will be using it without a desktop, so I wrote a function to test whether or not the program should print something. I am trying to save SRAM and shave off execution time due to unneeded Serial.print calls.

Code: [Select]
void setup()
{
  // some code here
}

void loop()
{
  // some code here

  SerialPrintWrap("I can't get it to work.");
}

void SerialPrintWrap(char conditionalPrint[])
{
  if(digitalRead(verbosePin) == HIGH)
  {
    Serial.println(F(conditionalPrint));
  }
}


Are there workarounds for this problem? Thanks!

PaulS

Quote
Are there workarounds for this problem?
The F() macro keeps string literals from being copied from flash memory to SRAM.

It is NOT to be used around arguments passed to the function. It CAN be used in the call to the function, but then the function needs to be defined differently.

The Print class is what Serial derives from. Look at how it deals with strings in SRAM and in flash. Two different functions, and you (or the compiler) must call the correct one.
The art of getting good answers lies in asking good questions.

Whandall

Code: [Select]
byte verbosePin = 12;
void setup() {
  Serial.begin(250000);
  pinMode(verbosePin, OUTPUT);
  digitalWrite(verbosePin, HIGH);
  SerialPrintWrap(F("It could work this way."));
}
void loop() {}

void SerialPrintWrap(const __FlashStringHelper* conditionalPrint) {
  if (digitalRead(verbosePin) == HIGH) {
    Serial.println(conditionalPrint);
  }
}
Code: [Select]
It could work this way.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

berds

And it did indeed. I see that you used the FlashStringHelper directly as a parameter. Wow. I really do have much to learn. Thanks!

PaulS

That code won't work with:
Code: [Select]
   SerialPrintWrap("SomeText");

or
Code: [Select]
   float pi = 3.14159;
   char fltBuff[10];
   dtostrf(pi, 8, 5, fltBuff);
   SerialPrintWrap(fltBuff);
The art of getting good answers lies in asking good questions.

Whandall

Just create a function for the standard case too:
Code: [Select]
byte verbosePin = 12;
void setup() {
  Serial.begin(250000);
  pinMode(verbosePin, OUTPUT);
  digitalWrite(verbosePin, HIGH);
  SerialPrintWrap(F("It could work this way."));
  SerialPrintWrap("And it could work this way.");
}
void loop() {}

void SerialPrintWrap(const __FlashStringHelper* conditionalPrint) {
  if (digitalRead(verbosePin) == HIGH) {
    Serial.println(conditionalPrint);
  }
}
void SerialPrintWrap(const char* conditionalPrint) {
  if (digitalRead(verbosePin) == HIGH) {
    Serial.println(conditionalPrint);
  }
}
Code: [Select]
It could work this way.
And it could work this way.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Go Up