BPI-Leaf-S3+MicroPython: Display Web Clock on OLED screen

Hardware preparation

Hardware_overview

  • 3.7V lithium battery with ZH 1.5 2-Pin JST connector
  • Any generic SSD1306 OLED display modules using I²C communication protocol
  • Some wires for connection
  • WiFi hotspot

BPI-Leaf-S3 :

The ESP32-S3 chip on the BPI-Leaf-S3 has two I²C bus interfaces.

There is a SH1.0 4-pin connector opposite the battery connector that can be used for I²C device connection.

SDA is connected to GPIO15, SCL is connected to GPIO16, so no matter which connection method is used, it is ok.

How to connect

SSD1306 OLED BPI-Leaf-S3
GND GND
VCC 3V3
SCL 16
SDA 15

Get Web Clock

There are many APIs on the web that can be used to get the time , such as WorldTimeAPI .

image

This API is free and does not need to register an account, which is very convenient.

There are very easy to understand routines on the website, you can know how to use it in a few minutes.

To get the time in Hong Kong, for example, use this URL:

http://worldtimeapi.org/api/timezone/Asia/Hong_Kong

Libraries

In order for BPI-Leaf-S3 to get API information on the network and display it on the SSD1306 OLED, we need two libraries.

micropython-lib/urequests.py at master · micropython/micropython-lib (github.com)

micropython/ssd1306.py at master · micropython/micropython (github.com)

Download them and upload to the flash of the board.

image

MicroPython Code

Web-RTC-Clock.py

from machine import I2C,Pin,RTC
from ssd1306 import SSD1306_I2C
from neopixel import NeoPixel
import time,network
import urequests

SSID = "wifi-ssid"
PASSWORD = "wifi-password"
Url = "http://worldtimeapi.org/api/timezone/Asia/Hong_Kong"
week_list=["Mon.","Tue.","Wed.","Thu.","Fri.","Sat.","Sun."]

rtc = RTC()
print(rtc.datetime())

sda_pin=Pin(15,Pin.PULL_UP)
scl_pin=Pin(16,Pin.PULL_UP)

i2c = I2C(1,sda=sda_pin, scl=scl_pin, freq=800_000)
print(i2c.scan())
oled = SSD1306_I2C(128, 64, i2c, addr=0x3c)
    
def display():
    datetime=rtc.datetime()
    oled.fill(0)
    oled.text("{0}/{1:0>2d}/{2:0>2d}<{3}>".format(datetime[0],datetime[1],datetime[2],week_list[datetime[3]]), 0,  0)
    oled.text("{0:0>2d}:{1:0>2d}:{2:0>2d}".format(datetime[4],datetime[5],datetime[6]), 32,  8)
    oled.show()

def ConnectNet():
    pin_48 = Pin(48, Pin.OUT)#Use GPIO48 as the signal line of WS2812
    np = NeoPixel(pin_48, 1,bpp=3, timing=1)
    np[0] = (25,0,0)
    np.write()
    try:
        wifi = network.WLAN(network.STA_IF)#Create a network interface
        wifi.active(True)#activate interface
        print(wifi.scan())#Output scanned SSID
        if not wifi.isconnected():
            wifi.connect(SSID,PASSWORD)#Connect to the specified SSID
            print('start to connect wifi')
            oled.text("WiFi connect", 0,  0)
            oled.show()
            for i in range(30):
                print('try to connect wifi in {}s'.format(i))
                oled.text(".", 12*8+i*4,  0)
                oled.show()
                time.sleep(1)
                if wifi.isconnected():
                    oled.fill(0)
                    break
        if wifi.isconnected():
            np[0] = (0,25,0)
            np.write()
            print('WiFi connection OK!')
            print('Network Config=',wifi.ifconfig())#Get and print the  IP address, subnet mask, gateway and DNS server.
            oled.text("WiFi connect!IP:", 0,  0)
            oled.text("{}".format(wifi.ifconfig()[0]), 0,  8)
            oled.show()
            time.sleep_ms(1500)
            np[0] = (0,0,0)
            np.write()
        else:
            print('WiFi connection Error')
    except Exception as e: print(e)

def net_rtc():
    requests = urequests.get(Url)#Open the URL to get information through the urequests module
    print(requests.text)#Output all acquired information in text form
    parsed = requests.json()#Convert to json format for separating out the information
    datetime_str = str(parsed["datetime"])#Extract datetime information and save to variable as string format
    year = int(datetime_str[0:4])#The string is sliced and saved as an integer to the corresponding variable
    month = int(datetime_str[5:7])
    day = int(datetime_str[8:10])
    #weekday=str(parsed["day_of_week"])
    hour = int(datetime_str[11:13])
    minute = int(datetime_str[14:16])
    second = int(datetime_str[17:19])
    subsecond = int(round(int(datetime_str[20:26]) / 10000))

    rtc.datetime((year, month, day, 0, hour, minute, second, subsecond))#Update internal RTC
    print(rtc.datetime())
    print("RTC updated\n")

ConnectNet()
net_rtc()
while True:
    display()
    time.sleep_ms(100)

Modify the string type variable SSID PASSWORD to your available wifi hotspot.

main.py

with open('Web-RTC-Clock.py', encoding='utf-8') as f:

    #print(u'')

    exec(f.read())

Upload main.py, Web-RTC-Clock.py to the flash of the board as well.

image

Either battery powered or USB powered can be used.

wiki page: https://wiki.banana-pi.org/BPI-Leaf-S3