Where to set variable on HTTP request

This is example code of led blinking . variable interval is already initialized in code. But I want to set variable interval on API call, Idon't understand how to do it

const int ledPin =  LED_BUILTIN;           // the number of the LED pin
int ledState = LOW;                        // ledState used to set the LED
unsigned long previousMillis = 0;         // will store last time LED was updated
const long interval = 1000;               // interval at which to blink (milliseconds)

void setup() {

  pinMode(ledPin, OUTPUT);                // set the digital pin as output:
}

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Here I have tried

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

EthernetClient client;

int    HTTP_PORT   = 80;
String HTTP_METHOD = "GET"; // or POST
char   HOST_NAME[] = "makegjjgj.com";
String PATH_NAME   = "/index";

int Delay;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);                // set the digital pin as output:
  // connect to server on port 80:
  if (client.connect(HOST_NAME, HTTP_PORT)) {
    // if connected:
    Serial.println("Connected to server");
    // make a HTTP request:
    // send HTTP header
    client.println(HTTP_METHOD + " " + PATH_NAME + " HTTP/1.1");
    client.println("Host: " + String(HOST_NAME));
    client.println("Connection: close");
    client.println(); // end HTTP header

    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
        StaticJsonDocument<24> doc;

        DeserializationError error = deserializeJson(doc, input);

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

        Delay = doc["Delay"]; // 5
      }

      // the server's disconnected, stop the client:
      client.stop();
      Serial.println();
      Serial.println("disconnected");
    } else {// if not connected:
      Serial.println("connection failed");
    }
  }

  void loop() {

  }

response

{
    "Delay": 5000
}

@johnwasser

My question where should I read data from server in main loop or setup ?

When I read in setup I don't get data while when I read in main loop I get the data, please clarify approch

You are trying to deserialize "input", what and where is it?? If you have forgotten, here is a remainder:

You should try to find examples on "http how to post json" and "http how to get json"..

1 Like

Assuming it works and that Delay is a global variable

  • if you read in the setup then you will read the information only once and use that for the rest of the code.
  • if you read in the loop, it will slow somewhat your code - possibly messing with the timing if you want ultra short delays, but it will be updated every time based on what the server sends back
1 Like

Hi Danois90

I didn't forget that link,

it is confirmed i have to read the response in setup. I don't understand why I get data in loop while I can't find in setup.

I need to read the data in setup

what could be the reason i get data in loop but not when i try in setup?

Apparently you did because your question is answered in it.

"interval" should not be declared "const". If it is only required to be set once, set it in "setup()". If it may be changed during runtime, set it in "loop()" but make it in intervals not for each iteration. How to recover the value can be deduced from the other thread.

from the code you posted, you were getting a response from the setup

may be you try multiple times in the loop?

I don't have my laptop in hand but I show you two examples, first pattern work for me

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>


byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 10, 20);
IPAddress server(192, 168, 10, 22);


EthernetClient client;

int    HTTP_PORT   = 80;
String HTTP_METHOD = "GET"; // or POST
String PATH_NAME   = "/index";
String queryString = String("?192");

int Delay;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  client.connect(server,  8001);

  delay(1500);

  if (client.connected()) {
    Serial.println("connected");;
    client.println(HTTP_METHOD + " " + PATH_NAME +  queryString + " HTTP/1.1");
    client.println("Host: " + String(server));
    client.println(); // End of header

  } else {// if not connected:
    Serial.println("connection failed");
  }
}

void loop() {

  if (client.available()) {
    // read an incoming byte from the server and print it to serial monitor:
    char c = client.read();
    Serial.print(c);
    StaticJsonDocument<24> doc;

    DeserializationError error = deserializeJson(doc, client);

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

    Delay = doc["Delay"]; // 5
  }

}

I don't know why this doesn't work for me I don't know why I can't read data with following pattern

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>


byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 10, 20);
IPAddress server(192, 168, 10, 22);


EthernetClient client;

int    HTTP_PORT   = 80;
String HTTP_METHOD = "GET"; // or POST
String PATH_NAME   = "/index";
String queryString = String("?192");

int Delay;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  client.connect(server,  8001);

  delay(1500);

  if (client.connected()) {
    Serial.println("connected");;
    client.println(HTTP_METHOD + " " + PATH_NAME +  queryString + " HTTP/1.1");
    client.println("Host: " + String(server));
    client.println(); // End of header

    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
        StaticJsonDocument<24> doc;

        DeserializationError error = deserializeJson(doc, client);

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

        Delay = doc["Delay"]; // 5
      }
    
    } 
  }else {// if not connected:
      Serial.println("connection failed");
    }
}

void loop() {

}

what do you see in the second case?

Is either the right approach? In your sketch the Arduino acts as a client. How will it know when the delay should be updated? It would have to continuously send requests to the server, which would be like a DoS attack, in order to detect a change in the required delay.

Would it not be better to have the Arduino act as a server? That way, a remote client can request a change to the delay when it needs to change. The updated delay value could be indicated as a parameter in the request, so that no JSON message is needed.

I didn't see the data on the serial monitor when I tested. I don't have Arduino right now, I can test using some print statement and tell you when I'm at homey

As you where told multiple times in the other topic, you do not mind the HTTP response (including headers), all you do is read one character and then "deserializeJson" has to handle the rest - which is invalid JSON. The solution to this problem was provided in the other topic, so..........

I get error Invalid response

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>


byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 10, 20);
IPAddress server(192, 168, 10, 22);


EthernetClient client;

int    HTTP_PORT   = 8001;
String HTTP_METHOD = "GET"; // or POST
String PATH_NAME   = "/index";
String queryString = String("?192");

int Delay;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  client.connect(server,  8001);

  delay(1500);

  if (client.connected()) {
    Serial.println("connected");;
    client.println(HTTP_METHOD + " " + PATH_NAME +  queryString + " HTTP/1.1");
    client.println("Host: " + String(server));
    client.println(); // End of header

    // Check HTTP status
    char status[32] = {0};
    client.readBytesUntil('\r', status, sizeof(status));
    if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
      Serial.print(F("Unexpected response: "));
      Serial.println(status);
      client.stop();
      return;
    }

    // Skip HTTP headers
    char endOfHeaders[] = "\r\n\r\n";
    if (!client.find(endOfHeaders)) {
      Serial.println(F("Invalid response"));
      client.stop();
      return;
    }
    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
        StaticJsonDocument<24> doc;

        DeserializationError error = deserializeJson(doc, client);

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

        Delay = doc["Delay"]; // 5
      }

    }
  } else {// if not connected:
    Serial.println("connection failed");
  }
}

void loop() {

}

Anybody have any idea what's going wrong in sketch.

Why it's not working inside setup?

did you see this being printed ?

or you saw this

    Serial.println("connected");;

and if it connected, did you see "Unexpected response" or "Invalid response"?

why do you have delay(1500);?

1 Like

First i see the "connected" display on monitor
And then i see "Unexpected response"

I looked in many source codes. Ethernet module takes time to initialize

may be make real cString out of this by adding a trailing null char (and check the returned value to see if you got a timeout)
once done, print it as well to see what you received

I didn't understand how to do this in code?

All C strings are null terminated

    char status[32+1] = {0}; // +1 for the trailing null char
    int count = client.readBytesUntil('\r', status, sizeof(status) - 1);
    if (count == 0 ) {
      // error timeout
    } else {
      status[n] = '\0'; // terminate the cString
    }

not saying this is the issue, but could if you fill up the buffer

printing then the buffer would give you a sense for what you really get back

1 Like

Set up is not in my hand so I am just making test program that i would try

#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>


byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 10, 20);
IPAddress server(192, 168, 10, 22);


EthernetClient client;

int    HTTP_PORT   = 8001;
String HTTP_METHOD = "GET"; // or POST
String PATH_NAME   = "/index";
String queryString = String("?192");

int Delay;

void setup() {
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  client.connect(server,  8001);

  delay(1500);

  if (client.connected()) {
    Serial.println("connected");;
    client.println(HTTP_METHOD + " " + PATH_NAME +  queryString + " HTTP/1.1");
    client.println("Host: " + String(server));
    client.println(); // End of header

    // Check HTTP status
    char status[32 + 1] = {0}; // +1 for the trailing null char
    int count = client.readBytesUntil('\r', status, sizeof(status) - 1);

    if (count == 0 ) {
      // error timeout
    } else {
      //status[n] = '\0'; // terminate the cString
      status[33] = '\0'; // terminate the cString
      
    }

    if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
      Serial.print(F("Unexpected response: "));
      Serial.println(status);
      client.stop();
      return;
    }

    // Skip HTTP headers
    char endOfHeaders[] = "\r\n\r\n";
    if (!client.find(endOfHeaders)) {
      Serial.println(F("Invalid response"));
      client.stop();
      return;
    }
    while (client.connected()) {
      if (client.available()) {
        // read an incoming byte from the server and print it to serial monitor:
        char c = client.read();
        Serial.print(c);
        StaticJsonDocument<24> doc;

        DeserializationError error = deserializeJson(doc, client);

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

        Delay = doc["Delay"]; // 5
      }

    }
  } else {// if not connected:
    Serial.println("connection failed");
  }
}

void loop() {

}

n was not declared anywhere I am adding null terminator at 33 position end of string