esp32 micropython oled实时时钟

news2024/12/23 15:22:47

简介

 

合宙esp32C3,128*64 I2C oled,硬件i2c,将下面两个py文件放入esp32.

ssd1306.py是我优化后的,为了避免错误,使用我提供的ssd1306驱动

只支持128*64的I2C oled

代码

main.py

import network
import urequests
import ujson
import time
from machine import RTC,Pin,I2C,Timer
from ssd1306 import SSD1306_I2C

#实例化oled屏
i2c=I2C(0,scl=Pin(5),sda=Pin(4))
oled=SSD1306_I2C(i2c)
#联网设置
url='http://worldtimeapi.org/api/timezone/Asia/Shanghai'
rtc=RTC()
wifi=network.WLAN(network.STA_IF)
wifi.active(True)
#连接wifi,有一定几率连接失败
while not wifi.isconnected():
    wifi.connect('szsb','55555555')
    oled.fill(0)
    oled.text('connecting...',0,0)
    oled.show()
#更新显示连接wifi信息   
oled.fill(0)
oled.text('connect to szsb',0,0)
oled.show()
#获取网络时钟
response=urequests.get(url)
if response.status_code==200:
    parsed=ujson.loads(response.text)#用json处理获取的文本
    datetime_str=str(parsed['datetime'])
    year=int(datetime_str[0:4])
    month=int(datetime_str[5:7])
    day=int(datetime_str[8:10])
    hour=int(datetime_str[11:13])
    minute=int(datetime_str[14:16])
    second=int(datetime_str[17:19])
    msecond=int(datetime_str[20:26])
    #将(年,月,日,星期,小时,分钟,秒,毫秒)赋值给内部实时时钟RTC
    rtc.datetime((year,month,day,parsed['day_of_week'],hour,minute,second,msecond))

#定时器回调函数,从已经初始化的RTC读取时间信息并显示到oled屏
def gain_time():
        date_str='{:4}/{:02}/{:02}'.format(rtc.datetime()[0],rtc.datetime()[1],rtc.datetime()[2])
        time_str='{:02}:{:02}:{:02}'.format(rtc.datetime()[4],rtc.datetime()[5],rtc.datetime()[6])
        oled.fill(0)
        oled.text('SCAU Clock',20,0)
        oled.text('Date:'+date_str,0,25)
        oled.text('Time:'+time_str,0,35)
        oled.text('week:'+str(rtc.datetime()[3]+1),0,45)
        oled.show()

#死循环,1秒调用1次回调函数
while True:
    tim=Timer(0)
    tim.init(period=1000, mode=Timer.PERIODIC, callback=gain_time())
    
    

ssd1306.py

import framebuf
# 寄存器定义
SET_CONTRAST        = const(0x81)
SET_ENTIRE_ON       = const(0xa4)
SET_NORM_INV        = const(0xa6)
SET_MEM_ADDR        = const(0x20)
SET_COL_ADDR        = const(0x21)
SET_PAGE_ADDR       = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_DISP            = const(0xae)
SET_SEG_REMAP       = const(0xa0)
SET_MUX_RATIO       = const(0xa8)
SET_COM_OUT_DIR     = const(0xc0)
SET_DISP_OFFSET     = const(0xd3)
SET_COM_PIN_CFG     = const(0xda)
SET_DISP_CLK_DIV    = const(0xd5)
SET_PRECHARGE       = const(0xd9)
SET_VCOM_DESEL      = const(0xdb)
SET_CHARGE_PUMP     = const(0x8d)


class SSD1306:
    def __init__(self,external_vcc):
        self.width = 128
        self.height = 64
        self.external_vcc = external_vcc
        self.pages = 8
        self.init_display()

    def init_display(self):
        for cmd in (
            SET_DISP | 0x00, #熄屏
            SET_MEM_ADDR, 0x00, #水平寻址
            SET_DISP_START_LINE | 0x00,#显示起始行地址
            SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
            SET_MUX_RATIO, 63,
            SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
            SET_DISP_OFFSET, 0x00,
            SET_COM_PIN_CFG, 0x12,
            # timing and driving scheme
            SET_DISP_CLK_DIV, 0x80,
            SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
            SET_VCOM_DESEL, 0x30, # 0.83*Vcc
            # display
            SET_CONTRAST, 0xff, # maximum
            SET_ENTIRE_ON, # output follows RAM contents
            SET_NORM_INV, # not inverted
            # charge pump
            SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
            0x2e, # 禁止滚动
            0xae | 0x01): #开屏
            self.write_cmd(cmd)
        self.fill(0)
        self.show()
        
    def v_scroll(self, d=1): 
        self.write_cmd(0x2e) # 关闭滚动
        if d:
            self.write_cmd(0x26) # 向左
            self.write_cmd(0x00)
            self.write_cmd(0x07) # 起始页
            self.write_cmd(0x00) # 滚动帧率
            self.write_cmd(0x00) # 结束页
        else:
            self.write_cmd(0x27) # 向左
            self.write_cmd(0x00)
            self.write_cmd(0x00) # 起始页
            self.write_cmd(0x00) # 滚动帧率
            self.write_cmd(0x07) # 结束页
            
        self.write_cmd(0x00)
        self.write_cmd(0xff)
        self.write_cmd(0x2f) # 开启滚动
    
    def poweroff(self):
        self.write_cmd(const(0xae) | 0x00)#熄屏

    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)

    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))

    def show(self):
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(0)
        self.write_cmd(127)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(63)
        self.write_framebuf()

    def fill(self, c):
        self.framebuf.fill(c)

    def pixel(self, x, y, c):
        self.framebuf.pixel(x, y, c)

    def text(self, string, x, y, c=1):
        self.framebuf.text(string, x, y, c)
        
    def hline(self,x,y,w,c=1):
        self.framebuf.hline(x,y,w,c)
    
    def vline(self,x,y,h,c=1):
        self.framebuf.vline(x,y,h,c)
        
    def line(self,x1,y1,x2,y2,c=1):
        self.framebuf.line(x1,y1,x2,y2,c)
        
    def rect(self,x,y,w,h,c=1,f=False):
        self.framebuf.rect(x,y,w,h,c,f)
        
    def ellipse(self,x,y,xr,yr,c,f=False,m=15):
        self.framebuf.ellipse(x,y,xr,yr,c,f,m)
        
    def cube(self,x,y,l):
        self.rect(x,y,l,l)
        self.rect(x+int(0.5*l),int(y-0.5*l),l,l)
        self.line(x,y,int(x+0.5*l),int(y-0.5*l),1)
        self.line(x+l,y,int(x+1.5*l),int(y-0.5*l),1)
        self.line(x,y+l,int(x+0.5*l),int(y+0.5*l),1)
        self.line(x+l,y+l,int(x+1.5*l),int(y+0.5*l),1)
    
    def p8(self,page,x,y):
        for e in range(8):
            byte=bin(page[e]).replace('0b','')
            while len(byte)<8:
                byte='0'+byte
            for i in range(8):
                if byte[i]=='1':
                    self.pixel(x+e,y+i,int(byte[i]))
    
    def p16(self,page,x,y):
        for e in range(32):
            byte=bin(page[e]).replace('0b','')
            while len(byte)<8:
                byte='0'+byte
            for i in range(8):
                if byte[i] and e<16:
                    self.pixel(x+e,y+i,int(byte[i]))
                elif byte[i] and e>=16:
                    self.pixel(x-16+e,y+8+i,int(byte[i]))

    def p32(self,page,x,y):
        for e in range(128):
            byte=bin(page[e]).replace('0b','')
            while len(byte)<8:
                byte='0'+byte
            for i in range(8):
                if byte[i] and e<32:
                    self.pixel(x+e,y+i,int(byte[i]))
                elif byte[i] and 32<=e<64:
                    self.pixel(x+e-32,y+8+i,int(byte[i]))
                elif byte[i] and 64<=e<96:
                    self.pixel(x+e-64,y+16+i,int(byte[i]))
                elif byte[i] and 96<=e<128:
                    self.pixel(x+e-96,y+24+i,int(byte[i]))

class SSD1306_I2C(SSD1306):
    def __init__(self,i2c, addr=0x3c, external_vcc=False):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        # buffer需要8 * 128的显示字节加1字节命令
        self.buffer = bytearray(8 * 128 + 1)
        self.buffer[0] = 0x40  # Co=0, D/C=1
        self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], 128, 64)
        super().__init__(external_vcc)

    def write_cmd(self, cmd):
        self.temp[0] = 0x80 # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)

    def write_framebuf(self):
        self.i2c.writeto(self.addr, self.buffer)

效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/913723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构——布隆计算器

文章目录 1.什么是布隆过滤器&#xff1f;2.布隆过滤器的原理介绍3.布隆过滤器使用场景4.通过 Java 编程手动实现布隆过滤器5.利用Google开源的 Guava中自带的布隆过滤器6.Redis 中的布隆过滤器6.1介绍6.2使用Docker安装6.3常用命令一览6.4实际使用 1.什么是布隆过滤器&#xf…

JavaScript基础(Dom操作)

目录 一&#xff0c;BOM模型1.1&#xff0c;BOM可实现功能 二&#xff0c;Window对象的常用属性2.1&#xff0c;Window对象的常用方法2.1-1&#xff0c;open()和close()方法 三&#xff0c;History对象四&#xff0c;Location对象五&#xff0c;Document对象的常用方法六&#…

配置PPPoE拨号双链路负载分担示例

配置PPPoE拨号双链路负载分担示例 组网需求 如图1所示&#xff0c;设备作为企业出口网关&#xff0c;通过PPPoE拨号双上行接入Internet&#xff0c;链路1和链路2的出口路由采用等价路由进行负载分担。设备上配置NAT实现企业私网用户访问Internet。 图1 设备作为PPPoE Client…

MySQL 实战(一):实现“附近的人”功能

❤️ 个人主页&#xff1a;水滴技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; &#x1f338; 订阅专栏&#xff1a;MySQL 教程&#xff1a;从入门到精通 文章目录 ST_Distance_Sphere 函数示例一&#xff1a;计算北京站到北京西站的距…

Neo4j实现表字段级血缘关系

需求背景 需要在前端页面展示当前表字段的所有上下游血缘关系&#xff0c;以进一步做数据诊断治理。大致效果图如下&#xff1a; 首先这里解释什么是表字段血缘关系&#xff0c;SQL 示例&#xff1a; CREATE TABLE IF NOT EXISTS table_b AS SELECT order_id, order_status F…

分布式数据库架构:高可用、高性能的数据存储

在现代信息时代&#xff0c;数据是企业发展的核心。为了支持海量数据的存储、高并发访问以及保证数据的可靠性&#xff0c;分布式数据库架构应运而生。分布式数据库架构是一种将数据存储在多个物理节点上&#xff0c;并通过一系列复杂的协调和管理机制来提供高可用性和高性能的…

云农场种植:互联网+智慧牧场,为农业注入新的活力和创新

随着科技的不断发展&#xff0c;数字化农业正逐渐成为现代农业的趋势。传统农业面临着土地资源有限、劳动力不足等问题&#xff0c;而云农场种植模式通过数字化技术的运用&#xff0c;互联网养殖着重于“绿色、特色产品和智慧生态”&#xff0c;通过建立“线上养殖线下托养线上…

配置NTP时间服务器

1.配置ntp时间服务器&#xff0c;确保客户端主机能和服务主机同步时间 ​ 客户端主机 同步成功 2.配置ssh免密登陆&#xff0c;能够通过客户端主机通过redhat用户和服务端主机基于公钥验证方式进行远程连接

【严重】Coremail 远程命令执行漏洞

漏洞描述 Coremail是广东盈世计算机科技有限公司推出的一款大型企业邮件系统。 在 Coremail XT5/XT6 版本中&#xff0c;邮件处理功能存在溢出风险&#xff0c;攻击者构造恶意邮件&#xff0c;向任意邮箱地址发送该恶意邮件&#xff0c;当服务器处理邮件时&#xff0c;会触发…

凯迪正大—直流电阻测试仪

一、产品概述 武汉凯迪正大直流电阻测量仪是变压器制造中半成品、成品出厂试验、安装、交接试验及电力部门预防性试验的必测项目&#xff0c;能有效发现变压器线圈的选材、焊接、连接部位松动、缺股、断线等制造缺陷和运行后存在的隐患。 为了满足变压器直流电阻测量的需要&a…

浏览器原生的 画中画 特性

Chrome 116 作为Google浏览器的最新稳定版本已正式发布。Chrome 浏览器支持视频画中画&#xff08;HTMLVideoElement&#xff09;已有一段时间&#xff0c;而 Chrome 116 则新增了文档画中画模式。这种"文档画中画"模式提供了一个始终在顶部的窗口&#xff0c;可以填…

sql server 、mysql CTE 公用表表达式

sql server 详细 mysql CTE CTE 是一个命名的临时结果集&#xff0c;作用范围是当前语句。CTE可以理解成一个可以复用的子查询&#xff0c;当然跟子查询还是有点区别的&#xff0c;CTE可以引用其他CTE&#xff0c;但子查询不能引用其它子查询。所以&#xff0c;开发中建议…

新高-新低指数(NH-NL)指标公式,判断多空力度

在《以交易为生》这本书中&#xff0c;作者埃尔德根据其经验&#xff0c;认为新高-新低指数(NH-NL)是股市的最佳领先指标。在任意一天中&#xff0c;创一年新高的股票是强势股&#xff0c;而创一年新低的股票是弱势股。新高-新低指数通过比较强势股和弱势股的数量来跟踪市场领导…

【Jenkins】持续集成部署学习

【Jenkins】持续集成部署学习 【一】安装部署【1】Jenkins所处位置【2】Docker安装Gitlab&#xff08;1&#xff09;首先准备一台空的虚拟机服务器&#xff08;2&#xff09;安装服务器所需的依赖&#xff08;3&#xff09;Docker的安装&#xff08;4&#xff09;阿里云镜像加速…

「UG/NX」Block UI 截面构建器SectionBuilder

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#

容器插件工具kubectl-images

容器插件工具 简单方便查找镜像源信息&#xff0c;kubectl-images 代码地址&#xff1a;https://github.com/chenjiandongx/kubectl-images 此工具可以快捷执行命令来查看集群内ns&#xff0c;pod&#xff0c;及镜像等信息&#xff1b; 查看帮助项 ~ kubectl images --help …

HarmonyOS开发第一步,熟知开发工具DevEco Studio

俗话说的好&#xff0c;工欲善其事&#xff0c;必先利其器&#xff0c;走进HarmonyOS第一步&#xff0c;开发工具必须先行&#xff0c;当然了&#xff0c;关于开发工具的使用&#xff0c;官网和其他的博客也有很多的讲解&#xff0c;但是并没有按照常用的功能进行概述&#xff…

ELK中Logstash的基本配置和用法

文章目录 Logstash的条件判断Logstash的输入插件Stdin输入文件内容输入filter过滤器 Logstash的输出插件测试收集日志启动kibana在kibana中配置索引数据 在 《Elasticsearch搜索引擎系统入门》中简单描述了Logstah的安装&#xff0c;本篇文章将较为详细的讲解Logstash的基本配置…

Docker搭建个人网盘、私有仓库

1、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘 [rootlocalhost ~]# docker pull mysql:5.6 [rootlocalhost ~]# docker pull owncloud [rootlocalhost ~]# docker run -itd --name mysql --env MYSQL_ROOT_PASSWORD123456 mysql:5.6 [rootlocalhost ~]# doc…

汽车企业数据泄露频发,其中特斯拉数据泄露影响达7.5万人

据美国有线电视新闻网&#xff08;CNN Business&#xff09;8月19日报道&#xff0c;特斯拉此前发生的大规模数据泄露事件&#xff0c;泄露了超过7.5万人的个人信息&#xff0c;这是“内部不法行为”的结果。 特斯拉在发给员工的通知中表示&#xff0c;被泄露的“特斯拉文件”包…