Tab5X

Support the following products:

Tab5X

Supported Components

Tab5X inherits the Tab5 manifest and includes these user-facing packages:

  • M5UI: The m5ui LVGL component library, including m5ui.M5Keyboard.

  • Module: The module package for M-BUS expansion modules.

  • Unit: The unit package for Unit drivers.

  • USB: The usb.device package, including HID, mouse, and keyboard support.

  • Chain: The chain package for Chain devices.

  • Tab5: The tab5 package for Tab5 and Tab5X keyboard support.

Supported Display Fonts

The Tab5X firmware includes the following Montserrat fonts for LVGL and M5UI: lv.font_montserrat_12, lv.font_montserrat_14, lv.font_montserrat_16, lv.font_montserrat_18, lv.font_montserrat_20, lv.font_montserrat_22, lv.font_montserrat_24, lv.font_montserrat_30, lv.font_montserrat_36, lv.font_montserrat_40, lv.font_montserrat_44, and lv.font_montserrat_48.

For M5.Lcd.FONTS, the firmware also provides AlibabaPuHuiTiCN24, AlibabaSansJA24, and AlibabaSansKR24 for Chinese, Japanese, and Korean text respectively.

UiFlow2 Example

Power Management

Open the tab5x_power_example.m5f2 project in UiFlow2.

This example controls the PORT.A output, USB Type-A output, and battery charging. It also displays the battery level, voltage, current, and charging state.

UiFlow2 Code Block:

tab5x_power_example.png

Audio Recording and Playback

Open the tab5x_audio_example.m5f2 project in UiFlow2.

This example records up to 10 seconds of 16 kHz, 16-bit mono PCM audio and plays the recording back. The controls update as recording and playback state changes.

UiFlow2 Code Block:

tab5x_audio_example.png

IMU Sensor

Open the tab5x_imu_example.m5f2 project in UiFlow2.

This example displays the three-axis accelerometer data in g and the three-axis gyroscope data in dps.

UiFlow2 Code Block:

tab5x_imu_example.png

RTC

Open the tab5x_rtc_example.m5f2 project in UiFlow2.

This example displays the date and time from the hardware RTC. The hour, minute, and second controls update the RTC immediately.

UiFlow2 Code Block:

tab5x_rtc_example.png

MicroPython Example

Power Management

This example controls PORT.A, USB Type-A, and battery charging while displaying battery level, voltage, current, and charging state.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10
 11
 12page0 = None
 13label_title = None
 14button_port_a = None
 15button_port_usb = None
 16button_charge = None
 17label_battery = None
 18label_current = None
 19label_charging = None
 20
 21
 22port_a = None
 23port_usb = None
 24charge_enabled = None
 25battery_level = None
 26battery_voltage = None
 27battery_current = None
 28
 29
 30def button_port_a_pressed_event(event_struct):
 31    global \
 32        page0, \
 33        label_title, \
 34        button_port_a, \
 35        button_port_usb, \
 36        button_charge, \
 37        label_battery, \
 38        label_current, \
 39        label_charging, \
 40        port_a, \
 41        port_usb, \
 42        charge_enabled, \
 43        battery_level, \
 44        battery_voltage, \
 45        battery_current
 46    if port_a:
 47        port_a = False
 48        Power.setExtOutput(False, M5.Power.PORT.A)
 49        button_port_a.set_btn_text(str("PORT.A OFF"))
 50        button_port_a.set_bg_color(0x5F6B75, 255, lv.PART.MAIN | lv.STATE.DEFAULT)
 51    else:
 52        port_a = True
 53        Power.setExtOutput(True, M5.Power.PORT.A)
 54        button_port_a.set_btn_text(str("PORT.A ON"))
 55        button_port_a.set_bg_color(0x2EAD65, 255, lv.PART.MAIN | lv.STATE.DEFAULT)
 56
 57
 58def button_port_usb_pressed_event(event_struct):
 59    global \
 60        page0, \
 61        label_title, \
 62        button_port_a, \
 63        button_port_usb, \
 64        button_charge, \
 65        label_battery, \
 66        label_current, \
 67        label_charging, \
 68        port_a, \
 69        port_usb, \
 70        charge_enabled, \
 71        battery_level, \
 72        battery_voltage, \
 73        battery_current
 74    if port_usb:
 75        port_usb = False
 76        Power.setExtOutput(False, M5.Power.PORT.USB)
 77        button_port_usb.set_btn_text(str("USB Type-A OFF"))
 78        button_port_usb.set_bg_color(0x5F6B75, 255, lv.PART.MAIN | lv.STATE.DEFAULT)
 79    else:
 80        port_usb = True
 81        Power.setExtOutput(True, M5.Power.PORT.USB)
 82        button_port_usb.set_btn_text(str("USB Type-A ON"))
 83        button_port_usb.set_bg_color(0x2EAD65, 255, lv.PART.MAIN | lv.STATE.DEFAULT)
 84
 85
 86def button_charge_pressed_event(event_struct):
 87    global \
 88        page0, \
 89        label_title, \
 90        button_port_a, \
 91        button_port_usb, \
 92        button_charge, \
 93        label_battery, \
 94        label_current, \
 95        label_charging, \
 96        port_a, \
 97        port_usb, \
 98        charge_enabled, \
 99        battery_level, \
100        battery_voltage, \
101        battery_current
102    if charge_enabled:
103        charge_enabled = False
104        Power.setBatteryCharge(False)
105        button_charge.set_btn_text(str("CHARGE OFF"))
106        button_charge.set_bg_color(0x5F6B75, 255, lv.PART.MAIN | lv.STATE.DEFAULT)
107    else:
108        charge_enabled = True
109        Power.setBatteryCharge(True)
110        button_charge.set_btn_text(str("CHARGE ON"))
111        button_charge.set_bg_color(0x2EAD65, 255, lv.PART.MAIN | lv.STATE.DEFAULT)
112
113
114def button_port_a_event_handler(event_struct):
115    global \
116        page0, \
117        label_title, \
118        button_port_a, \
119        button_port_usb, \
120        button_charge, \
121        label_battery, \
122        label_current, \
123        label_charging, \
124        port_a, \
125        port_usb, \
126        charge_enabled, \
127        battery_level, \
128        battery_voltage, \
129        battery_current
130    event = event_struct.code
131    if event == lv.EVENT.PRESSED and True:
132        button_port_a_pressed_event(event_struct)
133    return
134
135
136def button_port_usb_event_handler(event_struct):
137    global \
138        page0, \
139        label_title, \
140        button_port_a, \
141        button_port_usb, \
142        button_charge, \
143        label_battery, \
144        label_current, \
145        label_charging, \
146        port_a, \
147        port_usb, \
148        charge_enabled, \
149        battery_level, \
150        battery_voltage, \
151        battery_current
152    event = event_struct.code
153    if event == lv.EVENT.PRESSED and True:
154        button_port_usb_pressed_event(event_struct)
155    return
156
157
158def button_charge_event_handler(event_struct):
159    global \
160        page0, \
161        label_title, \
162        button_port_a, \
163        button_port_usb, \
164        button_charge, \
165        label_battery, \
166        label_current, \
167        label_charging, \
168        port_a, \
169        port_usb, \
170        charge_enabled, \
171        battery_level, \
172        battery_voltage, \
173        battery_current
174    event = event_struct.code
175    if event == lv.EVENT.PRESSED and True:
176        button_charge_pressed_event(event_struct)
177    return
178
179
180def setup():
181    global \
182        page0, \
183        label_title, \
184        button_port_a, \
185        button_port_usb, \
186        button_charge, \
187        label_battery, \
188        label_current, \
189        label_charging, \
190        port_a, \
191        port_usb, \
192        charge_enabled, \
193        battery_level, \
194        battery_voltage, \
195        battery_current
196
197    M5.begin()
198    Widgets.setRotation(3)
199    m5ui.init()
200    page0 = m5ui.M5Page(bg_c=0x101820)
201    label_title = m5ui.M5Label(
202        "Power Example",
203        x=465,
204        y=35,
205        text_c=0x1976D2,
206        bg_c=0x101820,
207        bg_opa=0,
208        font=lv.font_montserrat_48,
209        parent=page0,
210    )
211    button_port_a = m5ui.M5Button(
212        text="PORT.A OFF",
213        x=70,
214        y=160,
215        bg_c=0x5F6B75,
216        text_c=0xF4F7FA,
217        font=lv.font_montserrat_40,
218        parent=page0,
219    )
220    button_port_usb = m5ui.M5Button(
221        text="USB Type-A OFF",
222        x=70,
223        y=310,
224        bg_c=0x5F6B75,
225        text_c=0xF4F7FA,
226        font=lv.font_montserrat_40,
227        parent=page0,
228    )
229    button_charge = m5ui.M5Button(
230        text="CHARGE ON",
231        x=70,
232        y=460,
233        bg_c=0x2EAD65,
234        text_c=0xF4F7FA,
235        font=lv.font_montserrat_40,
236        parent=page0,
237    )
238    label_battery = m5ui.M5Label(
239        "Battery: --%   -.--- V",
240        x=600,
241        y=210,
242        text_c=0xF4F7FA,
243        bg_c=0x101820,
244        bg_opa=0,
245        font=lv.font_montserrat_48,
246        parent=page0,
247    )
248    label_current = m5ui.M5Label(
249        "Current: -- mA",
250        x=600,
251        y=330,
252        text_c=0xF4F7FA,
253        bg_c=0x101820,
254        bg_opa=0,
255        font=lv.font_montserrat_48,
256        parent=page0,
257    )
258    label_charging = m5ui.M5Label(
259        "Charging: --",
260        x=600,
261        y=450,
262        text_c=0x9FB3C8,
263        bg_c=0x101820,
264        bg_opa=0,
265        font=lv.font_montserrat_48,
266        parent=page0,
267    )
268
269    button_port_a.add_event_cb(button_port_a_event_handler, lv.EVENT.ALL, None)
270    button_port_usb.add_event_cb(button_port_usb_event_handler, lv.EVENT.ALL, None)
271    button_charge.add_event_cb(button_charge_event_handler, lv.EVENT.ALL, None)
272
273    page0.screen_load()
274    Power.setBatteryCharge(True)
275    port_a = False
276    port_usb = False
277    charge_enabled = True
278    battery_level = Power.getBatteryLevel()
279    battery_voltage = Power.getBatteryVoltage()
280    battery_current = Power.getBatteryCurrent()
281    label_current.set_text(str((str("Current: ") + str((str(battery_current) + str(" mA"))))))
282    label_battery.set_text(
283        str(
284            (
285                str("Battery: ")
286                + str(
287                    (
288                        str(battery_level)
289                        + str((str("%   ") + str((str((battery_voltage / 1000)) + str(" V")))))
290                    )
291                )
292            )
293        )
294    )
295    if battery_current > 10:
296        label_charging.set_text(str("Charging: YES"))
297        label_battery.set_text_color(0x2EAD65, 255, 0)
298        label_charging.set_text_color(0x2EAD65, 255, 0)
299    else:
300        label_charging.set_text(str("Charging: NO"))
301        label_battery.set_text_color(0xF4F7FA, 255, 0)
302        label_charging.set_text_color(0x9FB3C8, 255, 0)
303
304
305def loop():
306    global \
307        page0, \
308        label_title, \
309        button_port_a, \
310        button_port_usb, \
311        button_charge, \
312        label_battery, \
313        label_current, \
314        label_charging, \
315        port_a, \
316        port_usb, \
317        charge_enabled, \
318        battery_level, \
319        battery_voltage, \
320        battery_current
321    M5.update()
322    battery_level = Power.getBatteryLevel()
323    battery_voltage = Power.getBatteryVoltage()
324    battery_current = Power.getBatteryCurrent()
325    label_current.set_text(str((str("Current: ") + str((str(battery_current) + str(" mA"))))))
326    label_battery.set_text(
327        str(
328            (
329                str("Battery: ")
330                + str(
331                    (
332                        str(battery_level)
333                        + str((str("%   ") + str((str((battery_voltage / 1000)) + str(" V")))))
334                    )
335                )
336            )
337        )
338    )
339    if battery_current > 10:
340        label_charging.set_text(str("Charging: YES"))
341        label_battery.set_text_color(0x2EAD65, 255, 0)
342        label_charging.set_text_color(0x2EAD65, 255, 0)
343    else:
344        label_charging.set_text(str("Charging: NO"))
345        label_battery.set_text_color(0xF4F7FA, 255, 0)
346        label_charging.set_text_color(0x9FB3C8, 255, 0)
347
348
349if __name__ == "__main__":
350    try:
351        setup()
352        while True:
353            loop()
354    except (Exception, KeyboardInterrupt) as e:
355        try:
356            m5ui.deinit()
357            from utility import print_error_msg
358
359            print_error_msg(e)
360        except ImportError:
361            print("please update to latest firmware")

Audio Recording and Playback

This example records up to 10 seconds of PCM audio and plays the recorded buffer.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10from audio import Recorder
 11from audio import Player
 12import time
 13
 14
 15page0 = None
 16label_title = None
 17button_record = None
 18button_play = None
 19label_status = None
 20label_format = None
 21recorder = None
 22player = None
 23
 24
 25recordDuration = None
 26playing = None
 27recordStart = None
 28recording = None
 29hasRecording = None
 30playStart = None
 31audioBuffer = None
 32recordTime = None
 33
 34
 35def button_record_pressed_event(event_struct):
 36    global \
 37        page0, \
 38        label_title, \
 39        button_record, \
 40        button_play, \
 41        label_status, \
 42        label_format, \
 43        recorder, \
 44        player, \
 45        recordDuration, \
 46        playing, \
 47        recordStart, \
 48        recording, \
 49        hasRecording, \
 50        playStart, \
 51        audioBuffer, \
 52        recordTime
 53    if recorder.is_recording():
 54        recordDuration = time.ticks_diff((time.ticks_ms()), recordStart)
 55        recorder.stop()
 56        recording = False
 57        hasRecording = True
 58        button_record.set_btn_text(str("START RECORD"))
 59        label_status.set_text(str("Recording stopped"))
 60    else:
 61        if playing:
 62            player.stop()
 63            playing = False
 64            button_play.set_btn_text(str("START PLAY"))
 65        Speaker.setPA(False)
 66        hasRecording = False
 67        recordStart = time.ticks_ms()
 68        button_record.set_btn_text(str("STOP RECORD"))
 69        label_status.set_text(str("Recording... maximum 10 seconds"))
 70        audioBuffer = recorder.create_pcm_buf(recordTime)
 71        recorder.record_into(audioBuffer, False)
 72        recording = True
 73
 74
 75def button_play_pressed_event(event_struct):
 76    global \
 77        page0, \
 78        label_title, \
 79        button_record, \
 80        button_play, \
 81        label_status, \
 82        label_format, \
 83        recorder, \
 84        player, \
 85        recordDuration, \
 86        playing, \
 87        recordStart, \
 88        recording, \
 89        hasRecording, \
 90        playStart, \
 91        audioBuffer, \
 92        recordTime
 93    if playing:
 94        player.stop()
 95        playing = False
 96        button_play.set_btn_text(str("START PLAY"))
 97        label_status.set_text(str("Playback stopped"))
 98    else:
 99        if recorder.is_recording():
100            label_status.set_text(str("Wait for recording to stop"))
101        else:
102            if hasRecording:
103                Speaker.setPA(True)
104                time.sleep_ms(100)
105                button_play.set_btn_text(str("STOP PLAY"))
106                label_status.set_text(str("Playing..."))
107                player.play_raw(
108                    audioBuffer, sample=16000, stereo=False, bits=16, pos=0, volume=80, sync=False
109                )
110                playStart = time.ticks_ms()
111                playing = True
112            else:
113                label_status.set_text(str("Record audio first"))
114
115
116def button_record_event_handler(event_struct):
117    global \
118        page0, \
119        label_title, \
120        button_record, \
121        button_play, \
122        label_status, \
123        label_format, \
124        recorder, \
125        player, \
126        recordDuration, \
127        playing, \
128        recordStart, \
129        recording, \
130        hasRecording, \
131        playStart, \
132        audioBuffer, \
133        recordTime
134    event = event_struct.code
135    if event == lv.EVENT.PRESSED and True:
136        button_record_pressed_event(event_struct)
137    return
138
139
140def button_play_event_handler(event_struct):
141    global \
142        page0, \
143        label_title, \
144        button_record, \
145        button_play, \
146        label_status, \
147        label_format, \
148        recorder, \
149        player, \
150        recordDuration, \
151        playing, \
152        recordStart, \
153        recording, \
154        hasRecording, \
155        playStart, \
156        audioBuffer, \
157        recordTime
158    event = event_struct.code
159    if event == lv.EVENT.PRESSED and True:
160        button_play_pressed_event(event_struct)
161    return
162
163
164def setup():
165    global \
166        page0, \
167        label_title, \
168        button_record, \
169        button_play, \
170        label_status, \
171        label_format, \
172        recorder, \
173        player, \
174        recordDuration, \
175        playing, \
176        recordStart, \
177        recording, \
178        hasRecording, \
179        playStart, \
180        audioBuffer, \
181        recordTime
182
183    M5.begin()
184    Widgets.setRotation(3)
185    m5ui.init()
186    page0 = m5ui.M5Page(bg_c=0x101820)
187    label_title = m5ui.M5Label(
188        "Audio Example",
189        x=480,
190        y=35,
191        text_c=0xE99628,
192        bg_c=0x101820,
193        bg_opa=0,
194        font=lv.font_montserrat_48,
195        parent=page0,
196    )
197    button_record = m5ui.M5Button(
198        text="START RECORD",
199        x=70,
200        y=175,
201        bg_c=0xD84545,
202        text_c=0xF4F7FA,
203        font=lv.font_montserrat_48,
204        parent=page0,
205    )
206    button_play = m5ui.M5Button(
207        text="START PLAY",
208        x=710,
209        y=175,
210        bg_c=0x2EAD65,
211        text_c=0xF4F7FA,
212        font=lv.font_montserrat_48,
213        parent=page0,
214    )
215    label_status = m5ui.M5Label(
216        "Ready. Maximum recording length: 10s",
217        x=70,
218        y=420,
219        text_c=0x9FB3C8,
220        bg_c=0x101820,
221        bg_opa=0,
222        font=lv.font_montserrat_48,
223        parent=page0,
224    )
225    label_format = m5ui.M5Label(
226        "16 kHz / 16-bit / mono PCM",
227        x=70,
228        y=535,
229        text_c=0x9FB3C8,
230        bg_c=0x101820,
231        bg_opa=0,
232        font=lv.font_montserrat_48,
233        parent=page0,
234    )
235
236    button_record.add_event_cb(button_record_event_handler, lv.EVENT.ALL, None)
237    button_play.add_event_cb(button_play_event_handler, lv.EVENT.ALL, None)
238
239    page0.screen_load()
240    button_record.set_size(500, 140)
241    button_play.set_size(500, 140)
242    Mic.end()
243    recorder = Recorder(16000, 16, False)
244    player = Player(None)
245    player.stop()
246    player.set_vol(100)
247    recordTime = 10
248    audioBuffer = recorder.create_pcm_buf(recordTime)
249    recording = False
250    playing = False
251    hasRecording = False
252    recordStart = 0
253    recordDuration = 10000
254    playStart = 0
255
256
257def loop():
258    global \
259        page0, \
260        label_title, \
261        button_record, \
262        button_play, \
263        label_status, \
264        label_format, \
265        recorder, \
266        player, \
267        recordDuration, \
268        playing, \
269        recordStart, \
270        recording, \
271        hasRecording, \
272        playStart, \
273        audioBuffer, \
274        recordTime
275    M5.update()
276    if recording and not (recorder.is_recording()):
277        recordDuration = time.ticks_diff((time.ticks_ms()), recordStart)
278        recording = False
279        hasRecording = True
280        button_record.set_btn_text(str("START RECORD"))
281        label_status.set_text(str("Recording complete"))
282    if playing and (time.ticks_diff((time.ticks_ms()), playStart)) >= recordDuration:
283        player.stop()
284        Speaker.setPA(False)
285        playing = False
286        button_play.set_btn_text(str("START PLAY"))
287        label_status.set_text(str("Playback complete"))
288
289
290if __name__ == "__main__":
291    try:
292        setup()
293        while True:
294            loop()
295    except (Exception, KeyboardInterrupt) as e:
296        try:
297            m5ui.deinit()
298            from utility import print_error_msg
299
300            print_error_msg(e)
301        except ImportError:
302            print("please update to latest firmware")

IMU Sensor

This example reads and displays the three accelerometer and three gyroscope axes.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10
 11
 12page0 = None
 13label_title = None
 14label_acc_title = None
 15label_acc_x = None
 16label_acc_y = None
 17label_acc_z = None
 18label_gyro_title = None
 19label_gyro_x = None
 20label_gyro_y = None
 21label_gyro_z = None
 22label_footer = None
 23
 24
 25accel = None
 26gyro = None
 27acc_x = None
 28acc_y = None
 29acc_z = None
 30gyro_x = None
 31gyro_y = None
 32gyro_z = None
 33
 34
 35def setup():
 36    global \
 37        page0, \
 38        label_title, \
 39        label_acc_title, \
 40        label_acc_x, \
 41        label_acc_y, \
 42        label_acc_z, \
 43        label_gyro_title, \
 44        label_gyro_x, \
 45        label_gyro_y, \
 46        label_gyro_z, \
 47        label_footer, \
 48        accel, \
 49        gyro, \
 50        acc_x, \
 51        acc_y, \
 52        acc_z, \
 53        gyro_x, \
 54        gyro_y, \
 55        gyro_z
 56
 57    M5.begin()
 58    Widgets.setRotation(3)
 59    m5ui.init()
 60    page0 = m5ui.M5Page(bg_c=0x101820)
 61    label_title = m5ui.M5Label(
 62        "IMU Example",
 63        x=465,
 64        y=30,
 65        text_c=0x2EAD65,
 66        bg_c=0x101820,
 67        bg_opa=0,
 68        font=lv.font_montserrat_48,
 69        parent=page0,
 70    )
 71    label_acc_title = m5ui.M5Label(
 72        "Accelerometer",
 73        x=140,
 74        y=125,
 75        text_c=0x9FB3C8,
 76        bg_c=0x101820,
 77        bg_opa=0,
 78        font=lv.font_montserrat_48,
 79        parent=page0,
 80    )
 81    label_acc_x = m5ui.M5Label(
 82        "X: -- g",
 83        x=120,
 84        y=220,
 85        text_c=0xF4F7FA,
 86        bg_c=0x101820,
 87        bg_opa=0,
 88        font=lv.font_montserrat_48,
 89        parent=page0,
 90    )
 91    label_acc_y = m5ui.M5Label(
 92        "Y: -- g",
 93        x=120,
 94        y=350,
 95        text_c=0xF4F7FA,
 96        bg_c=0x101820,
 97        bg_opa=0,
 98        font=lv.font_montserrat_48,
 99        parent=page0,
100    )
101    label_acc_z = m5ui.M5Label(
102        "Z: -- g",
103        x=120,
104        y=480,
105        text_c=0xF4F7FA,
106        bg_c=0x101820,
107        bg_opa=0,
108        font=lv.font_montserrat_48,
109        parent=page0,
110    )
111    label_gyro_title = m5ui.M5Label(
112        "Gyroscope",
113        x=825,
114        y=125,
115        text_c=0x9FB3C8,
116        bg_c=0x101820,
117        bg_opa=0,
118        font=lv.font_montserrat_48,
119        parent=page0,
120    )
121    label_gyro_x = m5ui.M5Label(
122        "X: -- dps",
123        x=760,
124        y=220,
125        text_c=0xF4F7FA,
126        bg_c=0x101820,
127        bg_opa=0,
128        font=lv.font_montserrat_48,
129        parent=page0,
130    )
131    label_gyro_y = m5ui.M5Label(
132        "Y: -- dps",
133        x=760,
134        y=350,
135        text_c=0xF4F7FA,
136        bg_c=0x101820,
137        bg_opa=0,
138        font=lv.font_montserrat_48,
139        parent=page0,
140    )
141    label_gyro_z = m5ui.M5Label(
142        "Z: -- dps",
143        x=760,
144        y=480,
145        text_c=0xF4F7FA,
146        bg_c=0x101820,
147        bg_opa=0,
148        font=lv.font_montserrat_48,
149        parent=page0,
150    )
151    label_footer = m5ui.M5Label(
152        "Live data",
153        x=535,
154        y=610,
155        text_c=0x9FB3C8,
156        bg_c=0x101820,
157        bg_opa=0,
158        font=lv.font_montserrat_48,
159        parent=page0,
160    )
161
162    page0.screen_load()
163
164
165def loop():
166    global \
167        page0, \
168        label_title, \
169        label_acc_title, \
170        label_acc_x, \
171        label_acc_y, \
172        label_acc_z, \
173        label_gyro_title, \
174        label_gyro_x, \
175        label_gyro_y, \
176        label_gyro_z, \
177        label_footer, \
178        accel, \
179        gyro, \
180        acc_x, \
181        acc_y, \
182        acc_z, \
183        gyro_x, \
184        gyro_y, \
185        gyro_z
186    M5.update()
187    accel = Imu.getAccel()
188    gyro = Imu.getGyro()
189    acc_x = accel[0]
190    acc_y = accel[1]
191    acc_z = accel[2]
192    gyro_x = gyro[0]
193    gyro_y = gyro[1]
194    gyro_z = gyro[2]
195    label_acc_x.set_text(str((str("X: ") + str((str(acc_x) + str(" g"))))))
196    label_acc_y.set_text(str((str("Y: ") + str((str(acc_y) + str(" g"))))))
197    label_acc_z.set_text(str((str("Z: ") + str((str(acc_z) + str(" g"))))))
198    label_gyro_x.set_text(str((str("X: ") + str((str(gyro_x) + str(" dps"))))))
199    label_gyro_y.set_text(str((str("Y: ") + str((str(gyro_y) + str(" dps"))))))
200    label_gyro_z.set_text(str((str("Z: ") + str((str(gyro_z) + str(" dps"))))))
201
202
203if __name__ == "__main__":
204    try:
205        setup()
206        while True:
207            loop()
208    except (Exception, KeyboardInterrupt) as e:
209        try:
210            m5ui.deinit()
211            from utility import print_error_msg
212
213            print_error_msg(e)
214        except ImportError:
215            print("please update to latest firmware")

RTC

This example displays and updates the hardware RTC date and time.

MicroPython Code Block:

  1# SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8import m5ui
  9import lvgl as lv
 10from hardware import RTC
 11
 12
 13page0 = None
 14label_title = None
 15label_date = None
 16label_hour = None
 17label_colon_1 = None
 18label_minute = None
 19label_colon_2 = None
 20label_second = None
 21button_hour_minus = None
 22button_hour_plus = None
 23button_minute_minus = None
 24button_minute_plus = None
 25button_second_minus = None
 26button_second_plus = None
 27label_hour_control = None
 28label_minute_control = None
 29label_second_control = None
 30rtc = None
 31
 32
 33editing = None
 34hour = None
 35minute = None
 36second = None
 37now = None
 38year = None
 39month = None
 40day = None
 41
 42
 43def button_hour_minus_pressed_event(event_struct):
 44    global \
 45        page0, \
 46        label_title, \
 47        label_date, \
 48        label_hour, \
 49        label_colon_1, \
 50        label_minute, \
 51        label_colon_2, \
 52        label_second, \
 53        button_hour_minus, \
 54        button_hour_plus, \
 55        button_minute_minus, \
 56        button_minute_plus, \
 57        button_second_minus, \
 58        button_second_plus, \
 59        label_hour_control, \
 60        label_minute_control, \
 61        label_second_control, \
 62        rtc, \
 63        editing, \
 64        hour, \
 65        minute, \
 66        second, \
 67        now, \
 68        year, \
 69        month, \
 70        day
 71    editing = True
 72    hour = hour - 1
 73    if hour < 0:
 74        hour = 23
 75    label_hour.set_text(str(hour))
 76
 77
 78def button_hour_plus_pressed_event(event_struct):
 79    global \
 80        page0, \
 81        label_title, \
 82        label_date, \
 83        label_hour, \
 84        label_colon_1, \
 85        label_minute, \
 86        label_colon_2, \
 87        label_second, \
 88        button_hour_minus, \
 89        button_hour_plus, \
 90        button_minute_minus, \
 91        button_minute_plus, \
 92        button_second_minus, \
 93        button_second_plus, \
 94        label_hour_control, \
 95        label_minute_control, \
 96        label_second_control, \
 97        rtc, \
 98        editing, \
 99        hour, \
100        minute, \
101        second, \
102        now, \
103        year, \
104        month, \
105        day
106    editing = True
107    hour = hour + 1
108    if hour > 23:
109        hour = 0
110    label_hour.set_text(str(hour))
111
112
113def button_minute_minus_pressed_event(event_struct):
114    global \
115        page0, \
116        label_title, \
117        label_date, \
118        label_hour, \
119        label_colon_1, \
120        label_minute, \
121        label_colon_2, \
122        label_second, \
123        button_hour_minus, \
124        button_hour_plus, \
125        button_minute_minus, \
126        button_minute_plus, \
127        button_second_minus, \
128        button_second_plus, \
129        label_hour_control, \
130        label_minute_control, \
131        label_second_control, \
132        rtc, \
133        editing, \
134        hour, \
135        minute, \
136        second, \
137        now, \
138        year, \
139        month, \
140        day
141    editing = True
142    minute = minute - 1
143    if minute < 0:
144        minute = 59
145    label_minute.set_text(str(minute))
146
147
148def button_minute_plus_pressed_event(event_struct):
149    global \
150        page0, \
151        label_title, \
152        label_date, \
153        label_hour, \
154        label_colon_1, \
155        label_minute, \
156        label_colon_2, \
157        label_second, \
158        button_hour_minus, \
159        button_hour_plus, \
160        button_minute_minus, \
161        button_minute_plus, \
162        button_second_minus, \
163        button_second_plus, \
164        label_hour_control, \
165        label_minute_control, \
166        label_second_control, \
167        rtc, \
168        editing, \
169        hour, \
170        minute, \
171        second, \
172        now, \
173        year, \
174        month, \
175        day
176    editing = True
177    minute = minute + 1
178    if minute > 59:
179        minute = 0
180    label_minute.set_text(str(minute))
181
182
183def button_second_minus_pressed_event(event_struct):
184    global \
185        page0, \
186        label_title, \
187        label_date, \
188        label_hour, \
189        label_colon_1, \
190        label_minute, \
191        label_colon_2, \
192        label_second, \
193        button_hour_minus, \
194        button_hour_plus, \
195        button_minute_minus, \
196        button_minute_plus, \
197        button_second_minus, \
198        button_second_plus, \
199        label_hour_control, \
200        label_minute_control, \
201        label_second_control, \
202        rtc, \
203        editing, \
204        hour, \
205        minute, \
206        second, \
207        now, \
208        year, \
209        month, \
210        day
211    editing = True
212    second = second - 1
213    if second < 0:
214        second = 59
215    label_second.set_text(str(second))
216
217
218def button_second_plus_pressed_event(event_struct):
219    global \
220        page0, \
221        label_title, \
222        label_date, \
223        label_hour, \
224        label_colon_1, \
225        label_minute, \
226        label_colon_2, \
227        label_second, \
228        button_hour_minus, \
229        button_hour_plus, \
230        button_minute_minus, \
231        button_minute_plus, \
232        button_second_minus, \
233        button_second_plus, \
234        label_hour_control, \
235        label_minute_control, \
236        label_second_control, \
237        rtc, \
238        editing, \
239        hour, \
240        minute, \
241        second, \
242        now, \
243        year, \
244        month, \
245        day
246    editing = True
247    second = second + 1
248    if second > 59:
249        second = 0
250    label_second.set_text(str(second))
251
252
253def button_hour_minus_event_handler(event_struct):
254    global \
255        page0, \
256        label_title, \
257        label_date, \
258        label_hour, \
259        label_colon_1, \
260        label_minute, \
261        label_colon_2, \
262        label_second, \
263        button_hour_minus, \
264        button_hour_plus, \
265        button_minute_minus, \
266        button_minute_plus, \
267        button_second_minus, \
268        button_second_plus, \
269        label_hour_control, \
270        label_minute_control, \
271        label_second_control, \
272        rtc, \
273        editing, \
274        hour, \
275        minute, \
276        second, \
277        now, \
278        year, \
279        month, \
280        day
281    event = event_struct.code
282    if event == lv.EVENT.PRESSED and True:
283        button_hour_minus_pressed_event(event_struct)
284    return
285
286
287def button_hour_plus_event_handler(event_struct):
288    global \
289        page0, \
290        label_title, \
291        label_date, \
292        label_hour, \
293        label_colon_1, \
294        label_minute, \
295        label_colon_2, \
296        label_second, \
297        button_hour_minus, \
298        button_hour_plus, \
299        button_minute_minus, \
300        button_minute_plus, \
301        button_second_minus, \
302        button_second_plus, \
303        label_hour_control, \
304        label_minute_control, \
305        label_second_control, \
306        rtc, \
307        editing, \
308        hour, \
309        minute, \
310        second, \
311        now, \
312        year, \
313        month, \
314        day
315    event = event_struct.code
316    if event == lv.EVENT.PRESSED and True:
317        button_hour_plus_pressed_event(event_struct)
318    return
319
320
321def button_minute_minus_event_handler(event_struct):
322    global \
323        page0, \
324        label_title, \
325        label_date, \
326        label_hour, \
327        label_colon_1, \
328        label_minute, \
329        label_colon_2, \
330        label_second, \
331        button_hour_minus, \
332        button_hour_plus, \
333        button_minute_minus, \
334        button_minute_plus, \
335        button_second_minus, \
336        button_second_plus, \
337        label_hour_control, \
338        label_minute_control, \
339        label_second_control, \
340        rtc, \
341        editing, \
342        hour, \
343        minute, \
344        second, \
345        now, \
346        year, \
347        month, \
348        day
349    event = event_struct.code
350    if event == lv.EVENT.PRESSED and True:
351        button_minute_minus_pressed_event(event_struct)
352    return
353
354
355def button_minute_plus_event_handler(event_struct):
356    global \
357        page0, \
358        label_title, \
359        label_date, \
360        label_hour, \
361        label_colon_1, \
362        label_minute, \
363        label_colon_2, \
364        label_second, \
365        button_hour_minus, \
366        button_hour_plus, \
367        button_minute_minus, \
368        button_minute_plus, \
369        button_second_minus, \
370        button_second_plus, \
371        label_hour_control, \
372        label_minute_control, \
373        label_second_control, \
374        rtc, \
375        editing, \
376        hour, \
377        minute, \
378        second, \
379        now, \
380        year, \
381        month, \
382        day
383    event = event_struct.code
384    if event == lv.EVENT.PRESSED and True:
385        button_minute_plus_pressed_event(event_struct)
386    return
387
388
389def button_second_minus_event_handler(event_struct):
390    global \
391        page0, \
392        label_title, \
393        label_date, \
394        label_hour, \
395        label_colon_1, \
396        label_minute, \
397        label_colon_2, \
398        label_second, \
399        button_hour_minus, \
400        button_hour_plus, \
401        button_minute_minus, \
402        button_minute_plus, \
403        button_second_minus, \
404        button_second_plus, \
405        label_hour_control, \
406        label_minute_control, \
407        label_second_control, \
408        rtc, \
409        editing, \
410        hour, \
411        minute, \
412        second, \
413        now, \
414        year, \
415        month, \
416        day
417    event = event_struct.code
418    if event == lv.EVENT.PRESSED and True:
419        button_second_minus_pressed_event(event_struct)
420    return
421
422
423def button_second_plus_event_handler(event_struct):
424    global \
425        page0, \
426        label_title, \
427        label_date, \
428        label_hour, \
429        label_colon_1, \
430        label_minute, \
431        label_colon_2, \
432        label_second, \
433        button_hour_minus, \
434        button_hour_plus, \
435        button_minute_minus, \
436        button_minute_plus, \
437        button_second_minus, \
438        button_second_plus, \
439        label_hour_control, \
440        label_minute_control, \
441        label_second_control, \
442        rtc, \
443        editing, \
444        hour, \
445        minute, \
446        second, \
447        now, \
448        year, \
449        month, \
450        day
451    event = event_struct.code
452    if event == lv.EVENT.PRESSED and True:
453        button_second_plus_pressed_event(event_struct)
454    return
455
456
457def setup():
458    global \
459        page0, \
460        label_title, \
461        label_date, \
462        label_hour, \
463        label_colon_1, \
464        label_minute, \
465        label_colon_2, \
466        label_second, \
467        button_hour_minus, \
468        button_hour_plus, \
469        button_minute_minus, \
470        button_minute_plus, \
471        button_second_minus, \
472        button_second_plus, \
473        label_hour_control, \
474        label_minute_control, \
475        label_second_control, \
476        rtc, \
477        editing, \
478        hour, \
479        minute, \
480        second, \
481        now, \
482        year, \
483        month, \
484        day
485
486    M5.begin()
487    Widgets.setRotation(3)
488    m5ui.init()
489    page0 = m5ui.M5Page(bg_c=0x101820)
490    label_title = m5ui.M5Label(
491        "RTC Example",
492        x=480,
493        y=35,
494        text_c=0xE99628,
495        bg_c=0x101820,
496        bg_opa=0,
497        font=lv.font_montserrat_48,
498        parent=page0,
499    )
500    label_date = m5ui.M5Label(
501        "2026-01-01",
502        x=510,
503        y=125,
504        text_c=0xF4F7FA,
505        bg_c=0x101820,
506        bg_opa=0,
507        font=lv.font_montserrat_48,
508        parent=page0,
509    )
510    label_hour = m5ui.M5Label(
511        "00",
512        x=440,
513        y=220,
514        text_c=0x2EAD65,
515        bg_c=0x101820,
516        bg_opa=0,
517        font=lv.font_montserrat_48,
518        parent=page0,
519    )
520    label_colon_1 = m5ui.M5Label(
521        ":",
522        x=565,
523        y=220,
524        text_c=0x2EAD65,
525        bg_c=0x101820,
526        bg_opa=0,
527        font=lv.font_montserrat_48,
528        parent=page0,
529    )
530    label_minute = m5ui.M5Label(
531        "00",
532        x=635,
533        y=220,
534        text_c=0x2EAD65,
535        bg_c=0x101820,
536        bg_opa=0,
537        font=lv.font_montserrat_48,
538        parent=page0,
539    )
540    label_colon_2 = m5ui.M5Label(
541        ":",
542        x=760,
543        y=220,
544        text_c=0x2EAD65,
545        bg_c=0x101820,
546        bg_opa=0,
547        font=lv.font_montserrat_48,
548        parent=page0,
549    )
550    label_second = m5ui.M5Label(
551        "00",
552        x=830,
553        y=220,
554        text_c=0x2EAD65,
555        bg_c=0x101820,
556        bg_opa=0,
557        font=lv.font_montserrat_48,
558        parent=page0,
559    )
560    button_hour_minus = m5ui.M5Button(
561        text="-",
562        x=100,
563        y=390,
564        bg_c=0xD84545,
565        text_c=0xF4F7FA,
566        font=lv.font_montserrat_48,
567        parent=page0,
568    )
569    button_hour_plus = m5ui.M5Button(
570        text="+",
571        x=290,
572        y=390,
573        bg_c=0x2EAD65,
574        text_c=0xF4F7FA,
575        font=lv.font_montserrat_48,
576        parent=page0,
577    )
578    button_minute_minus = m5ui.M5Button(
579        text="-",
580        x=480,
581        y=390,
582        bg_c=0xD84545,
583        text_c=0xF4F7FA,
584        font=lv.font_montserrat_48,
585        parent=page0,
586    )
587    button_minute_plus = m5ui.M5Button(
588        text="+",
589        x=670,
590        y=390,
591        bg_c=0x2EAD65,
592        text_c=0xF4F7FA,
593        font=lv.font_montserrat_48,
594        parent=page0,
595    )
596    button_second_minus = m5ui.M5Button(
597        text="-",
598        x=860,
599        y=390,
600        bg_c=0xD84545,
601        text_c=0xF4F7FA,
602        font=lv.font_montserrat_48,
603        parent=page0,
604    )
605    button_second_plus = m5ui.M5Button(
606        text="+",
607        x=1050,
608        y=390,
609        bg_c=0x2EAD65,
610        text_c=0xF4F7FA,
611        font=lv.font_montserrat_48,
612        parent=page0,
613    )
614    label_hour_control = m5ui.M5Label(
615        "HOUR",
616        x=195,
617        y=320,
618        text_c=0x9FB3C8,
619        bg_c=0x101820,
620        bg_opa=0,
621        font=lv.font_montserrat_48,
622        parent=page0,
623    )
624    label_minute_control = m5ui.M5Label(
625        "MIN",
626        x=618,
627        y=320,
628        text_c=0x9FB3C8,
629        bg_c=0x101820,
630        bg_opa=0,
631        font=lv.font_montserrat_48,
632        parent=page0,
633    )
634    label_second_control = m5ui.M5Label(
635        "SEC",
636        x=998,
637        y=320,
638        text_c=0x9FB3C8,
639        bg_c=0x101820,
640        bg_opa=0,
641        font=lv.font_montserrat_48,
642        parent=page0,
643    )
644
645    button_hour_minus.add_event_cb(button_hour_minus_event_handler, lv.EVENT.ALL, None)
646    button_hour_plus.add_event_cb(button_hour_plus_event_handler, lv.EVENT.ALL, None)
647    button_minute_minus.add_event_cb(button_minute_minus_event_handler, lv.EVENT.ALL, None)
648    button_minute_plus.add_event_cb(button_minute_plus_event_handler, lv.EVENT.ALL, None)
649    button_second_minus.add_event_cb(button_second_minus_event_handler, lv.EVENT.ALL, None)
650    button_second_plus.add_event_cb(button_second_plus_event_handler, lv.EVENT.ALL, None)
651
652    rtc = RTC()
653    page0.screen_load()
654    now = rtc.datetime()
655    year = now[0]
656    month = now[1]
657    day = now[2]
658    hour = now[4]
659    minute = now[5]
660    second = now[6]
661    editing = False
662    label_date.set_text(
663        str((str((str(year) + str("-"))) + str((str((str(month) + str("-"))) + str(day)))))
664    )
665    label_hour.set_text(str(hour))
666    label_minute.set_text(str(minute))
667    label_second.set_text(str(second))
668    button_hour_minus.set_pos(100, 390)
669    button_hour_minus.set_size(170, 90)
670    button_hour_plus.set_pos(290, 390)
671    button_hour_plus.set_size(170, 90)
672    button_minute_minus.set_pos(480, 390)
673    button_minute_minus.set_size(170, 90)
674    button_minute_plus.set_pos(670, 390)
675    button_minute_plus.set_size(170, 90)
676    button_second_minus.set_pos(860, 390)
677    button_second_minus.set_size(170, 90)
678    button_second_plus.set_pos(1050, 390)
679    button_second_plus.set_size(170, 90)
680
681
682def loop():
683    global \
684        page0, \
685        label_title, \
686        label_date, \
687        label_hour, \
688        label_colon_1, \
689        label_minute, \
690        label_colon_2, \
691        label_second, \
692        button_hour_minus, \
693        button_hour_plus, \
694        button_minute_minus, \
695        button_minute_plus, \
696        button_second_minus, \
697        button_second_plus, \
698        label_hour_control, \
699        label_minute_control, \
700        label_second_control, \
701        rtc, \
702        editing, \
703        hour, \
704        minute, \
705        second, \
706        now, \
707        year, \
708        month, \
709        day
710    M5.update()
711    now = rtc.datetime()
712    if not editing:
713        year = now[0]
714        month = now[1]
715        day = now[2]
716        hour = now[4]
717        minute = now[5]
718        second = now[6]
719        label_date.set_text(
720            str((str((str(year) + str("-"))) + str((str((str(month) + str("-"))) + str(day)))))
721        )
722        label_hour.set_text(str(hour))
723        label_minute.set_text(str(minute))
724        label_second.set_text(str(second))
725    else:
726        rtc.init((year, month, day, hour, minute, second, 0, 0))
727        editing = False
728
729
730if __name__ == "__main__":
731    try:
732        setup()
733        while True:
734            loop()
735    except (Exception, KeyboardInterrupt) as e:
736        try:
737            m5ui.deinit()
738            from utility import print_error_msg
739
740            print_error_msg(e)
741        except ImportError:
742            print("please update to latest firmware")