#
openglass 2026-05-25

OpenGlass 开源智能眼镜复刻

By io 59 Views 23 MIN READ 0 Comments
用不到 $25 的现成组件,把任意眼镜改造成 AI 智能眼镜。拍照识别、语音问答、实时翻译全搞定。

项目简介

OpenGlass是一个开源智能眼镜项目,硬件核心是 Seeed Studio XIAO ESP32S3 Sense 开发板,通过 BLE 将摄像头画面和麦克风音频传给手机/电脑,再调用 LLM 实现看图问答、物体识别、文字翻译等功能。


一、硬件清单

组件说明
Seeed Studio XIAO ESP32S3 Sense带摄像头+麦克风的 ESP32 开发板
EEMB LP502030 3.7V 250mAH 电池锂电池供电
3D 打印眼镜支架STL 文件下载

二、Arduino IDE 环境配置(含国内离线安装脚本)

2.1 安装 Arduino IDE

官网下载安装即可。

2.2 添加 ESP32 开发板支持

国内网络直接通过 IDE 下载 ESP32 工具包极其困难,下面提供一键脚本方案。

第 1 步: 添加开发板管理器 URL

打开 Arduino IDE → 文件首选项附加开发板管理器网址,填入:

https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json

国内网络如果打不开,用镜像:

https://espressif.github.io/arduino-esp32/package_esp32_index.json

第 2 步: 用脚本离线下载 ESP32 2.0.17 工具包

将以下脚本保存为 download_esp32.py,与 package_esp32_index.json 放在同一目录下运行。脚本会通过 v4.gh-proxy.org 镜像加速下载,并支持断点续传。

#!/usr/bin/env python3
"""
ESP32 Arduino Core 2.0.17 工具包下载脚本(支持断点续传)
镜像加速:https://v4.gh-proxy.org/
"""

import json
import os
import urllib.request
import urllib.error
import urllib.parse
from pathlib import Path

MIRROR_PREFIX = "https://v4.gh-proxy.org/"
DOWNLOAD_DIR = Path("./esp32_tools")
CHUNK_SIZE = 8192

def get_all_urls(json_file):
    """从 package_esp32_index.json 中提取所有 url 字段"""
    with open(json_file, 'r', encoding='utf-8') as f:
        data = json.load(f)

    urls = set()
    packages = data.get("packages", [])
    for pkg in packages:
        for plat in pkg.get("platforms", []):
            if "url" in plat:
                urls.add(plat["url"])
        for tool in pkg.get("tools", []):
            for sys in tool.get("systems", []):
                if "url" in sys:
                    urls.add(sys["url"])
    return list(urls)

def get_filename_from_url(url):
    """从 URL 中提取文件名"""
    parsed = urllib.parse.urlparse(url)
    name = os.path.basename(parsed.path)
    return name if name else "unknown.bin"

def download_file(url, dest_path):
    """下载单个文件,支持断点续传"""
    mirror_url = MIRROR_PREFIX + url
    downloaded = 0
    if dest_path.exists():
        downloaded = dest_path.stat().st_size

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
    }
    if downloaded > 0:
        headers['Range'] = f'bytes={downloaded}-'

    req = urllib.request.Request(mirror_url, headers=headers)

    try:
        with urllib.request.urlopen(req) as resp:
            status = resp.status
            if status == 206:
                mode = 'ab'
            elif status == 200:
                mode = 'wb'
                if downloaded > 0:
                    print(f"服务器不支持断点续传,将重新下载整个文件")
                    downloaded = 0
            else:
                print(f"未预期的 HTTP 状态码: {status}")
                return False

            content_length = resp.headers.get('Content-Length')
            total_size = downloaded + int(content_length) if content_length else None

            dest_path.parent.mkdir(parents=True, exist_ok=True)

            with open(dest_path, mode) as f:
                while True:
                    chunk = resp.read(CHUNK_SIZE)
                    if not chunk:
                        break
                    f.write(chunk)
                    downloaded += len(chunk)
                    if total_size:
                        percent = downloaded / total_size * 100
                        print(f"\r进度: {downloaded}/{total_size} ({percent:.1f}%)", end='')
                    else:
                        print(f"\r已下载: {downloaded} bytes", end='')
                print()
        return True

    except urllib.error.HTTPError as e:
        if e.code == 416:
            print("文件已完整下载,跳过")
            return True
        else:
            print(f"HTTP 错误 {e.code}: {e.reason}")
            return False
    except Exception as e:
        print(f"下载失败: {e}")
        return False

def main():
    json_file = "package_esp32_index.json"
    if not os.path.exists(json_file):
        print(f"错误: 找不到 {json_file},请将文件放在脚本同级目录下")
        return

    print("正在解析 JSON 文件...")
    urls = get_all_urls(json_file)
    print(f"共发现 {len(urls)} 个唯一下载链接\n")

    for idx, url in enumerate(urls, start=1):
        filename = get_filename_from_url(url)
        dest_path = DOWNLOAD_DIR / filename
        print(f"[{idx}/{len(urls)}] 处理: {filename}")

        success = download_file(url, dest_path)
        if not success:
            print(f"警告: 文件 {filename} 下载失败,请稍后重试。\n")
        else:
            print(f"完成: {dest_path}\n")

    print("所有文件处理完毕。")

if __name__ == "__main__":
    main()

第 3 步: 复制到 Arduino15 staging 目录

下载完成后,将 esp32_tools 目录下的所有压缩包复制到:

C:\Users\<你的用户名>\AppData\Local\Arduino15\staging\packages\

然后打开 Arduino IDE → 工具开发板开发板管理器,搜索 esp32,选择 2.0.17 版本安装。IDE 会直接从本地 staging 目录读取,不再走网络下载。

2.3 选择开发板和端口

  • 用 USB-C 数据线连接 XIAO ESP32S3
  • Arduino IDE 顶部选端口(通常是 COM3 或更高)
  • 左侧开发板搜索 xiao,选择 XIAO_ESP32S3

三、烧录固件

3.1 关键配置

烧录前务必在 工具 下拉菜单中设置:

PSRAM: "OPI PSRAM"

不设此项,上传到 0x10000 分区时会报 Packet content transfer stopped

3.2 刷入固件

  1. 打开 firmware/firmware.ino
  2. 点击 上传 按钮
  3. 等待编译+烧录完成

四、BootLoader 救砖模式

折腾过程中遇到以下问题:

  • 开发板连上电脑但 识别不到端口
  • 显示端口但 上传程序失败

进入 BootLoader 模式的方法:

方法步骤
方法一1. 断开 USB → 2. 按住 Boot 微动开关(黄色 LED 上方,Type-C 接口右侧) → 3. 保持按住,插上 USB → 4. 松开 Boot 开关
方法二按住 Boot 开关不放 → 按一下 Reset 开关(红色 LED 上方) → 松开 Boot

进入 BootLoader 后,可以先上传 文件示例01.BasicsBlink 验证板子是否正常(黄色 LED 一秒间隔闪烁)。


五、软件端部署

5.1 克隆项目并安装依赖

git clone https://github.com/BasedHardware/openglass.git
cd openglass
npm install
国内网络慢可改用 Gitee 镜像或挂代理。

5.2 配置 API Key

编辑 sources/keys.ts,配置你的 LLM 后端:

export const keys = {
    groq: process.env.EXPO_PUBLIC_GROQ_API_KEY ?? '',
    ollama: process.env.EXPO_PUBLIC_OLLAMA_API_URL ?? '',
    openai: process.env.EXPO_PUBLIC_OPENAI_API_KEY ?? '',
};

项目默认使用 Ollama(本地 moondream 模型做图像描述)+ Groq(Llama3 做问答)。也可以改用 OpenAI GPT-4o。

5.3 启动应用

npm start

打开浏览器访问 http://localhost:8081,点击 "Connect to the device" 通过 Web Bluetooth 连接 XIAO ESP32S3(BLE 名称为 OpenGlass)。

连接后,眼镜会每 5 秒自动拍照并推送给 AI 分析。底部的输入框可以直接语音提问,AI 基于拍到的画面回答你。

这里图片上传成功


六、常见问题

问题解决
固件上传报 Packet content transfer stopped确保 PSRAM 设为 OPI PSRAM,换一条 USB-C 数据线(必须支持数据传输)
npm install 太慢换淘宝镜像 npm config set registry https://registry.npmmirror.com
连不上眼镜 BLE确认浏览器支持 Web Bluetooth(Chrome/Edge),确保眼镜已上电
Arduino IDE Boards Manager 下载失败使用上述离线下载脚本,手动放入 staging 目录

参考链接

本文由 io 原创

采用 CC BY-NC-SA 4.0 协议进行许可

转载请注明出处:https://godd.asia/index.php/archives/23/

TAGS: openglass

相关推荐

  • 暂无相关推荐,看看别的吧。

0 评论

发表评论