-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
using with strings ? #4
Comments
Hi, this issue is quite difficult to find a nice solution. However I have come up with a basic workaround. Basically, I have a new type: First though, if you want an array of Before I add this next fix to the lib I want to test it thoroughly, so here is some instructions so you can use it now. Here is the template< unsigned N >
struct cstr_p{
char_p *begin() const{ return (char_p*) &pstr[0];}
char_p *end() const{ return (char_p*) &pstr[N]; }
operator __FlashStringHelper*() const{ return ( __FlashStringHelper* ) &pstr; }
char_p &operator [] (int addr) const{ return *(const char_p*) &pstr[addr]; }
const char pstr[N];
}; Then to declare a string, you construct it like this: const cstr_p< 14 > pStr PROGMEM = {"A test String"}; Notice the size of the string (including the null) is needed in the template brackets. And the usage is quite straight forward. for( auto &c : pStr ) //Ranged loop over whole string (C++11 only, IDE 1.6.2 and above)
Serial.print( c );
for( int i = 0 ; i < sizeof(pStr) ; ++i ){ //Standard for loop
Serial.print( pStr[i] );
}
Serial.write(pStr[0]); //Print single character
Serial.print(pStr); //Print whole string And here is a complete sketch if you would like to test it. #include <PGMWrap.h>
template< unsigned N >
struct cstr_p{
char_p *begin() const{ return (char_p*) &pstr[0];}
char_p *end() const{ return (char_p*) &pstr[N]; }
operator __FlashStringHelper*() const{ return ( __FlashStringHelper* ) &pstr; }
char_p &operator [] (int addr) const{ return *(const char_p*) &pstr[addr]; }
const char pstr[N];
};
const cstr_p< 14 > pStr PROGMEM = {"A test String"};
void setup() {
Serial.begin(9600);
for( auto &c : pStr ) //Ranged loop over whole string
Serial.print( c );
Serial.write('\n'); //Move to next line
for( int i = 0 ; i < sizeof(pStr) ; ++i ){ //Standard for loop
Serial.print( pStr[i] );
}
Serial.write('\n');
Serial.write(pStr[0]); //Print single character
Serial.write('\n');
Serial.print(pStr); //Print whole string
}
void loop() {} Let me know how you go. Cheers. |
Hi Chris, I will test your solution and let you know. 2 questions about it:
I got a project here with a very huge menu system (for the GUI) with more than 100 lines of text, my solution up to know is as follows:
|
Hi, this will need some investigation as I have not used UTF-8 within the Arduino environment. However to solve the length problem, use a define for your strings, then you can change the size without having to count each time they change: #define text "Some text"
#define text1 "Some other text "
const cstr_p< sizeof(text) > pStr PROGMEM = {text};
const cstr_p< sizeof(text1) > pStr1 PROGMEM = {text1}; I'll investigate other methods, however this should work for now. |
your example works.
but of course counting the size of the string (including the null) is challenging for the user... ;-) using #defines works:
using #defines works with UTF-8 as well:
|
Good to hear, You could shrink it to a single line per string with a define if you have many strings. #define createPGMStr( name, text ) const cstr_p< sizeof(text) > name PROGMEM = {text}
createPGMStr( pStr, "some text" );
createPGMStr( pStr1, "some other text" );
createPGMStr( pStr2, "even more text" ); |
Wow, THAT's what I'm looking for ! I think this is really easy to understand by users of every skill level, So all you have to do is to integrate this in your PGMWrap-library somehow (?) |
unfortunately my menu example sketch grows from 13000 bytes to 20000 bytes, when using the before:
after:
|
I'll have a look and see what is going on. |
hi cris |
Hi,
how can strings be used with a "PGMWrap-like" style ?
this will not compile
const char_p my_string[] PROGMEM = "my Text";
cause of "invalid conversion from 'char*' to 'const char&" issue
the goal is to be able to use strings from flash like any other string (from RAM):
Serial.print(my_string);
The text was updated successfully, but these errors were encountered: