Arduino Forum

Using Arduino => Storage => Topic started by: SouthernAtHeart on May 20, 2011, 07:01 am

Title: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 07:01 am
In my code, I have lots of messages that I send to my LCD as in the following example:
Code: [Select]

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:
Code: [Select]

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/ (http://arduiniana.org/libraries/flash/)
Title: Re: help using the flash.h library and functions
Post by: AWOL on May 20, 2011, 01:55 pm
Quote
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.
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 04:36 pm
I tried this, but it's still not workig:
Code: [Select]
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:
Quote

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.
Title: Re: help using the flash.h library and functions
Post by: AWOL on May 20, 2011, 04:56 pm
I didn't say a String (note the capital), I said a string - a plain old C string.
A null-terminated char array.
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 04:58 pm

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...
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 05:22 pm
I'm at a loss here...  I thought that's what I had the first go round.
Is the problem with this part:
Code: [Select]
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/ (http://arduiniana.org/libraries/flash/)
Title: Re: help using the flash.h library and functions
Post by: AWOL on May 20, 2011, 06:43 pm
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.
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 06:53 pm
I found it, I think.  I can't test it right now, but this compiles:
Code: [Select]
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'
Title: Re: help using the flash.h library and functions
Post by: AWOL on May 20, 2011, 06:56 pm
Quote
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?
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 07:51 pm

Quote
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:

Code: [Select]
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
}

Title: Re: help using the flash.h library and functions
Post by: AWOL on May 20, 2011, 08:50 pm
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?
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 10:30 pm

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

Thanks,

Title: Re: help using the flash.h library and functions
Post by: AWOL on May 20, 2011, 10:53 pm
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)
Code: [Select]

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.
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 20, 2011, 11:47 pm
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"?
Code: [Select]
#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
        }
    }
}


Title: Re: help using the flash.h library and functions
Post by: AWOL on May 21, 2011, 12:13 am
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.
Title: Anyone who understands how the flash.h library works?
Post by: SouthernAtHeart on May 21, 2011, 04:37 am
I'm a self taught programmer, and I had a poor teacher!  :)

I've look at all three examples in the flash example liberary, twice.  I've read the http://arduiniana.org/libraries/flash/ (http://arduiniana.org/libraries/flash/) 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 arduiniana.org/libraries/flash/

Title: Re: help using the flash.h library and functions
Post by: rbtying on May 21, 2011, 04:54 am
Seems to be pretty simple, according to the documentation:

Code: [Select]

LiquidCrystal lcd();
// ...

// in some method or another
  lcd << F("foo, bar, this is a flash string");
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 21, 2011, 05:17 am

Seems to be pretty simple, according to the documentation:

Code: [Select]

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,
Title: Re: help using the flash.h library and functions
Post by: rbtying on May 21, 2011, 05:33 am
Code: [Select]

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");
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 21, 2011, 06:02 am

Code: [Select]

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...
Title: Re: help using the flash.h library and functions
Post by: rbtying on May 21, 2011, 06:18 am
I just tested this, and it does work:

Code: [Select]

#include <Flash.h>

FLASH_STRING(foo, "foobar123456");

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

void loop() {
  for (uint8_t i = 0; i < foo.length(); i++) {
    Serial.print(foo[i]);
    delay(100);
  }
  Serial.print("\r\n");
}


If there's an issue with the code, it's on your LCD's side.
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 21, 2011, 06:42 am
Yes, but I have no idea how to make it work for myself.
I guess I'm stumped on this one.
Worse yet, I feel like I never really explained my problem in such a way that someone understands it, I think that's worse than being stumped! :(
Title: Re: help using the flash.h library and functions
Post by: rbtying on May 21, 2011, 07:05 am
Providing some LCD documentation would really help - we've been approaching this problem as if you just have a Serial output, so if your LCD needs something different, do tell.

Your sendMsg() function can be rewritten to be equivalent to this:
Code: [Select]

void sendMsg(_FLASH_STRING str) {
  for (int i = 0; i < str.length(); i++) {
    Serial.print(str[i]);
  }
}

or, more like your original, like this:
Code: [Select]

void sendMsg(_FLASH_STRING str) {
  int i = 0;
  while (1) {
    Serial.print(str[i]);
    i++;
    if (i == str.length()) break;
  }
}
Title: Re: help using the flash.h library and functions
Post by: SouthernAtHeart on May 21, 2011, 07:19 am
IT WORKS!  IT REALLY WORKS!! 
I don't know what those underscores mean, but this sure is simple.  I looked at the http://arduiniana.org/libraries/flash/ (http://arduiniana.org/libraries/flash/) page again, but don't really see anything pointing me to this answer.  I wish I understood why it works, but there are some thing about this I know I'll never understand. 
Thanks again!
Title: Re: help using the flash.h library and functions
Post by: rbtying on May 21, 2011, 07:21 am
FLASH_STRING(foo, "bar") creates an object of type _FLASH_STRING with a value "bar".  This is explained in the comments section at the bottom of the page, and can be easily figured out if you look at the source code of the header file (Flash.h).