Basic GET request WifiNINA

Hi!
I'm trying to do basic GET-request to an API.
For testing purpose I'm currently using the Star Wars API, but I always receive a status code of -2.

I'm not sure what I'm doing wrong, the board is connected to the WiFi, so is my laptop.
If I use Postman to do the same request I get a correct response.

The JSON response is not really what I need, most important is that I get the succesful response code 200.
I'm already trying for 2 days :sos:

I use the ArduinoHttpClient library and their example of "Simple GET client".
But so far, I don't get it working.

/*
  Simple GET client for ArduinoHttpClient library
  Connects to server once every five seconds, sends a GET request

  created 14 Feb 2016
  modified 22 Jan 2019
  by Tom Igoe
  
  this example is in the public domain
 */
#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

char serverAddress[] = "http://swapi.dev/api/people/1";  // server address
int port = 80;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
  }

  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop() {
  Serial.println("making GET request");
  client.get("/");

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
  Serial.println("Wait five seconds");
  delay(5000);
}

Monitor:

11:41:14.539 -> Wait five seconds
11:41:19.540 -> making GET request
11:41:50.576 -> Status code: -2
11:41:50.576 -> Response: 

(this goes on and on) 

char serverAddress[] = "swapi.dev";

and

client.get("/api/people/1");

Just after a quick peek (I'll have a more detailed look later as soon as I'll have enough time), I supect it's a timeout. But I wonder how Arduino could translate "swapi.dev" into an IP address: if it's your development PC, try to directly put on the URI its IP address instead of that hostname and see if it works (in this case, you could just assign a static address to your PC).

Thank you for your reply! I actually did tried this already.
The weird thing is that I get a response code of 301 (which is "Moved Permanently").
So something is still different as when I send it with postman, which results in 200 OK.

I would expect the same when doing this with the nano 33.
I did tried to print the path I'm actually am requesting, without succes.

I've tried this by entering my own computer IP but no luck? Basically I'm returning than to the original SimpleGET example.

it is because the site requires secure connection (https).
use

int port = 443;

WiFiSSLClient wifi;
1 Like

Hi Juraj,

Okay, so the Star Wars API worked.
However I know call a GET-request to my server which runs at 192.168.2.198/command, port 80

If I fire this with postman it works, but again if I fire it from the nano board, it doesn't.
Do you maybe have a clue?

I've tried a variant as this:

#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h" 

//--> DEFINE NETWORK SETTINGS
char ssid[] = SECRET_SSID;       
char pass[] = SECRET_PASS;    
int keyIndex = 0;           

char server[] = "192.168.2.198";         // server address
int port = 80;                           // 443 in case of API-call / star wars :)

int status = WL_IDLE_STATUS;

//--> DEFINE CONNECTIONS
#define LED_PIN 19         // LED connected to A5
const int RELAY_PIN = 2;   // relay connected to D2
const int BUTTON_PIN = 3;  // button connected to D3

//--> SYSTEM VARIABLES
bool actionAllowed = false;  // default state
bool debug = false;          // extended monitoring

//--> PROGRAM VARIABLES
int actionDuration = 5000;                  // how long action is active
int afterAction = 600000 - actionDuration;  //default is 10 minutes - actionDuration
const String fadeDurationAction = "10";     // Speed duration of X-fade
const String defaultFadeDuration = "1";     // Default duration of x-fade (functions as reset)

WiFiClient client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  analogWrite(LED_PIN, 0);
  digitalWrite(RELAY_PIN, LOW);
  delay(4000);
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to WiFi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /RemoteCommands/SetStorageDeckB=S2P1 HTTP/1.1");
    client.println("Server: MADRIX");
    client.println("Connection: close");
    client.println();
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    // do nothing forevermore:
    while (true);
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

This returns a bad request (400)

And I've tried this:

#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"

//--> DEFINE NETWORK SETTINGS
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;
int keyIndex = 0;            // your network key index number (needed only for WEP)

char serverAddress[] = "192.168.2.198";  // server address
int port = 80;                           // 443 in case of API-call / star wars :)

WiFiSSLClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;  // default state

//--> DEFINE CONNECTIONS
#define LED_PIN 19         // LED connected to A5
const int RELAY_PIN = 2;   // relay connected to D2
const int BUTTON_PIN = 3;  // button connected to D3

//--> SYSTEM VARIABLES
bool actionAllowed = false;  // default state
bool debug = false;          // extended monitoring

//--> PROGRAM VARIABLES
int actionDuration = 5000;                  // how long action is active
int afterAction = 600000 - actionDuration;  //default is 10 minutes - actionDuration
const String fadeDurationAction = "10";     // Speed duration of X-fade
const String defaultFadeDuration = "1";     // Default duration of x-fade (functions as reset)


void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  analogWrite(LED_PIN, 0);
  digitalWrite(RELAY_PIN, LOW);
  delay(4000);

  while (status != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
    status = WiFi.begin(ssid, pass);
  }

  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {  //Check the current connection status
    analogWrite(LED_PIN, 100);            //indicate active connection
    actionAllowed = true;

    digitalWrite(RELAY_PIN, HIGH);
    int state = digitalRead(BUTTON_PIN);

    if (!state && actionAllowed) {
      executeAction();
    }
  } else {
    analogWrite(LED_PIN, 0);
    actionAllowed = false;
  }

  delay(100);
}

void executeAction() {
  actionAllowed = false;
  digitalWrite(RELAY_PIN, LOW);

  //trigger the action
  Serial.println("making GET request");

  //part 1: change fade speed
  client.get("/RemoteCommands/SetFadeTime=" + fadeDurationAction);
  if (debug) {
    debugInformation();
  }
  delay(100);

  //ROUTE 1 - Direct fade to effect:
  //part 2: select effect (Storage 2 Place 1 in this case)
  // client.get("/RemoteCommands/SetStorageDeckB=S2P1");    // enable/disable me
  // if (debug) {
  //   debugInformation();
  // }
  // delay(fadeDuration);                                            // enable/disable me
  //END ROUTE 1

  //ROUTE 2 - "Show" route to effect:
  //part 2: select effect (Go to black first)
  client.get("/RemoteCommands/SetStorageDeckB=S2P99");
  if (debug) {
    debugInformation();
  }
  delay(10000);  // delay as long as fadeDuration

  //part 3: change fade speed (0 set for quick change)
  client.get("/RemoteCommands/SetFadeTime=0");
  if (debug) {
    debugInformation();
  }
  delay(100);

  //part 4: start effect
  client.get("/RemoteCommands/SetStorageDeckB=S2P1");
  if (debug) {
    debugInformation();
  }

  //--> DURATION OF EFFECT
  delay(actionDuration);

  //PART OF ROUTE 2
  //part 5: return to black
  client.get("/RemoteCommands/SetStorageDeckB=S2P99");
  if (debug) {
    debugInformation();
  }
  delay(100);  // delay as long as fadeDuration

  //part 6: reset fade time
  client.get("/RemoteCommands/SetFadeTime=" + defaultFadeDuration);
  if (debug) {
    debugInformation();
  }
  delay(100);
  //END OF ROUTE 2

  //trigger the return-to scene
  Serial.println("making return- GET request");
  client.get("/RemoteCommands/SetFadeToDeckA");
  if (debug) {
    debugInformation();
  }
  //disable button for a while
  delay(afterAction);
}

void debugInformation() {
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
}

Which returns response code -2 again.

Do you have a clue?

shouldn't there be a ? somewhere to separate the path from parameters?
like SetStorageDeck?B=S2P1 or /RemoteCommands?SetStorageDeckB=S2P1?

This /RemoteCommands?SetStorageDeckB=S2P1 actually works with Postman.

But if I try it with Arduino results in:

Starting connection to server...
connected to server
HTTP/1.1 400 Bad Request
Host:
Server: MADRIX
Last-Modified: Thu, 25 May 2023 16:22:54 GMT
Content-Type: text/html

but you have /RemoteCommands/SetStorageDeckB=S2P1 in the sketch

use

client.print("Server: ");
client.println(serverAddress);

Like this?

  if (client.connect(server, port)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /RemoteCommands?SetStorageDeckB=S2P1 HTTP/1.1");
    client.println("Host: 192.168.2.198");
    client.print("Server: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  }

server is defined before setup()

char server[] = "192.168.2.198";         // server address

If I upload this, same result:

Starting connection to server...
connected to server
HTTP/1.1 400 Bad Request
Host:
Server: MADRIX
Last-Modified: Thu, 25 May 2023 17:05:34 GMT
Content-Type: text/html
Content-Length: 72
Cache-Control: max-age=0

sorry I copied your error. it should be "Host:", not "Server:"

    client.println("GET /RemoteCommands?SetStorageDeckB=S2P1 HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();

Still same results...!! So annoying.

Current code:

#include <SPI.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h" 

//--> DEFINE NETWORK SETTINGS
char ssid[] = SECRET_SSID;       
char pass[] = SECRET_PASS;    
int keyIndex = 0;           

char server[] = "192.168.2.198";         // server address
int port = 80;                           // 443 in case of API-call / star wars :)

int status = WL_IDLE_STATUS;

//--> DEFINE CONNECTIONS
#define LED_PIN 19         // LED connected to A5
const int RELAY_PIN = 2;   // relay connected to D2
const int BUTTON_PIN = 3;  // button connected to D3

//--> SYSTEM VARIABLES
bool actionAllowed = false;  // default state
bool debug = false;          // extended monitoring

//--> PROGRAM VARIABLES
int actionDuration = 5000;                  // how long action is active
int afterAction = 600000 - actionDuration;  //default is 10 minutes - actionDuration
const String fadeDurationAction = "10";     // Speed duration of X-fade
const String defaultFadeDuration = "1";     // Default duration of x-fade (functions as reset)

WiFiClient client;

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);

  analogWrite(LED_PIN, 0);
  digitalWrite(RELAY_PIN, LOW);
  delay(4000);
  
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }
  Serial.println("Connected to WiFi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    //try:
    // client.println("GET 192.168.2.198/RemoteCommands?SetStorageDeckB=S2P1 HTTP/1.1");
    //original:
    client.println("GET /RemoteCommands?SetStorageDeckB=S2P1 HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println();
  }
}

void loop() {
  // if there are incoming bytes available
  // from the server, read them and print them:
  while (client.available()) {
    char c = client.read();
    Serial.write(c);
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting from server.");
    client.stop();

    // do nothing forevermore:
    while (true);
  }
}


void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

Monitor:

Starting connection to server...
connected to server
HTTP/1.1 400 Bad Request
Host:
Server: MADRIX
Last-Modified: Fri, 26 May 2023 08:38:12 GMT
Content-Type: text/html
Content-Length: 72
Cache-Control: max-age=0

I've also tried some variations, but still it ends up the same.
I was expecting this would work way easier as thought before..

Would be really happy if someone sees the problem. I'll continuing with testing variations...

Postman works

check the web server logs if there are some details about why the request is bad

Hi Juraj, sorry how can I do this?

The server side is not logging. It's just an "open" api waiting for matching HTTP-calls.

I've tried the SimpleGet example again.. Just to go back to basic

/*
  Simple GET client for ArduinoHttpClient library
  Connects to server once every five seconds, sends a GET request

  created 14 Feb 2016
  modified 22 Jan 2019
  by Tom Igoe
  
  this example is in the public domain
 */
#include <ArduinoHttpClient.h>
#include <WiFiNINA.h>

#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;

char serverAddress[] = "192.168.2.198";  // server address
int port = 80;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
  }

  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop() {
  Serial.println("making GET request");
  client.get("/RemoteCommands?SetStorageDeckB=S2P1");

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
  Serial.println("Wait five seconds");
  delay(5000);
}

response in monitor:

IP Address: 192.168.2.143
making GET request
Status code: -3
Response: 
Wait five seconds
making GET request

What is Status code: -3?

Hmm thanks... Weird..