I'm trying to retrieve METAR (weather) info from my local airport using a MKR1000 and WiFi101 library.
My problem is that I make a request in HTTP while it looks like the server expects a request in HTTPS.
Below is the answer I get :
Starting connection to server...
connected to server
HTTP/1.1 302 Object Moved
Location: https://tgftp.nws.noaa.gov/data/observations/metar/stations/XXXX.TXT
Content-Type: text/html
Cache-Control: private
Connection: close
<head><body> This object may be found <a HREF="https://tgftp.nws.noaa.gov/data/observations/metar/stations/XXXX.TXT">here</a> </body>
disconnecting from server.
Am I using the right library ?
Is my MKR1000 able to make a HTTPS connection or shall I upgrade to MKR1010 ?
If yes, Is this why MKR1010 embeds an encryption chip ?
The MKR1000 has the same ATECC508 CryptoAuthentication chip as the MKR WiFi 1010. In the case of the MKR1000, it's integrated into the ATSAMW25 module, while on the MKR WiFi 1010 it's a separate chip.
I don't need to change my arduino.
The cryptochip is for WIFI connection, not for internet, HTTP connection, right ?
I gave a try to WiFiSSLClient.
I change from the port 80 to 443 to the server.
But now, I can't connnect anymore to the server.
Here is my code :
#include <SPI.h>
#include <WiFi101.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS)
//char server[] = "www.google.com"; // name address for Google (using DNS)
char server[] = "tgftp.nws.noaa.gov"; // NOAA server for METAR
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiSSLClient client;
//******************************** printWiFiStatus() **********************************
void printWiFiStatus() {
// 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);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
//**************************************** setup() **********************************
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// 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.connectSSL(server, 443)) { // port 80 for HTTP, port 443 for HTTPS ?
Serial.println("connected to server");
// Make a HTTP request:
client.println("GET /data/observations/metar/stations/XXXX.TXT HTTP/1.1");
client.println("Host: tgftp.nws.noaa.gov");
client.println("Connection: close");
client.println();
}
// 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);
}
} ///////////////////////// end of setup() /////////////////////////
void loop() {
}
I'm still grinding on this.
I noticed the firmware of the MKR1000 has to be updated accordingly to the last revision of the Wfif101 library.
It's done now.
With the same tool, FirmwareUpdater, I could add SSL root certificate to the specific site i'm trying to connect to.
But still, when I connect without SSL, I get this answer :
Starting connection to server...
connected to server
HTTP/1.1 302 Object Moved
Location: https://tgftp.nws.noaa.gov/data/observations/metar/stations/XXXX.TXT
Content-Type: text/html
Cache-Control: private
Connection: close
<head><body> This object may be found <a HREF="https://tgftp.nws.noaa.gov/data/observations/metar/stations/XXXX.TXT">here</a> </body>
disconnecting from server.
When I try client.connectSSL(server, 443) :
Starting connection to server...
disconnecting from server.
And when I paste the address in the web page's bar :
I'm not used to post on forums.
I went through the forum instructions.
All I saw is that I used "quote" to paste in code, that I modified.
What I got from serial monitor, I left it as a quote.
I did put http in capital in my title ?
In the beginning I was asking about the compliance of my microcontroller with the application.
Now, I'm asking question about code, so I'm not anymore in the right section ?
I shall open a new post in a different section, "programming question" ?
David_Normand:
All I saw is that I used "quote" to paste in code, that I modified.
That is the idea, makes it readable, prevents it running too long down the page and importantly, mono-spaces it and prevents "smiley" substitution.
David_Normand:
What I got from serial monitor, I left it as a quote.
Should also be marked up as "code" for all the same reasons. Using "quote" italicises it which is a nuisance in readability. Italics are only to draw attention to specific points!
David_Normand:
I did put http in capital in my title ?
That's fine. HTML markup tags are actually case-insensitive, but capitals are not advised. And the major objection is to all-caps in a subject heading or posting which is considered an indicator of gross foolishness. You did not do that.
David_Normand:
Now, I'm asking question about code, so I'm not anymore in the right section ?
Why would you not be?
David_Normand:
I shall open a new post in a different section, "programming question" ?
Very bad idea, "cross-posting". Wastes people's time and effort because they may not be aware of what you have already explained and what has already been explained to you and you cannot reasonably expect them to search your history to find the missing details.
In fact, most (well, many) of us consider the "Programming questions" section to be too tedious to look at, concerned more with esoterica of the language than the practical application to a specific project.
But still, when I connect without SSL, I get this answer
This is normal. The web server is re-directing the client to use SSL/https.
This is normal for websites that do not support non-SSL connections. Web
browsers automatically handle HTTP re-direct, the Arduino does not. Stick to
using https.
Move the chunk of code that reads the HTTP response into loop(). Your code
assumes the web server responds nearly instaneously which might work for a
server on your network but will fail for a remote server.
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);
}
}
Paul__B:
In fact, most (well, many) of us consider the "Programming questions" section to be too tedious to look at, concerned more with esoterica of the language than the practical application to a specific project.
Although I agree with the rest of your reply (well, I'd quibble about HTTPS since that's an acronym, not HTML markup, and thus should be capitalized) but I disagree with this statement. I have found the programming questions to be possibly the most actively monitored and responded to topic on this forum. You only need to review the posts in that section to see what an excellent job the forum members do at quickly providing high quality answers. I've noticed that often there are multiple people competing to answer the question within minutes of it being asked. So I would not discourage people from posting in that section as long their question is on topic.
David_Normand:
Thank you for taking the time to explain.
I modified my post.
Terrific!
pert:
I have found the programming questions to be possibly the most actively monitored and responded to topic on this forum. You only need to review the posts in that section to see what an excellent job the forum members do at quickly providing high quality answers.
Fair enough. My apologies; I simply do not have the time to devote to that deluge of traffic.
I have moved the part of code that reads the HTTPS response into loop(). It doesn't work better.
I wonder if the MKR1000 is able to read fast enough the SSL response or if I need to place a delay to wait for the answer in loop() ?
Here is the actual code :
#include <SPI.h>
#include <WiFi101.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key Index number (needed only for WEP)
int status = WL_IDLE_STATUS;
char server[] = "tgftp.nws.noaa.gov"; // NOAA server for METAR
// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):
WiFiSSLClient client;
//******************************** printWiFiStatus() **********************************
void printWiFiStatus() {
// 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);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
//**************************************** setup() **********************************
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// 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.connectSSL(server, 443)) { // port 80 for HTTP, port 443 for HTTPS
Serial.println("connected to server");
// Make a HTTP request:
client.println("GET /data/observations/metar/stations/XXXX.TXT HTTP/1.1");
client.println("Host: tgftp.nws.noaa.gov");
client.println("Connection: close");
client.println();
}
} ///////////////////////// end of setup() /////////////////////////
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);
}
}
Attempting to connect to SSID: mckinley_guest
Connected to wifi
SSID: mckinley_guest
IP Address: 192.168.0.103
signal strength (RSSI):-67 dBm
Starting connection to server...
disconnecting from server.
I have the latest WiFi firmware installed on my MKR 1000.
Since the connection fails (the line "connected to server" never appears), there will never be an HTTP response. Could be a problem with the certificate validation but that happens inside the WINC1500. Perhaps the WiFi101 library maintainer would have some insight.
I just had a try at adding the SSL root certificate for tgftp.nws.noaa.gov to the MKR 1000 using Tools > WiFi101 / WiFiNINA Firmware Updater. The certificate process seemed to go fine but then I ran the sketch again and got the same result as before.
The possibility exists that the failure is a bug in the WINC1500 firmware. The WINC1500 firmware is closed source so there is no way to see what it does. Perhaps the WiFi101 library maintainers know more about debugging TLS connection failures.
This is surprising it works on MKR1010 and not on MKR1000.
I'm currently connecting from home network. I can't do it at work so I tried on my cell phone, with the same result.
I got a redirection response in HTTP, but no response in HTTPS.
I then took a Yun shield lying in a drawer, and put it on a ZERO, updated it's firmware to 1.6.2.
I used the HTTPClient example of the Bridge library, that I modified.
Unfortunately I got still the same result, a redirection answer for an HTTP request and no answer for an HTTPS one.
BTW, I'm using library WiFi101 version 0.16.0 and MKR1000 is running 19.6.1 firmware.