Passing char arrays on flash as parameter

Hi, I am trying to do something similar to:

const char test_var[] PROGMEM = “This is a test”;

void foo(char char_array_in_flash[]) {
  Serial.println(char_array_in_flash);
}

void setup()
{
  Serial.begin(9600);
}

void loop(){
  foo(test_var);
  delay(5000);
{

Can someone please explain me why it is not working and what is the best way to do so?
Sorry if it's a dummy question, but I'm new with C++ programming.

You can use strcpy_P to copy from PROGMEM to an array in RAM and pass that to foo().

The problem is that Arduino is RAM sensitive. Usually, we don't have so much available RAM. Is there a way to do this passing as reference and avoid using RAM?

It eventually has to be pulled into RAM to print it. The overloaded print() function in Print.cpp does this one character at a time. Also, you need to use a cast to identify that you're supplying a pointer to a string stored in PROGMEM. Try:

const char test_var[] PROGMEM = "This is a test";

void foo(const __FlashStringHelper * char_array_in_flash) {
  Serial.println(char_array_in_flash);
}

void setup()
{
  Serial.begin(9600);
}

void loop(){
  foo((const __FlashStringHelper *)test_var);
  delay(5000);
}

The clue is to use __FlashStringHelper instead of char. It's an incomplete helper type to tell Serial.print to read the string from flash rather than from RAM.

[color=#5e6d03]#undef[/color] [color=#000000]PSTR[/color]
[color=#5e6d03]#define[/color] [color=#000000]PSTR[/color][color=#000000]([/color][color=#000000]s[/color][color=#000000])[/color] [color=#000000]([/color][color=#000000][[/color][color=#000000]][/color][color=#000000]{[/color] [color=#00979c]static[/color] [color=#00979c]const[/color] [color=#00979c]char[/color] [color=#000000]c[/color][color=#000000][[/color][color=#000000]][/color] [color=#00979c]PROGMEM[/color] [color=#434f54]=[/color] [color=#000000]([/color][color=#000000]s[/color][color=#000000])[/color][color=#000000];[/color] [color=#5e6d03]return[/color] [color=#434f54]&[/color][color=#000000]c[/color][color=#000000][[/color][color=#000000]0[/color][color=#000000]][/color][color=#000000];[/color] [color=#000000]}[/color][color=#000000]([/color][color=#000000])[/color][color=#000000])[/color]

[color=#00979c]const[/color] [color=#00979c]auto[/color] [color=#000000]test_var[/color] [color=#434f54]=[/color] [color=#000000]F[/color][color=#000000]([/color][color=#005c5f]"This is a test"[/color][color=#000000])[/color][color=#000000];[/color] [color=#434f54]// F(...) places string in Flash[/color]

[color=#00979c]void[/color] [color=#000000]foo[/color][color=#000000]([/color][color=#00979c]const[/color] [color=#000000]__FlashStringHelper[/color] [color=#434f54]*[/color][color=#000000]char_array_in_flash[/color][color=#000000])[/color] [color=#000000]{[/color]
  [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]println[/color][color=#000000]([/color][color=#000000]char_array_in_flash[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]

[color=#00979c]void[/color] [color=#5e6d03]setup[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color][color=#000000]([/color][color=#000000]9600[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]

[color=#00979c]void[/color] [color=#5e6d03]loop[/color][color=#000000]([/color][color=#000000])[/color] [color=#000000]{[/color]
  [color=#000000]foo[/color][color=#000000]([/color][color=#000000]test_var[/color][color=#000000])[/color][color=#000000];[/color]
  [color=#d35400]delay[/color][color=#000000]([/color][color=#000000]5000[/color][color=#000000])[/color][color=#000000];[/color]
[color=#000000]}[/color]

See this thread as to why the PSTR hack is necessary: declare string variable - #11 by PieterP - Programming Questions - Arduino Forum

Pieter

This version works fine:

const char test_var[] PROGMEM = "This is a test";


void foo(const char char_array_in_flash[]) 
{
  // Casting to "__FlashStringHelper *" is a trick to let .print() and .println() know that the
  // data is in PROGMEM.
  Serial.println((__FlashStringHelper *)char_array_in_flash);
}


void setup()
{
  Serial.begin(9600);
}


void loop() 
{
  foo(test_var);
  delay(5000);
}