#include <WiFi.
h>
#include <Servo.h>
// SSID and password for the access point
const char* ssid = "PicoW_ap"; // name for your wifi
const char* password = "12345678"; // password for the wifi
// Servo pin
const int servoPin = 4; // PWM pin for Servo
// Motor driver pins
const int IN1 = 10; // assign the pin no. which you will connect to the RPI Pico
const int IN2 = 11; // assign the pin no. which you will connect to the RPI Pico
const int ENA = 12; // assign the pin no. which you will connect to the RPI Pico
// Create a WiFiServer object for the TCP server
WiFiServer server(80);
// Create a Servo object
Servo myServo;
void setup() {
// Start Serial for debugging
[Link](115200);
delay(5000);
// Attach the Servo to the pin
[Link](servoPin);
[Link](90); // Start with the servo in the center position
// Set motor driver pins as outputs
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
// Set up the access point
[Link]("Setting up WiFi AP...");
[Link](ssid, password);
IPAddress IP = [Link]();
[Link]("AP IP address: ");
[Link](IP);
// Start the server
[Link]();
}
void loop() {
// Check if a client has connected
WiFiClient client = [Link]();
digitalWrite(LED_BUILTIN, HIGH);
if (client) {
[Link]("New client connected");
// Wait until the client sends some data
while ([Link]()) {
if ([Link]()) {
// Read the request
String request = [Link]('\r');
[Link]("Received request: ");
[Link](request);
// Parse the joystick values
if ([Link]("GET /control?")) {
String action = parseQueryParam(request, "action");
String speed = parseQueryParam(request, "speed");
// Control the servo based on joystick input
handleServoControl(action, speed);
if ([Link]("GET /led?")) {
String state = parseQueryParam(request, "state");
if (state == "on") {
digitalWrite(LED_BUILTIN, HIGH); // Turn LED on
} else if (state == "off") {
digitalWrite(LED_BUILTIN, LOW); // Turn LED off
}
}
// Send a response
[Link]("HTTP/1.1 200 OK");
[Link]("Content-Type: text/html");
[Link]("Connection: close");
[Link]();
[Link]("<!DOCTYPE HTML>");
[Link]("<html>");
[Link]("<head><title>Servo Control</title>");
[Link]("<style>");
[Link]("body { font-family: Arial, sans-serif; text-align: center; background-color:
#f0f0f0; }");
[Link](".control-panel { margin: 20px auto; padding: 20px; border-radius: 10px;
background-color: #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); }");
[Link](".joystick { width: 200px; height: 200px; background-color: #007bff;
border-radius: 50%; position: relative; margin: 20px auto; cursor: pointer; touch-action:
none; }");
[Link](".joystick-inner { width: 50px; height: 50px; background-color: #fff; border-
radius: 50%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }");
[Link](".status { margin-top: 20px; font-size: 18px; }");
[Link]("</style>");
[Link]("</head>");
[Link]("<body>");
[Link]("<h1>Servo Control</h1>");
[Link]("<div class='control-panel'>");
[Link]("<div class='joystick' id='joystick'>");
[Link]("<div class='joystick-inner' id='joystick-inner'></div>");
[Link]("</div>");
[Link]("<div class='status'>");
[Link]("<p>Status: <span id='status'>Idle</span></p>");
[Link]("</div>");
[Link]("</div>");
[Link]("<script>");
[Link]("const joystick = [Link]('joystick');");
[Link]("const joystickInner = [Link]('joystick-inner');");
[Link]("const statusElement = [Link]('status');");
[Link]("[Link]('mousedown', onJoystickMouseDown);");
[Link]("[Link]('touchstart', onJoystickTouchStart);");
[Link]("function onJoystickMouseDown(event) {");
[Link](" [Link]('mousemove', onJoystickMouseMove);");
[Link](" [Link]('mouseup', onJoystickMouseUp);");
[Link](" moveJoystick(event);");
[Link]("}");
[Link]("function onJoystickMouseMove(event) {");
[Link](" moveJoystick(event);");
[Link]("}");
[Link]("function onJoystickMouseUp() {");
[Link](" [Link]('mousemove',
onJoystickMouseMove);");
[Link](" [Link]('mouseup', onJoystickMouseUp);");
[Link](" [Link] = 'translate(-50%, -50%)';");
[Link](" [Link] = 'Idle';");
[Link](" sendControlCommand('stop', 0);");
[Link]("}");
[Link]("function onJoystickTouchStart(event) {");
[Link](" [Link]('touchmove', onJoystickTouchMove);");
[Link](" [Link]('touchend', onJoystickTouchEnd);");
[Link](" moveJoystick([Link][0]);");
[Link]("}");
[Link]("function onJoystickTouchMove(event) {");
[Link](" moveJoystick([Link][0]);");
[Link]("}");
[Link]("function onJoystickTouchEnd() {");
[Link](" [Link]('touchmove', onJoystickTouchMove);");
[Link](" [Link]('touchend', onJoystickTouchEnd);");
[Link](" [Link] = 'translate(-50%, -50%)';");
[Link](" [Link] = 'Idle';");
[Link](" sendControlCommand('stop', 0);");
[Link]("}");
[Link]("function moveJoystick(event) {");
[Link](" const rect = [Link]();");
[Link](" const joystickRadius = [Link] / 2;");
[Link](" const centerX = [Link] + joystickRadius;");
[Link](" const centerY = [Link] + joystickRadius;");
[Link](" const x = [Link] - centerX;");
[Link](" const y = [Link] - centerY;");
[Link](" const distance = [Link]([Link](x * x + y * y), joystickRadius);");
[Link](" const angle = Math.atan2(y, x);");
[Link](" const speed = [Link]((distance / joystickRadius) * 100);");
[Link](" const direction = getDirection(angle);");
[Link](" [Link] = `translate(-50%, -50%) translate(${x}px, $
{y}px)`;");
[Link](" [Link] = `Moving ${direction} with speed ${speed}`;");
[Link](" sendControlCommand(direction, speed);");
[Link]("}");
[Link]("function getDirection(angle) {");
[Link](" if (angle > -[Link] / 4 && angle <= [Link] / 4) return 'right';");
[Link](" if (angle > [Link] / 4 && angle <= 3 * [Link] / 4) return 'forward';");
[Link](" if (angle > -3 * [Link] / 4 && angle <= -[Link] / 4) return
'backward';");
[Link](" return 'left';");
[Link]("}");
[Link]("function sendControlCommand(action, speed) {");
[Link](" const xhr = new XMLHttpRequest();");
[Link](" [Link]('GET', `/control?action=${action}&speed=${speed}`);");
[Link](" [Link]();");
[Link]("}");
[Link]("</script>");
[Link]("<button onclick=\"controlLED('on')\">Turn LED On</button>");
[Link]("<button onclick=\"controlLED('off')\">Turn LED Off</button>");
[Link]("<script>");
[Link]("function controlLED(state) {");
[Link](" const xhr = new XMLHttpRequest();");
[Link](" [Link]('GET', `/led?state=${state}`);");
[Link](" [Link]();");
[Link]("}");
[Link]("</script>");
[Link]("</body>");
[Link]("</html>");
digitalWrite(LED_BUILTIN, LOW);
break;
}
digitalWrite(LED_BUILTIN, LOW);
}
// Give the client time to receive the data
delay(1);
// Close the connection
[Link]();
[Link]("Client disconnected");
}
}
void handleServoControl(String action, String speed) {
int angle = map([Link](), 0, 100, 0, 180); // Map 0-100 speed to 0-180 degrees for the
servo
int motorSpeed = map([Link](), 0, 100, 0, 255); // Map 0-100 speed to 0-255 PWM
value
if (action == "stop" || (action == "left" && angle < 60) || (action == "right" && angle < 60)) {
[Link](90); // Center position
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
analogWrite(ENA, 0);
}
else if (action == "left" && angle >45) {
[Link](90 - 60 ); // Example logic for turning left, adjust as needed
}
else if (action == "right" && angle >45) {
[Link](90 + 60 ); // Example logic for turning right, adjust as needed
}
if (action == "forward") {
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(ENA, motorSpeed);
if (angle > 70){[Link](90);}
}
else if (action == "backward") {
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(ENA, motorSpeed);
if (angle > 70){[Link](90);}
}
}
String parseQueryParam(String request, String param) {
int startIndex = [Link](param + "=");
if (startIndex == -1) return "";
startIndex += [Link]() + 1;
int endIndex = [Link]("&", startIndex);
if (endIndex == -1) endIndex = [Link](" ", startIndex);
return [Link](startIndex, endIndex);
}