Flash library weirdness?

Hi,
I'm trying to work with the Flash library by Mikal Hart (see: Flash | Arduiniana ). Either I don't understand how it works, or there's something wrong.... I've distilled the strangeness down to the example code below. Can someone explain why the sketch below does not seem to assign the correct value (9) to the variable x2? (using a regular, non-flash int array it works as expected...)
I get the following output:

————————
5 , 9
5 , 5
————————

Of course I expect the 2nd line to be identical to the 1st, but it’s not… (using arduino 0022 with arduino nano 328)
thanks,
——————————

#include <Flash.h>
FLASH_ARRAY(int, arrayData, 5, 9);

void setup() {
  Serial.begin(57600);
  Serial.println("------------------------");
  int x1=arrayData[0];
  int x2=arrayData[1];
  Serial.print(arrayData[0]);
  Serial.print(" , ");
  Serial.println(arrayData[1]);
  Serial.print(x1); 
  Serial.print(" , ");
  Serial.println(x2);
  Serial.println("------------------------");
}

void loop() {
}

First, when posting code, please, wrap your code in "code" tags. (In the post editor click the "#" button to see what they look like.) Second, before posting your code, in the IDE go to the "Tools" menu and select "Auto Format". It cleans up the code quite nicely. Third, when referring to something not included with the IDE it is best to provide a link. "The Flash library" could refer to many things.

All that said, I'm not sure I understand why that is happening either. You might try contacting the library's Author (and if you get an answer post it back here...)

James, thanks for the tips; I've clarified my post a bit. Please excuse my n00bness... I posted about this on the autor's page Flash | Arduiniana , but my comment appears to be stuck in "awaiting moderation" limbo, so I hoped someone here could help.

Anyway, I've been playing around with this example, and the value assigned to x2 seems to differ, depending on where I include the Serial.print() line for the other variable, x1... Weird bug?

For example, if I comment out the " Serial.print(x1); " line, the value for x2 changes to what I expect...

#include <Flash.h>
FLASH_ARRAY(int, arrayData, 5, 9);

void setup() {
  Serial.begin(57600);
  Serial.println("------------------------");
  int x1=arrayData[0];
  int x2=arrayData[1];
  Serial.print(arrayData[0]);
  Serial.print(" , ");
  Serial.println(arrayData[1]);
  //Serial.print(x1); 
  Serial.print(" , ");
  Serial.println(x2); 
  Serial.println("------------------------");
}

void loop() {
}

Output (this is what I expect):

5 , 9
, 9

Also.... If I move the assignment of the x2 variable further down, I also get the "correct" value....

#include <Flash.h>
FLASH_ARRAY(int, arrayData, 5, 9);

void setup() {
  Serial.begin(57600);
  Serial.println("------------------------");
  int x1=arrayData[0];
  Serial.print(arrayData[0]);
  Serial.print(" , ");
  Serial.println(arrayData[1]);
  Serial.print(x1); 
  Serial.print(" , ");
  int x2=arrayData[1];
  Serial.println(x2); 
  Serial.println("------------------------");
}

void loop() {
}

Output (also is what I expect):

5 , 9
5 , 9

Can anyone else confirm this strange behavior? Hopefully the library's author can chime in on this.

but my comment appears to be stuck in "awaiting moderation" limbo, so I hoped someone here could help.

That's generally a good sign. I force all the comments on my blog to go into moderation. It takes longer for someone else to seem them, but it also means I read each one.

There was a note on the author's page regarding how to print. I wonder if that explains any of the issue you are seeing: "Flash objects can also be “printed” using the familiar Serial.print[ln] syntax, but this requires a small patch to the core Print.h file. See “Patching Print.h” below."

I did run your code and duplicated your behavior. I tried several different iterations and couldn't find something that worked.

Thanks for confirming this behavior...

I didn't yet do the print patch listed on the site, but the issue appears even when not using any print methods at all. I tested by counting LED blinks instead of using the serial monitor. Again, it seems to depend on placement of sections of code. If i move the x2 variable assignment line to right before the second blink loop, all of a sudden the code seems to work...

#include <Flash.h>
FLASH_ARRAY(int, arrayData, 5, 9);

void setup() {
  pinMode(13, OUTPUT);  
  int x1=arrayData[0];
  int x2=arrayData[1];  // if this line is moved past the 1st blink sequence, there is no issue....
  int i;

  // count the 1st set of blinks for x1 value
  //we expect 5 blinks, and we get 5 blinks
  for (i = 1; i <= x1; i++) { 
    digitalWrite(13, HIGH);   
    delay(200);                  
    digitalWrite(13, LOW);
    delay(200);    
  }
  delay(2000);  // wait a couple sec's

  // count the 2nd set of blinks for x2 value
  //we expect 9 blinks, but only get 5 (same as x1 value)
  //(unless we move the "x2" assignment here, then everything seems to be normal...)
  for (i = 1; i <= x2; i++) { 
    digitalWrite(13, HIGH);   
    delay(200);                  
    digitalWrite(13, LOW);
    delay(200);    
  }
}

void loop() {
}

Your comment about where x2 is defined got me thinking. What would matter about the location? Time.

This works:

#include <Flash.h>

FLASH_ARRAY(int, arrayData, 5 , 9);

void setup() {
  Serial.begin(9600);
  int x1 = arrayData[0];
  delay(100);
  int x2 = arrayData[1];

  Serial.println();
  Serial.print(x1);
  Serial.print(" , ");
  Serial.println(x2);
}

void loop() {
}

I don't understand why the delay is necessary, though.

Interesting... However, I don't know if it's actually the time duration that is influencing the result. Reducing the delay(), and even changing it to delayMicroseconds(1) still gives the "correct" result. However, if I replace the delayMicroseconds(1) to a for loop that calculates a million square roots (below), the weirdness returns... Surely, it takes longer than 1 microsecond to calculate a million square roots?

#include <Flash.h>
FLASH_ARRAY(int, arrayData, 5, 9);

void setup() {
  Serial.begin(57600);
  int x1 = arrayData[0];
  for (long i = 1; i <= 1000000; i++) {
    sqrt(i);  
  }
  int x2 = arrayData[1];
  Serial.println();
  Serial.print(x1);
  Serial.print(" , ");
  Serial.println(x2);
}

void loop() {
}

This is an example where the compiler is trying to help you.

The compiler knows that sqrt(i)'s result isn't being stored or used. A variable that is only referenced inside of a loop/block and no where else, generally causes the loop to get optimized out. Change to:

  long total;
  for (long i = 1; i <= 1000; i++) {
    total += sqrt(i);  
  }
  Serial.println(total);  //use the variable out side of the loop's scope.

Notice I moved the loop down to 1000. I wasn't patient enough to wait for 1 million.

Aha, I didn't know the compiler was that smart...

Anyway, delayMicroseconds(0); seems to do the trick as well, so i'll just add that into my "real" code for know. It just bothers me that I don't know why it's required. Let's hope Mikal Hart can give some insight.

Thanks for your help

Mikal Hart can't currently give any insight, unfortunately. :slight_smile:

Why timing would have anything to do with this is hard to comprehend. I may have to do some serious debugging. Thanks for bringing this to my attention.

M

I think what you are looking at, is the way the compiler is working and allocating storage, which then interferes with the macros.
The requirement for
Delay(xxx);
can be completely negated
and the bug appears to clear-up with a small change. (yes I know it changes the meaning of the code, but the issue is incorrect values influenced by irrelevant coding sequences )

static int x1=arrayData[0];
static int x2=arrayData[1];

After this change the test cases appear to function correctly