Newbie question - how to get started?



  • I wanted to add that you should NOT be intimidated by all this micropython, repl, etc.
    It will be coming to you step by step. You are in the right direction by getting your hands dirty and going beyond uiflow.

    Things to take in consideration about your core2:

    • It is based on ESP32 microcontroller
    • Uiflow runs on micropython.
      With just those 2 things you can find a whole lot of answers online. In fact most of my programming time is spend reading forums looking for answers for my questions.

    and of course a lot of this community is eager to help "newbies" so our community grows. So ask away.



  • Thanks. I was hoping that I could just import the micropython code that was generated in my UIFlow project and run it.... That would have been too easy:-).

    I was able to load modules as you described, but haven't found the right module to get the lcd.clear() to work. Will keep digging. Also, I imported my UIFlow code, but the 'run' command in MU reboots my Core2. This is what the REPL window shows:

    raw REPL; CTRL-B to exit

    OK
    MPY: soft reboot

       _  __ _               
    

    _ ()/ | | _____ __
    | | | | | |
    | |/ _ \ \ /\ / /
    | || | | | | () \ V V /
    _
    ,||| ||___/ _/_/

    assertion "ATB_GET_KIND(block) == AT_HEAD" failed: file "../../py/gc.c", line 590, function: gc_free
    abort() was called at PC 0x401e53d3 on core 1

    ELF file SHA256: 0000000000000000

    Backtrace: 0x400961cb:0x3ffcf710 0x400965bd:0x3ffcf730 0x401e53d3:0x3ffcf750 0x400d3729:0x3ffcf780 0x400d2df1:0x3ffcf7a0 0x40121a8f:0x3ffcf7c0 0x40135f61:0x3ffcf7e0 0x4012e25a:0x3ffcf800 0x4012e271:0x3ffcf820 0x4013017f:0x3ffcf840 0x40136ff9:0x3ffcf870 0x40173253:0x3ffcf8a0 0x400e47c5:0x3ffcf8c0 0x400e0539:0x3ffcf8e0 0x400e068a:0x3ffcf900 0x400e61d4:0x3ffcf920 0x400e620f:0x3ffcf950 0x400ebb65:0x3ffcf970 0x400e070e:0x3ffcfa50 0x400eef69:0x3ffcfa90 0x400e499e:0x3ffcfb30 0x400e0539:0x3ffcfb90 0x400e0562:0x3ffcfbb0 0x400eb985:0x3ffcfbd0 0x400eba02:0x3ffcfc60 0x400ebd79:0x3ffcfc90 0x400e070e:0x3ffcfd70 0x400eef69:0x3ffcfdb0 0x400e499e:0x3ffcfe50 0x400e0539:0x3ffcfe80 0x400e0562:0x3ffcfea0 0x40174e70:0x3ffcfec0 0x40175139:0x3ffcff50 0x400f8372:0x3ffcff80 0x40097315:0x3ffcffb0

    Rebooting...
    ets Jul 29 2019 12:21:46

    rst:0xc (SW_CPU_RESET),boot:0x17 (SPI_FAST_FLASH_BOOT)
    configsip: 0, SPIWP:0xee
    clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
    mode:DIO, clock div:1
    load:0x3fff0018,len:4
    load:0x3fff001c,len:5280
    ho 0 tail 12 room 4
    load:0x40078000,len:13424
    load:0x40080400,len:3568
    entry 0x4008063c

       _  __ _               
    

    _ ()/ | | _____ __
    | | | | | |
    | |/ _ \ \ /\ / /
    | || | | | | () \ V V /
    _
    ,||| ||___/ _/_/

    APIKEY: E3FAB316
    MicroPython d97cf60fd-dirty on 2021-03-16; M5Stack with ESP32
    Type "help()" for more information.



  • if you do import module "m5stack"

    import m5stack

    and do a:

    dir(m5stack)

    ['__class__', '__name__', '__file__', 'btn', 'btnA', 'btnB', 'btnC', 'decoder', 'display', 'espidf', 'gc', 'lvesp32', 'machine', 'rtch', 'touch', 'power', 'rtc', 'lv', 'get_png_info', 'open_png', 'binascii', 'Axp192', 'i2c_bus', 'i2c', 'lcd', 'disp_buf1', 'buf1_1', 'buf1_2', 'disp_drv', 'indev_drv', 'button', 'time_ex', 'timEx', 'timeSchedule', 'timerSch', 'BM8563', 'Speaker', 'speaker', 'Rgb_multi', 'rgb', 'node_id', 'psram_init', '_remote_init', 'remoteInit']

    you will see one of those methods is called: lcd
    if you go again and do a

    dir(m5stack.lcd)

    ['__class__', 'clear', 'print', 'BLACK', 'BLUE', 'BMP', 'BOTTOM', 'CENTER', 'COLOR_BITS16', 'COLOR_BITS24', 'CYAN', 'DARKCYAN', 'DARKGREEN', 'DARKGREY', 'FONT_7seg', 'FONT_Comic', 'FONT_Default', 'FONT_DefaultSmall', 'FONT_DejaVu18', 'FONT_DejaVu24', 'FONT_DejaVu40', 'FONT_DejaVu56', 'FONT_DejaVu72', 'FONT_Minya', 'FONT_Small', 'FONT_Tooney', 'FONT_Ubuntu', 'GREEN', 'GREENYELLOW', 'HSPI', 'ICON_App', 'ICON_AppIcon', 'ICON_AppMenu', 'ICON_Cloud', 'ICON_Eath', 'ICON_Key', 'ICON_ListOFF', 'ICON_ListON', 'ICON_Machine', 'ICON_Retry', 'ICON_SetMenu', 'ICON_Setup', 'ICON_USB', 'ICON_Url', 'ICON_Wifi', 'ICON_WifiBig', 'JPG', 'LANDSCAPE', 'LANDSCAPE_FLIP', 'LASTX', 'LASTY', 'LIGHTGREY', 'M5STACK', 'MAGENTA', 'MAROON', 'NAVY', 'OLIVE', 'ORANGE', 'PINK', 'PORTRAIT', 'PORTRAIT_FLIP', 'PURPLE', 'RED', 'RIGHT', 'SPRITE_16BIT', 'SPRITE_1BIT', 'SPRITE_8BIT', 'VSPI', 'WHITE', 'YELLOW', 'arc', 'attrib7seg', 'circle', 'clearwin', 'compileFont', 'drawCircle', 'drawLine', 'drawPixel', 'drawRect', 'drawRoundRect', 'drawSwitchBtn', 'drawTriangle', 'ellipse', 'fill', 'fillCircle', 'fillRect', 'fillRoundRect', 'fillScreen', 'fillTriangle', 'font', 'fontSize', 'getCursor', 'get_bg', 'get_fg', 'hsb2rgb', 'image', 'image_buff', 'line', 'lineByAngle', 'orient', 'pixel', 'polygon', 'println', 'qrcode', 'rect', 'resetwin', 'restorewin', 'roundrect', 'savewin', 'screensize', 'setColor', 'setCursor', 'setRotation', 'setTextColor', 'set_bg', 'set_fg', 'setwin', 'sprite_create', 'sprite_delete', 'sprite_deselect', 'sprite_drawGrayMap', 'sprite_select', 'sprite_show', 'text', 'textClear', 'textWidth', 'text_x', 'text_y', 'tft_deselect', 'tft_readcmd', 'tft_select', 'tft_setspeed', 'tft_writecmd', 'tft_writecmddata', 'triangle', 'winsize']

    it will show you the methods for that.
    one of them being "clear"
    so...
    if you do:

    m5stack.lcd.clear()

    you will clear screen.

    AN alternative for dir() is to type the name of the module then a period "." and TAB key
    like this:

    m5stack.TABkey

    I could have just told you to do:

    import m5stack
    m5stack.lcd.clear()

    But i did all that so you can find more interesting stuff by yourself. Remember to check out some basic python tutorials.

    About your error of core2 rebooting... yes that is the RTOS rebooting for a wrong memory access.



  • @marcvl said in Newbie question - how to get started?:

    I'm so confused on how to run micropython directly on the Core2. I followed the M5Stack video about downloading MU but I can't get it to work.

    • Mu is connecting to my Core2 ok. (Core2 is flashed with the latest version of UIFlow and connected over USB)
    • In REPL mode, I'm getting a prompt, but the example of the video ("lcd.clear()") fails with 'NameError: 'lcd' isn't defined'
    • The Files icon is greyed out (even after trying the workaround suggested in the video)
    • I tried to run a Micropython program (copied it over from a UIFlow project). When tapping 'run', the device does a soft reboot and goes straight back into the program it was running before

    What I am missing?

    Hello and welcome to the forum.
    First switch to thonny as its a little bit easier to use than mu
    https://thonny.org
    Next visit micropython.org.
    Next you will need to do a lot of reading as you need to learn about Python, micropython and then M5Stacks implementation of Micropython (reading up on adafruits circuitpython may confuse you.)



  • This is all super helpful. Thank you! I will start building up my UIFlow-generated micro python code step by step to see when I hit the error that causes the reboot.



  • There is also my own work in progress documents https://github.com/Ajb2k3/UIFlowHandbook



  • Made great progress. Thermostat is up and running. Display is rendering fine. MQTT integration with HA works...

    One question as I'm working on aligning all the labels, sliders, images and other visual elements .... I can't figure out how to "center align" things. For example, I have a text label with varying length. I'd like to anchor that label on the screen by specifying the x,y coordinates of the center of the label, as opposed to the top left corner. How do I do that?



  • @marcvl
    Hello,
    Besides the "auto align" of the uiflow interface, you would need to make that by programming. By programming i am refering to either pure code or BLOCKS)

    For example: (And i do not have the right numbers or functions at hand)

    if your screen is 320x180
    then the center of the screen would be 160x90
    If your button (or any object) is 20w x 10h... how would you put it at center?

    myX= 160-10
    myY= 90-5
    button1 = M5Btn(text='Button', x=myX, y=myY, w=20, h=10)

    So you sustract the half of the size of your object from the half size of your screen.
    And you can do that with relation to any object or any kind of reticle.

    Some objects like buttons have properties like width height, x and y.
    so if you ask for button1.w or button1.h (you have to check the real properties of your object, it could be button1.width or button1.height, check the documentation.) This way you can re arrenge your ui programatically asking for an object size and position.

    like this:(its just an example i dont think it works)
    button1 = M5Btn(text='Button', x=0, y=0 w=20, h=10)
    button1.x = myScreen.width - (button1.w / 2)
    button1.y = myScreen.height - (button1.h / 2)

    And from this you get into more complex reticles. A good advice is to plan your interface ahead of time and think of this aligments from the start.
    You will get a hang of that with time and will discover more easy ways to do it or more efficent ones.

    I recommend you search for tutorials on programming UI interfaces and aligning them. Most of the time i do not use the UI composition screen, i just drop the elements and i align them programatically.

    Maybe.. there is a way to do it easy on UIFLOW, but if you really want to have control of your elements and interface, you need to know by code where your objects are in relation to one another.

    Hope i did not confuse you too much.



  • Thanks. This all makes sense. How would you do this with an item that doesn't have a fixed width or height, specifically a label. The w and h of the label depend on the text in it. I'm struggling with finding a way to center align the text, either programmatically or through some of M5stack's functions?

    There are bunch of functions in mstack_ui that deal with alignment (ALIGN_CENTER, ...) but I can't find any documentation on how to use them and these functions don't even have the basic Docstrings attached to them:

    >>> help (M5Slider.set_align)
    object <function set_align at 0x3f8402b0> is of type function



  • @marcvl said in Newbie question - how to get started?:

    Thanks. This all makes sense. How would you do this with an item that doesn't have a fixed width or height, specifically a label. The w and h of the label depend on the text in it. I'm struggling with finding a way to center align the text, either programmatically or through some of M5stack's functions?

    There are bunch of functions in mstack_ui that deal with alignment (ALIGN_CENTER, ...) but I can't find any documentation on how to use them and these functions don't even have the basic Docstrings attached to them:

    >>> help (M5Slider.set_align)
    object <function set_align at 0x3f8402b0> is of type function

    Some of us have only just discovered them but I haven't had the time to look and experiment let alone document!



  • @marcvl on the Core2 the widgets are implemented trough LVGL. For the alignments flags you can look at this page:
    https://docs.lvgl.io/v7/en/html/widgets/obj.html



  • @dario That's great. I figured out how to do it...

    Here's what I discovered:

    • It seems like the M5 set_align function is slightly different from the LVGL implementation. My understanding from the LVGL documentation is that set_align(ALIGN.CENTER) should center-align the text within the label. However, the M5 equivalent set_align(ALIGN_CENTER) also centers the entire label horizontally, ignoring the previous label position definition.

    • The M5 version of set_align however takes extra arguments to specify x and y offset. So you can say <lbl_name>.set_align(ALIGN_CENTER, 0, -10)

    • There is no auto-align feature as far as I can tell. LVGL has a function set_auto_realign(True), but I couldn't find the equivalent with M5. So every time I change the text in the label I have to re-run the alignment function.

    But, hey, it works. So I'm not complaining :)



  • On to the next issue.... I've been trying to get m5mqtt_subscribe to work and staring at the code for a few hours .... Maybe some fresh eyes can help pinpoint the problem.

    MQTT is set up correctly. M5 is publishing data to home assistant (through Mosquitto) without issues. However, I can't get the reverse to work (ie. Home Assistant publishing data to the M5).

    I have confirmed that HA is doing the right thing .... i.e. publishing data on an agreed topic. Example: here's what HA publishes to change the target temperature of the thermostat:

    core2/thermostat/temperature/command 21.11111111111111

    Here's my micropython code on the M5:

    DEFAULT_TOPIC_THERMOSTAT_PREFIX = "core2/thermostat/"
    TOPIC_TEMPERATURE_COMMAND = "temperature/command"
    m5mqtt.subscribe(DEFAULT_TOPIC_THERMOSTAT_PREFIX + TOPIC_TEMPERATURE_COMMAND, rcv_target_temp)
    
    def rcv_target_temp(topic_data):
        global target_temp
        m5mqtt.publish(DEFAULT_TOPIC_DEBUG,'Received target_temp: %f' % topic_data)
        target_temp = round(topic_data)
    

    The rcv_target_temp code never gets executed. No errors are being reported. What am I doing wrong?



  • Ok, this time I'm going to solve my own problem :-)

    The issue was that the m5mqtt.subscribe code was in the wrong place. You have to put it before mqtt.start(). In my case, I had inserted it after mqtt.start().

    Also round(topic_data) doesn't work because there's a type mismatch. round(float(topic_data)) did work.



  • @marcvl Really?

    Wow thanks for discovering the m5mqtt.subscribe/mqtt.start issue.
    BTW is this in micropython?



  • @ajb2k3 Yes, this is in micropython. I need to do a little bit more work but will post my code on Github soon.



  • Github repository of my MQTT Thermostat running on Core2 is here.

    It's pretty cool. The thermostat supports various modes: off/auto/manual/heat/cool/fan. You can specify minimum cycle duration as well as set swing mode parameters. It automatically gets discovered by Home Assistant. You can set thermostat mode and target temperature in Home Assistant and they will automatically get reflected on the Core2 display.

    It currently relies on the ENVII module for temperature reading, and requires a WIFI connection and an active MQTT broker. I haven't had time to implement error handling, so if something goes wrong, it might be non-obvious to figure out why. More work to be done.

    I couldn't figure out how to enable touch for a specific screen area without using visible buttons with M5stack_UI, so instead I used an lvgl button with invisible borders.