Pages: [1]   Go Down
Author Topic: Flash: A new PROGMEM library  (Read 2817 times)
0 Members and 1 Guest are viewing this topic.
Austin, TX USA
Offline Offline
God Member
*****
Karma: 4
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Flash
I have written a new library, Flash, which abstracts away most of the complexity of PROGMEM.   It provides String, Array, and Table types that make ROM-based data collections as easy to use as “normal” types.  Each overrides the C++ [] operator, so to get at individual elements, one simply uses familiar array syntax.  For example, if you have 1000 floating point temperatures in a flash-based “temperature_table” array, you might write code like this:

Code:
     for (int i=0; i<temperature_table.count(); ++i)
        if (temperature_table[i] > 98.6)
          Serial.println(temperature_table[i]);

Font tables are a good application for Flash.  Assuming that font_table is a 256x7 table of On/Off values, one row for each character, this simple example displays the number “2” on a 7-segment display:

Code:
     int digit = '2';
      for (int i=0; i<7; ++i)
        digitalWrite(pin[i], font_table[digit][i]);

Inline ROM Strings
One of the most useful features of Flash is the ability to use “inline”, or unnamed ROM-based strings.  This provides a tremendous convenience for applications that process lots of string data.  To print an inline flash string, you use the library's built-in F() macro:

 
Code:
    Serial << F("A very long ROM-based string….");
For those uncomfortable with the << streaming notation, you can also write

Code:
     Serial.print(F("A very long ROM-based string…"));
but this requires a minor patch to core file Print.h to tell it about Flash objects.  (See the file patching_print.txt.)

I welcome feedback and suggestions for improvement.  The library is posted here.

Thanks,


Mikal
« Last Edit: March 25, 2009, 03:42:20 pm by mikalhart » Logged

Connecticut, US
Offline Offline
Edison Member
*
Karma: 2
Posts: 1036
Whatduino
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset


Huzzah, very nice!  I have mostly avoided PROGMEM due to the byte-for-byte problem.  I almost made a PROGMEM_readAnything() to make RAM copies, but that defeats the purpose in most cases.  I really do wish the ATmega didn't require a completely different instruction to address prom, but oh well.
Logged

0
Offline Offline
God Member
*****
Karma: 0
Posts: 588
LumiNet rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

great work!

Nice idea and good explanation on your site.
I will test it soon. I really like the idea of FLASH_TABLE and the patch to Print.h is useful because people are very used to print and println.
Logged


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

Thank you both for the kind feedback.  I think Flash is some of my most useful work.

I published a new version (2) Wednesday that reduces the flash space overhead consumed by String objects.

Thanks again!

Mikal

Logged

Brooklyn, NY
Offline Offline
Jr. Member
**
Karma: 0
Posts: 92
Webduino / RGB LED Shield
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is very cool.  I'll add some pointers to this into my Webduino library and documentation, as it looks to be a better solution than what I did; in that library, I made a P() macro that defined a progmem string then added a printP method to the WebServer class for printing them out.

I'm also going to adopt your template for adding a no-cost stream operator.  I was really missing that one!

Thanks.
Logged

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

Thanks, Ben.  For a long time people have wanted a way to print() a PROGMEM string as easily as a "normal" string.  The problem, as I'm sure you noticed, is that gcc does not consider a prog_char * sufficiently different from a char *, so you can't override print() on that basis.  But it occurred to me one day that if one were to define a lightweight class to wrap PROGMEM strings, that would be sufficiently different.

I appreciate the feedback.

Mikal
Logged

Amsterdam
Offline Offline
Full Member
***
Karma: 0
Posts: 137
he's looking at you, kiddy...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

i got a compile error using your library.

"error: 'cosarray' was not declared in this scope In function 'void closedoors()':"

tools:
Arduino 0017
Arduiniana flash 2.0

code snippets:
Code:
#include <Flash.h>
#include <EEPROM.h>
...
void setup(){
 FLASH_ARRAY(float, cosarray,
  cos(0),cos(4.5),cos(9),cos(13.5),
  cos(18),cos(22.5),cos(27),cos(31.5),
  cos(36),cos(40.5),cos(45),cos(49.5),
  cos(54),cos(58.5),cos(63),cos(67.5),
  cos(72),cos(76.5),cos(81),cos(85.5)); //define array of cos(x) in progmem

}

void opendoors(){
...
      stepper(int(minDelay + delayVal + cosarray[trajectCounter]*(maxDelay)));

}

i have no idea what goes wrong. FLASH_ARRAY is red, so is recognized by the ide

the next uses a direct paste from http://arduiniana.org/libraries/flash/ and yelds the same error. :-(

Code:
#include <Flash.h>
float result = 0;

void setup(){
  FLASH_ARRAY(float, temperatures, 23.1, 23.1, 23.2, 23.2, 23.4,
    23.7, 25.0, 26.0, 26.8, 28.8, 30.2, 31.9, 33.1, 33.1, 33.2,
    33.2, 33.4, 33.7, 35.0, 36.0, 36.8, 38.8, 40.2, 41.9);
}

void loop(){
  result = temperatures[4];
}
Logged

--
"We're all in this together..."

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 176
Posts: 12283
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Move the cosarray declaration...

Code:
#include <Flash.h>
#include <EEPROM.h>

FLASH_ARRAY(float, cosarray,
  cos(0),cos(4.5),cos(9),cos(13.5),
  cos(18),cos(22.5),cos(27),cos(31.5),
  cos(36),cos(40.5),cos(45),cos(49.5),
  cos(54),cos(58.5),cos(63),cos(67.5),
  cos(72),cos(76.5),cos(81),cos(85.5)); //define array of cos(x) in progmem

void setup()
{
}

void opendoors()
{
...
      stepper(int(minDelay + delayVal + cosarray[trajectCounter]*(maxDelay)));
}
Logged

Amsterdam
Offline Offline
Full Member
***
Karma: 0
Posts: 137
he's looking at you, kiddy...
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah. a macro is just a declaration. of course.  smiley-razz
Logged

--
"We're all in this together..."

Pages: [1]   Go Up
Jump to: