https://toitlang.org/ logo
Join Discord
Powered by
# general
  • z

    z3ugma

    11/01/2025, 11:01 PM
    haha I'm not upset with you or toit...blame is on MacOS here
  • f

    floitsch

    11/01/2025, 11:01 PM
    still 🙂
  • g

    GitHub

    11/02/2025, 1:10 PM
    message has been deleted
  • f

    floitsch

    11/02/2025, 1:11 PM
    @z3ugma I pushed a new Jaguar release that should fix the flashing. Thanks for reporting.
  • z

    z3ugma

    11/02/2025, 2:51 PM
    I noticed that @kasperl has a lot of repos that use
    Services
    but I want some advice on when that's a better architecture pattern than using
    Tasks
    in a single container Some things I expect to do: - Wifi and setting provisioning from an HTML interface with HTTP - Control loop monitoring - sensing temperature and other environment variables over I2C, turning GPIO pins on and off - MQTT - reporting environment vars as state, accepting changes to control loop settings - UART between two ESP32 boards, sending messages from one board to another
  • z

    z3ugma

    11/02/2025, 2:58 PM
    I am reading through https://github.com/toitlang/toit/discussions/869 which goes into more depth than the tutorial
  • z

    z3ugma

    11/02/2025, 3:00 PM
    also https://github.com/toitlang/toit/discussions/1558 looks related
  • f

    floitsch

    11/02/2025, 3:03 PM
    Generally, I would say: - services are more flexible. They allow to exchange parts without needing to change the actual program. - they put more work on the API, but once it's there, it's easier to use (See the
    sensors
    package). - they make it possible to "override" services by just installing a higher-priority one. (Artemis uses this to implement a network manager that opens the cellular driver when a user does a
    net.open
    ). However, they are less efficient. Even for the
    sensor
    package, I expect users to start prototyping with the services, and then merge the drivers into their applications once they optimize. At least if it makes a difference for them.
  • f

    floitsch

    11/02/2025, 3:04 PM
    They also need more work to write the API. If there is an exception, it can also be a bit harder to figure out where the error originates from.
  • f

    floitsch

    11/02/2025, 3:06 PM
    Personally I'm a big fan of services. Especially the
    sensors
    package and API. It's a bit more work to write the sensor packages themselves, but it means that users can install "drivers" like on a modern OS, and then just use them without needing to worry about how the sensor data is provided.
  • z

    z3ugma

    11/02/2025, 3:11 PM
    vs having a separate
    temp_sensor.toit
    file and importing it at the top of a main coordinator script, and updating that file when needed? The major benefit being clear separation of code paths - if there's a crash in the sensor driver you know where it came from?
  • f

    floitsch

    11/02/2025, 3:19 PM
    It's not a big change, but yes. you need the import
    temp-sensor
    at the top of the file. With the sensors package you would just import
    sensors
    , independently of which kind of sensor you use. Fundamentally, if you have hardware that doesn't change, then services don't help that much. if you write more generic software (for example for different projects), then services can make your code more flexible/generic.
  • f

    floitsch

    11/02/2025, 3:24 PM
    Another big advantage of services is, of course, that they can be used by multiple containers. Sometimes, that's the main reason we have them. That argument is less true, if you write a single container app, though.
  • z

    z3ugma

    11/02/2025, 3:30 PM
    hm, let me take another guess How about a desktop volume knob it has a few functions - read the knob encoder - output a graphical image of the volume to an LCD screen - send the volume command to the computer over USB.HID would you architect this as a single container with tasks, where the tasks yield to each other - hey, check to see if the volume knob was turned; hey, we received a VOLUME_UP command from the operating system over USB there's some synchronized state you end up a bit with the Model-View-Update pattern
  • f

    floitsch

    11/02/2025, 4:00 PM
    I would probably start with a single container
  • f

    floitsch

    11/02/2025, 4:02 PM
    The moment you wait for something from the system you will yield automatically. So you shouldn't need to worry about yielding.
  • f

    floitsch

    11/02/2025, 4:02 PM
    A single application should be easier to develop.
  • f

    floitsch

    11/02/2025, 4:03 PM
    You might want to create a second container if you want to run the containers (UI +?) in parallel.
  • f

    floitsch

    11/02/2025, 4:04 PM
    Similarly you might do containers later if you do more projects and would like to just install a container instead of creating multiple versions of the same library with different hardware.
  • f

    floitsch

    11/02/2025, 4:06 PM
    Btw: @milkmansson did something slightly similar to what you plan to do. Maybe he can point you to his project. I have done a BLE hid library. It's not published yet, but that can be changed 🙂
  • m

    milkmansson

    11/02/2025, 4:55 PM
    Hey @z3ugma, I've done a few sensor packages, mostly I2c, although none yet as services.
  • f

    floitsch

    11/02/2025, 4:56 PM
    @milkmansson I'm mostly talking about the knob encoder and the LCD screen.
  • m

    milkmansson

    11/02/2025, 4:57 PM
    Have had a go at 'loop that checks for a state' method, but the best I think is the 'pin.wait-for' method, which sleeps until the right time, so super efficient, and super reactive.
  • m

    milkmansson

    11/02/2025, 5:01 PM
    I'm happy to share.. In my case I made the screen update mechanism into a task, which updates in the background every xxx ms (just paints the display with the level etc).
  • m

    milkmansson

    11/02/2025, 5:04 PM
    I had a battery level made with pictogrammers icons in the top corner, which updates on a different (slower) schedule, but operates the same way, which decouples the two functions.
  • m

    milkmansson

    11/02/2025, 5:05 PM
    Added a mutex as well, as a global, to avoid updates colliding.
  • m

    milkmansson

    11/02/2025, 5:09 PM
    I also try to keep a map of the started tasks to make sure I have a chance later of finding and shutting down task if it's necessary.
  • m

    milkmansson

    11/02/2025, 5:09 PM
    So the rotary encoder just does it's thing without having to insert screen update instructions through it's code.
  • k

    kasperl

    11/02/2025, 5:10 PM
    If you can start the tasks in one place, you might benefit from the
    Task.group
    helper.
  • k

    kasperl

    11/02/2025, 5:12 PM
    https://libs.toit.io/core/task/class-Task#group(2%2C0%2C0%2Crequired)