Pārlūkot izejas kodu

Refactor: Complete architecture overhaul with Config class, HTTPServer encapsulation, and XML documentation

faqmoroz 1 nedēļu atpakaļ
vecāks
revīzija
47e5720a18
7 mainītis faili ar 636 papildinājumiem un 155 dzēšanām
  1. 22 0
      Config.cpp
  2. 42 0
      Config.h
  3. 187 0
      HTTPServer.cpp
  4. 107 0
      HTTPServer.h
  5. 93 0
      ShutterController.cpp
  6. 106 0
      ShutterController.h
  7. 79 155
      minolta_remote_v1.ino

+ 22 - 0
Config.cpp

@@ -0,0 +1,22 @@
+#include "Config.h"
+
+/// <summary>
+/// Static initialization of WiFi configuration values.
+/// These values define the WiFi access point credentials and network settings
+/// that the ESP8266 will use when operating as an access point.
+/// </summary>
+
+/// <summary>WiFi SSID for the access point</summary>
+const char* Config::WIFI_SSID = "MINOLTA_REMOTE_CONTROL";
+
+/// <summary>WiFi password for secure access point connection</summary>
+const char* Config::WIFI_PASSWORD = "12345678";
+
+/// <summary>Static IP address assigned to the ESP8266 access point</summary>
+const IPAddress Config::WIFI_IP(192, 168, 1, 200);
+
+/// <summary>Gateway IP address for the local network</summary>
+const IPAddress Config::WIFI_GATEWAY(192, 168, 1, 1);
+
+/// <summary>Subnet mask for the local network</summary>
+const IPAddress Config::WIFI_SUBNET(255, 255, 255, 0);

+ 42 - 0
Config.h

@@ -0,0 +1,42 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <ESP8266WiFi.h>
+
+/// <summary>
+/// Central configuration class for Minolta remote control application.
+/// Centralizes all hardware pins, WiFi settings, server configuration, and serial settings.
+/// All configuration values are defined as static constants for easy modification.
+/// </summary>
+class Config
+{
+public:
+    /// <summary>GPIO pin number for camera focus control (D1/GPIO5)</summary>
+    static const uint8_t PIN_FOCUS = 5;
+    
+    /// <summary>GPIO pin number for camera shutter control (D2/GPIO4)</summary>
+    static const uint8_t PIN_SHUTTER = 4;
+    
+    /// <summary>WiFi network SSID (access point name)</summary>
+    static const char* WIFI_SSID;
+    
+    /// <summary>WiFi network password</summary>
+    static const char* WIFI_PASSWORD;
+    
+    /// <summary>Static IP address for the WiFi access point</summary>
+    static const IPAddress WIFI_IP;
+    
+    /// <summary>Gateway IP address for the WiFi access point</summary>
+    static const IPAddress WIFI_GATEWAY;
+    
+    /// <summary>Subnet mask for the WiFi access point</summary>
+    static const IPAddress WIFI_SUBNET;
+    
+    /// <summary>Port number for the HTTP server (default: 80)</summary>
+    static const uint16_t HTTP_PORT = 80;
+    
+    /// <summary>Serial communication baud rate (default: 115200)</summary>
+    static const uint32_t SERIAL_BAUD = 115200;
+};
+
+#endif // CONFIG_H

+ 187 - 0
HTTPServer.cpp

@@ -0,0 +1,187 @@
+#include "HTTPServer.h"
+#include <Arduino.h>
+
+/// <summary>
+/// Constructs an HTTPServer instance with the specified port and shutter controller.
+/// Creates a new AsyncWebServer instance but does not start it yet.
+/// </summary>
+HTTPServer::HTTPServer(uint16_t port, IShutterController* controller)
+    : shutterController(controller)
+{
+    server = new AsyncWebServer(port);
+}
+
+/// <summary>
+/// Destructor that properly cleans up the AsyncWebServer instance.
+/// </summary>
+HTTPServer::~HTTPServer()
+{
+    if (server)
+    {
+        delete server;
+    }
+}
+
+/// <summary>
+/// Configures the ESP8266 as a WiFi access point with the provided credentials.
+/// Sets up the static IP configuration and starts the access point.
+/// </summary>
+void HTTPServer::setupWiFiAP(const char* ssid, const char* password,
+                             IPAddress local_IP, IPAddress gateway, IPAddress subnet)
+{
+    if (!WiFi.softAPConfig(local_IP, gateway, subnet))
+    {
+        Serial.println("Failed to config IP");
+    }
+    WiFi.softAP(ssid, password);
+    Serial.println(WiFi.softAPIP());
+    Serial.println("AP Started - Waiting for connections");
+}
+
+/// <summary>
+/// Registers all HTTP API routes and their corresponding handlers.
+/// Associates each route with its handler method using lambda expressions.
+/// </summary>
+void HTTPServer::setupRoutes()
+{
+    // Focus endpoint
+    server->on("/api/focus", HTTP_GET, [this](AsyncWebServerRequest *request) {
+        handleFocus(request);
+    });
+
+    // Take photo endpoint
+    server->on("/api/takePhoto", HTTP_GET, [this](AsyncWebServerRequest *request) {
+        handleTakePhoto(request);
+    });
+
+    // Reset endpoint
+    server->on("/api/reset", HTTP_GET, [this](AsyncWebServerRequest *request) {
+        handleReset(request);
+    });
+
+    // Multiple shoot endpoint
+    server->on("/api/multiple", HTTP_GET, [this](AsyncWebServerRequest *request) {
+        handleMultiple(request);
+    });
+
+    // Health check endpoint
+    server->on("/get", HTTP_GET, [this](AsyncWebServerRequest *request) {
+        handleHealthCheck(request);
+    });
+}
+
+/// <summary>
+/// Handles GET /api/focus request to perform a half press (focus) operation.
+/// Logs the request, activates the camera focus, and responds with success.
+/// </summary>
+void HTTPServer::handleFocus(AsyncWebServerRequest *request)
+{
+    onRequestStart("api/focus");
+    shutterController->halfPress();
+    onRequestEnd("api/focus");
+    request->send(200, "application/json", "{\"result\":\"true\"}");
+}
+
+/// <summary>
+/// Handles GET /api/takePhoto request to take a photograph.
+/// Supports optional "msec" query parameter to control the shutter hold duration (default: 1000ms).
+/// </summary>
+void HTTPServer::handleTakePhoto(AsyncWebServerRequest *request)
+{
+    onRequestStart("api/takePhoto");
+    if (request->hasParam("msec"))
+    {
+        int ms = request->getParam("msec")->value().toInt();
+        shutterController->pressFullWithDelay(ms);
+    }
+    else
+    {
+        shutterController->pressFullWithDelay(1000);
+    }
+    onRequestEnd("api/takePhoto");
+    request->send(200, "application/json", "{\"result\":\"true\"}");
+}
+
+/// <summary>
+/// Handles GET /api/reset request to release the shutter and return to neutral position.
+/// Logs the request, releases all controls, and responds with success.
+/// </summary>
+void HTTPServer::handleReset(AsyncWebServerRequest *request)
+{
+    onRequestStart("api/reset");
+    shutterController->unPress();
+    onRequestEnd("api/reset");
+    request->send(200, "application/json", "{\"result\":\"true\"}");
+}
+
+/// <summary>
+/// Handles GET /api/multiple request to take multiple photos in sequence.
+/// Requires query parameters: "count" (number of photos) and "delay" (ms between shots).
+/// Supports optional "msec" parameter for individual shot duration (default: 1000ms).
+/// </summary>
+void HTTPServer::handleMultiple(AsyncWebServerRequest *request)
+{
+    onRequestStart("api/multiple");
+    if (request->hasParam("count") && request->hasParam("delay"))
+    {
+        int ms = 1000;
+        int count = request->getParam("count")->value().toInt();
+        int delayMs = request->getParam("delay")->value().toInt();
+        if (request->hasParam("msec"))
+        {
+            ms = request->getParam("msec")->value().toInt();
+        }
+        shutterController->multipleShoot(ms, count, delayMs);
+    }
+    onRequestEnd("api/multiple");
+    request->send(200, "application/json", "{\"result\":\"true\"}");
+}
+
+/// <summary>
+/// Handles GET /get request as a simple health check endpoint.
+/// Returns a plain text "Is working" response to verify server connectivity.
+/// </summary>
+void HTTPServer::handleHealthCheck(AsyncWebServerRequest *request)
+{
+    onRequestStart("get");
+    onRequestEnd("get");
+    request->send(200, "text/plain", "Is working");
+}
+
+/// <summary>
+/// Logs the start of a request to the serial console and enables the status LED.
+/// Called at the beginning of each request handler.
+/// </summary>
+/// <param name="endpoint">The name of the API endpoint being processed</param>
+void HTTPServer::onRequestStart(const char* endpoint)
+{
+    Serial.print("[REQUEST] ");
+    Serial.println(endpoint);
+    digitalWrite(LED_BUILTIN, HIGH);
+}
+
+/// <summary>
+/// Logs the completion of a request to the serial console and disables the status LED.
+/// Called at the end of each request handler.
+/// </summary>
+/// <param name="endpoint">The name of the API endpoint that was processed</param>
+void HTTPServer::onRequestEnd(const char* endpoint)
+{
+    digitalWrite(LED_BUILTIN, LOW);
+    Serial.print("[RESPONSE] ");
+    Serial.println(endpoint);
+}
+
+/// <summary>
+/// Initializes the WiFi access point and starts the HTTP server.
+/// Must be called during application setup to enable the server.
+/// Calls setupWiFiAP() to configure WiFi, setupRoutes() to register endpoints, and starts the server.
+/// </summary>
+void HTTPServer::begin(const char* ssid, const char* password,
+                       IPAddress local_IP, IPAddress gateway, IPAddress subnet)
+{
+    setupWiFiAP(ssid, password, local_IP, gateway, subnet);
+    setupRoutes();
+    server->begin();
+    Serial.println("HTTP Server started");
+}

+ 107 - 0
HTTPServer.h

@@ -0,0 +1,107 @@
+#ifndef HTTP_SERVER_H
+#define HTTP_SERVER_H
+
+#include <ESPAsyncWebServer.h>
+#include <ESP8266WiFi.h>
+#include "ShutterController.h"
+
+/// <summary>
+/// HTTP server for handling Minolta remote control API requests.
+/// Manages WiFi access point configuration, HTTP routes, and request handling
+/// for camera control operations like focus, shutter, and multiple shots.
+/// </summary>
+class HTTPServer
+{
+private:
+    /// <summary>Pointer to the AsyncWebServer instance</summary>
+    AsyncWebServer* server;
+    
+    /// <summary>Pointer to the ShutterController interface for camera control</summary>
+    IShutterController* shutterController;
+    
+    /// <summary>Registers all HTTP API endpoints and their handlers</summary>
+    void setupRoutes();
+    
+    /// <summary>
+    /// Handles GET /api/focus request to perform a half press (focus).
+    /// </summary>
+    /// <param name="request">Async web server request object</param>
+    void handleFocus(AsyncWebServerRequest *request);
+    
+    /// <summary>
+    /// Handles GET /api/takePhoto request to take a photo with optional delay.
+    /// Accepts optional query parameter "msec" for photo hold duration.
+    /// </summary>
+    /// <param name="request">Async web server request object</param>
+    void handleTakePhoto(AsyncWebServerRequest *request);
+    
+    /// <summary>
+    /// Handles GET /api/reset request to release the shutter and return to neutral position.
+    /// </summary>
+    /// <param name="request">Async web server request object</param>
+    void handleReset(AsyncWebServerRequest *request);
+    
+    /// <summary>
+    /// Handles GET /api/multiple request to take multiple photos in sequence.
+    /// Accepts query parameters: "count" (number of photos) and "delay" (ms between shots).
+    /// Optional parameter "msec" specifies duration of each shot.
+    /// </summary>
+    /// <param name="request">Async web server request object</param>
+    void handleMultiple(AsyncWebServerRequest *request);
+    
+    /// <summary>
+    /// Handles GET /get request as a health check endpoint.
+    /// </summary>
+    /// <param name="request">Async web server request object</param>
+    void handleHealthCheck(AsyncWebServerRequest *request);
+    
+    /// <summary>
+    /// Logs the start of a request processing and enables the status LED.
+    /// </summary>
+    /// <param name="endpoint">Name of the API endpoint being processed</param>
+    void onRequestStart(const char* endpoint);
+    
+    /// <summary>
+    /// Logs the completion of a request processing and disables the status LED.
+    /// </summary>
+    /// <param name="endpoint">Name of the API endpoint that was processed</param>
+    void onRequestEnd(const char* endpoint);
+    
+public:
+    /// <summary>
+    /// Constructs an HTTPServer instance.
+    /// </summary>
+    /// <param name="port">HTTP server port number (typically 80)</param>
+    /// <param name="controller">Pointer to ShutterController for camera operations</param>
+    HTTPServer(uint16_t port, IShutterController* controller);
+    
+    /// <summary>
+    /// Destructor that cleans up the AsyncWebServer instance.
+    /// </summary>
+    ~HTTPServer();
+    
+    /// <summary>
+    /// Initializes the WiFi access point and starts the HTTP server.
+    /// Must be called during application setup.
+    /// </summary>
+    /// <param name="ssid">WiFi network name</param>
+    /// <param name="password">WiFi network password</param>
+    /// <param name="local_IP">Static IP address for the access point</param>
+    /// <param name="gateway">Gateway IP address</param>
+    /// <param name="subnet">Subnet mask</param>
+    void begin(const char* ssid, const char* password, 
+               IPAddress local_IP, IPAddress gateway, IPAddress subnet);
+    
+    /// <summary>
+    /// Configures the ESP8266 as a WiFi access point with the specified credentials.
+    /// </summary>
+    /// <param name="ssid">WiFi network name</param>
+    /// <param name="password">WiFi network password</param>
+    /// <param name="local_IP">Static IP address for the access point</param>
+    /// <param name="gateway">Gateway IP address</param>
+    /// <param name="subnet">Subnet mask</param>
+    void setupWiFiAP(const char* ssid, const char* password,
+                     IPAddress local_IP, IPAddress gateway, IPAddress subnet);
+};
+
+#endif // HTTP_SERVER_H

+ 93 - 0
ShutterController.cpp

@@ -0,0 +1,93 @@
+#include "ShutterController.h"
+#include <Arduino.h>
+
+/// <summary>
+/// Constructs a ShutterController instance with specified GPIO pins.
+/// </summary>
+ShutterController::ShutterController(uint8_t focusPin, uint8_t shutterPin)
+    : focusPin(focusPin), shutterPin(shutterPin), isFocusPressed(false)
+{
+}
+
+/// <summary>
+/// Performs a half press of the shutter to initiate focus.
+/// Sets the focus pin HIGH and marks focus as pressed.
+/// </summary>
+void ShutterController::halfPress()
+{
+    digitalWrite(focusPin, HIGH);
+    isFocusPressed = true;
+}
+
+/// <summary>
+/// Performs a full press of the shutter to take a photo.
+/// Automatically half-presses the shutter if not already pressed.
+/// Sets the shutter pin HIGH to simulate a full button press.
+/// </summary>
+void ShutterController::fullPress()
+{
+    if (!isFocusPressed)
+    {
+        halfPress();
+        delay(1000);
+    }
+    
+    digitalWrite(shutterPin, HIGH);
+}
+
+/// <summary>
+/// Presses the shutter fully, waits for the specified delay, then releases.
+/// Automatically returns to neutral position after the delay.
+/// </summary>
+/// <param name="ms">Delay in milliseconds between full press and release</param>
+void ShutterController::pressFullWithDelay(int ms)
+{
+    fullPress();
+    delay(ms);
+    unPress();
+}
+
+/// <summary>
+/// Releases the shutter and returns to neutral position.
+/// Sets both focus and shutter pins LOW and updates the focus state.
+/// </summary>
+void ShutterController::unPress()
+{
+    digitalWrite(shutterPin, LOW);
+    digitalWrite(focusPin, LOW);
+    isFocusPressed = false;
+}
+
+/// <summary>
+/// Takes multiple photos in sequence with configurable timing.
+/// Ensures focus is locked before taking photos, then executes the sequence.
+/// </summary>
+/// <param name="ms">Duration of each full press in milliseconds</param>
+/// <param name="count">Number of photos to take</param>
+/// <param name="delayMs">Delay between consecutive shots in milliseconds</param>
+void ShutterController::multipleShoot(int ms, int count, int delayMs)
+{
+    if (!isFocusPressed)
+    {
+        halfPress();
+        delay(1000);
+    }
+    
+    while (count > 0)
+    {
+        fullPress();
+        delay(ms);
+        digitalWrite(shutterPin, LOW);
+        count--;
+        delay(delayMs);
+    }
+}
+
+/// <summary>
+/// Returns the current focus press state.
+/// </summary>
+/// <returns>True if focus is currently pressed, false otherwise</returns>
+bool ShutterController::getFocusPressedState() const
+{
+    return isFocusPressed;
+}

+ 106 - 0
ShutterController.h

@@ -0,0 +1,106 @@
+#ifndef SHUTTER_CONTROLLER_H
+#define SHUTTER_CONTROLLER_H
+
+/// <summary>
+/// Interface for camera shutter control operations.
+/// Defines the contract for controlling camera focus and shutter functionality.
+/// </summary>
+class IShutterController
+{
+public:
+    virtual ~IShutterController() = default;
+    
+    /// <summary>
+    /// Performs a half press of the shutter to initiate focus.
+    /// This is equivalent to pressing the shutter button halfway down.
+    /// </summary>
+    virtual void halfPress() = 0;
+    
+    /// <summary>
+    /// Performs a full press of the shutter to take a photo.
+    /// Automatically calls halfPress() if not already pressed.
+    /// </summary>
+    virtual void fullPress() = 0;
+    
+    /// <summary>
+    /// Releases the shutter and returns to neutral position.
+    /// Resets focus state and shutter pin to LOW.
+    /// </summary>
+    virtual void unPress() = 0;
+    
+    /// <summary>
+    /// Presses the shutter fully, waits for specified delay, then releases.
+    /// </summary>
+    /// <param name="ms">Delay in milliseconds between full press and release</param>
+    virtual void pressFullWithDelay(int ms) = 0;
+    
+    /// <summary>
+    /// Takes multiple photos in sequence with configurable timing.
+    /// </summary>
+    /// <param name="ms">Duration of each full press in milliseconds</param>
+    /// <param name="count">Number of photos to take</param>
+    /// <param name="delayMs">Delay between consecutive shots in milliseconds</param>
+    virtual void multipleShoot(int ms, int count, int delayMs) = 0;
+};
+
+/// <summary>
+/// Implementation of camera shutter control for Minolta remote.
+/// Controls focus and shutter via GPIO pins to simulate button presses.
+/// </summary>
+class ShutterController : public IShutterController
+{
+private:
+    /// <summary>GPIO pin number for focus control</summary>
+    uint8_t focusPin;
+    
+    /// <summary>GPIO pin number for shutter control</summary>
+    uint8_t shutterPin;
+    
+    /// <summary>Flag indicating whether focus is currently pressed</summary>
+    bool isFocusPressed;
+    
+public:
+    /// <summary>
+    /// Constructs a ShutterController instance.
+    /// </summary>
+    /// <param name="focusPin">GPIO pin for focus control (e.g., D1/GPIO5)</param>
+    /// <param name="shutterPin">GPIO pin for shutter control (e.g., D2/GPIO4)</param>
+    ShutterController(uint8_t focusPin, uint8_t shutterPin);
+    
+    /// <summary>
+    /// Performs a half press of the shutter to initiate focus.
+    /// </summary>
+    void halfPress() override;
+    
+    /// <summary>
+    /// Performs a full press of the shutter to take a photo.
+    /// </summary>
+    void fullPress() override;
+    
+    /// <summary>
+    /// Releases the shutter and returns to neutral position.
+    /// </summary>
+    void unPress() override;
+    
+    /// <summary>
+    /// Presses the shutter fully, waits for specified delay, then releases.
+    /// </summary>
+    /// <param name="ms">Delay in milliseconds between full press and release</param>
+    void pressFullWithDelay(int ms) override;
+    
+    /// <summary>
+    /// Takes multiple photos in sequence with configurable timing.
+    /// </summary>
+    /// <param name="ms">Duration of each full press in milliseconds</param>
+    /// <param name="count">Number of photos to take</param>
+    /// <param name="delayMs">Delay between consecutive shots in milliseconds</param>
+    void multipleShoot(int ms, int count, int delayMs) override;
+    
+    /// <summary>
+    /// Gets the current focus press state.
+    /// </summary>
+    /// <returns>True if focus is currently pressed, false otherwise</returns>
+    bool getFocusPressedState() const;
+};
+
+#endif // SHUTTER_CONTROLLER_H

+ 79 - 155
minolta_remote_v1.ino

@@ -1,14 +1,34 @@
-#include <ArduinoJson.h>
+/// <summary>
+/// Minolta Remote Control Application
+/// 
+/// This application implements a WiFi-controlled remote for Minolta cameras.
+/// Running on an ESP8266 microcontroller, it creates a WiFi access point and provides
+/// an HTTP API for controlling camera focus and shutter functions remotely.
+/// 
+/// Features:
+/// - WiFi Access Point for remote connectivity
+/// - HTTP REST API for camera control
+/// - Support for half-press (focus), full-press (capture), and multiple shots
+/// - Status LED feedback (GPIO-2/LED_BUILTIN)
+/// 
+/// Hardware:
+/// - ESP8266 D1 Mini microcontroller
+/// - GPIO5 (D1) - Focus control pin
+/// - GPIO4 (D2) - Shutter control pin
+/// - GPIO2 (LED_BUILTIN) - Status LED indicator
+/// 
+/// API Endpoints:
+/// - GET /api/focus - Perform a half press (focus)
+/// - GET /api/takePhoto[?msec=duration] - Take a photo
+/// - GET /api/reset - Release the shutter
+/// - GET /api/multiple?count=n&delay=ms[&msec=duration] - Take multiple photos
+/// - GET /get - Health check
+/// </summary>
 
-#include <AsyncEventSource.h>
-#include <AsyncJson.h>
-#include <AsyncWebSocket.h>
-#include <AsyncWebSynchronization.h>
-#include <ESPAsyncWebServer.h>
-#include <StringArray.h>
-#include <WebAuthentication.h>
-#include <WebHandlerImpl.h>
-#include <WebResponseImpl.h>
+#include <ArduinoJson.h>
+#include "Config.h"
+#include "ShutterController.h"
+#include "HTTPServer.h"
 
 #include <AsyncEventSource.h>
 #include <AsyncJson.h>
@@ -39,159 +59,63 @@
 #include <WiFiServerSecureBearSSL.h>
 #include <WiFiUdp.h>
 
-static const uint8_t D1   = 5;
-static const uint8_t D2   = 4;
-static const char* ssid = "MINOLTA_REMOTE_CONTROL";
-static const char* password = "12345678";
-bool isFocusPressed = false;
-IPAddress local_IP(192,168,1,200);
-IPAddress gateway(192,168,1,1);
-IPAddress subnet(255,255,255,0);
-AsyncWebServer server(80);
-
-void setup() {
-  // put your setup code here, to run once:
-  Serial.begin(115200);
-  pinMode(LED_BUILTIN, OUTPUT);  // Initialize the LED_BUILTIN pin as an output
+static const uint8_t D1   = Config::PIN_FOCUS;
+static const uint8_t D2   = Config::PIN_SHUTTER;
+static const char* ssid = Config::WIFI_SSID;
+static const char* password = Config::WIFI_PASSWORD;
+IPAddress local_IP = Config::WIFI_IP;
+IPAddress gateway = Config::WIFI_GATEWAY;
+IPAddress subnet = Config::WIFI_SUBNET;
+
+/// <summary>Pointer to the ShutterController instance for camera control operations</summary>
+IShutterController* shutterController = nullptr;
+
+/// <summary>Pointer to the HTTPServer instance for handling API requests</summary>
+HTTPServer* httpServer = nullptr;
+
+/// <summary>
+/// Initializes all hardware components: serial communication and GPIO pins.
+/// Sets up serial communication at the configured baud rate,
+/// configures all GPIO pins as outputs, and initializes them to LOW.
+/// Logs a confirmation message to the serial console upon completion.
+/// </summary>
+void initializeHardware()
+{
+  Serial.begin(Config::SERIAL_BAUD);
+  pinMode(LED_BUILTIN, OUTPUT);
   pinMode(D1, OUTPUT);
   pinMode(D2, OUTPUT);
-  digitalWrite(LED_BUILTIN, LOW); 
+  digitalWrite(LED_BUILTIN, LOW);
   digitalWrite(D1, LOW);
   digitalWrite(D2, LOW);
-  if (!WiFi.softAPConfig (local_IP, gateway, subnet))
-  {   
-    Serial.println("Failed to config IP");
-  }
-  WiFi.softAP(ssid, password);
-  Serial.println(WiFi.softAPIP());
-  Serial.println("Waiting for connect");
-  /*while(WiFi.status() != WL_CONNECTED)
-  {
-    digitalWrite(LED_BUILTIN, HIGH); 
-    delay(500);
-    Serial.print(".");  
-    Serial.print(WiFi.status());
-    digitalWrite(LED_BUILTIN, LOW); 
-  }*/
-   Serial.println("Client connected");
-
-   server.on("/api/focus",HTTP_GET, [](AsyncWebServerRequest *request)
-   {
-    Serial.println("api/focus");
-    digitalWrite(LED_BUILTIN, HIGH); 
-    halfPress();
-    digitalWrite(LED_BUILTIN, LOW); 
-    request->send(200,"application/json","{\"result\":\"true\"}");
-   });
-
-   server.on("/api/takePhoto",HTTP_GET, [](AsyncWebServerRequest *request)
-   {
-    Serial.println("api/takePhoto");
-    digitalWrite(LED_BUILTIN, HIGH); 
-    if (request->hasParam("msec"))
-    {
-      int ms = request->getParam("msec")->value().toInt();
-    }
-    else
-    {
-      pressFullWithDelay(1000);
-    }
-    digitalWrite(LED_BUILTIN, LOW); 
-    request->send(200,"application/json","{\"result\":\"true\"}");
-   });
-
-   server.on("/api/reset",HTTP_GET, [](AsyncWebServerRequest *request)
-   {
-    Serial.println("api/reset");
-    digitalWrite(LED_BUILTIN, HIGH); 
-    unPress();
-    digitalWrite(LED_BUILTIN, LOW); 
-    request->send(200,"application/json","{\"result\":\"true\"}");
-   });
-
-    server.on("/api/multiple",HTTP_GET, [](AsyncWebServerRequest *request)
-   {
-    Serial.println("api/multiple");
-    digitalWrite(LED_BUILTIN, HIGH); 
-    if (request->hasParam("count") && request->hasParam("delay"))
-    {
-      int ms = 1000;
-      int count = request->getParam("count")->value().toInt();
-      int delayMs = request->getParam("delay")->value().toInt();
-      if (request->hasParam("msec"))
-      {
-        ms = request->getParam("msec")->value().toInt();
-      }
-      if (!isFocusPressed)
-      {
-        halfPress();
-        delay(1000);
-      }
-      while (count>0)
-      {
-        fullPress();
-        delay(ms);
-        digitalWrite(D2, LOW);
-        count--;
-        delay(delayMs);
-      }
-    }
-    digitalWrite(LED_BUILTIN, LOW); 
-    request->send(200,"application/json","{\"result\":\"true\"}");
-   });
-   server.on("/get", HTTP_GET, [](AsyncWebServerRequest *request){    request->send(200, "text/plain", "Is working"); });
-    server.begin();
+  Serial.println("Hardware initialized");
 }
 
-void halfPress()
-{
-    digitalWrite(D1, HIGH);
-    isFocusPressed = true;
-}
-
-void fullPress()
-{
-  if (!isFocusPressed)
-    {
-      halfPress();
-      delay(1000);
-    }
-    
-    digitalWrite(D2, HIGH);
-}
-
-void pressFullWithDelay(int ms)
-{
-    fullPress();
-    delay(ms);
-    unPress();
-}
-
-void unPress()
-{
-  digitalWrite(D2, LOW);
-  digitalWrite(D1, LOW);
-  isFocusPressed = false;
-}
-
-void multipleShoot(int ms, int count, int delayMs)
-{
-  if (!isFocusPressed)
-      {
-        halfPress();
-        delay(1000);
-      }
-  while (count>0)
-      {
-        fullPress();
-        delay(ms);
-        digitalWrite(D2, LOW);
-        count--;
-        delay(delayMs);
-      }  
+/// <summary>
+/// Arduino setup function called once on device boot.
+/// Initializes all system components in sequence:
+/// 1. Hardware (serial, GPIO pins)
+/// 2. ShutterController for camera control
+/// 3. HTTPServer with WiFi access point
+/// After setup completes, the device is ready to accept API requests.
+/// </summary>
+void setup() {
+  // Initialize hardware (serial and pins)
+  initializeHardware();
+  
+  // Initialize ShutterController
+  shutterController = new ShutterController(D1, D2);
+  
+  // Initialize HTTPServer
+  httpServer = new HTTPServer(Config::HTTP_PORT, shutterController);
+  httpServer->begin(ssid, password, local_IP, gateway, subnet);
 }
 
-
+/// <summary>
+/// Arduino loop function called repeatedly after setup completes.
+/// Currently empty as the HTTP server runs asynchronously via interrupts.
+/// Can be extended in the future for periodic tasks or health monitoring.
+/// </summary>
 void loop() {
   // put your main code here, to run repeatedly: