help using the flash.h library and functions

In my code, I have lots of messages that I send to my LCD as in the following example:

sendMessage("My LK1602 display has a built in automatic line shifting feature that movess"
    "the line up one when it come to the end, so it makes"
    "this message scroll very nicely in conjunction with my timed 'sendMessage' function.");

...

void sendMessage(char myMessage[]) {
    i = 0;  //reset display character counter
    LCDclear();
    while(1) {  //loop 
        if(millis() - prevLCDtime > 100 ) {  //continue every 10 ms
            prevLCDtime = millis();        //update the time counter
            Serial.print(myMessage[i]);    //print the next letter to the display
            i = i + 1; //increase counter
            if (i == strlen(myMessage)) break;  //when the counter i gets to the end of the message, break
        }
    }
    delay(1000);  //time to read the last line
    LCDclear();
}

But I'm trying to figure out how to get all my messages in flash, and still have them work with this scrolling routine I made that slowly prints the message out across the LCD.
I don't know enough about why it doesn't work to explain it, but what I tried as seen below, gives me an error. If there's a whole better way to do this, I'm not partial to my scrolling function, but I do need the message to be delivered to the LCD in this timed fashion one way or another, to make a nice readable message.

this doesn't work with my sendMessage() function:

FLASH_STRING(Str1, "Water value settings have been deleted.");

...
sendMessage(Str1);

ps. I should add this link to the flash library page that I'm using:
http://arduiniana.org/libraries/flash/

this doesn't work with my sendMessage() function

Your sendMessage function expects a char*, i.e a pointer to a character in RAM.
You need a version that expects a string from PROGMEM, or you need to copy your string from PROGMEM to RAM first.

I tried this, but it's still not workig:

void sendMessage(String myMessage) {

    i = 0;  //reset display character counter
    LCDclear();
    while(1) {  //loop 
        if(millis() - prevLCDtime > 100 ) {  //continue every 10 ms
            prevLCDtime = millis();        //update the time counter
            Serial.print(myMessage.charAt(i));    //print the next letter to the display
            i = i + 1; //increase counter
            if (i == myMessage.length()) break;  //when the counter i gets to the end of the message, break
        }
    }

The reference page showed the STRING.charAt(), and STRING.length() which seem to be what I need if I pass a STRING to the function, but I get the error:

Coffee_Water_Station_V5_1_2.cpp: In function 'void SaveSettings()':
Eeprom:28: error: conversion from '_FLASH_STRING' to non-scalar type 'String' requested

???
thanks.

I didn't say a String (note the capital), I said a string - a plain old C string.
A null-terminated char array.

AWOL:
I didn't say a String (note the capital), I said a string - a plain old C string.
A null-terminated char array.

ok, let me do some more research in the reference section...

I'm at a loss here... I thought that's what I had the first go round.
Is the problem with this part:

FLASH_STRING(Str1, "Water value settings have been deleted.");

This page seem fairly clear to me, but it doesn't really say anything about string, only String.
http://arduiniana.org/libraries/flash/

You need to convert your FLASH_STRING to a String for that method to work - have a look at the library.
Note that the String library expect to find its data in RAM, not flash.

I found it, I think. I can't test it right now, but this compiles:

void temp(){
  // 2.d Using the flash string copy() method, which copies some or all characters (internally uses strncpy_P)
  char extract[] = {0}; //this should work for any length of message I pass to it, right?
  big_string.copy(extract, big_string.length(), 0); // Copy all characters from offset 0
  sendMessage(extract);
}

thanks,

ps. I changed the name of my Flash string to 'big_string'

char extract[] = {0}; //this should work for any length of message I pass to it, right?

No. Pretty dangerous.

You know how long the FLASH_STRING is, so why not use that length?

AWOL:

char extract[] = {0}; //this should work for any length of message I pass to it, right?

No. Pretty dangerous.

You know how long the FLASH_STRING is, so why not use that length?

...but they are all different lengths. ...my flash strings are anywhere from a couple words, to a few sentences.
Maybe I'm not making myself clear, let me explain again: My code has lots a text it sends to the LCD, which needs to be send 1 char at a time, with a little delay between each char, making a nice user experience with the LCD.
These messages can be anything from "Settings saved", to "a very long 3 sentence description of some function or other"

I was hoping to be able to save all this text in Flash, and have 1 function like the sendMessage function I made, so that anytime in my code I can just say sendMessage 'whatever the message is'.

Is my send message function the way to go, or is there a better way to do this? This is my whole sendMessage() function:

void sendMessage(char myMessage[]) {

    i = 0;  //reset display character counter
    LCDclear();
    while(1) {  //loop 
        if(millis() - prevLCDtime > 100 ) {  //continue every 10 ms
            prevLCDtime = millis();        //update the time counter
            Serial.print(myMessage[i]);    //print the next letter to the display
            i = i + 1; //increase counter
            if (i == strlen(myMessage)) break;  //when the counter i gets to the end of the message, break
        }
    }
    delay(1000);  //time to read the last line
    LCDclear();
    cups = 0;  //reset the cups counter
    prevKeypress = millis();  //reset last keypress time
    Serial.flush();  //clear any keypresses during this message
}

When you call the function that converts a FLASH String to a RAM String (or a RAM string), you can call a function (I'm guessing wildly here) that can tell you how long that particular String, so why not use that value to define the size of your buffer?

AWOL:
When you call the function that converts a FLASH String to a RAM String (or a RAM string), you can call a function (I'm guessing wildly here) that can tell you how long that particular String, so why not use that value to define the size of your buffer?

Sorry, I'm a self taught programmer, and I didn't have a good teacher! I'm getting further and further lost here.
If it's not too much to ask, can someone show me a simple example code of what to do here to get data to my LCD letter by letter, when the data is stored in flash, with this library:
http://arduiniana.org/libraries/flash/

Thanks,

When I said "guessing wildly" I really wasn't joking.
However, reading the docs, there is a method called "length" which returns the length of the FLASH_STRING.

Now remembering that a C string needs a terminator, in your function try something like (I obviously haven't tried compiled or tested this)

size_t len = myString.length();
char buffer [len];
myString.copy (buffer, len);
buffer [len] = '\0';
// buffer now contains your string, however long it happened to be.

There are probably prettier ways.

To simplify, here an small working example sketch. This is working with the string NOT in flash. So where/how to I change this to use the flash string, "MYString"?

#include <Flash.h>

//a sample string in flash that I don't know how to use:
FLASH_STRING(MyString, "press the  * key");


void setup(){
Serial.begin(9600);
}

void loop(){
sendMessage("This is an example of a message");    //send the message
delay(10000); //wait 10 seconds
}

void sendMessage(char myMessage[]) {

    int i = 0;  //reset display character counter
    long prevLCDtime;    
    while(1) {  //begin loop 
        if(millis() - prevLCDtime > 100 ) {  //continue every 10 ms
            prevLCDtime = millis();        //update the time counter
            Serial.print(myMessage[i]);    //print the next letter to the display
            i = i + 1; //increase counter
            if (i == strlen(myMessage)) break;  //when the counter i gets to the end of the message, break
        }
    }
}

You have the library.
I don't.

You have a String in flash memory called "MyMessage".
You have (a rather complicated) function called "sendMessage". (Hint: simplify until you know what you're doing)
"sendMessage" requires that you get a string (a char array) called "myMessage" to print to the serial output.
So, modify the function "sendMessage" so that it accepts a String in FLASH memory, then within "sendMessage" read that String into a char array in RAM.
Then send the RAM char string to the serial interface.

Read the library documentation; try some of the suggested modifications.

I'm a self taught programmer, and I had a poor teacher! :slight_smile:

I've look at all three examples in the flash example liberary, twice. I've read the Flash | Arduiniana probably 3 times. my Arduino programming probably looks pathethic, but I manage, and I really enjoy Arduino a lot. I just can't figure out how to move my messages that I send to an LCD over into flash, so I have room to add a few more features.
Is there anyone else who understands how the flash.h library works who could read post 13 of this thread, which pretty well in a nutshell explains my problem.
I can't get the syntax down for how to print out, letter by letter, a string from flash. I'm not even sure which flash type I need to save my strings as. All I'm sure about is, is that it's not nearly as easy as it sounded the first time I read Flash | Arduiniana

Seems to be pretty simple, according to the documentation:

LiquidCrystal lcd(); 
// ...

// in some method or another
  lcd << F("foo, bar, this is a flash string");

Aeturnalus:
Seems to be pretty simple, according to the documentation:

LiquidCrystal lcd(); 

// ...

// in some method or another
  lcd << F("foo, bar, this is a flash string");

yes, I've notice how very simple it is, that way, but it doesn't work for me. I guess post 13 didn't tell everything. My very first post tellss why this doesn't work for me. I need to send the string, one character at a time, to the lcd, which makes it nicely show up in a ver readable fashion, as the LCD I have has built in functionality for automatically moving the lines up.
See post 1

thanks,

FLASH_STRING(foo, "bar");

// somewhere in a method
for (uint8_t i = 0; i < foo.length(); i++) {
  char c = foo[i];
  Serial.print(c);
}
Serial.print("\r\n");

Aeturnalus:

FLASH_STRING(foo, "bar");

// somewhere in a method
for (uint8_t i = 0; i < foo.length(); i++) {
  char c = foo[i];
  Serial.print(c);
}
Serial.print("\r\n");

I worked with this awhile, with no luck...