Code Monkey home page Code Monkey logo

cardputer-microhydra's Introduction

           

Cardputer-MicroHydra

MicroHydra is a simple MicroPython based app launcher designed for the M5Stack Cardputer.

Microhydra Banner

MicroHydra is currently going through a major overhaul to enable multi-platform support. Many features and APIs will likely undergo significant change by version 2.0.
You can find these changes in the experimental-multiplatform branch.
please use the "releases" section for stable versions of MicroHydra.

This code was built with MicroPython v1.23.0 (preview), for a Generic ESP32-S3 controller.

The main function of MicroHydra is to provide an interface to easily switch between MicroPython apps.
And to help lower the barriers to entry for anyone wanting to develop apps for their Cardputer. Python scripts can be placed in the /apps folder on the flash, or in a /apps folder on a micro sd card. The launcher scans these two locations on startup.


Take a look at the wiki for some basic guides to get you started with a MicroPython app.

If you're looking for the compiled firmware, that lives over here.

And for a work-in-progress repository of MicroHydra apps, see here




how it works:

This program can be thought of as two main components; the launcher and the apploader.
The apploader is the "main.py" file in the root directory, and it's the first thing to run when the device is powered on.
The apploader reads the RTC memory to determine if it should load an app, otherwise, it loads the launcher.

The launcher is the main UI for the app switching functionality. Its primary responsibility is choosing an app, then storing its path in the RTC.memory. Once the app path is in the memory, it calls machine.reset() to refresh the system and return to the apploader, after which the apploader loads the target app.

This approach was chosen to help to prevent issues with memory managment or import conflicts between apps. Resetting the entire device means that the only thing thing loaded before the custom app, is the lightweight apploader.




Installing Apps:

Apps are designed to work very simply in this launcher. Any Python file placed in the "apps" folder on the flash, or the SD card, will be found and can be launched as an app. This works with .mpy files too, meaning machine code written in other languages can also be linked and run as an app (though I have not tested this yet)

This means that a simple app can be contained as one script, which will be executed when the app is selected from the launcher.
It also means more complicated apps can place a startup file in the apps directory, which imports anything it needs from another folder in the filesystem.

Some apps for MH can be found here, but there are many other apps (especially work-in-progress apps) living in other locations, as well.

Quick note about apps on the SD card: The apps wont be able to use SPI slot 2 for the display (or anything else) because it will be occupied by the SD card. Thankfully, the display works fine in slot 1.




Installing MicroHydra:

You can install MicroHydra a few different ways.

  • Install plain .py version on MicroPython:
    Flash Micropython to your Cardputer, and copy the contents of the "MicroHydra" folder over to the flash.
    This is the most convenient way to install for development, because you can simply open up the MH files to see what's going on.
    You can also find pre-compiled .mpy versions in "compiled.zip", in the releases section. These will use less memory and start faster.

  • Flash MH as a compiled firmware:
    The latest 'finished' version of MH, frozen into MicroPython, can be found here. (Look for the .bin file in 'releases'.)
    This is a form of MicroPython that has MH built in. This is the fastest and easiest to use form of MH
    And it can also be downloaded/installed from M5Burner.
    This has the drawback of not being able to pick apart or modify the core MH files, however.
    Make sure you erase the flash before installing. Put your device in download mode by holding G0 when plugging it in, if you are having issues



Here's a detailed walkthrough for installing MicroPython, and the ".py" form of MicroHydra:


Download the code from this repository as a zip file, and extract it somewhere on your computer.
Go to the 'releases' section to get .mpy files, or for a stable checkpoint of MH, if you encounter any issues.

Install Thonny: https://thonny.org/
Make sure to use a new version; older versions might fail to flash the ESP32-S3




Open Thonny and click this button in the bottom right:
image


Click "configure interpreter", and it should open this menu:
image


click "install or update micropython", and you should see another window:
image




Now you need to plug your Cardputer into the computer with USB. You'll probably have to put it into bootloader mode. To do that, press and hold the G0 button on the Cardputer while you plug it into your PC.

The G0 button is on the back edge of the Cardputer, and there's another G0 button on the Stamp




In "target port" you should now see a device with a name like "USB JTAG". Set the options in the window like this: image
And click Install
note: version 1.23+ is recommended currently, as it contains an important bugfix affecting MicroHydra's audio
You can also flash the MicroHydra Firmware '.bin' from this menu.

If installing didn't start, check that the correct device is selected, and it's in bootloader mode.


Once It has been flashed with MicroPython, unplug the device and plug it back in.
Thonny might not automatically detect it right away. If it doesn't, you can select it from the bottom right here:
image
And you might also need to click the red "stop/restart" button at the top to get it to appear.


If you see something like this in the bottom terminal, you've flashed it successfully!
image




To the left in Thonny, there should be a file browser. If there isn't, you need to hit "view">"Files" at the top.
Navigate to the folder where you downloaded this repository, and into the "MicroHydra" folder. Then, select all of the contents, and hit "Upload to /"
image


Once the files are transferred over to the Cardputer, you can test it out by disconnecting it, and powering it on. If everything is working, you should see the main launcher open up!

If you have any issues, feel free to reach out. MH is still growing, and I'm interested to hear of any trouble it might be giving you.

Demo GIF

cardputer-microhydra's People

Contributors

echo-lalia avatar gabriel-f-sousa avatar h-david-a avatar lana-chan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

cardputer-microhydra's Issues

Code Editor tab characters are confusing: possible improvement by making it automatic.

The previous update to HyDE.py has replaced space-indents and tab-indents with two different, reserved, special characters. And it has added an option to choose which one gets inserted when "tab" is pressed.

This functionality is a little bit confusing, because space indents and tab indents are kind of hard to tell apart in the current version. It also adds some unneeded complexity to the code by requiring any code that deals with space characters to check for both reserved indent characters.

I'm thinking this could be an improvement:

  • Remove distinction between tabs and space indentation.
  • Add a check to find the first occurrence of tabs, or space indentation. Use this to automatically set the tab-option to the appropriate mode
  • simplify code to only care about the one reserved indentation character
  • "save" method should replace all indentations with the automatically set tab mode

This would have the added benefit of giving HyDE the ability to convert tabs to spaces (and vice-versa) by changing the option in the menu.

slow st7789 driver

is there any reason why you're not using the compiled mpy version instead of the interpreted one? (other than it's extra steps to install)

SD card is not showing up in UI

I have seen no sd card or and flash pop up
I dont know is im just not doing something or im missing something
I flashed it on to my cardputer from the 5m burner and made a folder for the py files and notes
But It does not show up anywhere and i dont know how to derectly accese the flach to just add it to the flash
Some help would be nice thank you

oh and if you dont mine a seggestion
people showed a software similar to this booting and launching bin files or applications
Maybe the capabillity to boot up bins like other launchers would expand the capbilties of the laucher
:) also its cools stuff what yall are doing

Add fn-locks to smartkeyboard

It is super annoying to click arrows multiple times to navigate around big files.
Holding fn or ctrl modifiers is also painful :)
I propose to:

  1. Implement key repeats (holding a key will repeat the effect)
  2. Implement modifier-keys locks (e.g by triple click). That would require adding some visual indicator (I'd propose a popup in top-right corner with 4 small squares to indicate active locks)

Major API Overhaul is required for MicroHydra to enable multiplatform support.

In MicroHydra 1.0, the API for controlling the hardware is highly specific to the Cardputer. This means that, to create apps that work on multiple devices, you would need to completely rewrite large parts of the code for every single device.

In order for MicroHydra to support multiple platforms (such as the Cardputer II and the original Cardputer) simultaneously, the API for all of the built-in modules must be redesigned such that apps no longer need to specify exact Pins or other device-specific parameters in order to control things like the display, speaker, keyboard, etc.

For example, this:

# init object for accessing display
tft = st7789fbuf.ST7789(
    machine.SPI(
        1,baudrate=40000000,sck=machine.Pin(36),mosi=machine.Pin(35),miso=None),
    _DISPLAY_HEIGHT,
    _DISPLAY_WIDTH,
    reset=machine.Pin(33, machine.Pin.OUT),
    cs=machine.Pin(37, machine.Pin.OUT),
    dc=machine.Pin(34, machine.Pin.OUT),
    backlight=machine.Pin(38, machine.Pin.OUT),
    rotation=1,
    color_order=st7789fbuf.BGR
    )

Will not work on anything except the Cardputer.

MicroHydra can use device-specific modules to simplify this process, and make the display initialization code in each app would look like this:

tft = Display()

Running micropython apps

Hi,

I have a basic app which I have written using uiFlow 2 for the cardputer(using the envro IV sensor), the app runs fine on the cardputer and I can upload it to the device and it will run fine when I unplug it from my computer. I downloaded the main.py from the cardputer (this is my sensor code), renamed it and then uploaded it to the apps folder on my sd card for microhydra, microhydra sees it but I get an error message saying the M5 lib is unavailable, however it is on the device somewhere as the app will run separately from microhydra . I have tried one of the example programs and this works fine. So everything works independantly but when launching the app from Microhyrda it doesn't.

Do you have any ideas on this please?

Many thanks,

Matthew

Feature idea: Passing data to launched apps through MicroHydra bootloader. Support for file browsers and file handlers

This is an idea I'd like to work on. The ability for main.py to handle multiple arguments stored in RTC memory. Then, apps can be launched the same way, but apps could also send data to each other on startup through the RTC memory. I had this idea while thinking of how a file browser might be implemented, and here's how I envision it working:

  • File browser can show list of files and allow user to select a file.
  • File type is compared against a dictionary of file types and paths to file handlers.
  • File browser writes to RTC memory both the path to the file handler, and the path to the file. These would need to be joined by a predetermined character or set of characters that is disallowed from regular file paths. Currently I'm imagining something like "|//|", but I'm open to suggestions.
  • If main.py finds "|//|" in file path, uses str.split() to separate into a list, and launch the first element as an app, writing the rest back into RTC memory.
  • File handler app is now open, and can read RTC memory to find the path to the file it is meant to open.

I'm pretty excited about the potential possibilities something like this could open up. However I'm still not totally certain on how it would be best to format the special strings for this purpose. I also imagine the passed data could be JSON data, or something, instead.

We need popup_options_2d

I already made ChatGPT do coding, but it looks ugly.
You can insert this into lib/mhoverlay.py to see how it works:

    def popup_options_2d(self, options, title=None, shadow=True, extended_border=False, scrollable=False):
        """
        Display a popup message with given options arranged in 2D grid.
        Blocks until option selected, returns selection.
        """
        tft = self.display
        num_cols = 5  # Number of columns in the grid
        per_colomn = 6
        col_width = 240 // num_cols  # Width of each column
        row_height = 16  # Height of each row
        
        if scrollable:
            old_options = options
            options = old_options[:num_cols*per_colomn]

        if self.compatibility_mode:
            # draw box
            box_height = (len(options) // num_cols + 1) * row_height + 8
            box_y = 67 - (box_height // 2)
            if extended_border:
                tft.fill_rect(0, max(box_y - 10, 0), 240, min(box_height + 20, 135), self.config.palette[1])
            if title:
                self.draw_textbox(title, 120, box_y - 16, shadow=shadow, extended_border=extended_border)
        else:
            # draw box
            box_height = (len(options) // num_cols + 1) * row_height + 8
            box_y = 67 - (box_height // 2)
            if extended_border:
                tft.fill_rect(0, max(box_y - 10, 0), 240, min(box_height + 20, 135), self.config.palette[1])
            if title:
                self.draw_textbox(title, 120, box_y - 14, shadow=shadow, extended_border=extended_border)

        cursor_index = 0
        keys = self.kb.get_new_keys()
        while True:
            if self.compatibility_mode:
                # draw options
                for idx, option in enumerate(options):
                    col = idx % num_cols
                    row = idx // num_cols
                    x = col * col_width + (col_width - len(option) * 4) // 2
                    y = box_y + row * row_height + 4
                    if idx == cursor_index:
                        tft.fill_rect(x - 2, y - 2, len(option) * 4 + 4, 20, self.config.palette[0])
                        tft.text(self.font, option, x, y, self.config.palette[5], self.config.palette[0])
                    else:
                        tft.text(self.font, option, x, y, self.config.palette[4], self.config.palette[2])
            else:
                # draw options
                for idx, option in enumerate(options):
                    col = idx % num_cols
                    row = idx // num_cols
                    x = col * col_width + (col_width - len(option) * 4) // 2
                    y = box_y + row * row_height + 4
                    if idx == cursor_index:
                        tft.fill_rect(x - 2, y - 2, len(option) * 4 + 4, 20, self.config.palette[0])
                        tft.text(option, x, y, self.config.palette[5])
                    else:
                        tft.text(option, x, y, self.config.palette[4])
                tft.show()

            keys = self.kb.get_new_keys()
            for key in keys:
                if key == ";":  # Move cursor up
                    cursor_index = (cursor_index - num_cols) % len(options)
                elif key == ".":  # Move cursor down
                    cursor_index = (cursor_index + num_cols) % len(options)
                elif key == ",":  # Move cursor left
                    cursor_index = (cursor_index - 1) % len(options)
                elif key == "/":  # Move cursor right
                    cursor_index = (cursor_index + 1) % len(options)
                elif key == "w" and scrollable:
                    next_page_result = self.popup_options_2d(options=old_options[num_cols*per_colomn:], title=title, shadow=shadow,
                                                          extended_border=extended_border, scrollable=True)
                    if next_page_result != None:
                        return next_page_result
                    else:
                        cursor_index = 0
                elif key == "`" or key == "ESC" or key == "BSPC" or key == "a":
                    return None
                elif key == "ENT" or key == "GO":
                    return options[cursor_index]

            time.sleep_ms(10)

Question, is there a lib Package i can add onto my IDE

Hay is there a place with the full package of all the micropython libs used in apps or micro python used in microhydra
so i can plug the lib Package into Thonny so I can start to write up some apps and code
it would be nice to know so i can start to figure stuff out about how to make apps

also is there any network examples i can look at
I'm hopping to make a app to allow the carputer to use a ESB-NOW chat like system and some other stuff

sorry if i am just blind and couldn't find it
please correct me on anything I'm exited to learn and work on this
thank you for your time :)

End of lines getting stripped away in the editor

One-two symbols in the line ends getting stripped when opening files in editor.
Seems like the issue is with the code handling line breaks (\r\n) and trimming 2 last chars afterwards, and repeats once again:
#string formatter
def remove_line_breaks(line):
if line.endswith('\r') or line.endswith('\n'):
line = line[:-2]
if line.endswith('\r') or line.endswith('\n'):
line = line[:-2]
return line

I think, only last char shoud be trimmed: line = line[:-1]

RESOLVED

the wiki has some inaccuracies

Adding items in settings.py crashes settings app

I was trying to add 24h clock setting to settings.py (there were several iterations, ended up with this):

menu_def = [
    (HydraMenu.IntItem, 'volume', {'min_int':0,'max_int':10, 'instant_callback':update_config}),
    (HydraMenu.RGBItem, 'ui_color', {'instant_callback':update_config}),
    (HydraMenu.RGBItem, 'bg_color', {'instant_callback':update_config}),
    (HydraMenu.WriteItem, 'wifi_ssid', {}),
    (HydraMenu.WriteItem, 'wifi_pass', {'hide':True}),
    (HydraMenu.BoolItem, 'sync_clock', {}),
    **(HydraMenu.BoolItem, 'clock_24h', {}),**
    (HydraMenu.IntItem, 'timezone', {'min_int':-13,'max_int':13}),
    ]

Launching settings.py causes black screen.

'log.txt':

Tried to launch '/launcher/settings.py', but failed: '24h_clock'
Tried to launch '', but failed: ''
Tried to launch '', but failed: ''
Tried to launch '/launcher/settings.py', but failed: 'name 'false' isn't defined'
Tried to launch '', but failed: ''
Tried to launch '', but failed: ''
Tried to launch '/launcher/settings.py', but failed: 'clock_24h'
Tried to launch '', but failed: ''
Tried to launch '', but failed: ''
Tried to launch '', but failed: ''
Tried to launch '', but failed: ''
Tried to launch '/launcher/settings.py', but failed: 'clock_h'

Adding support for Daylight Saving Time Adjustment

Hi ,

Amazing library, made my entry into the world of MicroPython so easy.

Can I tinker with the code to add an option in the settings menu to enable Daylight Saving Time ?

You can let me know if that is the right way to do it or you have something else in mind

How about OTA updater? :)

There are new features almost every day!
I'd like to get them directly to the device :)
I've tried to adapt micropython_ota: https://github.com/mattjackets/micropython_ota/blob/main/micropython_ota.py
But it fails to download 'big' files: in my case it was failing on memory alocation for 44kb
Googled a bit, and it appears that there's a mrequests lib providing chunked downloads (https://github.com/SpotlightKid/mrequests/tree/master)

Looking into it. Any inputs are welcome!

allow passing bytearray to st7789fbuf

st7789fbuf gives errors easily, due to it's allocating of a large bytearray, potentially after other processes have already fragmented the heap.

Creating a large byte array and then deleting it right before creating the ST7789 object seems to work around this issue. A more elegant solution would probably be to simply pass that bytearray to the ST7789 on init. This way, the bytearray could be immediately allocated, and reused.

Attempting to burn your "MicroHydra" upload on M5Burner bricks the unit

Brand new, just got it today. Burning the firmware image (v0.2) that you uploaded to M5Burner results in my unit being bricked. After burning finished, instead of rebooting the screen just went black and now will no longer boot. No error messages, nada. Just a black screen.

Attempted to burn the original core image back to it, but M5Burner won't write to it, says it can't connect over the ComPort.

KeyError when using old/incorrect config

Using the wrong config.json can cause a KeyError, and prevent the launcher from starting.

lib.mhconfig.Config() should check that the required keys exist in the config,, in order to prevent this.

Code Editor does not auto delete/insert indentation properly

Last update to HyDE.py has added support for tab characters, and converted both tabs/spaces to reserved space characters to better take advantage of the small screen width.

This has broken the editor's ability to automatically indent on new lines, and it has caused the backspace on indentation to delete too many characters.

Possible solution: update newline method to check for the appropriate special characters rather than checking for spaces. Update backspace method to only delete one character.

tab characters render incorrectly in text editor

Currently HyDE does not support tab characters.

This issue comes from the current monospaced implementation. All characters are equally spaced, and the font does not have a built-in symbol for tab characters.

Current fix I'm imagining, is replacing tab characters with a couple of rare whitespace characters on file import, which will simulate a tab indent. Then when saving the file, the specific whitespace characters can be re-converted to tabs. I would also like to add some kind of config options to HyDE to switch between tabs and spaces.

If the above fix is implemented, then there could also be an opportunity to convert space indentation to a special character too, and add an option to control the desired amount of spaces to display with.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.