Pages: [1]   Go Down
Author Topic: Flash library weirdness?  (Read 920 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
I'm trying to work with the Flash library by Mikal Hart (see: http://arduiniana.org/libraries/flash/ ). 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,
——————————

Code:
#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() {
}
« Last Edit: January 06, 2012, 03:53:05 pm by Jesuis » Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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...)

Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 http://arduiniana.org/libraries/flash/ , 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...

Code:
#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....

Code:
#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.
« Last Edit: January 06, 2012, 04:07:46 pm by Jesuis » Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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...

Code:
#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() {
}

Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

This works:
Code:
#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.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

Code:
#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() {
}
Logged

Fort Lauderdale, FL
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6144
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

Code:
  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.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.c

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Austin, TX USA
Offline Offline
God Member
*****
Karma: 5
Posts: 998
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 98
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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 )

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

After this change the test cases appear to function correctly


« Last Edit: January 29, 2012, 04:07:17 am by hardcore » Logged

Pages: [1]   Go Up
Jump to: