Go Down

Topic: Function fails with passed in variable, but works if set manually. (Read 1 time) previous topic - next topic

allenhuffman

Apr 10, 2013, 07:07 pm Last Edit: Apr 10, 2013, 07:13 pm by allenhuffman Reason: 1
Greetings. I have an array of Flash strings, and I can show them directly like this:

Code: [Select]

Serial.println((_FlashStringHelper*)optCmd[0]);


I can also do that in a function:

Code: [Select]

void thisWorks(byte i)
{
 i = 0; // notice this override
 Serial.println((_FlashStringHelper*)optCmd[i]);
}


...but if I pass in a 0, and even verify it by printing it inside, it prints garbage:


Code: [Select]

void thisFails(byte i)
{
 // i = 0;
 Serial.println((_FlashStringHelper*)optCmd[i]);
}


I assume the preprocessor phase is doing something weird, but I have pruned this down to very simple code and cannot figure it out.

Anyone know what is going on?
Embedded Software Engineer
UNO | Leonardo | Due | Teensy | BASIC Stamp
http://www.subethasoftware.com

Erdin

What happens if you use the PGMT macro, http://arduino.cc/forum/index.php/topic,158375.msg1187237.html

I can't try a sketch, if I don't know what kind of strings. Both strings and array of pointers with PROGMEM and also with prog_uchar ?

allenhuffman

Here is a full example. The main for loop works and properly prints the strings. But, if you uncomment the "//Serial.println()" in thisFails(), it starts printing garbage.

The duplicate print in "thisFails()" is what I was trying to do, but I have yet to get it to work. Simply having a Serial.println() causing it to not work clues me in that it may just be another oddity with the compiler preprocessor.

Code: [Select]

#include <avr/pgmspace.h>

const char string1[] PROGMEM = "This is string #1";
const char string2[] PROGMEM = "This is string #2";
const char string3[] PROGMEM = "This is string #3";

const char *flashArray[] PROGMEM = { string1, string2, string3 };

void thisFails(int i);

void setup()
{
  int i;

  Serial.begin(9600);
  while(!Serial);

  for (i=0; i<3; i++) {
    Serial.println((__FlashStringHelper*)flashArray[i]);
    thisFails(i);
  }

  showFreeRam();
}

void loop()
{
}

void thisFails(int i)
{
  // Uncomment out the next line, and it stops working.
  //Serial.println("Comment this line out and it works.");

  // This is the line I want to work, but it always fails. BUT,
  // if you manually pass a number in to the flashArray[0], it
  // works, or if you set "i=0;" before it, it works. Weird.
  //Serial.println((__FlashStringHelper*)flashArray[i]);
}

// End of FlashTest
Embedded Software Engineer
UNO | Leonardo | Due | Teensy | BASIC Stamp
http://www.subethasoftware.com

Erdin

Why do it wrong, if you can do it right ?
Did you take a look at the other thread, and did you try that PGMT() macro ?

allenhuffman

Yes, I actually found that thread before when first researching PROGMEM. It is a very good one.

But this is actually a compiler question, not a PROGMEM question. My question here is what is the compiler doing to change things just by calling a Serial.println(). It's the third issue I have ran in to, with the last two being bugs requiring workarounds, and I am wondering if this is another one.

Looking at the source in Print.cpp, I see it has one that expects a "const __FlashSTringHelper *" and I am specifically casting to that. It looks like something may be trashing the stack or, perhaps, the preprocessor is misreading the source and changing the casting based on what it sees in the source code when that is there. (I am leaning to this second explanation, based on previous issues I have run in to.)
Embedded Software Engineer
UNO | Leonardo | Due | Teensy | BASIC Stamp
http://www.subethasoftware.com

Go Up