Pages: [1] 2   Go Down
Author Topic: help using the flash.h library and functions  (Read 2427 times)
0 Members and 1 Guest are viewing this topic.
South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In my code, I have lots of messages that I send to my LCD as in the following example:
Code:
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:
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/
« Last Edit: May 20, 2011, 12:02:55 am by SouthernAtHeart » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I tried this, but it's still not workig:
Code:
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.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm at a loss here...  I thought that's what I had the first go round.
Is the problem with this part:
Code:
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/
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I found it, I think.  I can't test it right now, but this compiles:
Code:
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'
« Last Edit: May 20, 2011, 11:56:08 am by SouthernAtHeart » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
}
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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,

Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

South East USA
Offline Offline
God Member
*****
Karma: 5
Posts: 655
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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
        }
    }
}

Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 309
Posts: 26487
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: May 20, 2011, 05:15:33 pm by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Pages: [1] 2   Go Up
Jump to: