How to create : int strcmp(const char*, const __FlashStringHelper*)'

Hi,

How can I compare string from Serial input with PROGMEM string? I have a code which splits serial input into CMD and ARG ( comma "," being the delimiter)

This code works:

if(strcmp(CMD,"STSCST")==0)//Set ScanStep
    {
       doSomething();//....
}

But this does not (as soon as I put the String in F() function).

if(strcmp(CMD,F("STSCST"))==0)//Set ScanStep
    {
       doSomething();//....
}

Error: SerialLayer:129: error: cannot convert 'const __FlashStringHelper*' to 'const char*' for argument '2' to 'int strcmp(const char*, const char*)'

Would I need to overload the strcmp function?

Would I need to overload the strcmp function?

Yes. And, since they are part of the standard C library, that is not a good idea. Rethinking what you are trying to do is a better idea.

What are you trying to do?

There are _P versions of many of the strXXX functions.

PaulS: Yes. And, since they are part of the standard C library, that is not a good idea. Rethinking what you are trying to do is a better idea.

What are you trying to do?

There are _P versions of many of the strXXX functions.

I am trying to compare string that is provided in Serial (Serial.read()) with string saved as F("") .

How do I use strcmp_P? 1. strcmp_P(CMD,F("FRMEM"))==0 2. strcmp_P(F("FRMEM"),CMD)==0 3. strcmp_P(CMD,"FRMEM")==0

Only 3rd one compiles but how does that help?

but how does that help?

The suggestion to use the _P versions was meant to tell you that you need to EXPLICITLY store the strings to be compared to in PROGMEM.

It doesn't help that you won't explain what you are trying to do. If you are comparing a lot of string constants, then just perhaps strings are NOT the way to go.

Just comparing strings for equality is a simple loop, you can stick progmem_read_byte in such a loop:

int i = 0 ;
while (a[i])
{
  char bc = progmem_read_byte (b, i) ;
  if (a[i] != bc) 
    return false ;
  i++ ;
}
return progmem_read_byte (b, i) == 0 ;

Warning, untested code snippet, take with a pinch of salt...

PaulS: The suggestion to use the _P versions was meant to tell you that you need to EXPLICITLY store the strings to be compared to in PROGMEM.

It doesn't help that you won't explain what you are trying to do. If you are comparing a lot of string constants, then just perhaps strings are NOT the way to go.

I am creating a sketch(Serial framework custom library) which will allow user to pass a COMMAND,ARGUMENT string. Arduino will then parse these into CMD and ARG variables. Next step is to compare the value in CMD with predefined char[] to determine the control of sketch.

For e.g. my sketch takes the following input:

MOVMOT1,1000

If this string is passed on serial, then arduino will work out to move motor #1 by 1000 steps

CMD will contain value as "MOVMOT" and then in loop, the code looks like

if(strcmp(CMD,"MOVMOT1")==0)
    {
      int chce = ((String)ARG).toInt();
      moveMotor(1,chce);
    }
    else if(strcmp(CMD,"MOVMOT2")==0)
    {
      int chce = ((String)ARG).toInt();
      moveMotor(2,chce);
}...

All this works but I would like to store the strings defined as "MOVMOT1" using the F() function, so they are not saved in SRAM

I am able to do this

const char string_MOVMOT1[] PROGMEM = "MOVMOT1";
const char string_MOTMOT2[] PROGMEM = "MOVMOT2";

....
if(strcmp_P(CMD,string_MOVMOT1)==0)
    {
      int chce = ((String)ARG).toInt();
      moveMotor(1,chce);
    }
    else if(strcmp_P(CMD,,string_MOVMOT2)==0)
    {
      int chce = ((String)ARG).toInt();
      moveMotor(2,chce);
}...

I am not sure that if the above code will move the strings into flash!

Hope this explains! (Sorry I thought that my previous post explained this).

N.B. I have to deal with 100 commands that user can enter; which means 100 strings to compare and decide!

I am not sure that if the above code will move the strings into flash!

That's what PROGMEM does.

Things like "MOVMOT, 1, 100", instead of "MOVMOT1, 100" would cut down on the number of choices that you need to support.

Not pissing away resources on Strings would save SRAM, too. If CMD is a char array, is it safe to assume that ARG is too? If so, atoi() and atof() don't require pissing away resources wrapping a string in a String just to make use of the data.

PaulS: That's what PROGMEM does.

How do I make sure? There are too many examples which shows different usage of strcmp_P. The function even works if the String is not declared as ProgMem.. I think I should assign a large string in ProgMem and then call

int freeRam () {
  extern int __heap_start, *__brkval;
  int v;
  return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

to see its outcome..