• 基于Lua框架下的合宙ESP32C3+1.5‘’Eink墨水屏天气时钟+OLED开源项目分享


    基于Lua框架下的合宙ESP32C3+1.5‘’Eink墨水屏天气时钟+OLED项目分享


    固件和脚本烧写教程,请参考上面的相关篇,本篇只这对部分内容进行说明。

    📖开源项目介绍

    📑合宙ESP32C3 电子墨水屏 OLED+ATH10 网络天气时钟,整合了官方demo实现的.

    合宙ESP32C3 墨水屏天气时钟

    • 📌项目地址:https://gitee.com/yingfumei96/ESP32C3

    📢接线说明

    在这里插入图片描述

    0.96/1.3 ssd1306/sh1106 IIC OLED  ----->ESP32C3
    SDA  ------>GPIO 4
    SCL ------->GPIO 5
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    🌻字体修改

    • 🌿资源包:https://gitee.com/openLuat/LuatOS
    • 📗具体字体请参考:LuatOS-master\components\luatfonts\luat_lib_fonts.c
        {.name="unifont_t_symbols", .font=u8g2_font_unifont_t_symbols},
        {.name="open_iconic_weather_6x_t", .font=u8g2_font_open_iconic_weather_6x_t},
        {.name="opposansm8", .font=u8g2_font_opposansm8},
        {.name="opposansm10", .font=u8g2_font_opposansm10},
        {.name="opposansm12", .font=u8g2_font_opposansm12},
        {.name="opposansm16", .font=u8g2_font_opposansm16},
        {.name="opposansm20", .font=u8g2_font_opposansm20},
        {.name="opposansm24", .font=u8g2_font_opposansm24},
        {.name="opposansm32", .font=u8g2_font_opposansm32},
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    🌷需要修改的地方说明

    local location = "101250303" --自己所在城市ID
    
    
    
    • 1
    • 2
    • 3
    • 📍国内城市编码表查询
    链接: https://pan.baidu.com/s/16YqQBNhNfd-Lm1cFvVY1mQ?pwd=3pnj 
    提取码: 3pnj 
    
    • 1
    • 2
    • 📌需自己注册天气API

    注册地址:https://tianqiapi.com/

    在这里插入图片描述

    appid = "8979xx36"
    appsecret = "OL8umxxP"
    
    • 1
    • 2
    • 📋填写自己的WIFI信息
    local wifiName,wifiPassword = "MERCURY_D268G","pba5ayzk"
    
    • 1

    🌼屏幕说明

     -- 初始化硬件i2c的ssd1306/sh1106
        -- ESP32C3 SDA:GPIO 4 ; SCL:GPIO 5
        -- 如果使用的是 ssd1306 0.96寸OLED,下面改成ssd1306,sh1106 1.3寸屏幕
        u8g2.begin({ic = "sh1106",direction = 0,mode="i2c_hw",i2c_id=0,i2c_speed = i2c.FAST}) -- direction 可选0 90 180 270
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    ⛳固件和脚本烧录

    在这里插入图片描述

    📝main.lua内容代码

    🔖本代码在原开源项目基础上做了修改,没有启用ATH10传感器,但是烧录脚本的时候需要添加进去。

    PROJECT = "wifidemo"
    
    VERSION = "1.0.0"
    
    
    
    local sys = require "sys"
    
    --添加硬狗防止程序卡死
    if wdt then
        wdt.init(15000)--初始化watchdog设置为15s
        sys.timerLoopStart(wdt.feed, 10000)--10s喂一次狗
    end
    
    --需要自行填写的东西
    
    --wifi信息
    
    
    
    --定义是否使用I2C 的ATH10好 OLED,默认零打开,其余任何字符都是关闭,这里只要Oled_on 不为0  ,就关闭了后面的所有OLED的显示
    local on = 0
    local off = 1
    
    --local ath10_on = on --加上ATH10 运存可能会不够,不需要就自己关了
    local oled_on = on --I2C OLED屏幕,买的是ssd1306,不需要就自己关了
    local eink_weather = on --水墨屏部分,不需要就自己关了,这里是按照合宙提供的方法解锁了IO11,没解锁的可以把水墨屏对应的针脚飞线插到别的地方,并且修改对应初始化代码即可
    --水墨屏初始化调用函数
    function elink_setup()
       -- 水墨屏初始化API 
       --eink.setup(0, 2,11,10,6,7)
        eink.setup(0, 2,11,10,6,7)
        -- body
    end
    --地区id,请前往https://api.luatos.org/luatos-calendar/v1/check-city/查询自己所在位置的id
    local location = "101250303" --城市ID
    --天气接口信息,需要自己申请,具体参数请参考https://api.luatos.org/页面上的描述
    
    local appid,appsecret = "",""
    appid = "89795xx6"
    appsecret = "OL8umxxP"
    --定义WIFI的名称和密码
    
    local wifiName,wifiPassword = "MERCURY_D268G","pba5ayzk"--填写自己的WIFI信息
    
    
    
    
    local function connectWifi()
    
        log.info("wlan", "wlan_init:", wlan.init())
    
    
    
        wlan.setMode(wlan.STATION)
    
        wlan.connect(wifiName,wifiPassword)
    
    
    
        -- 等待连上路由,此时还没获取到ip
    
        result, _ = sys.waitUntil("WLAN_STA_CONNECTED")
    
        log.info("wlan", "WLAN_STA_CONNECTED", result)
    
        -- 等到成功获取ip就代表连上局域网了
    
        result, data = sys.waitUntil("IP_READY")
    
        log.info("wlan", "IP_READY", result, data)
    
    end
    
    local function get_ntp_time()
        ntp.settz("CST-8") 
        ntp.init("ntp.ntsc.ac.cn")
        -- body
    end
    
    sys.subscribe(
        "NTP_SYNC_DONE",
        function()
            log.info("ntp", "done")
            log.info("date", os.date())
        end
    )
    
    
    
    local function requestHttp()
    
        local rd = {}
    
        local httpc = esphttp.init(esphttp.GET, "http://apicn.luatos.org:23328/luatos-calendar/v1?mac=111&battery=10&location="..location.."&appid="..appid.."&appsecret="..appsecret)
    
        if httpc then
    
            local ok, err = esphttp.perform(httpc, true)
    
            if ok then
    
                while 1 do
    
                    local result, c, ret, data = sys.waitUntil("ESPHTTP_EVT", 20000)
    
                    --log.info("httpc", result, c, ret)
    
                    if c == httpc then
    
                        if esphttp.is_done(httpc, ret) then
    
                            break
    
                        end
    
                        if ret == esphttp.EVENT_ON_DATA and esphttp.status_code(httpc) == 200 then
    
                            table.insert(rd,data)
    
                        end
    
                    end
    
                end
    
            else
    
                log.warn("esphttp", "bad perform", err)
    
           end
    
            esphttp.cleanup(httpc)
    
            if ok then
    
                return table.concat(rd)
    
            end
    
        end
    
    end
    
    
    
    local function refresh()
    
        log.info("refresh","start!")
        local data
    
        for i=1,5 do
            --重试最多五次
            data = requestHttp()
            if #data > 100 then
    
                break
    
            end
    
            log.info("load fail","retry!")
    
        end
    
        if #data < 100 then
    
            log.info("load fail","exit!")
    
            return
    
        end
    
        eink.model(eink.MODEL_1in54)
        -- log.info("eink.setup",eink.setup(0, 2,10,10,6,7)) 
        -- log.info("eink.setup",eink.setup(0, 2,11,10,6,7))
        
        log.info("eink.setup",elink_setup())
        --elnk_start = elnk_start + 1
        eink.setWin(200, 200, 2)--0代表不旋转,1,代表选择90度,2,代表选择180度
        eink.clear(1)
    
        log.info("eink", "end setup")
        eink.drawXbm(0, 0, 200, 200, data)--Elink屏幕显示
        -- 刷屏幕
        eink.show()
    
        eink.sleep()
    
        log.info("refresh","done")
    
    end
    
    --这里用于后面I2C读值四舍五入,例如
    --num1=(aht10_data.RH*100)  --基于小米蓝牙温湿度计比对调的湿度原始数据+/-差异值或者直接修改传感器读取代码,确保串口和屏幕信息一致
    --num2=(aht10_data.T)    --基于小米蓝牙温湿度计比对调的温度原始数据+/-差异值或者直接修改传感器读取代码,确保串口和屏幕信息一致
    --hum=keepDecimalTest(num1, 2)
    --temp=keepDecimalTest(num2, 2)   
    
    local function keepDecimalTest(num, n)
    
        if type(num) ~= "number" then
            return num    
        end
      --  n = n or 2
        return string.format("%." .. n .. "f", num)
    end
    
    --[[sys.taskInit(function()
    
        --先连wifi
       
    
        connectWifi()
    
       
        get_ntp_time()
    
    
        while true do
    
            refresh()
    
            sys.wait(3600*1000)
    
            --一小时刷新一次吧
    
        end
    
    end)
    ]]
     
    
    
    if oled_on == 0 then
    
        local TAG = "main"
    
    
        -- 初始化显示屏
    
        log.info(TAG, "init ssd1306/sh1106")
    
    
        -- 初始化硬件i2c的ssd1306/sh1106
        -- ESP32C3 SDA:GPIO 4 ; SCL:GPIO 5
        -- 如果使用的是 ssd1306 0.96寸OLED,下面改成ssd1306,sh1106 1.3寸屏幕
        u8g2.begin({ic = "sh1106",direction = 0,mode="i2c_hw",i2c_id=0,i2c_speed = i2c.FAST}) -- direction 可选0 90 180 270
    
        -- 初始化软件i2c的ssd1306
    
        -- u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_sw", i2c_scl=1, i2c_sda=4}) -- 通过PA1 SCL / PA4 SDA模拟
    
    
        u8g2.SetFontMode(1)
    
        u8g2.ClearBuffer()
    
        u8g2.SetFont(u8g2.font_opposansm12)--字体大小:8,12,16,20,24,32
    
        u8g2.DrawUTF8("Perseverance51", 3, 16)
    
        --u8g2.SetFont(u8g2.font_opposansm12_chinese)
    
        --u8g2.DrawUTF8("中文测试", 40, 38)
            
           
        --u8g2.SetFont(u8g2.font_opposansm8_chinese)
    
        u8g2.DrawUTF8("Hello World", 10, 42)
       
        u8g2.SendBuffer()
    
    end
    
    --local aht10 = require "aht10"
    if ath10_on == 0 then 
    
        aht10 = require "aht10"
    
        i2cid = 0
    
        i2c_speed = i2c.FAST
    
    end
    
    sys.taskInit(function()
            --链接WIFI
            rtc.set({year=2022,mon=10,day=16,hour=19,min=08,sec=43})
    
            connectWifi()
    
            --获取网络时间
            get_ntp_time()
            --加载天气图片到水墨屏
           if eink_weather == 0 then
            refresh()
           end
            local str_month1
            local str_day
            local str_month
            local str_year
            local str_time
            local str_datetime2
            local str_date
            local str_week
            local str_week1 = ""
            local str_week2 
            local str_voidhour
            local str_min
            local num3 = 2
    
            if ath10_on == 0 then
    
                i2c.setup(i2cid,i2c_speed)
    
                aht10.init(i2cid)
    
            end  -- sys.wait(2000)
       
    
           
            while 1 do
                sys.wait(50)
               
                local str_datetime = os.date()
                --log.info(str_datetime)--打印时间信息
                str_week = string.sub(str_datetime,1,3)
                str_month = string.sub(str_datetime,5,7)
                str_day = string.sub(str_datetime,9,10)
    
                if str_week == "Sun" then
                    str_week1 = "天"
                    str_week2 = 7
                elseif str_week == "Mon" then
                    str_week1 = "一"
                    str_week2 = 1
                elseif str_week == "Tue" then
                    str_week1 = "二"
                    str_week2 = 2
                elseif str_week == "Wed" then
                    str_week1 = "三"
                    str_week2 = 3
                elseif str_week == "Thu" then
                    str_week1 = "四"
                    str_week2 = 4
                elseif str_week == "Fri" then
                    str_week1 = "五"
                    str_week2 = 5
                elseif str_week == "Sat" then
                    str_week1 = "六"
                    str_week2 = 6
                end
    
                if(str_month=="Jan") then
                    str_month1 = "01"
                elseif str_month == "Feb" then
                    str_month1 = "02"
                elseif str_month == "Mar" then
                    str_month1 = "03"
                elseif str_month == "Apr" then
                    str_month1 = "04"
                elseif str_month == "May" then
                    str_month1 = "05"
                elseif str_month == "Jun" then
                    str_month1 = "06"
                elseif str_month == "Jul" then
                    str_month1 = "07"
                elseif str_month == "Aug" then
                    str_month1 = "08"
                elseif str_month == "Aep" then
                    str_month1 = "09"
                elseif str_month == "Oct" then
                    str_month1 = "10"
                elseif str_month == "Nov" then
                    str_month1 = "11"
                elseif str_month == "Dec" then
                    str_month1 = "12"
                end
                
                str_year = string.sub(str_datetime,21,24)
                str_time = string.sub(str_datetime,12,20)
               -- log.info("输出:"..str_time)
               str_voidhour = string.sub(str_datetime,15,19) --这里是截取时间数据里面的分和秒
               
           
               str_min = string.sub(str_datetime,18,19) --截取秒
    
            if ath10_on == 0  then 
    
                local aht10_data = aht10.get_data()
                num1=(aht10_data.RH*100)  --基于小米蓝牙温湿度计比对调的湿度原始数据+/-差异值或者直接修改传感器读取代码,确保串口和屏幕信息一致
                num2=(aht10_data.T)    --基于小米蓝牙温湿度计比对调的温度原始数据+/-差异值或者直接修改传感器读取代码,确保串口和屏幕信息一致
                hum=keepDecimalTest(num1, 2)
                temp=keepDecimalTest(num2, 2)           
                --u8g2.ClearBuffer() -- 清屏
                --u8g2.SetFont(u8g2.font_opposansm12_chinese)
                --  u8g2.SendBuffer()
                     
            end
               -- 定义OLED刷新
            if oled_on == 0 then
           
                u8g2.ClearBuffer()
                if ath10_on == 0 then
                    u8g2.SetFont(u8g2.font_opposansm8_chinese)
                    u8g2.DrawUTF8("温:"..temp.."C'", 0, 60)
                    u8g2.DrawUTF8("湿:"..hum.."%", 65,60)
                    --else
                        --u8g2.SetFont(u8g2.font_opposansm8)
                        --u8g2.DrawUTF8("U8g2+LuatOS", 30, 60)
                end 
    
                sys.wait(50)
                --u8g2.SetFont(u8g2.font_opposansm8_chinese)
                u8g2.SetFont(u8g2.font_opposansm12)--字体大小:8,12,16,20,24,32
                u8g2.DrawUTF8(str_year.."-"..str_month1.."-"..str_day.." "..str_week,2, 15)--OLED:2022-10-16 SUN显示位置
                
                u8g2.SetFont(u8g2.font_opposansm16)--字体大小:8,12,16,20,24,32
                -- u8g2.DrawUTF8("Week: "..str_week,5, 60)--星期显示位置
               -- sys.wait(50)
                
                u8g2.DrawUTF8(str_time,20, 52)
                u8g2.SendBuffer()
            end
               --u8g2.SetFont(u8g2.font_opposansm12_chinese)
               --u8g2.DrawUTF8("中文测试", 40, 38)
             --  u8g2.SendBuffer()
    
               -- 定义 水墨屏刷新的时间节点
            if eink_weather == 0 then
               -- if str_min == "59" then --可以每分钟刷新一次
                if str_voidhour == "00:00" or str_voidhour == "30:00" then --每整点或者30分刷新一次
                    log.info("1小时准点刷新水墨屏天气")
                    log.info(str_year.." "..str_month1.." "..str_day..str_time..str_week1)
                 --   后面的代码是为了限制水墨屏在一秒内刷新次数太多,造成RAM拥堵
                    num3 = num3 + 1
                    print("num3 = "..num3)
                    bbb = num3%3
                    if bbb == 0 then
                    num3 = 1
                    if oled_on == 0 then
                        u8g2.ClearBuffer()
                        u8g2.SetFont(u8g2.font_opposansm8_chinese)
                        u8g2.DrawUTF8(str_year.."-"..str_month1.."-"..str_day,30, 10)
                        sys.wait(50)
                        u8g2.DrawUTF8("天气更新中....",35, 35)
                        u8g2.DrawUTF8("星期"..str_week1,5, 60)
                        u8g2.SendBuffer()
                    end
                    
                    collectgarbage("collect")
    
                        refresh()
                    end
                end
            end
               -- lvgl.label_set_text(label_time,"#00CED1 "..str_year.."-"..str_month1.."-"..str_day.." ##00ff00 " ..str_time.."##90EE90 星期"..str_week1.."#")
                sys.wait(50)
        end
    end)
    
    sys.taskInit(function()
        local LEDA = gpio.setup(12, 0, gpio.PULLUP) -- PE07输出模式,内部上拉
        local LEDB = gpio.setup(13, 0, gpio.PULLUP) -- PE06输出模式,内部上拉
        --local LEDC = gpio.setup(pin.PD15, 0, gpio.PULLUP) -- PB10输出模式,内部上拉
        
            local count = 0
            while 1 do
              --  sys.wait(1000)
                -- 一闪一闪亮晶晶
                LEDA(0)
                LEDB(1)
                sys.wait(1000)
                LEDA(1)
                LEDB(0)
                sys.wait(1000)
                LEDA(1)
                LEDB(1)
                sys.wait(1000)
                LEDA(0)
                LEDB(0)
                sys.wait(1000)
               -- log.info("gpio", "Go Go Go", count, rtos.bsp())
               -- count = count + 1
            end
        end)
    
    
    -- 用户代码已结束-------------------------------------
    
    -- 结尾总是这一句
    
    sys.run()
    
    -- sys.run()之后后面不要加任何语句!!!!!
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448
    • 449
    • 450
    • 451
    • 452
    • 453
    • 454
    • 455
    • 456
    • 457
    • 458
    • 459
    • 460
    • 461
    • 462
    • 463
    • 464
    • 465
    • 466
    • 467
    • 468
    • 469
    • 470
    • 471
    • 472
    • 473
    • 474
    • 475
    • 476
    • 477
    • 478
    • 479
    • 480
    • 481
    • 482
    • 483
    • 484
    • 485
    • 486
    • 487
    • 488
    • 489
    • 490
    • 491
    • 492
    • 493
    • 494
    • 495
    • 496
    • 497
  • 相关阅读:
    java计算机毕业设计springboot+vue旅游记忆系统
    音视频视频点播
    国科大课程自动评价脚本JS
    信息化发展56
    应用现代化产业联盟,正式成立
    队列和进程的使用
    [附源码]SSM计算机毕业设计农贸产品交易系统JAVA
    【剑指offer系列】17-19
    【C++】STL——vector(万字详解)
    web前端大作业:诗人文化网页主题网站【唐代诗人】纯HTML+CSS制作
  • 原文地址:https://blog.csdn.net/weixin_42880082/article/details/127349585