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

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


  • 相关篇《基于Lua框架下的合宙ESP32C3+1.5‘’Eink墨水屏天气时钟项目》
  • ✨显示效果
  • OLED屏幕驱动采用的是U8g2库,理论上U8g2库支持的屏幕都可以支持,本篇只适配了ssd1306sh1106 IIC接口的屏幕。
  • 本项目使用的固件版本是:LuatOS-SoC_V0004_ESP32C3.soc

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

开源项目介绍

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

合宙ESP32C3 墨水屏天气时钟

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

接线说明

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

0.96/1.3 ssd1306/sh1106 IIC OLED  ----->ESP32C3
SDA  ------>GPIO 4
SCL ------->GPIO 5

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

字体修改

  • 资源包: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},

需要修改的地方说明

local location = "101250303" --自己所在城市ID


  • 国内城市编码表查询
链接: https://pan.baidu.com/s/16YqQBNhNfd-Lm1cFvVY1mQ?pwd=3pnj 
提取码: 3pnj 
  • 需自己注册天气API

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

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

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

屏幕说明

 -- 初始化硬件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

⛳固件和脚本烧录

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

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()之后后面不要加任何语句!!!!!


你可能感兴趣的:(Lua嵌入式开发,lua,EINK天气时钟)