Retrieve user data from Duolingo using Arduino Nano RP2040 Connect and WiFiNINA

Hi all,

I'm trying to read my user data from the Duolingo site using an Arduino Nano RP2040 connect. I'm using the WiFiNINA WiFiSSLClient example script (see end of post) but it never prints anything before disconnecting.

Going to "https://www.duolingo.com/2017-06-30/users?username=myUsername" displays the JSON data I want to access.

Likewise, using the example script with the demo Google URL and GET request works fine.

I have read through this similar post and followed their recommendations pinned in the first post: SOLVED: HTTP SSL Post via WifiNINA, Uno Wifi R2: Open Tesla Model 3 Charge Port

I have tried:

  • Updating the WiFi firmware
  • Uploading an SSL Root Certificate (duolingo.com) to the Arduino
  • Adding/removing the "www." from the URL
  • Trying a different username that also works in a web browser
  • Removing the " HTTP/1.1" from the end of the GET request
  • Shuffling bits of the URL between the Host and GET sections of the request

I'm honestly stumped as to what else I can try. Thanks in advance for any advice you can offer!

~Hazel

The code below is a variation of the WiFiSSLClient example script. (Sensitive data hidden - i.e. WiFi ID + password + Duolingo username.)

/*
This example creates a client object that connects and transfers
data using always SSL.

It is compatible with the methods normally related to plain
connections, like client.connect(host, port).

Written by Arturo Guadalupi
last revision November 2015

*/

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

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = "myNetwork";        // your network SSID (name)
char pass[] = "myPassword";   // 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[] = "www.duolingo.com";    // name address for Duolingo (using DNS)

// 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;

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
  }

  // 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, 443)) {
    Serial.println("connected to server");
    // Make a HTTP request:
    client.println("GET /2017-06-30/users?username=myUsername HTTP/1.1");
    client.println("Host: www.duolingo.com");
    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");
}

The serial monitor prints:

20:44:05.137 -> Attempting to connect to SSID: mySSID
20:44:16.267 -> Attempting to connect to SSID: mySSID
20:44:26.701 -> Connected to WiFi
20:44:26.701 -> SSID: mySSID
20:44:26.701 -> IP Address: myIP
20:44:26.701 -> signal strength (RSSI):-32 dBm
20:44:26.701 -> 
20:44:26.701 -> Starting connection to server...
20:44:37.335 -> 
20:44:37.335 -> disconnecting from server.

It looks like I didn't explain why I used connectSSL command vs standard connect, and I didn't leave comments in my code either (Shane). But perhaps it's worth giving that a try, referencing my final code example in the topic you linked?

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.