Skip to content

🌐 Mini Project Task 2 — Connecting the Edge Device to the Internet

2.0 — 🌿 Create a branch for this task

  1. On GitHub, in your fork, go to the branches page and click New branch. Name it task-2, create it from main, and click Create new branch.
  2. Open your cloned repository in VSCode.
  3. In a terminal, run git fetch to make VSCode aware of the new branch.
  4. Check out the new branch:
    git checkout task-2
    
  5. On GitHub, in your fork, click on Pull requestsNew pull request. Set base: main and compare: task-2. The description box will be pre-filled from the pull request template — skim it now, you'll fill it in as you go.
  6. Click the dropdown arrow on the Create pull request button and choose Create draft pull request instead.

All the work for this task should be committed to the task-2 branch.

What to put in the pull request description

  • Title: Task 2 — Connecting the edge device to the internet
  • Feature purpose: Get the device onto the Internet and prove it, rather than assuming it — joining a WiFi network only means it reached the local router, not that it can reach the outside world.
  • Feature architecture: setup() connects to WiFi via WiFi.begin()/WiFi.status() using credentials from secrets.h. handShakeProtocol() now uses this task's reset trigger: a WiFiClient connection attempt to an external server (httpbin.org), replacing the Serial Monitor input from Task 1.
  • Feature interfaces: The local WiFi network (SSID/password read from secrets.h); a TCP connection to httpbin.org on port 80.
  • Test plan: Serial Monitor shows "WiFi connected" on boot; pressing the button blinks the LED 3 times on a successful httpbin.org connection, 9 times on failure (see 2.3).
  • Implementation roadmap: e.g. create secrets.h with WiFi credentials → connect to WiFi in setup() → implement the WiFiClient handshake → build & upload → manually verify against 2.3.

Note

As with Task 1, this breakdown is scaffolding to show you what feature planning looks like. For your group project, you'll be doing this planning yourselves — nobody hands you the purpose, architecture, interfaces, and test plan up front.

2.1 — 🔐 Create a secret file to store your WiFi network name and password

Note

Sensitive information (WiFi passwords, API keys, AWS certificates, private keys) should never be stored directly in source code. Keeping these "secrets" in separate, non-tracked files prevents them from being accidentally committed to GitHub, shared publicly, or leaked to others. It also makes the project safer to distribute, easier to reuse across different environments, and simpler to rotate or update credentials without modifying the code itself.

  1. In firmware/include/, create a secret.h file.
  2. In this new file, add the following (replacing the placeholders):

    #define WIFI_SSID "your_wifi_name"
    #define WIFI_PASSWORD "your_wifi_password"
    
  3. Save the file.

2.2 — 📶 Update the firmware to connect to your WiFi router

Tip

Use the documentation of the WiFiNINA library to find out how to implement the following items.

  1. In firmware/platformio.ini, make sure that WiFiNINA is in the list of dependencies.
  2. In firmware/src/main.cpp's header, import secret.h.
  3. In firmware/src/main.cpp's setup() function, use WiFi.begin() and WiFi.status() to connect to your WiFi network and print in the serial monitor when connection has been established (examples in the documentation).
  4. Build the code and fix any errors that may arise.
  5. Upload the code to the Arduino and open the Serial monitor to check that it connects to the WiFi.

2.3 — ✅ Upload the firmware and test Internet connectivity

At this stage, your board connects to your WiFi router.

That does not automatically mean it has Internet access. It only means it joined the local network.

Now we verify that the device can reach an external server on the Internet (httpbin.org) by using client.connect().

sequenceDiagram
    box Edge Device
        participant PB as Push Button
        participant LED as LED
        participant MCU as Arduino (Firmware)
    end
    box Internet
        participant WIFI as WiFi Router
        participant EXT as httpbin.org
    end



    MCU->>WIFI: WiFi.begin(SSID, PASSWORD)
    WIFI-->>MCU: Connected (WL_CONNECTED)

    PB->>MCU: Button pressed
    MCU->>LED: Turn OFF

    MCU->>EXT: client.connect("httpbin.org", 80)

    alt Connection successful
        EXT-->>MCU: Connection established
        MCU->>LED: Blink 3 times
        MCU->>EXT: client.stop()
    else Connection failed
        MCU->>LED: Blink 9 times
    end

    MCU->>LED: Turn ON
  1. In firmware/src/main.cpp:
    • Create a WiFiClient object named client in the header.
    • Implement handShakeProtocol() so that if the client successfully connects to httpbin.org, blink the LED 3 times, then stop the client. If it doesn't connect, blink the LED 9 times. Finally, set resetReceived to 0, and set the LED to HIGH.
  2. Build the code and fix any errors that may arise.
  3. Upload the code to the Arduino and open the Serial monitor to check that it connects to the WiFi, then press the button and check that it successfully connects to httpbin.org.

2.4 — 🔀 Submit the task for review

  1. Commit and push your changes to the task-2 branch — they show up automatically in your draft pull request.
  2. Finish filling in the pull request description from the template (purpose, architecture, interfaces, test plan, roadmap).
  3. On the pull request page, click Ready for review to take it out of draft.
  4. Request a review from the course educator you added as a collaborator in Getting Started (click the gear icon next to Reviewers).
  5. Once the pull request is approved, click Merge pull requestConfirm merge.
  6. On GitHub, in your fork, click on Releases (in the right sidebar of the repository home page) → Create a new release. Click Choose a tag, type v2.0.0, and click Create new tag: v2.0.0 on publish. Make sure Target is set to main, then click Publish release.

💡 Solutions for Task 2

firmware/platformio.ini

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:mkrwifi1010]
platform = atmelsam
board = mkrwifi1010
framework = arduino
monitor_speed = 9600
lib_deps =
    WiFiNINA

firmware/src/main.cpp

#include <Arduino.h>
#include <WiFiNINA.h>
#include "secrets.h"

WiFiClient client;


// Pin definitions
const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  3;      // the number of the LED pin

// Status variables
int buttonState = 0;         // variable for reading the pushbutton status
int resetReceived = 0;       // variable for reading the reset status


// Function prototypes
void ledBlinkPatern(int pattern);
void handShakeProtocol();


// The setup function runs once when you press reset or power the board
void setup() {
    // initialize serial communication.
    Serial.begin(9600);
    // initialize the LED pin as an output.
    pinMode(ledPin, OUTPUT);
    // initialize the pushbutton pin as an input.
    pinMode(buttonPin, INPUT);
    // make sure the LED is on at the start
    digitalWrite(ledPin, HIGH);

    delay(5000); // Wait for 5 second to ensure the LED is on before connecting to WiFi
    Serial.println("Connecting to WiFi...");
    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }
    Serial.println("WiFi connected");

}

// The loop function runs over and over again forever
void loop() {

    buttonState = digitalRead(buttonPin);

    if (buttonState == HIGH && resetReceived == 0) {
        Serial.println("Button pressed, waiting for reset...");
        resetReceived = 1;
        digitalWrite(ledPin, LOW);
    }

    if (resetReceived == 1) {
        handShakeProtocol();
        delay(1000); // Add a delay to prevent the loop from running too fast after the handshake protocol is complete
    }


}



void ledBlinkPatern(int pattern) {
    /*************************************************************
    * This function is used to show the status of the LED.
    *
    * The pattern indicates how many times the LED will blink.
    * For example, if the pattern is 3, the LED will blink 3 times.
    **************************************************************/
    Serial.print("Status received:");
    Serial.println(pattern);
    for (int i = 0; i < pattern; i++) {
        digitalWrite(ledPin, HIGH);
        delay(500);
        digitalWrite(ledPin, LOW);
        delay(500);
    }
}

void handShakeProtocol() {
    /*************************************************************
    * This function is used to implement the handshake protocol between pressing the button and the reset of the LED.
    *
    * When the button is pressed, the LED will turn on and stay on until the reset is received.
    * Once the reset is received, the LED will turn off and the system will be ready for the next button press.
    * In task 1, the reset is triggered by waiting for an integer pattern to be sent through the serial monitor.
    * In task 2, the reset is triggered by connecting to an external server to check that the device is connected to the internet.
    * In task 3, the reset is triggered by waiting for an MQTT message that aknowledges that the device is connected to the MQTT broker.
    * In task 4, the reset is triggered by waiting for an MQTT message that sends a specific command to the device based on administrative rules defined in the cloud.
    **************************************************************/

    // TODO: YOUR CODE HERE
    Serial.println("Testing Internet connection...");

    if (client.connect("httpbin.org", 80)) {
        Serial.println("Internet connection successful.");
        ledBlinkPatern(3); // Blink the LED 3 times to indicate success
        client.stop(); // Close the connection after testing
    } else {
        Serial.println("Internet connection failed.");
        ledBlinkPatern(9); // Blink the LED 9 times to indicate failure
    }
    digitalWrite(ledPin, HIGH); // Turn the LED back on after the handshake protocol is complete
    resetReceived = 0; // Reset the handshake protocol for the next button press
}