合宙Air101的软硬件开发

        上半年利用业余时间使用国产芯片-合宙Air101 做了个小玩具,有点小成果,奈何现在忙带娃,基本没有时间继续了,已经吃灰了一段时间,做个总结,送有缘人。

         XT-E804是阿里平头哥的MCU,属于CSKY架构(与RISC-V接近),合宙Air101芯片是XT-E804的QFN32封装,4mm*4mm封装大小。具有32位高性能内核,主频最高可达240MHz。内置UART、SPI、I2C、GPIO、ADC、PWM等外设接口,内置2MB Flash,作为一般的IOT设备开发足够。

        部分原理图如下:

 使用的嘉立创EDA 专业版,布线图如下:

 背面接口见下图,采用常用的PH2.0卧式,3pin和4pin;供电使用常用的6pin TYPE-C;按键采用3*4*2.5轻触按键。屏幕采用1.14寸TFT显示屏,135*240分辨率,ST7789V驱动。同接口规格的还可以使用0.96寸显示屏,80*160分分辨率,ST7735驱动。板子整体尺寸为40mm*20mm。

        CN1做输入口可接单总线传感器(ds18b20)或NTC热敏电阻;CN2输出口可接5v继电器或MOS管模块,输出PWM信号和开关信号;CN3为usart接口,用于下载程序和通信;CN4为模拟I2C接口(硬件I2C被ADC占用),接传感器。 

        开始显示屏使用了8PIN插接款,后来发现接头有一定高度,后来改为焊线款,屏幕可以贴合到mcu上,更紧凑。

        3D效果图(开始显示屏使用了8PIN插接款,后来发现接头有一定高度,后来改为焊线款,屏幕可以贴合到mcu上,更紧凑):

换个角度看 : 

 软件部分,开发采用vscode,安装LuatIDE插件,采用合宙推荐的LuatOS开发,图形界面采用LVGL库。


-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "lvgldemo"
VERSION = "1.0.0"

log.info("main", PROJECT, VERSION)

-- sys库是标配
_G.sys = require("sys")

--添加硬狗防止程序卡死
if wdt then
    wdt.init(15000)--初始化watchdog设置为15s
    sys.timerLoopStart(wdt.feed, 10000)--10s喂一次狗
end

-- UI带屏的项目一般不需要低功耗了吧, 设置到最高性能
if mcu then
    mcu.setClk(240)
end

log.info("main", "ask for help", "https://wiki.luatos.com/")

--air101 v2 13pin
spi_lcd = spi.deviceSetup(0,pin.PB08,0,0,8,10*1000*1000,spi.MSB,1,1)
lcd.init("st7789",{port = "device",pin_dc = pin.PB10, pin_rst = pin.PB09,direction = 2,w = 240,h = 135,xoffset = 40,yoffset = 53},spi_lcd)


SignalOn = false
function getSignalState(t)
    if heatingMode == 1 then
        if SignalOn == false and t < trigerValue then 
            SignalOn = true
            gpio.set(pin.PB01,1)
        end
        if SignalOn == true and t > trigerValue+returnDifference then
            SignalOn = false
            gpio.set(pin.PB01,0)
        end
    else
        if SignalOn == false and t > trigerValue then 
            SignalOn = true
            gpio.set(pin.PB01,1)
        end
        if SignalOn == true and t < trigerValue-returnDifference then
            SignalOn = false
            gpio.set(pin.PB01,0)
        end
    end
    return SignalOn
end

function f0(v)
    if sensorID == 0 then--vcc voltage in mV
        lvgl.gauge_set_value(gauge,0,v//100)
    elseif sensorID == 2 then-- external voltage
        lvgl.gauge_set_value(gauge,0,v//100)
    elseif sensorID == 3 or sensorID == 4 then--external tempreture
        lvgl.gauge_set_value(gauge,0,math.floor(v))
        if getSignalState(v) == true then
            lvgl.switch_on(sw1, lvgl.ANIM_ON)
        else
            lvgl.switch_off(sw1, lvgl.ANIM_ON)
        end
    end
end
function drawGauge()--0
    local val = 30
    sensorOn = true
    sw1 = lvgl.switch_create(lvgl.scr_act())
    lvgl.obj_align(sw1, nil, lvgl.ALIGN_CENTER, 96, -51)
    --lvgl.obj_set_size(sw1, 20, 20)
    lvgl.switch_off(sw1, lvgl.ANIM_ON)
    gauge = lvgl.gauge_create(lvgl.scr_act())
    lvgl.obj_align(gauge, nil, lvgl.ALIGN_CENTER, -21, 30)
    lvgl.obj_set_size(gauge, 238, 238)
    lvgl.gauge_set_range(gauge, -20, 100)
    lvgl.gauge_set_scale(gauge,180,31,7)
    --lvgl.gauge_set_needle_count(g1, 1, lvgl.color_hex(0xFF0000))
    lvgl.gauge_set_critical_value(gauge, 80)
    sys.subscribe("value",f0)
    while true do
        local r,k = sys.waitUntil("key")
        if k=="3" then
            sys.unsubscribe("value",f0)
            lvgl.obj_clean(gauge)
            lvgl.obj_del(gauge)
            lvgl.obj_clean(sw1)
            lvgl.obj_del(sw1)
            log.info("key",k)
            return 2
        elseif k == "4" then
            sys.unsubscribe("value",f0)
            lvgl.obj_clean(gauge)
            lvgl.obj_del(gauge)
            lvgl.obj_clean(sw1)
            lvgl.obj_del(sw1)
            log.info("key",k)
            return 3
        elseif k=="5" then
            sys.unsubscribe("value",f0)
            lvgl.obj_clean(gauge)
            lvgl.obj_del(gauge)
            lvgl.obj_clean(sw1)
            lvgl.obj_del(sw1)
            log.info("key",k)
            return 1
        end
    end
end

function f1(v)
    if sensorID == 0 then
        lvgl.chart_set_next(chart, ser1, v//100)
    elseif sensorID == 2 then
        lvgl.chart_set_next(chart, ser1, v//100)
    elseif sensorID == 3 then
        lvgl.chart_set_next(chart, ser1, math.floor(v))
    elseif sensorID == 4 then
        lvgl.chart_set_next(chart, ser1, math.floor(v))
    end
    lvgl.chart_refresh(chart)
end
function drawChart()--1
    chart = lvgl.chart_create(lvgl.scr_act(), nil)
    lvgl.obj_set_size(chart, 240, 135)
    lvgl.obj_align(chart, nil, lvgl.ALIGN_CENTER, 0, 0)
    --lvgl.obj_set_stype_local_value_str(chart,lvgl.CONT_PART_MAIN,lvgl.STATE_DEFAULT,"                                                                     ")
    lvgl.chart_set_type(chart, lvgl.CHART_TYPE_LINE)-- 设置 Chart 的显示模式 (折线图)
    lvgl.chart_set_range(chart,-20,100)
    lvgl.chart_set_div_line_count(chart,5,8)
    lvgl.chart_set_point_count(chart,20)
    --lvgl.chart_set_y_tick_length(chart,0,0)
    --lvgl.chart_set_y_tick_texts(chart, "100\n80\n60\n40\n20\n0\n-20", 3, lvgl.CHART_AXIS_DRAW_LAST_TICK);
    ser1 = lvgl.chart_add_series(chart, lvgl.color_hex(0xFF0000))
    --ser2 = lvgl.chart_add_series(chart, lvgl.color_hex(0x008000))
    sys.subscribe("value",f1)
    while true do
        local r,k = sys.waitUntil("key")
        if k == "3" then
            sys.unsubscribe("value",f1)
            lvgl.obj_clean(chart)
            lvgl.obj_del(chart)
            return 0
        elseif k == "4" then
            log.info("key",k)
            sys.unsubscribe("value",f1)
            lvgl.obj_clean(chart)
            lvgl.obj_del(chart)
            return 3
        elseif k == "5" then
            sys.unsubscribe("value",f1)
            lvgl.obj_clean(chart)
            lvgl.obj_del(chart)
            return 2
        end
    end
end

function f2(v)
    lvgl.obj_clean(text)
    if sensorID == 0 then
        lvgl.label_set_text(text, string.format("%d mV",v))
    elseif sensorID == 2 then
            lvgl.label_set_text(text, string.format("%d mV",v))
    elseif sensorID == 3 then
        lvgl.label_set_text(text, string.format("%.1f °C",v))
    elseif sensorID == 4 then
        lvgl.label_set_text(text, string.format("%.1f °C",v))
    end
end
function drawText()--2
    local label1 = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(label1, nil, lvgl.ALIGN_CENTER, -40, -40)
    if sensorID == 0 then
        lvgl.label_set_text(label1, "VCC Voltage:")
    elseif sensorID == 3 then
        lvgl.label_set_text(label1,"DS18B20:")
    elseif sensorID == 4 then
        lvgl.label_set_text(label1,"NTC 10K B2950:")
    else
        lvgl.label_set_text(label1, "label1:")            
    end
    text = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(text, nil, lvgl.ALIGN_CENTER, -40, 10)
    sys.subscribe("value",f2)
    while true do
        local r,k = sys.waitUntil("key")
        if k == "3" then
            sys.unsubscribe("value",f2)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            lvgl.obj_clean(text)
            lvgl.obj_del(text)
            log.info("key",k)
            return 1
        elseif k == "4" then
            sys.unsubscribe("value",f2)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            lvgl.obj_clean(text)
            lvgl.obj_del(text)
            log.info("key",k)
            return 3
        elseif k == "5" then
            sys.unsubscribe("value",f2)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            lvgl.obj_clean(text)
            lvgl.obj_del(text)
            log.info("key",k)
            return 0
        end
    end
end

sensorID = 0
function setSensor()--3
    sensorOn = false
    local i = sensorID
    local label1 = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(label1, nil, lvgl.ALIGN_CENTER, -90, -40)
    lvgl.label_set_text(label1, "Data Source:")
    local dd = lvgl.dropdown_create(lvgl.scr_act(), nil)
    lvgl.dropdown_set_options(dd, [[VCC Voltage
    Chip Tempreture
    External Voltage
    DS18b20
    NTC 10k B:2950]])
    lvgl.obj_align(dd, nil, lvgl.ALIGN_CENTER, -40, 0)
    lvgl.obj_set_width(dd,180)
    lvgl.dropdown_set_selected(dd, i)
    while true do
        local r,k = sys.waitUntil("key")
        if k == "3" then
            i = (i+4)%5
            lvgl.dropdown_set_selected(dd, i)
        end
        if k == "4" then
            sensorID = lvgl.dropdown_get_selected(dd)
            log.info("sensorID",sensorID)
            lvgl.obj_clean(dd)
            lvgl.obj_del(dd)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            return 4
        end
        if k == "5" then
            i = (i+1)%5
            lvgl.dropdown_set_selected(dd, i)
        end
    end
end

heatingMode = false --1 for heating, 0 for refrigerating mode
function setHeatingMode()
    local i = 0
    if heatingMode == true then
        i = 1
    end
    local label1 = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(label1, nil, lvgl.ALIGN_CENTER, -90, -40)
    lvgl.label_set_text(label1, "Application Mode:")
    local dd = lvgl.dropdown_create(lvgl.scr_act(), nil)
    lvgl.dropdown_set_options(dd, [[Refrigerating Mode
    Heating Mode]])
    lvgl.obj_align(dd, nil, lvgl.ALIGN_CENTER, -40, 0)
    lvgl.obj_set_width(dd,200)
    lvgl.dropdown_set_selected(dd, i)
    while true do
        local r,k = sys.waitUntil("key")
        if k == "4" then
            i = lvgl.dropdown_get_selected(dd)
            if i == 1 then 
                heatingMode = true
            else
                heatingMode = false
            end
            log.info("heatingMode",heatingMode)
            lvgl.obj_clean(dd)
            lvgl.obj_del(dd)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            return 5
        else
            i = (i+1)%2
            lvgl.dropdown_set_selected(dd, i)
        end
    end
end

signalMode = 1 --5
function setSignalMode()--0 for PWM mode 1 for Relay Mode
    local i=signalMode
    local label1 = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(label1, nil, lvgl.ALIGN_CENTER, -90, -40)
    lvgl.label_set_text(label1, "Signal:")
    local dd = lvgl.dropdown_create(lvgl.scr_act(), nil)
    lvgl.dropdown_set_options(dd, [[ON/OFF
    PWM ON/OFF]])
    lvgl.obj_align(dd, nil, lvgl.ALIGN_CENTER, -40, 0)
    lvgl.obj_set_width(dd,180)
    lvgl.dropdown_set_selected(dd, i)
    while true do
        local r,k = sys.waitUntil("key")
        if k == "4" then
            signalMode = lvgl.dropdown_get_selected(dd)
            log.info("signalMode",signalMode)
            lvgl.obj_clean(dd)
            lvgl.obj_del(dd)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            return 6
        else
            i = (i+1)%2
            lvgl.dropdown_set_selected(dd, i)
        end
    end
end

trigerValue = 30.0
function setTrigerValue()--6
    local label1 = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(label1, nil, lvgl.ALIGN_CENTER, -90, -40)
    lvgl.label_set_text(label1, "Trigger Value:")
    local sb1 = lvgl.spinbox_create(lvgl.scr_act(),nil)
    lvgl.obj_set_width(sb1,120)
    lvgl.obj_align(sb1, nil, lvgl.ALIGN_CENTER, 0, 0)
    lvgl.spinbox_set_digit_format(sb1, 4, 3)
    lvgl.spinbox_set_range(sb1, -200, 1000)
    lvgl.spinbox_set_value(sb1,math.floor(trigerValue*10))
    while 1 do
        local r,k = sys.waitUntil("key")
        if k == "3" then
            lvgl.spinbox_decrement(sb1)
        elseif k == "4" then
            trigerValue = lvgl.spinbox_get_value(sb1)/10
            log.info("trigerValue",trigerValue)
            lvgl.obj_clean(sb1)
            lvgl.obj_del(sb1)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            return 7
        elseif k == "5" then
            lvgl.spinbox_increment(sb1)
        end
    end
end

returnDifference = 5.0
function setReturnDifference()--7
    local label1 = lvgl.label_create(lvgl.scr_act())
    lvgl.obj_align(label1, nil, lvgl.ALIGN_CENTER, -90, -40)
    lvgl.label_set_text(label1, "Return Difference:")
    local sb2 = lvgl.spinbox_create(lvgl.scr_act(),nil)
    lvgl.obj_set_width(sb2,80)
    lvgl.obj_align(sb2, nil, lvgl.ALIGN_CENTER, 0, 0)
    lvgl.spinbox_set_digit_format(sb2, 3, 2)
    lvgl.spinbox_set_range(sb2, 0, 1000)
    lvgl.spinbox_set_value(sb2,math.floor(returnDifference*10))
    while 1 do
        local r,k = sys.waitUntil("key")
        if k == "3" then
            lvgl.spinbox_decrement(sb2)
        elseif k == "4" then
            returnDifference = lvgl.spinbox_get_value(sb2)/10
            log.info("returnDifference",returnDifference)
            lvgl.obj_clean(sb2)
            lvgl.obj_del(sb2)
            lvgl.obj_clean(label1)
            lvgl.obj_del(label1)
            return 8
        elseif k == "5" then
            lvgl.spinbox_increment(sb2)
        end
    end
end

function screen(n)
    
    if n == 0 then
        return drawGauge()--仪表盘
    end
    if n == 1 then
        return drawChart()--折线图
    end
    if n==2 then
        return drawText()--输出模式,只用文字输出
    end
    if n==3 then
        return setSensor()--下拉选项框,传感器选择
    end
    if n==4 then
        return setHeatingMode()--下拉选项框,工作模式 加热 降温
    end
    if n==5 then
        return n+1  --不选PWM 模式
        --return setSignalMode()--下拉选项框,信号模式,0 pwm mode 1 继电器模式
    end
    if n==6 then
        return setTrigerValue()--下拉选项框,触发值
    end
    if n==7 then
        return setReturnDifference()--下拉选项框,回差值
    end
    if n==8 then
        --创建表格
        return n+1
    end
    --触发值
    if n==9 then
        return n+1
    end
    --回差
    if n==10 then
        return n+1
    end
    --回差
    if n==11 then
        return n+1
    end
    --回差
    if n==12 then
        return n+1
    end
    --回差
    if n==13 then
        return n+1
    end
    --回差
    if n==14 then
        return n+1
    end
    --回差
    if n==15 then
        return 0
    end
end

--------------------------------------
function getVccVolt()
    adc.open(11) -- VCC电压,最新代码才支持
    local v1,v2 = adc.read(11)
    adc.close(11)
    log.info("vccVolt",v1)
    return v1
end
function getChipTemp()
    adc.open(10) -- CPU温度
    local t1,t2 = adc.read(10)
    adc.close(10)
    return t1
end
function getPortVolt()
    adc.open(1) -- 模块上的ADC1脚-PA4, 0~2.4v,不要超过范围使用!!!
    local value,volt = adc.read(1)
    adc.close(1)
    log.info("adc",volt)
    return volt
end
function getDs18b20()
    while true do
        local value,status = sensor.ds18b20(4,false)
        if status == true then
            return value
        end
    end
end
function getNtcTemp()
    adc.open(1) -- 模块上的ADC1脚-PA4, 0~2.4v,不要超过范围使用!!!
    local value,volt = adc.read(1)
    adc.close(1)
    adc.open(11) -- VCC电压,最新代码才支持
    local v1,v2 = adc.read(11)
    adc.close(11)
    local resistant = 10000*volt/(v1-volt)
    local temp = 1/(1/298.15 + math.log(resistant/10000)/3950) - 273.15
    log.info("ntc",temp)
    return temp
end
-------------------get sensor value-------------------
sys.taskInit(function()
    while true do
        sys.wait(1000)
        if sensorOn == true then
            if sensorID == 0 then
                sys.publish("value",getVccVolt())
            end
            if sensorID == 1 then
                log.debug("value","chip_temp","not support")
            end
            if sensorID == 2 then--检测分压电压
                sys.publish("value",getPortVolt())
            end
            if sensorID == 3 then--DS18B20
                sys.publish("value",getDs18b20()/10)
            end
            if sensorID == 4 then
                sys.publish("value",getNtcTemp())
            end
        end
    end
end)

----按键检测
sys.taskInit(function()
    gpio.setup(pin.PB11, nil, gpio.PULLUP)--27,up
    gpio.setup(pin.PB04, nil, gpio.PULLUP)--20,center
    gpio.setup(pin.PB00, nil, gpio.PULLUP)--16,down
    gpio.setup(pin.PB01,0)                --PWM Signal
    while true do
        if gpio.get(27) == gpio.LOW then
            sys.publish("key","3")
        end
        if gpio.get(20) == gpio.LOW then
            sys.publish("key","4")
        end
        if gpio.get(16) == gpio.LOW then
            sys.publish("key","5")
        end
        sys.wait(150)
    end
end)

--SCREEN WINDOWS
sys.taskInit(function()
    sys.wait(100)
    log.info("lvgl", lvgl.init())
        -- ("default")("mono")("empty")("material_light")material_dark
    --lvgl.theme_set_act("mono")
        -- ("material_no_transition")("material_no_focus")
    scr = lvgl.scr_act()
    local font_20 = lvgl.font_load("/luadb/20_test_fonts.bin")
    
    lvgl.obj_set_style_local_text_font(lvgl.scr_act(), lvgl.LABEL_PART_MAIN, lvgl.STATE_DEFAULT, font_20)
    local screen_n = 0
    while true do
        screen_n = screen(screen_n)
    end
end)

-- 用户代码已结束---------------------------------------------
-- 结尾总是这一句
sys.run()
-- sys.run()之后后面不要加任何语句!!!!!

实物效果图两张:

<think>嗯,用户想了解Air780E和ESP32的对比或相关信息。首先,我需要确认这两款设备的基本信息。Air780E是通信推出的Cat.1模块,支持4G LTE网络,主要用于物联网应用。ESP32是乐鑫推出的Wi-Fi和蓝牙双模芯片,常用于低功耗物联网设备。 接下来,用户可能需要对比它们的网络连接方式。Air780E使用4G LTE,适需要广域覆盖的场景,而ESP32依赖Wi-Fi和蓝牙,适局域网连接。这一点在应用场景上会有明显区别,比如远程监控可能需要4G,而智能家居可能用Wi-Fi就够了。 然后是处理器性能。Air780E的主频和核心数可能更高,但需要具体参数。ESP32通常是双核Xtensa LX6,主频240MHz,处理能力不错。不过的模块可能集成了更多专用硬件,比如基带处理,这可能影响整体性能表现。 功耗也是一个关键点。4G模块通常比Wi-Fi耗电更多,所以Air780E可能在功耗上不如ESP32。这对电池供电的设备来说很重要,用户可能关心续航问题。 开发环境方面,ESP32有Arduino和ESP-IDF支持,生态成熟,资料多。Air780E可能使用Lua语言或AT指令,这对开发者来说学习曲线不同。需要确认用户是否有特定的开发偏好。 价格和供货情况,ESP32因为广泛应用,价格较低且容易购买。Air780E作为Cat.1模块,价格可能稍高,但的产品通常性价比较好。需要提醒用户考虑项目预算和量产需求。 应用场景方面,要分情况讨论。比如车载追踪、智能电表适Air780E的4G连接;而智能家居传感器、智能手表可能更适ESP32的Wi-Fi/蓝牙。用户可能有具体的项目类型,需要根据场景推荐。 可能用户的问题还包括如何选择模块,或者两者能否结使用。比如用ESP32处理本地数据,Air780E负责远程传输,这种组方案是否可行。此外,可能涉及通信协议、安全性、开发难度等更深层次的问题。 需要确保回答准确,引用相关资料。例如,引用中提到ESP协议涉及加密,可能和ESP32的命名无关,但需要注意区分。同时,用户提供的引用中有关于“航行”和“重要性”的内容,可能不相关,但需确保不混淆。 最后,生成的相关问题要覆盖用户可能进一步关心的点,比如性能对比、优缺点、选型建议、开发资源等,帮助他们深入决策。</think>### Air780E与ESP32对比分析 #### 1. 基础参数对比 | 特性 | Air780E | ESP32 | |-------------------|-------------------------------------------|-------------------------------------------| | **通信协议** | 4G LTE Cat.1[^1] | Wi-Fi 4 (802.11n)/蓝牙4.2+[^2] | | **处理器** | 联发科MTK6261D + 移芯EC618双核 | Xtensa LX6双核(240MHz) | | **开发语言** | Lua/AT指令 | C/C++/MicroPython/Arduino | | **典型功耗** | 待机<1mA,数据传输峰值~200mA | 待机<5mA,Wi-Fi传输峰值~120mA | | **价格范围** | ¥50-80 | ¥15-30 | #### 2. 关键差异点 - **网络覆盖** Air780E通过4G基站实现广域网连接,适无Wi-Fi覆盖场景(如车载设备、野外监测) ESP32依赖Wi-Fi/蓝牙的局域网连接,适室内智能家居场景 - **协议栈复杂度** Air780E内置完整TCP/IP协议栈,支持MQTT/HTTP等物联网协议 ESP32需要开发者自行实现网络协议封装 - **安全机制** Air780E支持SIM卡级身份认证 ESP32通过软加密实现安全通信(如TLS/SSL)[^3] #### 3. 选型建议 $$ \text{选择条件} = \begin{cases} \text{Air780E} & \text{远程数据传输} \geq 1\text{km} \\ \text{ESP32} & \text{局域组网成本} \leq ¥20/\text{节点} \end{cases} $$ #### 4. 典型应用场景 - **Air780E适用** ▫ 共享设备远程管理 ▫ 跨城市物流追踪 ▫ 需直接对接云平台的工业设备 - **ESP32适用** ▫ 家庭环境传感器网络 ▫ 蓝牙Mesh组网 ▫ 需要边缘计算的场景 ```c // ESP32典型Wi-Fi连接代码 #include <WiFi.h> void setup(){ WiFi.begin("SSID","PASSWORD"); while(WiFi.status()!=WL_CONNECTED){ delay(500); Serial.print("."); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值