# Project export: MindAssist

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2026
- Tagline: MindAssist is a brain-controlled robotic arm for assistive feeding that restores independence to people with motor impairments
- Devpost: https://devpost.com/software/mindassist
- GitHub: https://github.com/YehyunLee/MindAssist
- Video: https://www.youtube.com/embed/HoBlh9wGy-c?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 4 GitHub contributor(s) — YehyunLee (20 commits), Jessica Chen (5 commits), brandoncai888 (4 commits), Etienne Jacquot (1 commits)

## Devpost submission (written by the team)

### Inspiration

Millions of people living with motor impairments retain their thoughts and intentions, yet lose the ability to perform basic daily tasks. Something as simple as feeding oneself can become dependent on constant assistance. This loss is not just physical. It affects dignity, confidence, and autonomy. Assistive feeding devices have improved quality of life for many people with motor impairments. However, most current systems rely on residual physical input or voice commands, which can be unreliable and difficult to repeat. We were inspired by the gap between intention and execution. If someone can focus, that intent should be enough to initiate meaningful action. MindAssist translates simple neural signals directly into a complete assistive routine. Rather than requiring continuous control, it enables a single intentional mental state to trigger a safe, autonomous sequence.

### What it does

MindAssist is a brain-controlled assistive feeding system. Using a real-time EEG headset, a sustained focus signal activates a robotic arm that performs a complete feeding routine safely and autonomously. No physical interaction, no repeated voice commands, just focus-driven control. The system continuously processes EEG signals using thresholding, smoothing, and sustained activation detection to distinguish deliberate intent from noise. When a sustained focus signal is detected, the robotic arm activates. The arm moves from a neutral position to pick up food, uses computer vision to detect and align with the user’s mouth, delivers the bite safely, detects completion, and returns to neutral. The system then waits for the next intentional activation. For environmental awareness, we integrated a camera-based computer vision module. The system performs real-time face detection and mouth localization. The detected coordinates are used to adjust the final approach of the robotic arm, allowing dynamic alignment rather than fixed positioning. We structured the entire system as a finite state machine. This ensured safe transitions between idle, activation, feeding, and reset states, preventing repeated or unintended motion.

### How we built it

Our team brought together hardware and software engineers working at the intersection of robotics, signal processing, and computer vision. On the hardware side, we built and tuned the robotic arm, defined safe motion cases, and developed repeatable feeding trajectories. We experimented with different sensors and mounting configurations to improve reliability and stability. We also developed the EEG processing pipeline testing signal thresholds, implementing smoothing and sustained activation logic, and addressing connectivity instability. Bluetooth pairing was initially inconsistent, so we automated the connection process to make the system robust and repeatable. On the vision side, we implemented real-time face detection and object localization. We processed live camera frames, extracted coordinates, and translated those into spatial adjustments for the robotic arm. Latency optimization was critical to ensure that the arm’s movement felt responsive and aligned with the user’s position. The integration phase required unifying three asynchronous systems: neural input, mechanical actuation, and visual feedback. We built a structured software architecture to coordinate them deterministically, prioritizing safety, clarity, and reliability over complexity.

### Challenges we ran into

EEG signals are inherently unstable and sensitive to noise. Bluetooth pairing and data streaming were initially inconsistent, so we automated and stabilized the connection pipeline. Synchronizing EEG input, servo motion, and vision processing demanded strict control architecture to avoid timing conflicts. The robotic arm itself required precise tuning due to sensitive servo behavior. Achieving smooth, controlled movement while maintaining responsiveness was a key engineering challenge.

### Accomplishments we're proud of

This is an ambitious project, especially for a team including first-time hackers. We chose to work with inherently noisy EEG signals in a high-stakes and complex assistive context. Building a system that translates brain signals into physical motion required careful engineering and disciplined design decisions.

### What we learned

We learned that in assistive technology, simplicity often outperforms complexity. That insight guided our decision to use a simpler EEG interface with strong filtering and structured activation logic rather than a more complex but less stable signal classification system. We designed for reliability over sophistication.

### What's next

Longevity and motor impairment represent a growing, global challenge, making this a highly scalable problem space. While we focused on feeding, the same intent-driven control framework can extend to tasks such as medication management, object retrieval, communication aids, and environmental control. It can also be valuable to log the robotic arm’s actions in a database, enabling caregivers to monitor usage patterns and allowing the data to be analyzed further to inform healthcare decisions and long-term care optimization. Our immediate next step is engaging directly with the mobility-impaired community. Due to the constraints of a 36-hour build, we were not able to gather user feedback during development. We are eager to iterate based on real-world input and refine the system in collaboration with the individuals it is designed to support.

## README (from the GitHub repository)

# MindAssist

A **non-invasive, low-cost, mind-controlled robotic arm** using the NeuroSky MindWave Mobile 2 EEG headset to help people with limited mobility perform assistive tasks such as feeding and simple object grasping — purely through thought.

Inspired by Neuralink's CONVOY trial demo, recreated with affordable consumer hardware and open-source software.

## Problem Statement

> "One in three U.S. stroke survivors faces food insecurity — nearly twice the rate of people without stroke — because they often can't reliably feed themselves without assistance (American Heart Association, 2022). We're building a mind-controlled assistive arm so survivors can trigger an entire feeding routine with simple mental states, restoring autonomy even when fine motor control is gone."

## Hardware

- **EEG**: NeuroSky MindWave Mobile 2 (provides Attention, Meditation, and Blink values)
- **Robotic arm**: Hiwonder / LewanSoul miniArm Standard Kit — 5 DOF, high-precision digital servos, built-in Bluetooth, 6-channel knob controller for manual testing
- **Microcontroller**: miniArm Atmega328 controller board (kit default) / Arduino Uno R3 clone (backup)
- **Extras included with kit**: ESP32-Cam, glowing ultrasonic sensor, touch sensor, acceleration sensor

## Control Concept

| Mental State | Threshold | Action |
|---|---|---|
| **Focus** (high Attention) | > 65–75 | Move arm forward / lift / extend toward target |
| **Relax** (high Meditation) | > 65–75 | Retract arm / open gripper / return to rest |

## Architecture

```
MindWave Mobile 2 ──Bluetooth──▸ Laptop (Python)
                                    │
                              EEG parsing &
                              state machine (FSM)
                                    │
                              USB Serial commands
                                    │
                              Arduino miniArm ──▸ Servos
```

1. **EEG ingestion** — MindWave ↔ Bluetooth ↔ Python service parsing ThinkGear binary protocol directly (`pyserial`, no external EEG libs).
2. **State → motion planner** — Python FSM converts `FOCUS` / `RELAX` / `BLINK` into commands (`POS1`, `FEED`, `HOME`). Auto-completes the feeding routine if focus is sustained > 2 s.
3. **Robot layer** — Arduino serial parser + `Servo` library with preset joint positions (`reach()`, `lift()`, `feed()`, `home()`).

## Real-time EEG -> Commander bridge

`EEG/eeg_visualizer.py` now publishes live EEG packets on localhost UDP (`127.0.0.1:8765`), and `PythonInput/Commander.py` subscribes to that stream in real time.

- EEG stream payload fields: `attention`, `meditation`, `signal`, `blink`, `state`, `ts`
- Transport: local UDP JSON (same laptop, no cloud)
- Commander behavior: finite-state machine for robot-arm step commands (`0..3`)

FSM used by `PythonInput/Python.py`:

- `HOME` -> `REACH` when focus is high (`FOCUS`, attention >= 60) -> send `1`
- `REACH` -> `GRAB` on blink -> send `2`
- `GRAB` -> `RETURN` when relax is high (`RELAX`, meditation >= 60) -> send `3`
- `RETURN` -> `HOME` on relax/idle -> send `0`

If EEG stream is stale for 5 seconds, commander sends `0` (safe/home).

### Run both processes together

1. Terminal A: `python EEG/eeg_visualizer.py`
2. Terminal B: `python PythonInput/Commander.py`

Make sure `PORT` in `PythonInput/Python.py` matches your Arduino serial device.

## Documentation & Links

- [NeuroSky MindWave Mobile & Arduino tutorial](https://developer.neurosky.com/docs/doku.php?id=mindwave_mobile_and_arduino)
- [Hiwonder miniArm wiki](https://wiki.hiwonder.com/projects/miniArm/en/latest/)
- [miniArm Arduino IDE setup](https://docs.hiwonder.com/projects/miniArm/en/latest/docs/2.Set_Arduino_Environment.html)
- [MindWave Mobile 2 (RobotShop)](https://ca.robotshop.com/products/neurosky-mindwave-mobile-2-eeg-sensor-starter-kit)
- [miniArm Standard Kit (Amazon)](https://www.amazon.com/dp/B0DCB8KLGT?_encoding=UTF8&th=1)

Built with Codex.


## Detected evidence (automated analysis)

Indexed codebase: 25 recognized source files, 116 KB.
- C (language) — detected in the code
- C++ (language) — detected in the code
- FastAPI (technology) — detected in the code
- Python (language) — detected in the code
- OpenAI (technology) — claimed on Devpost, not found in the code

## Codebase structure (from repository index)

### Files (53 of 53)

```
.DS_Store
.gitignore
.idea/workspace.xml
docs.txt
EEG/bt_reset.py
EEG/eeg_processor.py
EEG/eeg_stream.py
EEG/eeg_test_conn.py
EEG/eeg_visualizer.py
FaceDetection/face_landmarker.task
FaceDetection/mouth_detection.py
flash_download_tool_3.9.7/configure/esp32s3/security.conf
flash_download_tool_3.9.7/configure/esp32s3/spi_download.conf
flash_download_tool_3.9.7/configure/esp32s3/utility.conf
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/color_detection_web.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/color_detection.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/face_detection_web.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/face_detection.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/image_transmit.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/image_transmit.bin_rep_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/line_patrol_web.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/line_patrol.bin_rep
flash_download_tool_3.9.7/dl_temp/_temp_by_dltool/downloadPanel1/logs/1020BA768E60.txt
flash_download_tool_3.9.7/dl_temp/bin_tmp/downloadPanel1/image_transmit.bin_rep
flash_download_tool_3.9.7/doc/release_note.txt
flash_download_tool_3.9.7/logs/1020BA768E60.txt
flash_download_tool_3.9.7/logs/24587CD554A0.txt
flash_download_tool_3.9.7/logs/CC8DA20C7CAC.txt
main.py
MiniArm_color_trace/hw_esp32cam_ctl.cpp
MiniArm_color_trace/hw_esp32cam_ctl.h
MiniArm_color_trace/MiniArm_color_trace.ino
MiniArm_Ultrasound_Grab/actions.h
MiniArm_Ultrasound_Grab/mini_servo.cpp
MiniArm_Ultrasound_Grab/mini_servo.h
MiniArm_Ultrasound_Grab/MiniArm_Ultrasound_Grab.ino
MiniArm_Ultrasound_Grab/tone.h
MiniArm_Ultrasound_Grab/Ultrasound.cpp
MiniArm_Ultrasound_Grab/Ultrasound.h
MiniArm/MiniArm.ino
MiniArm/tone.h
ObjectDetection/efficientdet_lite0.tflite
ObjectDetection/esp_cam_object_detection.py
ObjectDetection/esp_cam_viewer.py
ObjectDetection/modal_server.py
ObjectDetection/object_detection.py
ObjectDetection/object_stream.py
ObjectDetection/yolov8n.pt
PythonInput/Commander.py
PythonInput/PythonInput.ino
PythonInput/tone.h
readme.md
requirements.txt
```

### Dependencies

- requirements.txt: fastapi, matplotlib, mediapipe, numpy, opencv-python-headless, pillow, pyserial, requests, ultralytics, uvicorn

### Recent commits (newest first)

- Update readme.md
- Update readme.md
- narrow search range and adjust pick/serve poses
- rollback
- grab angles
- Merge branch 'combine2'
- 40 threshold and rm the overlay
- combine eeg and the robot arm
- Basic python code
- debug
- arm rotate
- refactor for main branch
- Merge branch 'main' of https://github.com/YehyunLee/MindAssist
- fix bug
- combine everything
- replace mediapipe with yolo
- call object detection instead
- gitignore
- main file for 3 major files
- Refactor, rename files and folders

## Key source files (fetched from GitHub, selected and truncated for size)

### requirements.txt

```
# Added for Modal server and client
fastapi
uvicorn
requests
pillow
opencv-python-headless
mediapipe
matplotlib
numpy
pyserial
ultralytics

```

### main.py

```python
import signal
import subprocess
import sys
import time
from pathlib import Path


ROOT = Path(__file__).resolve().parent

# Commander handles object-detection subprocesses internally.
TARGETS = [
    ROOT / "EEG" / "eeg_visualizer.py",
    ROOT / "PythonInput" / "Commander.py",
]


def start_process(script_path: Path) -> subprocess.Popen:
    return subprocess.Popen(
        [sys.executable, script_path.name],
        cwd=str(script_path.parent),
    )


def stop_all(procs):
    for p in procs:
        if p.poll() is None:
            p.terminate()
    deadline = time.time() + 5
    for p in procs:
        if p.poll() is None:
            remaining = max(0, deadline - time.time())
            try:
                p.wait(timeout=remaining)
            except subprocess.TimeoutExpired:
                p.kill()


def main():
    missing = [str(p) for p in TARGETS if not p.exists()]
    if missing:
        print("Missing script(s):")
        for m in missing:
            print(f"  - {m}")
        sys.exit(1)

    procs = []
    running = True

    def _handle_stop(_sig, _frame):
        nonlocal running
        running = False

    signal.signal(signal.SIGINT, _handle_stop)
    signal.signal(signal.SIGTERM, _handle_stop)

    try:
        for target in TARGETS:
            proc = start_process(target)
            procs.append(proc)
            print(f"Started {target} (pid={proc.pid})")

        while running:
            for p in procs:
                code = p.poll()
                if code is not None:
                    print(f"Process exited (pid={p.pid}, code={code}). Stopping all.")
                    running = False
                    break
            time.sleep(0.2)
    finally:
        stop_all(procs)
        print("All processes stopped.")


if __name__ == "__main__":
    main()

```

### MiniArm_Ultrasound_Grab/actions.h

```c
//动作组文件(action group file)
#include <Arduino.h>
#define action_count 1 //动作组数量(number of action groups)

static uint8_t action[action_count][20][6] = 
    {
      //动作组1(action group 1)
      {{1,40,15,175,65,90}, {1,40,30,125,165,90}, 
      {1,40,30,125,165,90},{1,80,30,125,165,90}, 
      {1,80,30,125,65,90}, {1,80,30,175,65,180}, 
      {1,80,30,125,165,180},{1,80,30,125,165,180},
      {1,40,30,125,165,180},
      {1,40,30,125,65,180}, {1,40,30,175,65,180}, 
      {1,40,15,175,65,90}, {0,0,0,0,0,0}}
    };
```

### MiniArm_Ultrasound_Grab/mini_servo.h

```c
#ifndef _HW_ACTION_CTL_
#define _HW_ACTION_CTL_
#include "actions.h"
#include <EEPROM.h>

#define EEPROM_START_FLAG "HIWONDER"
#define EEPROM_SERVO_OFFSET_START_ADDR 1024
#define EEPROM_SERVO_OFFSET_DATA_ADDR 1024+16
#define EEPROM_SERVO_OFFSET_LEN 6u

class HW_ACTION_CTL{
  public:
  /* the using angles of secondary development example */
    uint8_t extended_func_angles[5] = { 41 ,12 ,174 ,68 ,84 }; 
    //Control execution action group
    void action_set(int num);
    int action_state_get(void);
    void action_task(void);
    void read_offset();
    int8_t* get_offset(void);
    
  private:
    //Action group control variables
    int action_num = 0;
    int8_t servo_offset[5];
    uint8_t eeprom_read_buf[16];
};

#endif //_HW_ACTION_CTL_

```

### MiniArm_color_trace/hw_esp32cam_ctl.h

```c
/*
 * 2024/02/21 hiwonder CuZn
 * Arduino与ESP32Cam的IIC通讯类(the I2C communication class between Arduino and ESP32Cam)
 * 注意：每个不同的功能，ESP32Cam也要下载对应功能的ESP32Cam程序(Note: For each different function, ESP32Cam needs to be downloaded with corresponding ESP32Cam function)
 */

#ifndef __HW_ESP32CAM_CTL_H_
#define __HW_ESP32CAM_CTL_H_

#include <Arduino.h>
#include <Wire.h>

#define ESP32CAM_ADDR 0x52

class HW_ESP32Cam{
  public:
    //初始化IIC(initialize I2C)
    void begin(void);
    //人脸识别获取函数(face recognition obtaining function)
    bool faceDetect(void);
    //颜色识别获取函数(color recognition obtaining function)
    int colorDetect(void);
    // 颜色位置获取函数(color position obtaining function)
    bool color_position(uint16_t *color_info);

    void set_led(uint8_t lightness);

};

#endif //__ESP32CAM_CTL_H_


```

### ObjectDetection/object_stream.py

```python
"""Local UDP stream helpers for object-detection telemetry."""

from __future__ import annotations

import json
import socket
from typing import Any, Dict, Optional


UDP_HOST = "127.0.0.1"
UDP_PORT = 8766


class UDPBroadcaster:
    def __init__(self, host: str = UDP_HOST, port: int = UDP_PORT):
        self.addr = (host, port)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    def send(self, payload: Dict[str, Any]) -> None:
        msg = json.dumps(payload, separators=(",", ":")).encode("utf-8")
        self.sock.sendto(msg, self.addr)

    def close(self) -> None:
        try:
            self.sock.close()
        except OSError:
            pass


class UDPSubscriber:
    def __init__(self, host: str = UDP_HOST, port: int = UDP_PORT, timeout: float = 0.05):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.settimeout(timeout)
        self.sock.bind((host, port))

    def recv(self) -> Optional[Dict[str, Any]]:
        try:
            raw, _ = self.sock.recvfrom(4096)
        except socket.timeout:
            return None
        except OSError:
            return None
        try:
            return json.loads(raw.decode("utf-8"))
        except (UnicodeDecodeError, json.JSONDecodeError):
            return None

    def close(self) -> None:
        try:
            self.sock.close()
        except OSError:
            pass

```

### EEG/eeg_stream.py

```python
"""Local UDP stream helpers for EEG data sharing between processes."""

from __future__ import annotations

import json
import socket
from typing import Any, Dict, Optional


UDP_HOST = "127.0.0.1"
UDP_PORT = 8765


class UDPBroadcaster:
    """Sends small JSON EEG payloads over localhost UDP."""

    def __init__(self, host: str = UDP_HOST, port: int = UDP_PORT):
        self.addr = (host, port)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    def send(self, payload: Dict[str, Any]) -> None:
        msg = json.dumps(payload, separators=(",", ":")).encode("utf-8")
        self.sock.sendto(msg, self.addr)

    def close(self) -> None:
        try:
            self.sock.close()
        except OSError:
            pass


class UDPSubscriber:
    """Receives EEG payload JSON datagrams from localhost UDP."""

    def __init__(self, host: str = UDP_HOST, port: int = UDP_PORT, timeout: float = 0.1):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.settimeout(timeout)
        self.sock.bind((host, port))

    def recv(self) -> Optional[Dict[str, Any]]:
        try:
            raw, _ = self.sock.recvfrom(4096)
        except socket.timeout:
            return None
        except OSError:
            return None
        try:
            return json.loads(raw.decode("utf-8"))
        except (UnicodeDecodeError, json.JSONDecodeError):
            return None

    def close(self) -> None:
        try:
            self.sock.close()
        except OSError:
            pass

```

### EEG/eeg_test_conn.py

```python
import serial
import time
import glob
import signal
import sys
import threading

PORT_PATTERN = '/dev/tty.*Mind*'
BAUD = 57600

ser = None
running = True

def cleanup(*args):
    global ser, running
    running = False
    if ser and ser.is_open:
        ser.close()
        print("\nSerial port closed.")
    sys.exit(0)

def input_listener():
    """Background thread: type 'q' + Enter to quit gracefully."""
    global running
    while running:
        try:
            user_input = input()
            if user_input.strip().lower() == 'q':
                print("\nQuitting...")
                cleanup()
        except EOFError:
            break

signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)

listener = threading.Thread(target=input_listener, daemon=True)
listener.start()

def find_port():
    ports = glob.glob(PORT_PATTERN)
    return ports[0] if ports else None

while True:
    port = find_port()
    if not port:
        print("MindWave not found. Pair it in Bluetooth settings, then it will auto-detect...")
        while not port:
            time.sleep(2)
            port = find_port()
        print(f"Found: {port}")

    try:
        ser = serial.Serial(port, BAUD, timeout=3)
        print(f"Connected to {port}. Waiting for data... (ear clip on?)")
        print("Press 'q' + Enter to quit gracefully.")
        empty_count = 0
        while running:
            raw = ser.read()
            if raw:
                print(raw.hex(), end=' ', flush=True)
                empty_count = 0
            else:
                empty_count += 1
                if empty_count >= 5:
                    print(f"\nNo data for {empty_count * 3}s. Reconnecting...")
                    ser.close()
                    break
    except serial.SerialException as e:
        print(f"\nConnection lost: {e}")
        print("Will retry in 3s...")
        time.sleep(3)
```

### ObjectDetection/modal_server.py

```python
"""FastAPI YOLO inference server for ESP camera frames."""

from __future__ import annotations

import io
import os

import numpy as np
import uvicorn
from fastapi import FastAPI, File, HTTPException, UploadFile
from PIL import Image
from ultralytics import YOLO


app = FastAPI()

YOLO_MODEL_PATH = os.environ.get("YOLO_MODEL_PATH", "yolov8n.pt")
yolo_model = None


@app.on_event("startup")
async def startup_event():
    global yolo_model
    yolo_model = YOLO(YOLO_MODEL_PATH)
    print(f"[modal_server] Loaded YOLO model: {YOLO_MODEL_PATH}")


@app.get("/health")
async def health():
    return {"status": "ok", "model": YOLO_MODEL_PATH}


@app.post("/detect")
async def detect_image(file: UploadFile = File(...)):
    global yolo_model
    if yolo_model is None:
        raise HTTPException(status_code=503, detail="YOLO model not initialized")

    contents = await file.read()
    try:
        pil = Image.open(io.BytesIO(contents)).convert("RGB")
    except Exception as e:
        raise HTTPException(status_code=400, detail=f"Invalid image: {e}")

    img_np = np.array(pil)

    try:
        results = yolo_model(img_np, verbose=False)
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Inference failed: {e}")

    out = []
    for r in results:
        boxes = r.boxes
        if boxes is None:
            continue
        for box in boxes:
            x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())
            conf = float(box.conf[0].item())
            cls = int(box.cls[0].item())
            label = yolo_model.names.get(cls, str(cls))
            out.append(
                {
                    "label": label,
                    "score": conf,
                    "origin_x": x1,
                    "origin_y": y1,
                    "width": max(1, x2 - x1),
                    "height": max(1, y2 - y1),
                }
            )

    return {"detections": out}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8080)

```

### MiniArm_Ultrasound_Grab/Ultrasound.h

```c
#ifndef ULTRASOUND_H
#define ULTRASOUND_H

#include <Arduino.h>

#define ULTRASOUND_I2C_ADDR 0x77 

//寄存器(register)
#define DISDENCE_L    0//距离低8位，单位mm(the low 8 bits of the distance, in units of mm)
#define DISDENCE_H    1

#define RGB_BRIGHTNESS  50//0-255

#define RGB_WORK_MODE 2//RGB灯模式，0：用户自定义模式   1：呼吸灯模式  默认0(RGB light mode: 0 indicates custom mode; 1 indicates breathing light mode. The default mode is 0)

#define RGB1_R      3//1号探头的R值，0~255，默认0(The R value of probe 1 ranges from 0 to 255, with 0 as the default value)
#define RGB1_G      4//默认0(the default value is 0)
#define RGB1_B      5//默认255(the default value is 255)

#define RGB2_R      6//2号探头的R值，0~255，默认0(The R value of probe 2 ranges from 0 to 255, with 0 as the default value)
#define RGB2_G      7//默认0(the default value is 0)
#define RGB2_B      8//默认255(the default value is 255)

#define RGB1_R_BREATHING_CYCLE      9 //呼吸灯模式时，1号探头的R的呼吸周期，单位100ms 默认0，(The default breathing cycle for the red (R) component of probe 1 in breathing light mode is 0, in units of 100 milliseconds)
                                      //如果设置周期3000ms，则此值为30(If you set the cycle to 3000ms, the corresponding value for this parameter would be 30)
#define RGB1_G_BREATHING_CYCLE      10
#define RGB1_B_BREATHING_CYCLE      11

#define RGB2_R_BREATHING_CYCLE      12//2号探头(probe 2)
#define RGB2_G_BREATHING_CYCLE      13
#define RGB2_B_BREATHING_CYCLE      14

#define RGB_WORK_SIMPLE_MODE    0
#define RGB_WORK_BREATHING_MODE   1

class Ultrasound {
  public:
    Ultrasound();
    bool wireWriteByte(uint8_t addr, uint8_t val);
    bool wireWriteDataArray(uint8_t addr, uint8_t reg,uint8_t *val,unsigned int len);
    int wireReadDataArray(uint8_t addr, uint8_t reg, uint8_t *val, unsigned int len);
    
    void Breathing(uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2);
    void Color(uint8_t r1, uint8_t g1, uint8_t b1, uint8_t r2, uint8_t g2, uint8_t b2);
    //无过滤(unfiltered)
    u16 GetDistance();
    // 过滤过的(filtered)
    int Filter(void);
};
#endif

```

[15 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]