Error in Arduino IDE using strncmp function

1

I am using the following code to compare two strings and get the error:

>  #define _EXFUN(name, proto)  name proto
> 
>                               ^
> 
> exit status 1 invalid conversion from 'char' to 'const char*'
> [-fpermissive]

As I understand strncmp function is looking for 'const char*', but when I cast the 'chat' to 'const char*' I get weird results in serial monitor:

> Exception (28): epc1=0x40209035 epc2=0x00000000 epc3=0x00000000
> excvaddr=0x00000030 depc=0x00000000
> 
> ctx: cont  sp: 3ffffda0 end: 3fffffd0 offset: 01a0
> 
> >>>stack>>> 3fffff40:  40100fee 3ffe8c3c 000026fe 00000000   3fffff50:  401011c4 000026fe 3ffee75c 00000000   3fffff60:  3ffe8c70 3ffee75c
> 3ffe850c 3ffee75c   3fffff70:  3ffee6e0 3ffee7c8 40202fe8 3fffefb0  
> 3fffff80:  402014ce 00000001 00000001 402014c3   3fffff90:  00002580
> 3ffee6dc 00000014 4020292c   3fffffa0:  feefeffe 00000000 3ffee7c0
> 3ffee7c8   3fffffb0:  3fffdad0 00000000 3ffee7c0 40203074   3fffffc0: 
> feefeffe feefeffe 3ffe850c 401000e5   <<<stack<<< ?)βΈ®

The code itself:

#include <Wire.h>
#define I2C_ESP_ADDRESS 8
int count=0;
char model;
char reading;
char incoming;

void setup()
{
    Serial.begin(9600);
    Wire.begin(5,4);//Change to Wire.begin() for non ESP.
    /*model[0] = "e";
    model[1] = "0";
    for (int i = 1; i < 20; i++) {
        model[i] = 0;
    }*/
}

void loop()
{     
    Wire.requestFrom(I2C_ESP_ADDRESS,20);
    while (Wire.available())
    {
        delay(1);
        incoming = Wire.read();

        if (strncmp(incoming,"elxxxxxxxxxxxxxxxxxx",2) == 1 ) {
            model = incoming;
        } else { 
            reading = incoming;
        }
    }
}
c++
c
arduino
strncmp
asked on Stack Overflow Sep 19, 2018 by Shota Kvaratskhelia • edited Sep 24, 2018 by Hossein Golshani

2 Answers

0

On Arduino, Wire.read() reads a single byte only (char).

strncmp wants to compare two zero-terminated strings (const char *), and doesn't really deal with single characters, which is why you get the compiler error: It tells you that you can't just treat a char as if it was a const char *.

When you force it to do so anyways by casting to const char *, it treats the value of that single byte as a pointer, and strncmp reads places in memory that it probably isn't supposed to (whatever is at the address given by the value of the byte). That causes the crash that you saw.

Fundamentally, there seem to be a couple of mix-ups between strings (a sequence of bytes with a null byte at the end) and characters (just a single byte) here. In memory, the difference looks like this:

          +----+
char '*': | 42 |
          +----+

              +----+----+----+----+
string "***": | 42 | 42 | 42 |  0 |
              +----+----+----+----+

Both incoming and model are currently only capable of holding a single character. If you want to store multiple characters, consider using an array (char incoming[SIZE], where SIZE is the maximum size of the data).

Then, you can write incoming bytes to subsequent positions in the array, and ultimately compare the entire string at once using strncmp like you did before.

If you are really only looking to compare individual bytes as they come in, just compare them directly (incoming == 'x') or keep track of an index into your comparison string that you reset to zero at every mismatch.

answered on Stack Overflow Sep 19, 2018 by hlt
0

So this is the correct code that worked for me:

void loop() {

 Wire.requestFrom(I2C_ESP_ADDRESS,18);
 while (Wire.available()){



 incoming = Wire.read();
Serial.print(incoming);
 //Serial.print(incoming);

 //sprintf (incomingArray, "%.20", incoming);

  if ( incoming == 'e') {
    modelArray[0] = 'e';


    for (int i = 1; i < 18; i++ ){
      modelArray[i] = (char) Wire.read();
      Serial.print(modelArray[i-1]);
    }
  } 



    if ( incoming == 'a') {
    readingArray[0] = 'a';
   // Serial.print("Got Reading: ");

    for (int j = 1; j < 18; j++ ){
      readingArray[j] = (char) Wire.read();
      Serial.print(readingArray[j-1]);
    }

    Serial.println();

    }


}
answered on Stack Overflow Sep 24, 2018 by Shota Kvaratskhelia

User contributions licensed under CC BY-SA 3.0