{"id":22790784,"url":"https://github.com/lin775533/iot-swarm-system","last_synced_at":"2025-06-25T08:38:23.545Z","repository":{"id":261200686,"uuid":"883506265","full_name":"Lin775533/IOT-Swarm-System","owner":"Lin775533","description":"An IoT swarm system that coordinates multiple ESP8266 nodes to form a light-sensing network, where nodes communicate via UDP to elect a master based on highest light readings and report to a Raspberry Pi controller for LED visualization.","archived":false,"fork":false,"pushed_at":"2024-11-19T01:28:24.000Z","size":384,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-30T16:47:23.623Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lin775533.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-05T04:44:06.000Z","updated_at":"2024-11-19T01:28:28.000Z","dependencies_parsed_at":"2024-11-05T09:22:22.361Z","dependency_job_id":"1dd204b7-e340-4369-9aa1-394fb00eaaef","html_url":"https://github.com/Lin775533/IOT-Swarm-System","commit_stats":null,"previous_names":["lin775533/iot-swarm-system"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Lin775533/IOT-Swarm-System","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lin775533%2FIOT-Swarm-System","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lin775533%2FIOT-Swarm-System/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lin775533%2FIOT-Swarm-System/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lin775533%2FIOT-Swarm-System/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lin775533","download_url":"https://codeload.github.com/Lin775533/IOT-Swarm-System/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lin775533%2FIOT-Swarm-System/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261837395,"owners_count":23217423,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-12T02:29:05.054Z","updated_at":"2025-06-25T08:38:23.514Z","avatar_url":"https://github.com/Lin775533.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n\r\n# IoT Light Swarm System Documentation\r\n\r\n\r\n\r\n## 1. System Overview\r\n```mermaid\r\n\r\n\r\nsequenceDiagram\r\n    participant ESP1\r\n    participant ESP2\r\n    participant ESP3\r\n    participant Pi\r\n\r\n    ESP1-\u003e\u003eESP2: LIGHT message (200ms)\r\n    ESP2-\u003e\u003eESP3: LIGHT message (200ms)\r\n    ESP3-\u003e\u003eESP1: LIGHT message (200ms)\r\n    \r\n    Note over ESP1,ESP3: Highest reading becomes master\r\n    \r\n    ESP2-\u003e\u003ePi: MASTER message (1s)\r\n    \r\n    Note over Pi: Button Press\r\n    Pi-\u003e\u003eESP1: RESET\r\n    Pi-\u003e\u003eESP2: RESET\r\n    Pi-\u003e\u003eESP3: RESET\r\n    \r\n    Note over Pi: Button Press\r\n    Pi-\u003e\u003eESP1: ACTIVATE\r\n    Pi-\u003e\u003eESP2: ACTIVATE\r\n    Pi-\u003e\u003eESP3: ACTIVATE\r\n```\r\n\r\n### 1.1 Components Used\r\n- 1× Raspberry Pi (Controller)\r\n- 3× ESP8266 (Sensor Nodes)\r\n- 4× LEDs + Resistors (Pi Display)\r\n- 2× Onboard LEDs per ESP8266\r\n- 1× Push Button (Reset Control)\r\n- 3× Photoresistors (Light Sensing)\r\n\r\n## 2. Hardware Configuration\r\n\r\n### 2.1 Raspberry Pi Pinout\r\n![image](./Images/Pi_Configuration.png)\r\n\r\n```\r\nLED Connections:\r\n┌─────────────┬──────────────┬─────────┐\r\n│ Component   │ GPIO Pin     │ State   │\r\n├─────────────┼──────────────┼─────────┤\r\n│ Red LED     │ GPIO27 (330Ω)│ Active H│\r\n│ Green LED   │ GPIO23 (330Ω)│ Active H│\r\n│ Yellow LED  │ GPIO22 (330Ω)│ Active H│\r\n│ White LED   │ GPIO24 (330Ω)│ Active H│\r\n│ Reset Button│ GPIO15       │ Pull-DN │\r\n└─────────────┴──────────────┴─────────┘\r\n```\r\n\r\n### 2.2 ESP8266 Setup\r\n![image](./Images/ESP8266_Configuration.png)\r\n\r\n```\r\nSensor Circuit:\r\n┌─────────────┬──────────────┬─────────┐\r\n│ Component   │ Pin          │ Notes   │\r\n├─────────────┼──────────────┼─────────┤\r\n│ Light Sensor│ A0           │ Analog  │\r\n│ Status LED  │ GPIO2        │ Active L│\r\n│ Master LED  │ GPIO16 (330Ω)│ Active H│\r\n└─────────────┴──────────────┴─────────┘\r\n```\r\n\r\n## 3. Communication Protocol\r\n\r\n### 3.1 Network Configuration\r\n```\r\nNetwork Settings:\r\n┌────────────┬───────────────┐\r\n│ Parameter  │ Value         │\r\n├────────────┼───────────────┤\r\n│ UDP Port   │ 2910          │\r\n│ Pi IP      │ 192.168.1.81  │\r\n│ Broadcast  │ 192.168.1.255 │\r\n│ ESP IPs    │ DHCP Assigned │\r\n└────────────┴───────────────┘\r\n```\r\n\r\n### 3.2 Message Types\r\n```\r\n1. ESP Broadcast (200ms interval)\r\n   LIGHT:[deviceID]:[reading]\r\n   Example: \"LIGHT:1234:567\"\r\n\r\n2. Master Report (1s interval)\r\n   MASTER:[deviceID]:[reading]\r\n   Example: \"MASTER:1234:567\"\r\n\r\n3. Control Commands\r\n   Reset: \"RESET\"\r\n   Activate: \"ACTIVATE\"\r\n```\r\n\r\n## 4.Part 1 - Raspberry Pi WiFi setup and packet delivery\r\n\r\n### 4.1 System Flowchart\r\n![Pi Flowchart](./Images/Pi_Flowchart.jpg)\r\n\r\n\r\n### 4.2 State Descriptions\r\n```\r\n┌──────────────┬────────────────────────────┐\r\n│ State        │ Description                │\r\n├──────────────┼────────────────────────────┤\r\n│ Initial      │ GPIO/Network setup         │\r\n│ Listening    │ Monitor UDP packets        │\r\n│ LED Control  │ Update visual feedback     │\r\n│ Reset        │ System pause \u0026 clear       │\r\n│ Active       │ Normal operation           │\r\n└──────────────┴────────────────────────────┘\r\n```\r\n\r\n### 4.3 Main Functionality\r\n\r\n\r\n### State Descriptions\r\n\r\n1. **Initial State**\r\n   - Sets up GPIO pins (LED outputs, button input), initializes UDP socket on port 2910.\r\n   - Creates empty device tracking and LED assignment arrays.\r\n\r\n2. **Listening State**\r\n   - Continuously monitors for UDP messages starting with \"MASTER:\".\r\n   - Filters and processes only master device messages for LED control.\r\n\r\n3. **LED Control State**\r\n   - Controls LED behaviors based on master ESP data (assigns colors, manages flash rates).\r\n\r\n4. **Reset State**\r\n   - Clears all device data, turns on WHITE LED for 3 seconds, sends RESET command.\r\n5. **Active State**\r\n   - Normal operation where system processes messages and updates LED displays.\r\n\r\n### 4.4 Describe Pi code\r\n\r\n#### Input Functions\r\n```python\r\ndef receive_data(self):\r\n    # Receives UDP packets from ESPs\r\n    data, addr = self.sock.recvfrom(1024)\r\n    message = data.decode('utf-8')\r\n    if message.startswith('MASTER:'):\r\n        self.handle_message(message, addr)\r\n```\r\n\r\nExplanation:\r\n\r\n- Continuously listens for UDP packets on port 2910\r\n- Filters for MASTER messages only (format: \"MASTER:deviceID:reading\")\r\n- Runs in separate thread for non-blocking operation\r\n- Forwards valid messages for processing\r\n```python\r\ndef handle_button(self):\r\n    # Monitors reset button state\r\n    if GPIO.input(RESET_BUTTON) == GPIO.HIGH:\r\n        self.send_reset() if self.system_active else self.send_activate()\r\n```\r\n\r\n\r\n Explanation:\r\n- Monitors GPIO15 for button press events\r\n- debounce protection (500ms)\r\n- Toggles between reset and activate states\r\n#### Processing Functions\r\n```python\r\ndef handle_message(self, message, addr):\r\n    # Processes master messages and updates device tracking\r\n    _, device_id, reading = message.split(':')\r\n    # Update device data and LED assignments\r\n    device_data[device_id] = {\r\n        'reading': int(reading),\r\n        'last_seen': time.time()\r\n    }\r\n```\r\nExplanation:\r\n\r\n- Parses incoming MASTER messages\r\n- Maintains device tracking dictionary\r\n- Records timestamp for timeout detection\r\n- Manages LED assignments for new devices\r\n\r\n```python\r\ndef calculate_flash_delay(self, reading):\r\n    # Maps reading to LED flash delay\r\n    return max(0.1, 1.0 - (reading / 1023.0 * 0.9))\r\n```\r\nExplanation:\r\n\r\n- Converts sensor reading (0-1023) to flash delay\r\n- Higher reading = faster flash rate (0.1s - 1.0s)\r\n- Creates visual representation of light intensity\r\n#### Output Functions\r\n```python\r\ndef update_leds(self):\r\n    # Controls LED states for visual feedback\r\n    if self.current_master:\r\n        led_pin = device_led_assignments[self.current_master]\r\n        GPIO.output(led_pin, GPIO.HIGH)\r\n        time.sleep(self.calculate_flash_delay(reading))\r\n        GPIO.output(led_pin, GPIO.LOW)\r\n```\r\nExplanation:\r\n\r\n- Each ESP gets assigned specific LED color\r\n- Flash rate indicates light sensor reading\r\n- Only master's second LED is active at any time\r\n```python\r\ndef send_reset(self):\r\n    # Handles system reset\r\n    for led in [RED_LED, GREEN_LED, YELLOW_LED]:\r\n        GPIO.output(led, GPIO.LOW)\r\n    GPIO.output(WHITE_LED, GPIO.HIGH)\r\n    self.sock.sendto(b'RESET', (BROADCAST_IP, UDP_PORT))\r\n```\r\nExplanation:\r\n\r\n- Clears all device assignments\r\n- Turns off all RGB LEDs\r\n- Flashes WHITE LED for 3 seconds\r\n- Broadcasts RESET command to all ESPs\r\n\r\n\r\n## 5. Part 2 - ESP WiFi setup and packet delivery\r\n\r\n\r\n\r\n### 5.1 System Flow Chart\r\n![ESP8266 Flowchart](./Images/ESP8266_Flowchart.jpg)\r\n\r\n\r\n### 5.2 State Descriptions\r\n\r\n1. **Initial State**\r\n   - Configures GPIO (LED outputs, analog input), connects to WiFi.\r\n   - Generates unique device ID (1000-9999) for identification.\r\n   - Sets up UDP communication on port 2910.\r\n\r\n2. **Data Collection**\r\n   - Reads analog light sensor value (0-1023).\r\n   - Broadcasts readings every 200ms to other ESPs.\r\n   - Updates status LED based on reading intensity.\r\n\r\n3. **Master Election**\r\n   - Compares local reading with others in swarm.\r\n   - Highest reading becomes master with dedicated LED indicator.\r\n   - Device with highest reading sends data to Raspberry Pi.\r\n\r\n### 5.3 Main Functionality with Code Explanation\r\n\r\n#### Input Functions\r\n```cpp\r\n// 1. Light Sensor Reading\r\nvoid loop() {\r\n    currentReading = analogRead(LIGHT_SENSOR_PIN);\r\n    // Analog reading (0-1023) from photoresistor\r\n}\r\n\r\n// 2. Network Input\r\nvoid handleIncomingPackets() {\r\n    int packetSize = udp.parsePacket();\r\n    if (packetSize) {\r\n        // Read packet into buffer\r\n        udp.read(packetBuffer, PACKET_SIZE);\r\n        lastReceivedTime = millis();\r\n        \r\n        if (strncmp(packetBuffer, \"LIGHT:\", 6) == 0) {\r\n            // Process light readings from other ESPs\r\n            int remoteID, remoteReading;\r\n            sscanf(packetBuffer, \"LIGHT:%d:%d\", \r\n                   \u0026remoteID, \u0026remoteReading);\r\n        }\r\n    }\r\n}\r\n```\r\nExplanation:\r\n- `analogRead()` converts photoresistor voltage to digital value\r\n- `handleIncomingPackets()` processes UDP messages from other ESPs and Pi\r\n- Packet format validation prevents processing invalid data\r\n\r\n#### Processing Functions\r\n```cpp\r\n// 1. Master Election\r\nvoid updateMasterStatus() {\r\n    bool shouldBeMaster = true;\r\n    int highestReading = currentReading;\r\n    \r\n    // Compare with other devices\r\n    for (int i = 0; i \u003c numDevices; i++) {\r\n        if (swarmReadings[i].reading \u003e highestReading) {\r\n            shouldBeMaster = false;\r\n            highestReading = swarmReadings[i].reading;\r\n        }\r\n    }\r\n    \r\n    // Update master status\r\n    if (shouldBeMaster != isMaster) {\r\n        isMaster = shouldBeMaster;\r\n        digitalWrite(MASTER_LED, isMaster ? LOW : HIGH);\r\n    }\r\n}\r\n\r\n// 2. LED Control\r\nvoid handleStatusLED() {\r\n    // Calculate flash rate based on reading\r\n    int flashDelay = map(currentReading, 0, 1023, 1000, 100);\r\n    \r\n    if (millis() - lastToggle \u003e= flashDelay) {\r\n        digitalWrite(STATUS_LED, !digitalRead(STATUS_LED));\r\n        lastToggle = millis();\r\n    }\r\n}\r\n```\r\nExplanation:\r\n- `updateMasterStatus()` determines if this ESP has highest reading\r\n- `handleStatusLED()` creates visual feedback proportional to reading\r\n- LED flash rate increases with higher light readings\r\n\r\n#### Output Functions\r\n```cpp\r\n// 1. Broadcast to Other ESPs\r\nvoid broadcastReading() {\r\n    char message[32];\r\n    snprintf(message, sizeof(message), \"LIGHT:%d:%d\", \r\n             deviceID, currentReading);\r\n    \r\n    // Send to all ESPs\r\n    udp.beginPacketMulticast(broadcastIP, BROADCAST_PORT, \r\n                            WiFi.localIP());\r\n    udp.write(message);\r\n    udp.endPacket();\r\n}\r\n\r\n// 2. Report to Raspberry Pi\r\nvoid sendToRaspberryPi() {\r\n    if (!isMaster) return;\r\n    \r\n    char message[32];\r\n    snprintf(message, sizeof(message), \"MASTER:%d:%d\", \r\n             deviceID, currentReading);\r\n    \r\n    // Send to Pi\r\n    udp.beginPacket(raspberryPi, BROADCAST_PORT);\r\n    udp.write(message);\r\n    udp.endPacket();\r\n}\r\n```\r\nExplanation:\r\n- `broadcastReading()` shares readings with other ESPs every 200ms\r\n- `sendToRaspberryPi()` sends master data to Pi every second\r\n- Different message formats for ESP-to-ESP and ESP-to-Pi communication\r\n\r\n### Global Variables and Configuration\r\n```cpp\r\n// Network settings\r\nconst int BROADCAST_PORT = 2910;\r\nconst unsigned long BROADCAST_INTERVAL = 200;  // 200ms\r\nconst unsigned long MASTER_TIMEOUT = 2000;     // 2s\r\n\r\n// State tracking\r\nbool isActive = true;           // System active flag\r\nbool isMaster = false;          // Master status\r\nint deviceID;                   // Random device identifier\r\nint currentReading;             // Current sensor value\r\nint numDevices = 0;             // Active devices in swarm\r\n```\r\nExplanation:\r\n- Network parameters define communication timing\r\n- State variables track device status and readings\r\n- Timeouts ensure system resilience\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flin775533%2Fiot-swarm-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flin775533%2Fiot-swarm-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flin775533%2Fiot-swarm-system/lists"}