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;
}
}
}
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.
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();
}
}
User contributions licensed under CC BY-SA 3.0