0

I'm actually learning ESP32, its features and APIs.

My objective with this program is basically: to test some knowledges and techniques I've already developed and try, for the first time, an IoT application.

So, I have a class called myMQTT, it has two structs properties (NETWORK and MQTT):

class myMQTT{
  public:

  struct NETWORK
  {
    char *SSID, *PASSWORD, *IP;
  } NETWORK;

  struct MQTT
  {
    char *SEVER, *TOPIC, *USER, *PASSWORD;
    int PORT;
  } MQTT;

  myMQTT(){}

  void CONNECT(){

   }

};

How you can see, the structures give me pointers that I'd like to point to strings, like this:

void MQTTConnect(){

  myMQTT CONNECTION;

  CONNECTION.NETWORK.SSID = "SSID";  
  CONNECTION.NETWORK.PASSWORD = "1234";

  CONNECTION.MQTT.SEVER = "MQTT_SEVER";
  CONNECTION.MQTT.PORT = 1234;

  CONNECTION.MQTT.USER = "ESP32 | USER";
  CONNECTION.MQTT.PASSWORD = "ESP32 | PASS";
  CONNECTION.MQTT.TOPIC = "TEST";

  CONNECTION.CONNECT();

}

But the compiler gives me this warning:

ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

In examples on the internet, people usually code a MQTT connection using the libraries Wifi.h and PubSubClient.h, passing pointers as arguments to the classes methods:

#include <WiFi.h>
#include <PubSubClient.h>

// Replace the next variables with your SSID/Password combination
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Add your MQTT Broker IP address, example:
//const char* mqtt_server = "192.168.1.144";
const char* mqtt_server = "YOUR_MQTT_BROKER_IP_ADDRESS";

WiFiClient espClient;
PubSubClient client(espClient);

//CODE...

WiFi.begin(ssid, password);
client.setServer(mqtt_server, 1883);

//CODE...

Ref.: https://randomnerdtutorials.com/esp32-mqtt-publish-subscribe-arduino-ide/

I've already tried to use char arrays and Strings (Arduino Declaration).

I'd like to use the struct properties of my class to instance the other classes. How could I do that?

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • The question to you is do you understand why you get this error: `ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]`? – PaulMcKenzie Feb 03 '20 at 00:49
  • It won't work well if you or some other function attempts to change a character within that string, since string-literals are constants. – PaulMcKenzie Feb 03 '20 at 00:56
  • Please don't tag `c` if you clearly are writing C++, not C. – walnut Feb 03 '20 at 01:00
  • You aren't assigning a string to a char pointer. You are doing the opposite. – user207421 Feb 03 '20 at 01:01
  • Well, I know that it works well if you initialize the pointer with the string. ``` char pointer* = "String"; ``` I also know that to assign a string to pointer I use this structure: ``` char *str; str = "GfG"; ``` So, if I'm not wrong, I can declarate a pointer and initializate it after. But I think you're right and I don't understand what is happening. – Gabriel Godoi Feb 03 '20 at 01:02
  • 1
    First, why are you resorting to low-level character pointers at the class level? I understand if the underlying API requires a pointer to a character, but why impose that restriction on what seems to be a wrapper class? – PaulMcKenzie Feb 03 '20 at 01:04
  • @GabrielGodoi `char* str; str = "GfG";` doesn't work either. You can only assign string literals to `const char*`, not `char*`. Also you should prefer `std::string` over `char*` for strings. – walnut Feb 03 '20 at 01:04
  • @PaulMcKenzie, I thought that would be better than declare global variables or even locals, and restrict my code. Through little alterations this class would give me the possibility to connect to another MQTT Broker at running time. I'm also thinking about recycling and maintenance. – Gabriel Godoi Feb 03 '20 at 01:30
  • @walnut, could you enlighten me about the use of `std::string`? – Gabriel Godoi Feb 03 '20 at 01:30
  • @GabrielGodoi E.g.: `char *SSID, *PASSWORD, *IP;` -> `std::string SSID, PASSWORD, IP;`. This is much easier to work with than `char*`. I recommend you to work through [a good C++ introductory book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – walnut Feb 03 '20 at 01:38
  • As mentioned, replace all of those `char *` with `std::string`. When you actually call the API (regardless of what the API is supposed to do), if that API requires a character pointer, then you simply call it using the `c_str()` member function for `std::string`. That is how many, if not all high-level C++ wrappers for any API handles strings. There is no need to get into the weeds of `char *` pointers at the wrapper-class level. – PaulMcKenzie Feb 03 '20 at 01:43
  • Thank you all so much! You really helped me. I'll use the tips. – Gabriel Godoi Feb 03 '20 at 02:02

1 Answers1

3

You do everything right, but because of a bug in Arduino builder in IDE 1.8.11 a wrong library is used. Instead of the ESP32 WiFi library, it uses the old Arduino WiFi library. In this library the parameters in WiFi.begin have type of char*. It was not a problem while the conversion from const char* to char* was reported only as a warning. But in esp boards packages it is an error.

The solution is to install the previous version of Arduino IDE 1.8.10 or 1.8.9.

Juraj
  • 3,490
  • 4
  • 18
  • 25