🌐 Mini Project Task 2 — Connecting the Edge Device to the Internet¶
2.0 — 🌿 Create a branch for this task¶
- On GitHub, in your fork, go to the branches page and click
New branch. Name ittask-2, create it frommain, and clickCreate new branch. - Open your cloned repository in VSCode.
- In a terminal, run
git fetchto make VSCode aware of the new branch. - Check out the new branch:
- On GitHub, in your fork, click on
Pull requests→New pull request. Setbase: mainandcompare: 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. - Click the dropdown arrow on the
Create pull requestbutton and chooseCreate draft pull requestinstead.
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 viaWiFi.begin()/WiFi.status()using credentials fromsecrets.h.handShakeProtocol()now uses this task's reset trigger: aWiFiClientconnection 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 tohttpbin.orgon port 80. - Test plan: Serial Monitor shows "WiFi connected" on boot; pressing the button blinks the LED 3 times on a successful
httpbin.orgconnection, 9 times on failure (see 2.3). - Implementation roadmap: e.g. create
secrets.hwith WiFi credentials → connect to WiFi insetup()→ implement theWiFiClienthandshake → 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.
- In
firmware/include/, create asecret.hfile. -
In this new file, add the following (replacing the placeholders):
-
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.
- In
firmware/platformio.ini, make sure thatWiFiNINAis in the list of dependencies. - In
firmware/src/main.cpp's header, importsecret.h. - In
firmware/src/main.cpp'ssetup()function, useWiFi.begin()andWiFi.status()to connect to your WiFi network and print in the serial monitor when connection has been established (examples in the documentation). - Build the code and fix any errors that may arise.
- 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
- In
firmware/src/main.cpp:- Create a
WiFiClientobject namedclientin the header. - Implement
handShakeProtocol()so that if the client successfully connects tohttpbin.org, blink the LED 3 times, then stop the client. If it doesn't connect, blink the LED 9 times. Finally, setresetReceivedto 0, and set the LED to HIGH.
- Create a
- Build the code and fix any errors that may arise.
- 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¶
- Commit and push your changes to the
task-2branch — they show up automatically in your draft pull request. - Finish filling in the pull request description from the template (purpose, architecture, interfaces, test plan, roadmap).
- On the pull request page, click
Ready for reviewto take it out of draft. - Request a review from the course educator you added as a collaborator in Getting Started (click the gear icon next to
Reviewers). - Once the pull request is approved, click
Merge pull request→Confirm merge. - On GitHub, in your fork, click on
Releases(in the right sidebar of the repository home page) →Create a new release. ClickChoose a tag, typev2.0.0, and clickCreate new tag: v2.0.0 on publish. Make sureTargetis set tomain, then clickPublish 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
}