0

Right now I need to create an if statement that can compare a char pointer with a string like the following statement:

if (Start == "on"){
    Serial.println("virker");
}

The problem is that this simple sentence does not work. The variable Start is a string containing the word on that I get from a web page that sends a JSON object via a AJAX request. The object looks like this when I receive it:

{"start":"on","relay":"off","computer_alert":"off","esp_alert":"off","alarm1":{"tilstand":"off","tid":"null"},"alarm2":{"tilstand":"off","tid":"null"},"alarm3":{"tilstand":"off","tid":"null"}}

I've tried to give Start a value inside the program and that works. My entire code can be seen below:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <Hash.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ArduinoJson.h>

const char* ssid     = "ESP8266-Access-Point";
const char* password = "123456789";
const int buzzer = 0;
const int relay = 6;
const char* Start;
int d;
const char* test = "on";

const char* PARAM_INPUT_1 = "Json";

AsyncWebServer server(80);

void ekstern() {
    const int buzzer = 0;
    const int relay = 6;
    pinMode(relay and buzzer, OUTPUT);
}


void setup() {
    ESP.eraseConfig();
    Serial.begin(9600);
    WiFi.softAP(ssid, password);

    IPAddress IP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(IP);

    if(!SPIFFS.begin()){
        Serial.println("An Error has occurred while mounting SPIFFS");
        return;
    }
    server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(SPIFFS, "/HTML.html");
    });
    server.on("/JQ", HTTP_GET, [](AsyncWebServerRequest *request){
       request->send(SPIFFS, "/JQ.js");
    });
    server.on("/CSS", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(SPIFFS, "/CSS.css");
    });
    server.on("/GET", HTTP_GET, [] (AsyncWebServerRequest *request) {
        String json;
        if (request->hasParam(PARAM_INPUT_1)) {
            json = request->getParam(PARAM_INPUT_1)->value();
            Serial.println(json);
        }
        request->send(200, "text/plain", "OK");

        StaticJsonDocument<384> doc;

        DeserializationError error = deserializeJson(doc, json);

        if (error) {
            Serial.print(F("deserializeJson() failed: "));
            Serial.println(error.f_str());
            return;
        }

        Start = doc["start"]; // "off"
        const char* relay = doc["relay"]; // "off"
        const char* computer_alert = doc["computer_alert"]; // "off"
        const char* esp_alert = doc["esp_alert"]; // "off"
    
        const char* alarm1_tilstand = doc["alarm1"]["tilstand"]; // "off"
        long alarm1_tid = doc["alarm1"]["tid"]; // 3184358
    
        const char* alarm2_tilstand = doc["alarm2"]["tilstand"]; // "off"
        long alarm2_tid = doc["alarm2"]["tid"]; // 3184358
    
        const char* alarm3_tilstand = doc["alarm3"]["tilstand"]; // "off"
        long alarm3_tid = doc["alarm3"]["tid"]; // 3244358
        Serial.println(alarm3_tid);
        Serial.println(alarm3_tilstand);
    });
  
    server.begin();
}
void loop(){
    if (Start == "on"){
        Serial.println("virker");
    }
    Serial.println(Start);
    Serial.println("hallo");
    delay(5000);
}

I don't think it makes any difference, but I am using the ESP8266.

gre_gor
  • 6,669
  • 9
  • 47
  • 52
  • 4
    [`strcmp()`](https://en.cppreference.com/w/c/string/byte/strcmp) – 001 Feb 15 '22 at 14:40
  • https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/ https://arduinojson.org/v6/how-to/use-string-view-on-esp32/ – Marek R Feb 15 '22 at 14:45

2 Answers2

0

You can convert the value in the pointer to a String by useing the following command,

String();

For me it did not work when i used the following command,

strcmp();

The command just gave a exception (28) error. I feel a little bit stupid because i am pretty sure i used the String() before and it didnt work, but i must have done something else wrong because it wroks now. The solution was to write the if statement like this,

if(String(Start)=="on"){
Serial.println("virker");

}

UPD: The methode I described above does work, but stackoverflow user dpronin made me aware that the methode has some problems. The problem came from when the program received the JSON object because just saving the pointer made the program buggy. The solution was useing this command,

strncpy();

Which copies the string to another variable instead of just pointing to the memory addresse. When I changed to this methode my code worked. I will also say that it may be the reason why the following command didnt work,

strcmp();

I have tested it again after the changes.

  • 2
    How did you use `strcmp`? The correct usage would be something like `strcmp(a, b) == 0`. Is that what you did? – CoffeeTableEspresso Feb 15 '22 at 23:41
  • `String` is a C++ class in the Arduino library. A *string literal* like `"on"` is not a `String`, it is a *C-style string*. A `char*` value can also represent a C-style string. You compare C-style strings with `strcmp`. You can also convert one ot both of the C-style string operands to `String` and use `==`. – n. m. could be an AI Feb 18 '22 at 22:51
0

Your doc is a stack variable that will vanish as just you leave the request handler GET. This means that you will absolutely definitely access to already dangling pointer, which Start variable stores, in loop function because it points to the already not existing doc["start"]. You have to preserve data from doc["start"] rather than the pointer doc["start"] contains. For that you need to define Start as an array of chars and then use strncpy to copy characters from the doc["start"] into Start variable. Further, in loop function you need to use strcmp or strncmp to compare "on" with characters in the variable Start. As easy as it gets

UPD: Also GET request MUST NOT change the state of your server conventionally, therefore Start variable is not supposed to be altered

dpronin
  • 275
  • 1
  • 6