0
votes

I am using Arduino IDE to program an ESP8266, which is connected to a number of sensors. The end goal is to publish the sensor data via MQTT.

I have an array with sensor names:

const char* sensorIDArray[] = { // Used for the MQTT string
  "DS18B20_1",
  "DS18B20_2",
  "DS18B20_3",
  "DHT22_t",
  "DHT22_h",
  "Hygrometer_1",
  "Hygrometer_1",
  "Hygrometer_1",
  "Hygrometer_1",
  "Battery"
};

I have another array which is populated with some sensor readings:

float readingsArray[10]; //Saving the last measurement
/* Array element reminder:
 *
 * readingsArray[0] = DS18B20_1
 * readingsArray[1] = DS18B20_2
 * readingsArray[2] = DS18B20_3
 * readingsArray[3] = DHT22_t
 * readingsArray[4] = DHT22_h
 * readingsArray[5] = Hygrometer_1
 * readingsArray[6] = Hygrometer_2
 * readingsArray[7] = Hygrometer_3
 * readingsArray[8] = Hygrometer_4
 * readingsArray[9] = Battery
 */

I am then trying to send the reading to a MQTT client by looping through each element of the array:

char readingVal;
for (int i = 0; i<10; i++) {
    dtostrf(readingsArray[i], 7, 2, readingVal); //convert float to string
    char* topic = "ESPlant/" + sensorIDArray[i]; //concatenate MQTT topic
    client.publish(topic, readingVal);  //publish MQTT topic and sensor reading
    delay(10); //delay to ease burden on MQTT server.
}  

I am new to C++ and Arduino in general. I am very confused by char, char* and arrays of both, despite many hours of googling. The client.publish is limited to a String only (!!!) for the argument readingVal above. The error message is:

invalid conversion from 'char' to 'char*' [-fpermissive]

1
Why are you not using the Arduino String class? Why is readingVal of type char, when you are going to store a string in it? How do you expect char* topic = "ESPlant/" + sensorIDArray[i] to work? - Arnav Borborah
char* topic = "ESPlant/" + sensorIDArray[i]; -- This does not do concatenation in C++. To be honest with you, your issue has nothing to do with MQTT, Arduino, or anything else except, simple, basic, C++ that you will find in any textbook. - PaulMcKenzie
I started going down the route of String class but it seemed to be getting more complicated, can you give an example? I expect the topic to be a concatenation of for example ESPlant/ and DS18B20_1 for location 0. So the whole topic will read: ESPlant/DS18B20_1 - Edward Hammock
PaulMkenzie, many thank for your comment. I am not alone in finding this site very unwelcoming. Please can someone assist me with something constructive? Thanks. - Edward Hammock
@EdwardHammock C++ is not JavaScript or Python. You have two char pointers, and you do not concatenate those using +. Seems as if you're trying to write C++ by using other computer languages as a guide. That never works. The proper way to concatenate strings is to either use a string class to represent strings that has overloaded operator +, or if using string literals and char arrays, use strcat. But this should be covered in any good C++ tutorial, book, or website. - PaulMcKenzie

1 Answers

1
votes

As others have hinted at in the comments, it could not hurt to read a few Arduino tutorials. If you are not familiar with c "strings" you should definitely try to steer clear of them.

The String class was really created for those who don't really know c/c++. As you seem to know the Arduino language really is just c++, but they try to simplify things for those not familiar with it.

dtostrf() is a pretty complex function if you are not up on c/c++. For example the last parameter is supposed to be a "buffer", big enough to hold the result of the conversion. In your example you are passing a pointer with no memory allocated to it at all. You can avoid this using String.

String allows you do just to something like the following (from the tutorial here)

int sensorValue = analogRead(A0); 
String stringOne = "Sensor value: ";
String stringThree = stringOne + sensorValue;
Serial.println(stringThree);

When you reach a point that you need to pass a String to a function expecting a char* (c/c++ string), you can do something like this.

someFunctionNeedingACharArray(stringOne.c_str()); 

The c_str() method converts the String to a c/c++ style char* "string"

Hope this helps.