From 312a8a60c95925fdc0102f69ca7cf3190287035a Mon Sep 17 00:00:00 2001
From: Muhammad Hazimi Bin Yusri <mhby1g21@soton.ac.uk>
Date: Fri, 28 Feb 2025 15:40:09 +0000
Subject: [PATCH] added wifi version to be compatible with uno r4 wifi library

---
 wifi-test/get-mac-address-uno-r4.ino |  45 ++++
 wifi-test/wifi_with_ui_uno-r4.ino    | 333 +++++++++++++++++++++++++++
 2 files changed, 378 insertions(+)
 create mode 100644 wifi-test/get-mac-address-uno-r4.ino
 create mode 100644 wifi-test/wifi_with_ui_uno-r4.ino

diff --git a/wifi-test/get-mac-address-uno-r4.ino b/wifi-test/get-mac-address-uno-r4.ino
new file mode 100644
index 0000000..3d7eec3
--- /dev/null
+++ b/wifi-test/get-mac-address-uno-r4.ino
@@ -0,0 +1,45 @@
+#include <SPI.h>
+#include <WiFi.h>
+
+
+// For some reason, the mac adress code using WifiS3 give 00:00:00... which seems like placeholder value
+// so just used a phone hotspot and chech connected device mac address there.
+char ssid[] = "Danisha's A54";  // the name of your network
+char password[] = "reply1988";
+
+int status = WL_IDLE_STATUS;  // the Wifi radio's status
+
+byte mac[6];  // the MAC address of your Wifi shield
+
+void setup()
+{
+    Serial.begin(115200);
+
+    status = WiFi.begin(ssid, password);
+
+    if (status != WL_CONNECTED)
+    {
+        Serial.println("Couldn't get a wifi connection");
+        while (true)
+            ;
+    }
+    // if you are connected, print your MAC address:
+    else
+    {
+        WiFi.macAddress(mac);
+        Serial.print("MAC: ");
+        Serial.print(mac[5], HEX);
+        Serial.print(":");
+        Serial.print(mac[4], HEX);
+        Serial.print(":");
+        Serial.print(mac[3], HEX);
+        Serial.print(":");
+        Serial.print(mac[2], HEX);
+        Serial.print(":");
+        Serial.print(mac[1], HEX);
+        Serial.print(":");
+        Serial.println(mac[0], HEX);
+    }
+}
+
+void loop() {}
\ No newline at end of file
diff --git a/wifi-test/wifi_with_ui_uno-r4.ino b/wifi-test/wifi_with_ui_uno-r4.ino
new file mode 100644
index 0000000..6f683d3
--- /dev/null
+++ b/wifi-test/wifi_with_ui_uno-r4.ino
@@ -0,0 +1,333 @@
+#include <WiFiS3.h>
+#include <Servo.h>
+
+// WiFi credentials
+const char ssid[] = "SOTON-IoT";    
+const char pass[] = "pUguZXWtBDzl";    
+int status = WL_IDLE_STATUS;
+
+// Server settings
+WiFiServer server(80);
+
+// Create servo objects
+Servo index_f;
+Servo middle;
+Servo ring;
+Servo pinky;
+
+// Servo pins - UNO R4 WiFi has different pin layout, adjust if needed
+const int indexPin = 2;
+const int middlePin = 3;
+const int ringPin = 4;
+const int pinkyPin = 5;
+
+// Current positions
+int indexPos = 90;
+int middlePos = 90;
+int ringPos = 90;
+int pinkyPos = 90;
+
+// Target positions for smooth movement
+int indexTarget = 90;
+int middleTarget = 90;
+int ringTarget = 90;
+int pinkyTarget = 90;
+
+// Movement parameters
+const int STEP_DELAY = 5;  // Delay between steps (ms)
+const int STEP_SIZE = 15;  // Size of each step in degrees
+
+void setup() {
+  Serial.begin(9600);
+  
+  // Initialize servos
+  index_f.attach(indexPin);
+  middle.attach(middlePin);
+  ring.attach(ringPin);
+  pinky.attach(pinkyPin);
+  
+  // Set initial positions
+  index_f.write(indexPos);
+  middle.write(middlePos);
+  ring.write(ringPos);
+  pinky.write(pinkyPos);
+  
+  // Check for WiFi module
+  if (WiFi.status() == WL_NO_MODULE) {
+    Serial.println("Communication with WiFi module failed!");
+    while (true);
+  }
+
+  // Check firmware version
+  String fv = WiFi.firmwareVersion();
+  Serial.print("Firmware version: ");
+  Serial.println(fv);
+
+  // Attempt to connect to WiFi network
+  while (status != WL_CONNECTED) {
+    Serial.print("Attempting to connect to Network: ");
+    Serial.println(ssid);
+    status = WiFi.begin(ssid, pass);
+    delay(10000);
+  }
+
+  Serial.println("Connected to wifi");
+  printWiFiStatus();
+  
+  server.begin();
+}
+
+// Move all servos together for fist motion
+void moveAllServosSmooth(int targetPos) {
+  int maxSteps = 0;
+  
+  // Calculate the maximum number of steps needed
+  maxSteps = max(maxSteps, abs(indexTarget - indexPos));
+  maxSteps = max(maxSteps, abs(middleTarget - middlePos));
+  maxSteps = max(maxSteps, abs(ringTarget - ringPos));
+  maxSteps = max(maxSteps, abs(pinkyTarget - pinkyPos));
+  
+  if (maxSteps > 0) {
+    // Calculate step size for each finger
+    float indexStep = (float)(indexTarget - indexPos) / maxSteps;
+    float middleStep = (float)(middleTarget - middlePos) / maxSteps;
+    float ringStep = (float)(ringTarget - ringPos) / maxSteps;
+    float pinkyStep = (float)(pinkyTarget - pinkyPos) / maxSteps;
+    
+    // Move all fingers together
+    for (int i = 1; i <= maxSteps; i++) {
+      // Calculate next position for each finger
+      int newIndexPos = indexPos + round(indexStep * i);
+      int newMiddlePos = middlePos + round(middleStep * i);
+      int newRingPos = ringPos + round(ringStep * i);
+      int newPinkyPos = pinkyPos + round(pinkyStep * i);
+      
+      // Move all servos
+      index_f.write(newIndexPos);
+      middle.write(newMiddlePos);
+      ring.write(newRingPos);
+      pinky.write(newPinkyPos);
+      
+      delay(STEP_DELAY);
+    }
+    
+    // Update the current positions
+    indexPos = indexTarget;
+    middlePos = middleTarget;
+    ringPos = ringTarget;
+    pinkyPos = pinkyTarget;
+  }
+}
+
+// Individual servo movement for single finger control
+void moveServoSmooth(Servo &servo, int &currentPos, int targetPos) {
+  if (currentPos < targetPos) {
+    for (int pos = currentPos; pos <= targetPos; pos += STEP_SIZE) {
+      servo.write(pos);
+      currentPos = pos;
+      delay(STEP_DELAY);
+    }
+  } else {
+    for (int pos = currentPos; pos >= targetPos; pos -= STEP_SIZE) {
+      servo.write(pos);
+      currentPos = pos;
+      delay(STEP_DELAY);
+    }
+  }
+}
+
+void loop() {
+  // Check if any finger needs to move to its target position
+  bool needToMove = (indexPos != indexTarget) || 
+                    (middlePos != middleTarget) || 
+                    (ringPos != ringTarget) || 
+                    (pinkyPos != pinkyTarget);
+                    
+  // If all fingers have the same target (fist motion), move them simultaneously
+  bool sameFistMotion = (indexTarget == middleTarget && 
+                         middleTarget == ringTarget && 
+                         ringTarget == pinkyTarget);
+                         
+  if (needToMove) {
+    if (sameFistMotion) {
+      // Move all fingers together
+      moveAllServosSmooth(indexTarget);
+    } else {
+      // Move individual fingers
+      if (indexPos != indexTarget) moveServoSmooth(index_f, indexPos, indexTarget);
+      if (middlePos != middleTarget) moveServoSmooth(middle, middlePos, middleTarget);
+      if (ringPos != ringTarget) moveServoSmooth(ring, ringPos, ringTarget);
+      if (pinkyPos != pinkyTarget) moveServoSmooth(pinky, pinkyPos, pinkyTarget);
+    }
+  }
+  
+  WiFiClient client = server.available();
+  
+  if (client) {
+    Serial.println("New client connected");
+    String request = "";
+    boolean currentLineIsBlank = true;
+    
+    while (client.connected()) {
+      if (client.available()) {
+        char c = client.read();
+        request += c;
+        
+        if (c == '\n' && currentLineIsBlank) {
+          client.println("HTTP/1.1 200 OK");
+          client.println("Content-Type: text/html");
+          client.println("Connection: close");
+          client.println();
+          
+          // Send HTML page
+          client.println("<!DOCTYPE html>");
+          client.println("<html>");
+          client.println("<head>");
+          client.println("<title>Robotic Hand Control</title>");
+          client.println("<meta name='viewport' content='width=device-width, initial-scale=1'>");
+          client.println("<style>");
+          client.println("body { font-family: Arial; margin: 20px; }");
+          client.println(".control-group { margin-bottom: 20px; background: #f5f5f5; padding: 15px; border-radius: 8px; }");
+          client.println(".slider { width: 200px; margin: 10px 0; }");
+          client.println(".button { background: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; margin: 5px; }");
+          client.println(".button:hover { background: #45a049; }");
+          client.println(".preset { background: #2196F3; }");
+          client.println(".reset { background: #f44336; }");
+          client.println(".fist { background: #9C27B0; }");
+          client.println("</style>");
+          client.println("</head>");
+          client.println("<body>");
+          
+          client.println("<h1>Robotic Hand Control Panel</h1>");
+          
+          // Fist motion controls (added at top for prominence)
+          client.println("<div class='control-group'>");
+          client.println("<h2>Fist Motion Controls</h2>");
+          client.println("<button class='button fist' onclick='allFingers(0)'>Close Fist</button>");
+          client.println("<button class='button fist' onclick='allFingers(180)'>Open Hand</button>");
+          client.println("<button class='button fist' onclick='fistGrasp()'>Grasp Motion</button>");
+          client.println("</div>");
+          
+          // Individual finger controls
+          String fingers[] = {"Index", "Middle", "Ring", "Pinky"};
+          int positions[] = {indexPos, middlePos, ringPos, pinkyPos};
+          String endpoints[] = {"index", "middle", "ring", "pinky"};
+          
+          client.println("<div class='control-group'>");
+          client.println("<h2>Individual Finger Controls</h2>");
+          
+          for(int i = 0; i < 4; i++) {
+            client.println("<div style='margin-bottom:10px;'>");
+            client.println("<h3>" + fingers[i] + " Finger</h3>");
+            client.println("<input type='range' class='slider' min='0' max='180' value='" + String(positions[i]) + "' ");
+            client.println("oninput='updateFinger(\"" + endpoints[i] + "\", this.value)'>");
+            client.println("<span>Position: " + String(positions[i]) + "°</span>");
+            client.println("<br>");
+            client.println("<button class='button' onclick='updateFinger(\"" + endpoints[i] + "\", 0)'>Close</button>");
+            client.println("<button class='button' onclick='updateFinger(\"" + endpoints[i] + "\", 180)'>Open</button>");
+            client.println("</div>");
+          }
+          client.println("</div>");
+          
+          // Additional preset controls
+          client.println("<div class='control-group'>");
+          client.println("<h3>Other Controls</h3>");
+          client.println("<button class='button reset' onclick='resetPositions()'>Reset to 90°</button>");
+          client.println("</div>");
+          
+          // JavaScript
+          client.println("<script>");
+          client.println("function updateFinger(finger, angle) {");
+          client.println("  fetch('/' + finger + '/' + angle);");
+          client.println("}");
+          
+          client.println("function allFingers(angle) {");
+          client.println("  fetch('/fist/' + angle);");
+          client.println("}");
+          
+          client.println("function resetPositions() {");
+          client.println("  allFingers(90);");
+          client.println("}");
+          
+          client.println("function fistGrasp() {");
+          client.println("  // Open hand first");
+          client.println("  allFingers(180);");
+          client.println("  // Close after a delay");
+          client.println("  setTimeout(() => allFingers(0), 1500);");
+          client.println("  // Open again after another delay");
+          client.println("  setTimeout(() => allFingers(180), 3000);");
+          client.println("}");
+          client.println("</script>");
+          
+          client.println("</body></html>");
+          break;
+        }
+        if (c == '\n') {
+          currentLineIsBlank = true;
+        } else if (c != '\r') {
+          currentLineIsBlank = false;
+        }
+      }
+    }
+    
+    // Process the request
+    if (request.indexOf("GET /") != -1) {
+      processRequest(request);
+    }
+    
+    delay(10);
+    client.stop();
+    Serial.println("Client disconnected");
+  }
+}
+
+void processRequest(String request) {
+  int start = request.indexOf("GET ") + 4;
+  int end = request.indexOf(" HTTP");
+  
+  if (start != -1 && end != -1) {
+    String command = request.substring(start, end);
+    Serial.println("Command: " + command);
+    
+    // Parse command and set target positions
+    if (command.startsWith("/fist/")) {
+      // Set all fingers to same position
+      int angle = constrain(command.substring(6).toInt(), 0, 180);
+      indexTarget = angle;
+      middleTarget = angle;
+      ringTarget = angle;
+      pinkyTarget = angle;
+      Serial.println("Moving all fingers to " + String(angle));
+    }
+    else if (command.startsWith("/index/")) {
+      indexTarget = constrain(command.substring(7).toInt(), 0, 180);
+      Serial.println("Moving index to " + String(indexTarget));
+    }
+    else if (command.startsWith("/middle/")) {
+      middleTarget = constrain(command.substring(8).toInt(), 0, 180);
+      Serial.println("Moving middle to " + String(middleTarget));
+    }
+    else if (command.startsWith("/ring/")) {
+      ringTarget = constrain(command.substring(6).toInt(), 0, 180);
+      Serial.println("Moving ring to " + String(ringTarget));
+    }
+    else if (command.startsWith("/pinky/")) {
+      pinkyTarget = constrain(command.substring(7).toInt(), 0, 180);
+      Serial.println("Moving pinky to " + String(pinkyTarget));
+    }
+  }
+}
+
+void printWiFiStatus() {
+  Serial.print("SSID: ");
+  Serial.println(WiFi.SSID());
+
+  IPAddress ip = WiFi.localIP();
+  Serial.print("IP Address: ");
+  Serial.println(ip);
+
+  long rssi = WiFi.RSSI();
+  Serial.print("Signal strength (RSSI):");
+  Serial.print(rssi);
+  Serial.println(" dBm");
+}
\ No newline at end of file
-- 
GitLab