跳转至

06 AirCAMERA_1020

作者:王城钧 | 最后修改:2026-06-03

一、概述

AirCAMERA _1020 是合宙推出的一款 DVP 接口的 DVP 摄像头小板 +100 万像素 DVP 摄像头的配件板,其中:

1、默认选择 KC6060-V2.0 GC2145 最大 100 万像素;

2、1 个 24PIN 连接器(同 AirCAMERA_1000)连接摄像头模组,1 个 8 头双排插针(SCL SDA HSYN VSYN MCLK PCLK D0-7 PWDN RST VDD GND);

3、内置两路 LDO,一个 2.8V,供电给 AVDD 和 DOVDD;一个 1.8V,供电给 DVDD;

注意!DVP 摄像头需要的两路 LDO 需要内置;

4、适用于 Air8101 系列模组;

二、演示模块概述

本示例主要是展示 AirCAMERA_1020 的使用,本地拍摄照片后通过 httpplus 扩展库将图片上传至 air32.com

1、main.lua:主程序入口

2、take_photo_http_post.lua:执行拍照后上传照片至 air32.com

3、video_http_post.lua:执行录像后上传视频至 air32.com

4、netdrv_wifi.lua:连接 WIFI

注意事项:

1、如用 V1006 版本固件,请使用 2 号固件

2、建议使用 V2xxx 版本固件

3、仅支持 2.4G 的 WiFi,不支持 5G 的 WiFi

三、演示功能概述

1、主程序入口模块(main.lua)

  • 初始化项目信息和版本号
  • 初始化看门狗,并定时喂狗
  • 启动一个循环定时器,每隔 3 秒钟打印一次总内存,实时的已使用内存,历史最高的已使用内存情况方便分析内存使用是否有异常
  • 加载 netdrv_wifi 模块(通过 require "netdrv_wifi")
  • 加载 take_photo_http_post 模块(通过 require "take_photo_http_post")

2、WIFI 连接模块(netdrv_wifi.lua)

  • 订阅"IP_READY"和"IP_LOSE"
  • 根据对应的网络状态执行对应的动作
  • 联网成功则配置 DNS
  • 联网失败则打印联网失败日志

3、拍照上传业务模块(take_photo_http_post.lua)

  • 每 30 秒触发一次拍照:AirCAMERA_1020_func()
  • 每 3 秒打印一次系统和 LUA 的内存信息:memory_check()
  • 配置摄像头信息表:dvp_camera_param
  • 初始化摄像头:excamera.open()
  • 执行拍照:excamera.photo()
  • 上传照片:httpplus.request()
  • 关闭摄像头:excamera.close()

4、录像上传核心业务模块(video_http_post.lua)

  • 订阅 IP_READY 信息,确认联网后执行录像上传任务
  • 挂载 TF 卡 :系统启动时调用 mount_tf_card() 函数挂载 TF 卡
  • 等待外部触发事件 :触发摄像头后,等待 ONCE_RECORD 事件
  • 配置摄像头信息表 :dvp_camera_param
  • 初始化摄像头 :excamera.open()
  • 录制 30 秒 MP4 视频 :excamera.video()
  • 关闭摄像头 :excamera.close()
  • 上传视频 :httpplus.request() 将视频上传到服务器
  • 每 10 秒打印一次系统和 Lua 的内存信息 :memory_check()

四、准备硬件环境

4.1 拍照上传硬件环境:

1、Air8101 核心板一块

2、TYPE-C USB 数据线一根

3、合宙标准配件 AirCAMERA_1020 一块

4、Air8101 核心板和合宙标准配件 AirCAMERA_1020 的硬件接线方式为

Air8101 核心板通过 TYPE-C USB 口供电;(背面功耗测试开关拨到 OFF)

TYPE-C USB 数据线直接插到核心板的 TYPE-C USB 座子,另外一端连接电脑 USB 口

AirCAMERA_1020 配件板 +Air8101 核心板,硬件连接示意图见上图所示

4.2 录像上传硬件环境:

1、Air8101 开发板一块,8101 USB 转串口供电下载扩展板一个

2、TYPE-C USB 数据线一根

3、合宙标准配件 AirCAMERA_1020 DVP 摄像头一个

4、TF 卡一张

5、母对母杜邦线两根

6、Air8101 开发板通过 USB 转串口供电下载扩展板和 TYPE-C USB 数据线连接电脑,母对母杜邦线母头连接开发板 SD_3.3V 和 SWD 的 3.3V 供电相接(B10 开发板才需要,B11 以及以后的开发板不需要),TF 卡插进卡槽即可。DVP 摄像头接入开发板对应槽位即可

实物接线图如下图所示:

Air8101 核心板购买链接:Air8101 核心板 WiFi 4G 以太网 蓝牙 720P显示屏 200万拍照-淘宝网

AirCAMERA_1020 购买链接:AirCAMERA_1020 100万像素DVP摄像头小板-淘宝网

Air8101 开发板购买链接:Air8101 开发板 WIFI 4G 以太网 蓝牙 720P显示屏 200万像素拍照-淘宝网

五、准备软件环境

5.1 软件环境

在开始实践本示例之前,先筹备一下软件环境:

1、烧录工具:Luatools 下载调试工具

2、本demo开发测试时使用的固件为Air8101 V2010 版本固件,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;

3、脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air8101/demo/accessory_board/AirCAMERA_1020

4、lib 脚本文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件

准备好软件环境之后,接下来查看 Air8101 核心板使用说明,将本篇文章中演示使用的项目文件烧录到 Air8101 核心板中

准备好软件环境之后,接下来查看如何烧录项目文件到 Air8101 开发板,将本篇文章中演示使用的项目文件烧录到 Air8101 核心板中。

5.2 API 介绍

excamera 扩展库:https://docs.openluat.com/osapi/ext/excamera/

六、程序结构

AirCAMERA_1020/
│── main.lua
│── netdrv_wifi.lua
│── take_photo_http_post.lua
│── video_http_post.lua
│── readme.md

6.1 文件说明

  1. main.lua:主程序入口文件。
  2. netdrv_wifi.lua:连接 WIFI。
  3. take_photo_http_post.lua:执行拍照后上传照片至 air32.com
  4. video_http_post.lua:执行录像后上传照片至 air32.com

七、代码详解

7.1 main.lua

主程序文件 main.lua 是整个项目的入口点。它负责初始化系统环境。

7.2 netdrv_wifi.lua

本文件为 WIFI STA 网卡驱动模块,核心业务逻辑为:

1、初始化 WIFI 网络;

2、连接 WIFI 路由器;

3、和 WIFI 路由器之间的连接状态发生变化时,在日志中进行打印;

local exnetif = require "exnetif"

local function ip_ready_func(ip, adapter)
    if adapter == socket.LWIP_STA then
        -- 在位置1和2设置自定义的DNS服务器ip地址:
        -- "223.5.5.5",这个DNS服务器IP地址是阿里云提供的DNS服务器IP地址;
        -- "114.114.114.114",这个DNS服务器IP地址是国内通用的DNS服务器IP地址;
        -- 可以加上以下两行代码,在自动获取的DNS服务器工作不稳定的情况下,这两个新增的DNS服务器会使DNS服务更加稳定可靠;
        -- 如果使用专网卡,不要使用这两行代码;
        -- 如果使用国外的网络,不要使用这两行代码;
        socket.setDNS(adapter, 1, "223.5.5.5")
        socket.setDNS(adapter, 2, "114.114.114.114")

        log.info("netdrv_wifi.ip_ready_func", "IP_READY", socket.localIP(socket.LWIP_STA))
    end
end

local function ip_lose_func(adapter)
    if adapter == socket.LWIP_STA then
        log.warn("netdrv_wifi.ip_lose_func", "IP_LOSE")
    end
end


--WIFI联网成功(做为STATION成功连接AP,并且获取到了IP地址)后,内核固件会产生一个"IP_READY"消息
--各个功能模块可以订阅"IP_READY"消息实时处理WIFI联网成功的事件
--也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功

--WIFI断网后,内核固件会产生一个"IP_LOSE"消息
--各个功能模块可以订阅"IP_LOSE"消息实时处理WIFI断网的事件
--也可以在任何时刻调用socket.adapter(socket.LWIP_STA)来获取WIFI网络是否连接成功

--此处订阅"IP_READY"和"IP_LOSE"两种消息
--在消息的处理函数中,仅仅打印了一些信息,便于实时观察WIFI的连接状态
--也可以根据自己的项目需求,在消息处理函数中增加自己的业务逻辑控制,例如可以在连网状态发生改变时更新网络图标
sys.subscribe("IP_READY", ip_ready_func)
sys.subscribe("IP_LOSE", ip_lose_func)


-- 配置WiFi设备模式的单网卡,exnetif.set_priority_order使用的网卡编号为socket.LWIP_STA
-- ssid为要连接的WiFi路由器名称;
-- password为要连接的WiFi路由器密码;
-- 注意:仅支持2.4G的WiFi,不支持5G的WiFi;
-- 实际测试时,根据自己要连接的WiFi热点信息修改以下参数
exnetif.set_priority_order({
    {
        WIFI = {
            ssid = "A上海合宙通讯", 
            password = "HZ88888888"
        }
    }
})

7.3 take_photo_http_post.lua

使用 AirCAMERA_1020 DVP 摄像头完成拍照上传任务,每 30S 触发一次拍照

-- 功能:提供摄像头初始化、拍照和资源管理功能
-- 引入excamera扩展库模块
local excamera = require "excamera"
-- 引入httpplus扩展库模块
local httpplus = require "httpplus"

-- 定义照片保存方式,有三种类型:
-- 1、ZBUFF保存,输入"ZBUFF"即可,excamera库会自动处理ZBUFF
-- 2、保存到内存文件系统中,路径名需指向/ram/文件夹
-- 3、保存到内置FLASH文件系统中
-- 选择其中一个即可,注释另两个路径变量
local save_method = "ZBUFF"
-- local save_method = "/ram/test.jpg"
-- local save_method = "/test.jpg"

-- 拍照功能函数
-- 作用:循环监听拍照事件,执行摄像头初始化、拍照和资源释放
local function capture_func()
    -- 定义变量用于存储操作结果和数据
    local result, data
    -- 无限循环,持续等待拍照事件
    while true do
        -- 配置DVP摄像头参数表
        local dvp_camera_param = {
            id = camera.DVP, -- 摄像头类型,DVP接口
            sensor_width = 1280, -- 摄像头像素宽度,1280像素
            sensor_height = 720, -- 摄像头像素高度,720像素
            i2c_id = 1, -- I2C编号,默认值为1
            save_path = save_method -- 照片保存路径,保存在RAM中
        }
        -- 等待外部触发拍照事件(ONCE_CAPTURE)
        sys.waitUntil("ONCE_CAPTURE")
        -- 初始化摄像头,传入配置参数
        result = excamera.open(dvp_camera_param)
        -- 记录摄像头初始化状态
        log.info("初始化状态", result)
        -- 判断摄像头初始化是否成功,不成功则直接关闭,成功则启动拍照
        if result then
            -- 执行拍照操作
            result, data = excamera.photo()
            -- 拍照执行完成则上传,否则关闭摄像头
            if result then
                -- 通过网卡状态判断WIFI是否连接成功,WIFI连接成功后再运行照片上传任务。
                while not socket.adapter(socket.dft()) do
                    -- 在此处阻塞等待WIFI连接成功的消息"IP_READY",避免联网过快,丢失了"IP_READY"信息而导致一直被卡住。
                    -- 或者等待30秒超时退出阻塞等待状态
                    log.warn("tcp_client_main_task_func", "wait IP_READY")
                    sys.waitUntil("IP_READY", 30000)
                end
                if type(data) == "userdata" then
                    data = data:query()
                else
                    data = io.readFile(data)
                end
                -- 通过网卡(本demo使用的是socket.LWIP_STA网卡)将拍摄到的照片数据result上传到服务器air32.cn
                -- 如果上传成功,电脑上浏览器打开https://www.air32.cn/upload/jpg/,打开对应的测试日期目录,点击具体的测试时间照片,可以查看摄像头拍照上传的照片
                -- 执行httpplus.request后,等待服务器的http应答,此处会阻塞当前task,等待整个过程成功结束或者出现错误异常结束
                -- code表示结果,number类型,详细说明参考API手册,一般来说:
                --             200表示成功
                --             小于0的值表示出错,例如-8表示超时错误
                --             其余结果值参考API手册
                local code = httpplus.request({
                    url = "http://upload.air32.cn/api/upload/jpg",
                    method = "POST",
                    body = data
                })
                -- 打印http传输状态
                log.info("http_upload_photo_task_func", "httpplus.request", code)
            end
        end
        -- 判断是否ZBUFF存储方式,如果是文件系统保存则删除本地文件
        if save_method ~= "ZBUFF" then
            os.remove(dvp_camera_param.save_path)
        end
        -- 关闭摄像头,释放资源
        -- 使用ZBUFF存储方式时,close传入true后,excamera内部创建的ZBUFF会缩减至0字节,放出内存但是不释放ZBUFF,便于下次拍照时调用;
        -- 重复申请和释放ZBUFF会导致垃圾内存堆积,影响系统内存;
        excamera.close(true)
    end
end

-- 内存检查函数
-- 作用:定期监控系统内存使用情况
local function memory_check()
    -- 无限循环,定期检查内存
    while true do
        -- 等待3秒
        sys.wait(3000)
        -- 打印系统内存使用信息
        log.info("sys ram", rtos.meminfo("sys"))
        -- 打印Lua虚拟机内存使用信息
        log.info("lua ram", rtos.meminfo("lua"))
    end
end

-- AirCAMERA_1020 DEMO应用触发函数,每30S触发一次拍照
local function AirCAMERA_1020_func()
    while true do
        sys.publish("ONCE_CAPTURE")
        sys.wait(30000)
    end
end

-- 创建拍照功能任务
-- 作用:在单独的任务中运行拍照逻辑
sys.taskInit(capture_func)

-- 创建内存监控任务
-- 作用:在单独的任务中运行内存监控逻辑
sys.taskInit(memory_check)

-- 创建拍照触发任务
-- 作用:每30秒触发一次拍照上传业务
sys.taskInit(AirCAMERA_1020_func)

7.4 video_http_post.lua

使用 AirCAMERA_1020 DVP 摄像头完成录像上传任务,每 30S 触发一次录像

-- 引入excamera库
local excamera = require("excamera")
-- 引入httpplus库
local httpplus = require("httpplus")

-- TF卡挂载函数
local function mount_tf_card()
    -- gpio13为8101 TF卡的供电控制引脚,在挂载前需要设置为高电平
    gpio.setup(13, 1, gpio.PULLUP)

    local ret = fatfs.mount(fatfs.SDIO, "/sd")
    if ret then
        log.info("TF卡挂载成功")
        -- 检查空间
        local free_info = fatfs.getfree("/sd")
        if free_info then
            log.info("剩余空间:", free_info.free_kb / 1024, "MB")
        end
        return true
    else
        log.error("TF卡挂载失败")
        return false
    end
end

-- 视频录制功能函数
local function video_capture_func()
    -- 打开控制camera的LDO
    gpio.setup(28, 1, gpio.PULLUP)
    -- 设置记录第几个视频的变量
    local n = 0
    while true do
        -- 等待外部触发录制事件
        sys.waitUntil("ONCE_RECORD")
        -- 配置dvp摄像头参数表
        local dvp_camera_param = {
            id = camera.DVP,     -- 摄像头类型,USB接口
            sensor_width = 1280, -- 摄像头像素宽度,1280像素
            sensor_height = 720, -- 摄像头像素高度,720像素
            i2c_id = 1          -- I2C编号,默认值为1
        }

        -- 初始化摄像头,传入配置参数
        local result = excamera.open(dvp_camera_param)
        -- 记录摄像头初始化状态
        log.info("摄像头初始化状态", result)
        if result then
            -- 视频编号递增
            n = n + 1
            local filepath = "/sd/video_dvp_ " .. n .. ".mp4"

            -- 录制视频:文件路径、时长(ms)
            log.info("开始录制视频", filepath)
            local success = excamera.video(filepath, 30000) -- 录制30秒视频

            -- 关闭摄像头,释放资源
            excamera.close()

            if success then
                log.info("视频录制成功!")

                -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
                while not socket.adapter(socket.dft()) do
                    log.warn("wait IP_READY", socket.dft())
                    -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
                    -- 或者等待1秒超时退出阻塞等待状态;
                    -- 注意:此处的1000毫秒超时不要修改的更长;
                    -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
                    -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
                    -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
                    sys.waitUntil("IP_READY", 1000)
                end

                -- 创建上传选项
                local opts = {
                    url = "http://upload.air32.cn/api/upload/mp4",
                    method = "POST",
                    bodyfile = filepath,
                    timeout = 150
                }
                -- 执行上传并处理结果
                local code = httpplus.request(opts)

                if code == 200 then
                    log.info("http上传完成,code:", code)
                    log.info("上传成功")
                else
                    log.info("上传失败,code:", code)
                end
            else
                log.error("视频录制失败!")
            end
            -- 当项目不再需要保存此视频文件时,可以参考下面一行代码,在合适的位置删除视频文件
            os.remove(filepath)
        else
            log.error("摄像头初始化失败!")
        end
    end
end

-- AirCAMERA_1020 DEMO应用触发函数,每30S触发一次视频录制
local function AirCAMERA_1020_func()
    while true do
        sys.publish("ONCE_RECORD")
        sys.wait(30000)
    end
end

-- 内存检查函数
local function memory_check()
    while true do
        -- 等待10秒
        sys.wait(10000)
        -- 打印系统内存使用信息
        log.info("系统内存使用情况", rtos.meminfo("sys"))
        -- 打印Lua虚拟机内存使用信息
        log.info("Lua虚拟机内存使用情况", rtos.meminfo("lua"))
    end
end

-- 挂载TF卡任务
sys.taskInit(mount_tf_card)

-- 视频录制任务
sys.taskInit(video_capture_func)

-- 视频录制触发任务
sys.taskInit(AirCAMERA_1020_func)

-- 内存检查任务
sys.taskInit(memory_check)

7.5 photo_to_aircloud.lua

使用 AirCAMERA_1020 DVP 摄像头拍照完成后通过excloud上传至合宙IOT平台,每 30S 触发一次拍照

-- 摄像头拍照模块
-- 功能:提供摄像头初始化、拍照和资源管理功能
-- 引入excamera扩展库模块
local excamera = require "excamera"
-- 引入httpplus扩展库模块
local httpplus = require "httpplus"
-- 导入excloud库
local excloud = require "excloud"
-- 配置excloud参数
local project_auth_key = "123456"

-- 定义照片保存方式,有三种类型:
-- 1、ZBUFF保存,输入"ZBUFF"即可,excamera库会自动处理ZBUFF
-- 2、保存到内存文件系统中,路径名需指向/ram/文件夹
-- 3、保存到内置FLASH文件系统中
-- 选择其中一个即可,注释另两个路径变量
local save_method = "ZBUFF"
-- local save_method = "/ram/test.jpg"
-- local save_method = "/test.jpg"

--[[
excloud事件回调函数
参数:
    event: 事件类型字符串
    data: 事件数据,根据事件类型不同而不同

事件类型说明:
    connect_result: 连接结果
    auth_result: 认证结果
    disconnect: 断开连接
    reconnect_failed: 重连失败
]]
function on_excloud_event(event, data)
    -- 打印事件信息
    log.info("用户回调函数", event, json.encode(data))
    -- 处理连接结果事件
    if event == "connect_result" then
        if data.success then
            log.info("连接成功")
            -- 发布连接成功消息,通知其他任务
            sys.publish("aircloud_connected")
        else
            log.info("连接失败: " .. (data.error or "未知错误"))
        end
        -- 处理认证结果事件
    elseif event == "auth_result" then
        if data.success then
            log.info("认证成功")
        else
            log.info("认证失败: " .. data.message)
        end
        -- 处理断开连接事件
    elseif event == "disconnect" then
        log.warn("与服务器断开连接")
        -- 处理重连失败事件
    elseif event == "reconnect_failed" then
        log.info("重连失败,已尝试 " .. data.count .. " 次")
    end
end

-- 注册excloud事件回调函数
excloud.on(on_excloud_event)

--[[
excloud任务函数
功能:
    1. 等待网络连接就绪
    2. 配置excloud参数
    3. 初始化并开启excloud服务
    4. 启动自动心跳
]]
local function excloud_task_func()
    -- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
    while not socket.adapter(socket.dft()) do
        log.warn("excloud_task_func", "wait IP_READY", socket.dft())
        -- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
        -- 或者等待1秒超时退出阻塞等待状态;
        -- 注意:此处的1000毫秒超时不要修改的更长;
        -- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
        -- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
        -- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
        sys.waitUntil("IP_READY", 1000)
    end

    -- 检查是否使用默认的示例key
    if project_auth_key == "123" or project_auth_key == "123456" then
        log.warn("photo_to_aircloud",
            "请改为自己的key,如不知道对应key的可以查看main.lua 54-57行的指导进行添加key的操作")
    end

    local ok, err_msg = excloud.setup({
        use_getip = true, -- 使用getip服务
        device_type = 2, -- WIFI设备
        auth_key = project_auth_key, -- 认证密钥
        transport = "tcp", -- 使用TCP传输
        auto_reconnect = true, -- 自动重连
        reconnect_interval = 10, -- 重连间隔(秒)
        max_reconnect = 5, -- 最大重连次数
        mtn_log_enabled = true, -- 启用运维日志
        mtn_log_blocks = 2, -- 日志文件块数
        mtn_log_write_way = excloud.MTN_LOG_CACHE_WRITE -- 缓存写入方式
    })

    -- 检查初始化是否成功
    if not ok then
        log.info("初始化失败: " .. err_msg)
        return
    end
    log.info("excloud初始化成功")

    -- 开启excloud服务
    local ok, err_msg = excloud.open()
    if not ok then
        log.info("开启excloud服务失败: " .. err_msg)
        return
    end
    log.info("excloud服务已开启")

    -- 启动自动心跳,默认5分钟一次的心跳
    excloud.start_heartbeat()
    log.info("自动心跳已启动")
end

--[[
照片上传任务函数
功能:
    1. 等待excloud连接建立
    2. 等待图片数据
    3. 上传图片到云端
    4. 处理上传结果
]]
function upload_image_fun(image)
    if excloud.status().is_connected then
        log.info("开始上传图片")
        if image then
            local ok, err = excloud.upload_image(image, "test.jpg")
            if ok then
                log.info("图片上传成功")
                return true
            else
                log.error("图片上传失败:", err)
                return false
            end
        else
            log.warn("图片数据为空")
            return false
        end
    end
    log.info("excloud连接已断开,等待重连")
    return false
end

-- 拍照功能函数
-- 作用:循环监听拍照事件,执行摄像头初始化、拍照和资源释放
local function capture_func()
    -- 定义变量用于存储操作结果和数据
    local result, data, err
    -- 增加重试次数,最多重试5次,避免日志量过大
    local retry_count = 0
    -- 出现异常后重新初始化,最多重试5次
    while retry_count < 5 do
        -- 配置gc032a摄像头参数表
        local dvp_camera_param = {
            id = camera.DVP, -- 摄像头类型,DVP接口
            sensor_width = 1280, -- 摄像头像素宽度,1280像素
            sensor_height = 720, -- 摄像头像素高度,720像素
            save_path = save_method, -- 照片保存路径,保存在RAM中
            i2c_id = 1  -- 模块上使用的I2C编号
        }
        -- 初始化摄像头,传入配置参数
        result = excamera.open(dvp_camera_param)
        -- 记录摄像头初始化状态
        log.info("初始化状态", result)
        -- 判断摄像头初始化是否成功,不成功则直接关闭,成功则启动拍照
        -- 无限循环,持续等待拍照事件
        while result do
            -- 等待外部触发拍照事件(ONCE_CAPTURE)
            sys.waitUntil("ONCE_CAPTURE")
            -- 执行拍照操作
            result, data = excamera.photo()
            -- 拍照执行完成则上传,否则关闭摄像头
            if result then
                -- 通过网卡状态判断WIFI是否连接成功,WIFI连接成功后再运行照片上传任务。
                while not socket.adapter(socket.dft()) do
                    -- 在此处阻塞等待WIFI连接成功的消息"IP_READY",避免联网过快,丢失了"IP_READY"信息而导致一直被卡住。
                    -- 或者等待30秒超时退出阻塞等待状态
                    log.warn("tcp_client_main_task_func", "wait IP_READY")
                    sys.waitUntil("IP_READY", 30000)
                end
                upload_image_fun(data)
            end
            -- 判断是否ZBUFF存储方式,如果是文件系统保存则删除本地文件
            if save_method ~= "ZBUFF" then
                os.remove(spi_camera_param.save_path)
            end
        end
        -- 关闭摄像头,释放资源
        -- 使用ZBUFF存储方式时,close传入true后,excamera内部创建的ZBUFF会缩减至0字节,放出内存但是不释放ZBUFF,便于下次拍照时调用;
        -- 重复申请和释放ZBUFF会导致垃圾内存堆积,影响系统内存;
        excamera.close(true)
        -- 拍照出错,等待5秒,重试摄像头初始化
        sys.wait(5000)
        -- 重试次数增加
        retry_count = retry_count + 1
        log.info("retry_count", retry_count)
    end
    -- 重试5次后,提示用户检查摄像头连接或重启设备
    log.info("camera init failed, please check the camera connection or reboot, retry_count:", retry_count)
end

-- 内存检查函数
-- 作用:定期监控系统内存使用情况
local function memory_check()
    -- 无限循环,定期检查内存
    while true do
        -- 等待3秒
        sys.wait(3000)
        -- 打印系统内存使用信息
        log.info("sys ram", rtos.meminfo("sys"))
        -- 打印Lua虚拟机内存使用信息
        log.info("lua ram", rtos.meminfo("lua"))
    end
end

-- AirCAMERA_1040 DEMO应用触发函数,每30S触发一次拍照
local function AirCAMERA_1040_func()
    while true do
        sys.wait(30000)
        sys.publish("ONCE_CAPTURE")
    end
end

-- 启动excloud连接任务
sys.taskInit(excloud_task_func)

-- 创建拍照功能任务
-- 作用:在单独的任务中运行拍照逻辑
sys.taskInit(capture_func)

-- 创建内存监控任务
-- 作用:在单独的任务中运行内存监控逻辑
sys.taskInit(memory_check)

-- 创建拍照触发任务
-- 作用:每30秒触发一次拍照上传业务
sys.taskInit(AirCAMERA_1040_func)

八、运行结果展示

8.1 拍照后上传

”take_photo_http_post.lua“ DEMO中,因为Air32.com平台已经不开放使用了,所以该DEMO仅作上传照片至服务器的演示作用,使用时请将上传URL修改为您自己的服务器地址;

如下为”photo_to_aircloud.lua“的DEMO演示结果展示:

1、搭建硬件环境;

2、修改 netdrv_wifi.lua 中的 WIFI 账号密码;

3、获取合宙IOT平台的项目KEY,

alt text

并将其添加到photo_to_aircloud.lua中;

-- 配置excloud参数
local project_auth_key = "123456"

4、烧录 DEMO 代码;

5、等待30S完成拍照后上传IOT.Luatos.com平台,LUATOOLS会有如下打印;

[2026-05-20 10:29:40.613][CPU2][LTOS/N][000000031.720]:I/user.照片存储路径 ZBUFF*: 609937E0
[2026-05-20 10:29:40.617][CPU1][LTOS/N][000000031.728]:I/user.sys ram 235616 72720 73216
[2026-05-20 10:29:40.621][CPU1][LTOS/N][000000031.728]:I/user.lua ram 2097144 352536 352960
[2026-05-20 10:29:40.624][CPU2][LTOS/N][000000031.735]:I/user.摄像头数据 54467
[2026-05-20 10:29:40.627][CPU2][LTOS/N][000000031.736]:I/user.拍照完成
[2026-05-20 10:29:40.631][CPU2][LTOS/N][000000031.737]:I/user.开始上传图片
[2026-05-20 10:29:40.634][CPU2][LTOS/N][000000031.737]:I/user.[excloud]开始ZBUFF上传 类型: 1 文件: test.jpg 大小: 54467
[2026-05-20 10:29:40.638][CPU2][LTOS/N][000000031.737]:I/user.[excloud]构建发送数据 23 0 0 
[2026-05-20 10:29:40.642][CPU2][LTOS/N][000000031.739]:I/user.[excloud]构建发送数据 784 0 1 
[2026-05-20 10:29:40.647][CPU2][LTOS/N][000000031.740]:I/user.[excloud]构建发送数据 785 3 test.jpg 
[2026-05-20 10:29:40.650][CPU2][LTOS/N][000000031.740]:I/user.[excloud]构建发送数据 786 0 54467 
[2026-05-20 10:29:40.656][CPU2][LTOS/N][000000031.741]:I/user.[excloud]tlv发送数据长度4 48
[2026-05-20 10:29:40.660][CPU2][LTOS/N][000000031.742]:I/user.[excloud]构建消息头 
[2026-05-20 10:29:40.663][CPU1][LTOS/N][000000031.744]:I/user.用户回调函数 send_result {"sequence_num":2,"success":true,"error_msg":"Send successful"}
[2026-05-20 10:29:40.667][CPU1][LTOS/N][000000031.745]:I/user.[excloud]数据发送成功 64 字节
[2026-05-20 10:29:40.671][CPU1][LTOS/N][000000031.745]:I/user.[excloud]开始发送HTTP请求 URL: https://gps.openluat.com/iot/air_up/image
[2026-05-20 10:29:40.681][CPU1][LTOS/N][000000031.753]:connect to gps.openluat.com,443
[2026-05-20 10:29:40.685][CPU2][LTOS/N][000000031.754]:gps.openluat.com state 0 id 2 ipv6 0 use dns server0, try 0
[2026-05-20 10:29:40.689][CPU2][LTOS/N][000000031.754]:adatper 2 dns server 223.5.5.5
[2026-05-20 10:29:40.693][CPU2][LTOS/N][000000031.754]:dns udp sendto 223.5.5.5:53 from 192.168.1.116
[2026-05-20 10:29:40.697][CPU2][LTOS/N][000000031.769]:dns all done ,now stop
[2026-05-20 10:29:40.703][CPU2][LTOS/N][000000031.769]:adapter 2 connect 123.60.5.123:443 TCP
[2026-05-20 10:29:40.704][CPU1][LTOS/N][000000031.783]:I/user.[excloud]socket cb userdata: 60970790 33554450 0
[2026-05-20 10:29:40.708][CPU1][LTOS/N][000000031.783]:I/user.[excloud]socket 发送完成
[2026-05-20 10:29:41.134][CPU1][LTOS/N][000000032.243]:create large size: 128 kbyte, trigger force GC
[2026-05-20 10:29:43.090][CPU1][LTOS/N][000000034.207]:I/user.httpplus 服务器已完成响应
[2026-05-20 10:29:43.094][CPU1][LTOS/N][000000034.210]:I/user.[excloud]文件上传响应 HTTP Code: 200 Body: {"info":"iot./iot/air_up/image","code":0,"trace":"iot./iot/air_up/image trcace:","log":"^^^","value":{"uri":"/vsa/aircloud_image...
[2026-05-20 10:29:43.100][CPU1][LTOS/N][000000034.211]:I/user.[excloud]文件上传成功 URL: /vsa/aircloud_image/FFZDbqsuzrLpbgPfzVd7De/2026-05/C8478CA97DBE/20260520102943_test.jpg
[2026-05-20 10:29:43.103][CPU1][LTOS/N][000000034.211]:I/user.[excloud]构建发送数据 24 0 0 
[2026-05-20 10:29:43.107][CPU1][LTOS/N][000000034.212]:I/user.[excloud]构建发送数据 784 0 1 
[2026-05-20 10:29:43.112][CPU1][LTOS/N][000000034.213]:I/user.[excloud]构建发送数据 785 3 test.jpg 
[2026-05-20 10:29:43.114][CPU1][LTOS/N][000000034.214]:I/user.[excloud]构建发送数据 787 0 0 
[2026-05-20 10:29:43.117][CPU1][LTOS/N][000000034.215]:I/user.[excloud]tlv发送数据长度4 48
[2026-05-20 10:29:43.121][CPU1][LTOS/N][000000034.216]:I/user.[excloud]构建消息头 
[2026-05-20 10:29:43.127][CPU1][LTOS/N][000000034.218]:I/user.用户回调函数 send_result {"sequence_num":3,"success":true,"error_msg":"Send successful"}
[2026-05-20 10:29:43.130][CPU1][LTOS/N][000000034.218]:I/user.[excloud]数据发送成功 64 字节
[2026-05-20 10:29:43.133][CPU1][LTOS/N][000000034.222]:I/user.[excloud]文件上传完成
[2026-05-20 10:29:43.138][CPU1][LTOS/N][000000034.222]:I/user.图片上传成功
[2026-05-20 10:29:43.142][CPU1][LTOS/N][000000034.253]:I/user.[excloud]socket cb userdata: 60970790 33554450 0
[2026-05-20 10:29:43.146][CPU1][LTOS/N][000000034.253]:I/user.[excloud]socket 发送完成

6、登录 https://iot.luatos.com/ ;

alt text

就可以根据您设备的IMEI号和上传时间查看您所上传的照片了;

alt text

8.2 录像后上传

1、搭建硬件环境;

2、修改 netdrv_wifi.lua 中的 WIFI 账号密码;

3、烧录 DEMO 代码;

4、等待自动拍照完成后上传平台,LUATOOLS 会有如下打印;

[2026-02-11 15:03:46.133] luat:I(1352):fatfs:mount success at fat32
[2026-02-11 15:03:46.133] luat:U(1353):I/user.TF卡挂载成功
[2026-02-11 15:03:46.133] luat:U(1354):I/user.剩余空间: 15176.156250000 MB
[2026-02-11 15:03:46.139] ap0:hal:W(1248):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:03:46.139] luat:D(1361):i2c:i2c(1) gpio init : scl 0 sda 1
[2026-02-11 15:03:46.139] ap0:i2c:W(1249):i2c(1) master_read get ack failed
[2026-02-11 15:03:46.139] ap0:i2c:W(1249):i2c(1) master_read get ack failed
[2026-02-11 15:03:46.363] luat:U(1572):I/user.摄像头初始化状态 true
[2026-02-11 15:03:46.363] luat:U(1573):I/user.开始录制视频 /sd/video_dvp_ 1.mp4
[2026-02-11 15:03:46.363] luat:U(1585):I/user.excamera.mount_tf_card TF卡已经挂载
[2026-02-11 15:03:46.363] luat:U(1586):I/user.excamera.video 开始录制视频到 /sd/video_dvp_ 1.mp4
[2026-02-11 15:03:46.363] luat:U(1586):I/user.excamera.video lua内存: 2097144 171544 174512
[2026-02-11 15:03:46.363] luat:U(1586):I/user.excamera.video sys内存: 238608 72512 72512
[2026-02-11 15:03:46.363] ap0:CAM:W(1474):拍照/录像到文件录 /sd/video_dvp_ 1.mp4
[2026-02-11 15:03:46.380] ap0:CAM:W(1474):选定的捕捉模式 4
[2026-02-11 15:03:46.708] ap0:hal:W(1794):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:03:46.708] ap0:hal:W(1795):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:03:46.708] luat:D(1907):i2c:i2c(1) gpio init : scl 0 sda 1
[2026-02-11 15:03:46.708] ap0:i2c:W(1795):i2c(1) master_read get ack failed
[2026-02-11 15:03:46.708] ap0:i2c:W(1795):i2c(1) master_read get ack failed
[2026-02-11 15:03:47.370] wifid:I(2577):[KW:]scanu_confirm:status=0,req_type=0,upload_cnt=10,recv_cnt=45,time=1705885us,result=1,rfcli=0
[2026-02-11 15:03:47.370] wpa:I(2578):Scan completed in 1.704000 seconds
[2026-02-11 15:03:47.370] hitf:I(2578):get scan result:1
[2026-02-11 15:03:47.378] wpa:I(2579):State: SCANNING -> ASSOCIATING
[2026-02-11 15:03:47.378] wifid:I(2580):[KW:]conn vif0-0,auth_type:0,bssid:6924-6068-6ac3,ssid:116,is encryp:8.
[2026-02-11 15:03:47.378] wifid:I(2580):chan_ctxt_add: CTXT0,freq2412MHz,bw20MHz,pwr32dBm
[2026-02-11 15:03:47.378] wifid:I(2580):chan_reg_fix:VIF0,CTXT0,type3,ctxt_s0,nb_vif0
[2026-02-11 15:03:47.378] wifid:I(2581):mm_sta_add:vif 0,sta 0,status 0
[2026-02-11 15:03:47.418] wifid:I(2624):[KW:]auth_send:seq1, txtype0, auth_type0, seq46
[2026-02-11 15:03:47.418] wifid:I(2638):[KW:]sm_auth_handler: status code 0, tx status 0x80800200
[2026-02-11 15:03:47.418] wifid:I(2638):[KW:]assoc_req_send:is ht, seq_num:47
[2026-02-11 15:03:47.424] wifid:I(2642):[KW:]assoc_rsp:status0,tx_s0x80800000
[2026-02-11 15:03:47.424] wifid:I(2642):[KW:]mm_set_vif_state,vif=0,vif_type=0,is_active=1, aid=0x7,rssi=-54
[2026-02-11 15:03:47.424] wpa:I(2643):State: ASSOCIATING -> ASSOCIATED
[2026-02-11 15:03:47.433] wpa:I(2649):State: ASSOCIATED -> 4WAY_HANDSHAKE
[2026-02-11 15:03:47.433] wpa:I(2650):WPA: TK 3c761b19f4874417b9decf4cb47000e9
[2026-02-11 15:03:47.439] wpa:I(2660):State: 4WAY_HANDSHAKE -> 4WAY_HANDSHAKE
[2026-02-11 15:03:47.464] hitf:I(2667):add CCMP
[2026-02-11 15:03:47.464] wpa:I(2667):State: 4WAY_HANDSHAKE -> GROUP_HANDSHAKE
[2026-02-11 15:03:47.464] hitf:I(2668):add CCMP
[2026-02-11 15:03:47.464] wpa:I(2668):State: GROUP_HANDSHAKE -> COMPLETED
[2026-02-11 15:03:47.464] lwip:I(2669):sta ip start
[2026-02-11 15:03:47.464] lwip:I(2669):[KW:]sta:DHCP_DISCOVER()
[2026-02-11 15:03:47.477] lwip:I(2688):[KW:]sta:DHCP_OFFER received in DHCP_STATE_SELECTING state
[2026-02-11 15:03:47.477] lwip:I(2688):[KW:]sta:DHCP_REQUEST(netif=0x280655b4) en   1
[2026-02-11 15:03:47.482] lwip:I(2705):[KW:]sta:DHCP_ACK received
[2026-02-11 15:03:47.485] wifid:I(2706):[KW:]me dhcp done vif:0
[2026-02-11 15:03:47.485] event:W(2707):event <2 0> has no cb
[2026-02-11 15:03:47.491] ap0:lwip:I(2598):sta ip start
[2026-02-11 15:03:47.491] luat:D(2710):wlan:event_module 1 event_id 2
[2026-02-11 15:03:47.491] luat:D(2711):wlan:STA connected 116 
[2026-02-11 15:03:47.491] luat:D(2711):wlan:event_module 2 event_id 0
[2026-02-11 15:03:47.491] luat:D(2711):wlan:ipv4 got!! 192.168.0.107
[2026-02-11 15:03:47.491] luat:D(2711):net:network ready 2, setup dns server
[2026-02-11 15:03:47.505] luat:D(2721):wlan:set dns server to 103.85.84.202
[2026-02-11 15:03:47.505] luat:D(2721):net:设置DNS服务器 id 2 index 3 ip 103.85.84.202
[2026-02-11 15:03:47.505] luat:D(2721):wlan:sta ip 192.168.0.107
[2026-02-11 15:03:47.505] luat:U(2722):I/user.dnsproxy 开始监听
[2026-02-11 15:03:47.505] luat:D(2723):net:设置DNS服务器 id 2 index 0 ip 223.5.5.5
[2026-02-11 15:03:47.505] luat:D(2723):net:设置DNS服务器 id 2 index 1 ip 114.114.114.114
[2026-02-11 15:03:47.505] luat:U(2723):I/user.netdrv_wifi.ip_ready_func IP_READY 192.168.0.107 255.255.255.0 192.168.0.1 nil
[2026-02-11 15:03:47.807] luat:I(3006):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:48.456] luat:I(3655):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:49.109] luat:I(4304):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:49.757] luat:I(4953):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:50.438] luat:I(5648):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:51.089] luat:I(6297):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:51.739] luat:I(6946):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:52.389] luat:I(7595):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:53.038] luat:I(8244):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:53.828] luat:I(9031):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:54.571] luat:I(9773):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:55.363] luat:I(10560):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:56.093] luat:I(11302):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:56.153] luat:U(11355):I/user.系统内存使用情况 238608 113472 113936
[2026-02-11 15:03:56.153] luat:U(11356):I/user.Lua虚拟机内存使用情况 2097144 172704 174512
[2026-02-11 15:03:56.881] luat:I(12089):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:57.624] luat:I(12831):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:58.371] luat:I(13573):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:59.112] luat:I(14315):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:03:59.948] luat:I(15148):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:00.691] luat:I(15890):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:01.434] luat:I(16632):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:02.194] luat:I(17419):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:02.950] luat:I(18161):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:03.740] luat:I(18948):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:04.484] luat:I(19690):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:05.224] luat:I(20431):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:06.017] luat:I(21219):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:06.158] luat:U(21356):I/user.系统内存使用情况 238608 113472 113936
[2026-02-11 15:04:06.158] luat:U(21357):I/user.Lua虚拟机内存使用情况 2097144 172976 174512
[2026-02-11 15:04:06.796] luat:I(22007):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:07.541] luat:I(22749):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:08.289] luat:I(23491):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:09.079] luat:I(24278):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:09.808] luat:I(25020):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:10.600] luat:I(25807):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:11.343] luat:I(26549):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:12.133] luat:I(27336):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:12.877] luat:I(28078):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:13.638] luat:I(28866):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:14.395] luat:I(29607):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:15.184] luat:I(30395):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:15.933] luat:I(31137):mp4box:start flush buffer 262144 bytes 0x609e4720
[2026-02-11 15:04:16.147] luat:U(31357):I/user.系统内存使用情况 238608 113472 113936
[2026-02-11 15:04:16.147] luat:U(31358):I/user.Lua虚拟机内存使用情况 2097144 173464 174512
[2026-02-11 15:04:16.364] luat:I(31589):mp4box:start flush buffer 153195 bytes 0x609e4720
[2026-02-11 15:04:16.410] luat:I(31612):mp4box:mp4 file size before mdat 10376811
[2026-02-11 15:04:16.440] luat:I(31650):mp4box:总帧数 629, 关键帧数 5 总耗时 29104ms 平均帧率 21 fps
[2026-02-11 15:04:16.440] luat:I(31650):mp4box:mp4 file final size 10385006
[2026-02-11 15:04:16.446] luat:I(31659):mp4box:mp4 file closed, box write finished, file closed
[2026-02-11 15:04:16.503] luat:U(31703):I/user.excamera.video lua内存: 2097144 173648 174512
[2026-02-11 15:04:16.503] luat:U(31704):I/user.excamera.video sys内存: 238608 29976 113936
[2026-02-11 15:04:16.503] luat:U(31704):I/user.excamera.video 视频录制完成 /sd/video_dvp_ 1.mp4
[2026-02-11 15:04:16.503] luat:U(31704):I/user.视频录制成功!
[2026-02-11 15:04:16.503] luat:D(31709):socket:connect to upload.air32.cn,80
[2026-02-11 15:04:16.503] luat:D(31710):DNS:upload.air32.cn state 0 id 1 ipv6 0 use dns server0, try 0
[2026-02-11 15:04:16.503] luat:D(31710):net:adatper 2 dns server 223.5.5.5
[2026-02-11 15:04:16.503] luat:D(31711):net:dns udp sendto 223.5.5.5:53 from 192.168.0.107
[2026-02-11 15:04:17.497] luat:D(32710):DNS:upload.air32.cn state 0 id 1 ipv6 0 use dns server0, try 1
[2026-02-11 15:04:17.497] luat:D(32710):net:adatper 2 dns server 223.5.5.5
[2026-02-11 15:04:17.502] luat:D(32710):net:dns udp sendto 223.5.5.5:53 from 192.168.0.107
[2026-02-11 15:04:18.486] luat:D(33710):net:adatper 2 dns server 223.5.5.5
[2026-02-11 15:04:19.506] luat:D(34710):DNS:upload.air32.cn state 0 id 1 ipv6 0 use dns server0, try 2
[2026-02-11 15:04:19.506] luat:D(34710):net:adatper 2 dns server 223.5.5.5
[2026-02-11 15:04:19.506] luat:D(34710):net:dns udp sendto 223.5.5.5:53 from 192.168.0.107
[2026-02-11 15:04:19.569] luat:I(34778):DNS:dns all done ,now stop
[2026-02-11 15:04:19.569] luat:D(34778):net:adapter 2 connect 49.232.89.122:80 TCP
[2026-02-11 15:04:19.615] luat:I(34822):zbuff:create large size: 128 kbyte, trigger force GC
[2026-02-11 15:04:26.149] luat:U(41358):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:04:26.149] luat:U(41359):I/user.Lua虚拟机内存使用情况 2097144 175144 178464
[2026-02-11 15:04:36.141] luat:U(51359):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:04:36.141] luat:U(51360):I/user.Lua虚拟机内存使用情况 2097144 178128 178464
[2026-02-11 15:04:46.145] luat:U(61360):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:04:46.145] luat:U(61361):I/user.Lua虚拟机内存使用情况 2097144 181456 181456
[2026-02-11 15:04:56.134] luat:U(71361):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:04:56.134] luat:U(71362):I/user.Lua虚拟机内存使用情况 2097144 184568 184568
[2026-02-11 15:05:06.133] luat:U(81362):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:05:06.133] luat:U(81363):I/user.Lua虚拟机内存使用情况 2097144 187392 187392
[2026-02-11 15:05:16.149] luat:U(91363):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:05:16.149] luat:U(91364):I/user.Lua虚拟机内存使用情况 2097144 190736 190736
[2026-02-11 15:05:26.159] luat:U(101365):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:05:26.159] luat:U(101365):I/user.Lua虚拟机内存使用情况 2097144 193848 193848
[2026-02-11 15:05:36.145] luat:U(111366):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:05:36.145] luat:U(111367):I/user.Lua虚拟机内存使用情况 2097144 196672 196672
[2026-02-11 15:05:46.160] luat:U(121367):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:05:46.160] luat:U(121368):I/user.Lua虚拟机内存使用情况 2097144 209904 210000
[2026-02-11 15:05:55.665] luat:U(130877):I/user.httpplus 服务器已完成响应,开始解析响应
[2026-02-11 15:05:55.674] luat:U(130887):I/user.http上传完成,code: 200
[2026-02-11 15:05:55.674] luat:U(130888):I/user.上传成功
[2026-02-11 15:05:56.162] luat:U(131368):I/user.系统内存使用情况 238608 29896 113936
[2026-02-11 15:05:56.162] luat:U(131369):I/user.Lua虚拟机内存使用情况 2097144 241920 241920
[2026-02-11 15:05:59.200] cal:I(134406):idx:39=41+(-2),r:54,xtal:79,pwr_gain:a4ab7120
[2026-02-11 15:06:06.141] luat:U(141369):I/user.系统内存使用情况 238608 29896 113936
[2026-02-11 15:06:06.144] luat:U(141370):I/user.Lua虚拟机内存使用情况 2097144 242120 242120
[2026-02-11 15:06:16.120] ap0:hal:W(151244):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:06:16.120] ap0:hal:W(151245):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:06:16.120] luat:D(151358):i2c:i2c(1) gpio init : scl 0 sda 1
[2026-02-11 15:06:16.120] ap0:i2c:W(151246):i2c(1) master_read get ack failed
[2026-02-11 15:06:16.131] ap0:i2c:W(151246):i2c(1) master_read get ack failed
[2026-02-11 15:06:16.338] luat:U(151569):I/user.摄像头初始化状态 true
[2026-02-11 15:06:16.338] luat:U(151569):I/user.开始录制视频 /sd/video_dvp_ 2.mp4
[2026-02-11 15:06:16.345] luat:U(151578):I/user.excamera.mount_tf_card TF卡已经挂载
[2026-02-11 15:06:16.345] luat:U(151579):I/user.excamera.video 开始录制视频到 /sd/video_dvp_ 2.mp4
[2026-02-11 15:06:16.345] luat:U(151579):I/user.excamera.video lua内存: 2097144 243656 243656
[2026-02-11 15:06:16.345] luat:U(151579):I/user.excamera.video sys内存: 238608 72512 113936
[2026-02-11 15:06:16.345] ap0:CAM:W(151467):拍照/录像到文件录 /sd/video_dvp_ 2.mp4
[2026-02-11 15:06:16.345] ap0:CAM:W(151467):选定的捕捉模式 4
[2026-02-11 15:06:16.345] luat:U(151586):I/user.系统内存使用情况 238608 72512 113936
[2026-02-11 15:06:16.345] luat:U(151586):I/user.Lua虚拟机内存使用情况 2097144 243888 243888
[2026-02-11 15:06:16.618] ap0:hal:W(151744):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:06:16.618] ap0:hal:W(151744):gpio: 27 is used.Please confirm unmap isn't impact is working module.!
[2026-02-11 15:06:16.618] luat:D(151857):i2c:i2c(1) gpio init : scl 0 sda 1
[2026-02-11 15:06:16.618] ap0:i2c:W(151745):i2c(1) master_read get ack failed
[2026-02-11 15:06:16.618] ap0:i2c:W(151745):i2c(1) master_read get ack failed
[2026-02-11 15:06:17.721] luat:I(152956):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:18.374] luat:I(153604):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:19.022] luat:I(154253):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:19.718] luat:I(154948):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:20.371] luat:I(155596):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:21.006] luat:I(156245):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:21.704] luat:I(156940):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:22.351] luat:I(157589):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:23.004] luat:I(158238):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:23.779] luat:I(159025):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:24.542] luat:I(159768):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:25.273] luat:I(160509):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:26.061] luat:I(161296):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:26.355] luat:U(161587):I/user.系统内存使用情况 238608 113472 113936
[2026-02-11 15:06:26.355] luat:U(161587):I/user.Lua虚拟机内存使用情况 2097144 244120 244120
[2026-02-11 15:06:26.793] luat:I(162038):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:27.597] luat:I(162825):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:28.342] luat:I(163567):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:29.039] luat:I(164264):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:29.859] luat:I(165096):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:30.648] luat:I(165884):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:31.390] luat:I(166626):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:32.180] luat:I(167413):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:32.923] luat:I(168155):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:33.669] luat:I(168897):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:34.457] luat:I(169684):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:35.200] luat:I(170426):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:35.963] luat:I(171214):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:36.351] luat:U(171587):I/user.系统内存使用情况 238608 113472 113936
[2026-02-11 15:06:36.351] luat:U(171588):I/user.Lua虚拟机内存使用情况 2097144 244192 244288
[2026-02-11 15:06:36.725] luat:I(171956):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:37.517] luat:I(172743):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:38.246] luat:I(173485):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:39.034] luat:I(174273):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:39.776] luat:I(175015):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:40.517] luat:I(175757):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:41.309] luat:I(176544):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:42.052] luat:I(177286):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:42.842] luat:I(178074):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:43.585] luat:I(178816):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:44.346] luat:I(179603):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:45.103] luat:I(180345):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:45.897] luat:I(181132):mp4box:start flush buffer 262144 bytes 0x60a04748
[2026-02-11 15:06:46.331] luat:I(181584):mp4box:start flush buffer 156768 bytes 0x60a04748
[2026-02-11 15:06:46.379] luat:I(181607):mp4box:mp4 file size before mdat 10380384
[2026-02-11 15:06:46.383] luat:I(181631):mp4box:总帧数 630, 关键帧数 5 总耗时 29150ms 平均帧率 21 fps
[2026-02-11 15:06:46.383] luat:I(181631):mp4box:mp4 file final size 10388591
[2026-02-11 15:06:46.389] luat:I(181644):mp4box:mp4 file closed, box write finished, file closed
[2026-02-11 15:06:46.457] luat:U(181699):I/user.excamera.video lua内存: 2097144 244688 244688
[2026-02-11 15:06:46.457] luat:U(181700):I/user.excamera.video sys内存: 238608 29976 113936
[2026-02-11 15:06:46.457] luat:U(181700):I/user.excamera.video 视频录制完成 /sd/video_dvp_ 2.mp4
[2026-02-11 15:06:46.465] luat:U(181700):I/user.视频录制成功!
[2026-02-11 15:06:46.465] luat:D(181705):socket:connect to upload.air32.cn,80
[2026-02-11 15:06:46.465] luat:D(181706):DNS:upload.air32.cn state 0 id 2 ipv6 0 use dns server0, try 0
[2026-02-11 15:06:46.465] luat:D(181706):net:adatper 2 dns server 223.5.5.5
[2026-02-11 15:06:46.465] luat:D(181706):net:dns udp sendto 223.5.5.5:53 from 192.168.0.107
[2026-02-11 15:06:46.465] luat:U(181708):I/user.系统内存使用情况 238608 30104 113936
[2026-02-11 15:06:46.465] luat:U(181708):I/user.Lua虚拟机内存使用情况 2097144 246136 246136
[2026-02-11 15:06:46.484] luat:I(181738):DNS:dns all done ,now stop
[2026-02-11 15:06:46.484] luat:D(181739):net:adapter 2 connect 49.232.89.122:80 TCP
[2026-02-11 15:06:47.683] luat:I(182919):zbuff:create large size: 128 kbyte, trigger force GC
[2026-02-11 15:06:56.475] luat:U(191708):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:06:56.475] luat:U(191709):I/user.Lua虚拟机内存使用情况 2097144 176280 248736
[2026-02-11 15:07:06.461] luat:U(201709):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:07:06.461] luat:U(201710):I/user.Lua虚拟机内存使用情况 2097144 182520 248736
[2026-02-11 15:07:16.472] luat:U(211710):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:07:16.472] luat:U(211711):I/user.Lua虚拟机内存使用情况 2097144 187104 248736
[2026-02-11 15:07:26.477] luat:U(221711):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:07:26.477] luat:U(221712):I/user.Lua虚拟机内存使用情况 2097144 191968 248736
[2026-02-11 15:07:36.474] luat:U(231712):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:07:36.474] luat:U(231713):I/user.Lua虚拟机内存使用情况 2097144 196816 248736
[2026-02-11 15:07:44.231] cal:I(239466):idx:39=41+(-2),r:54,xtal:79,pwr_gain:a4ab7120
[2026-02-11 15:07:46.476] luat:U(241713):I/user.系统内存使用情况 238608 30184 113936
[2026-02-11 15:07:46.476] luat:U(241714):I/user.Lua虚拟机内存使用情况 2097144 200376 248736
[2026-02-11 15:07:55.161] luat:U(250402):I/user.httpplus 服务器已完成响应,开始解析响应
[2026-02-11 15:07:55.174] luat:U(250412):I/user.http上传完成,code: 200
[2026-02-11 15:07:55.174] luat:U(250412):I/user.上传成功

点击 www.air32.cn 查看录制的视频

九、总结

通过本文学习,你可以学习到使用 Air8101 核心板 +AirCAMERA_1020 的拍照以及照片上传、Air8101 开发板 +AirCAMERA_1020 录像以及视频上传功能。