giuliomoro As you will have noticed, that one is not a "Bela program" as such.

giuliomoro so it doesn't have setup(), render() and cleanup()

that threw me off a little, yes. was looking for those 🙂

giuliomoro The fact that it doesn't call the Bela API and doesn't run a Bela audio thread is actually a requirement for it to be able to run at the same time.

aha. makes sense.

giuliomoro What you need to do instead is to pick a digital pin not used by Bela (or by anything else) and use the Gpio class.

ok.. got some reading to do!
and there was me thinking this would be relatively straightforward 0_0

thanks for spending your sundays helping strangers, by the way.

    Remork and there was me thinking this would be relatively straightforward 0_0

    it's not too hard, really ... this should be all you need

    #include <Gpio.h>
    
    // globals
    int gResetPin = ...; // TODO: find a free pin
    Gpio gResetGpio;
    
    ...
    
    // inside some init function:
    gResetGpio.open(gResetPin, Gpio::OUTPUT);
    
    // when needed:
    gResetGpio.write(false);
    usleep(1000);
    gResetGpio.write(true);

      i tried something very much along those lines yesterday night using P2-7 and it looks promising.
      (copied and adapted from the synchronous-gpio example.. so i'm glad i got that right, hah)

      didn't have a mosfet on hand to try the extra 12v switching, so for now i had to run the sketch manually and print a message-to-self to plug in the adapter, giving myself 5 seconds to do so 🙂
      bit stupid, but it seemed to work - now need to implement a switching system and try running at boot..

      giuliomoro it's not too hard, really

      true. just another hurdle to take. just meant to say that i did come across a lot of new info for this project, what with the OLED, combining lists to symbols and using arrays in Pd, and now this.. but all very useful for the future!
      and it demonstrates yet again how helpful this forum is.
      still, i'm quite glad i'm not pushing up to the deadline yet 🙂 all of this learning took me longer than anticipated, shall we say.

        Remork giuliomoro it's not too hard, really

        didn't want that to sound bad ... I just wanted to follow up from the previous post, which was pointing to a lengthy explanation and an API documentation, with a barebones practical example

          giuliomoro with a barebones practical example

          and a very useful one, indeed. 🙂 copy/paste FTW.
          used one pin for reset, and another to switch the 12v line (high side switching w/ a 2n3904 - BD140 combo, as i didn't have any P-channel Mosfets around.)
          set project to run on boot, and now i get my startup message to greet me after plugging in! huzzah!

          phfew. that is beautiful.

          so now i'd run this sketch in the background like before? cool.
          ALMOST THERE.

          in terms of timing - does this sort of 'background' thread start up first, compared to Audio/Pd?
          or do they run in parallel?
          not that it matters much, just wondering what the mechanics are.

          i have loaded a welcome message at the end of the SDD1309 driver sketch, to have some kind of visual on the state of the driver and the I2C connection. i'm thinking of leaving that in there, and loading all the arrays in Pd after a long button press, trying to spread some of the heavier lifting needed at startup. it also would prevent me from sending OSC messages from Pd too quickly - seeing that startup screen should also mean OSC is running in the background and is ready to receive.

            Remork phfew. that is beautiful.

            indeed!

            Remork in terms of timing - does this sort of 'background' thread start up first, compared to Audio/Pd?

            probably a bit later. I'd recommend that you don't rely on any particular startup order. Just have one ping the other until the other responds, then you'll know they are both alive.

            Remork spread some of the heavier lifting needed at startup

            For most application, "startup" heavy lifting is "free": you'll get mode switches, dropouts, whatever, doesn't matter: you haven't started yet! If anything, it's better to avoid spreading it out so that it completes as fast as possible ... if - on the other hand - you are trying to do the "startup heavy lifting" while at the same time playing some audio (e.g.: a power on tone), then the "spreading" can definitely help!

              giuliomoro probably a bit later. I'd recommend that you don't rely on any particular startup order.

              later? hmm, i expected it the other way around for some reason. good to know.

              giuliomoro Just have one ping the other until the other responds, then you'll know they are both alive.

              since - as you may have noticed - my coding skills are rather limited, i guess that would be banging

              [connect bela.local 7562(
              I
              [netsend]

              until [netsend] returns a 1? will try.

              not too worried about the startup procedure, actually, apart from getting the order and the timing right - speed doesn't really matter. this is for an art exhibition, so the startup is non-public.. the only audience interaction is the pressing of a button to get a soundfile to play, but it should be up and running when the doors open.

                I think this should work.

                Remork but it should be up and running when the doors open.

                then you could even wait 10 seconds after the patch starts and most likely everything will be online.

                Remork , i expected it the other way around for some reason. good to know.

                The line

                After=network-online.target

                in the .service file is what tells it in what order the script should be started. As it needs network, I set it to be online after network-online. Bela programs - generally speaking - do not need to wait for the network, so it starts as soon as possible after the kernel modules have been loaded:

                Requires=systemd-modules-load.service

                which is a bit earlier than the network target. These - however - are just the times when the processes are started. Whether one or the other comes online first depends on too many things I don't know ... anyhow, most likely the Bela program will get to render() before the other one.

                Remork [connect bela.local 7562(
                I
                [netsend]

                until [netsend] returns a 1? will try.

                no. You will need to use [netsend -u], because OscReceiver on OSC2OLED4Bela uses UDP. When you try to [connect( to a UDP port, no connection is actually established (it only sets some internal parameters0 and [netsend]'s output will send out a 1 even though the destination is not online yet.

                I thought more of something like sending an arbitrary "test" OSC message and modifying OSC2OLED4Bela so that it responds to it. This is actually easier said than done, as I see now that there are no OSC-sending capabilities in there at the moment, so you'd need to add a OscSender object and also UdpServer should be modified to use recvfrom() in order to be able to retrieve the address from which a message was received and use that for a response. Not impossible, but maybe for now you are better off just waiting 10 seconds before expecting the OSC2OLED4Bela to be online.

                  this is clearly over-engineering, but you could have a Bela digital in connected to the pin you are toggling from OSC2OLED4Bela and monitor that pin from within the Pd patch 🙂

                    giuliomoro this is clearly over-engineering, but you could have a Bela digital in connected to the pin you are toggling from OSC2OLED4Bela and monitor that pin from within the Pd patch

                    hahaa
                    like it!

                    i guess the only real issue is indeed when to bang the [netsend -u -b] object (which is was using, actually).
                    have to make sure it doesn't get banged before the custom render is online, and then fails to connect.

                    now over-engineering is my middle name. 🙂
                    but in this case, maybe i'll just wait a couple of seconds..
                    or i could manually bang the connection with the button? once i see my startup message, that should have given Pd plenty of time - and that message only appears after the render is running.
                    will run soms tests asap.

                    thanks for all the help so far!

                    giuliomoro This is actually easier said than done, as I see now that there are no OSC-sending capabilities in there at the moment, so you'd need to add a OscSender object and also UdpServer should be modified to use recvfrom() in order to be able to retrieve the address from which a message was received and use that for a response.

                    Actually, without any changes to the libraries, you could just hardcode a port number to send messages to in OSC2OLED4Bela and have a OscSender object send to it in response to a /ping or something like that ...

                    hahaaa
                    it feels like we're actually creating problems now. 🙂

                    didn't have the time today, will probably be thursday before i manage to come back to this.
                    keep u posted.

                    Remork used one pin for reset, and another to switch the 12v line (high side switching w/ a 2n3904 - BD140 combo, as i didn't have any P-channel Mosfets around.)
                    set project to run on boot, and now i get my startup message to greet me after plugging in! huzzah!

                    huzzah'd too soon.

                    don't know how or why, but it doesn't want to play anymore.
                    both pins just stay high continuously.
                    when you say

                    giuliomoro // inside some init function:
                    gResetGpio.open(gResetPin, Gpio:😮UTPUT);

                    could you elaborate on 'some init function' here?
                    i'm thinking that's (one of the places) where it may be going wrong.

                    i have the write commands in the beginning of the main() now, where i think they belong.
                    but i'm unsure as to where to put the setup lines.

                      Remork could you elaborate on 'some init function' here?

                      Inside main(), at the top, would be fine.

                      Remork both pins just stay high continuously.

                      Both pins ... which ones?

                      What happens in the destructor of Gpio is dependent on whether the pin was already "exported" before the program started. Also, whether the destructor is executed at all depends on whether the program exits cleanly. You could try adding gResetGpio.write(0) just before returning from main() to ensure the pin goes back to 0. Feel free to post your code here if that helps.

                        i was trying to use Gpio pins 30 and 31 (P2_5 and P2_7).

                        this is what would need to happen:

                        "Power ON sequence:
                        1. Power ON VDD (= 3.3v)
                        2. After 3.3v become stable, set RES# pin LOW (logic low) for at least 3us and then HIGH (logic
                        high).
                        3. After set RES# pin LOW (logic low), wait for at least 3us. Then Power ON VCC.(= 12v)
                        4. After 12V become stable, send command AFh for display ON.
                        SEG/COM will be ON after 100ms."

                        so ideally, i'd start off with ResetPin high and 12vPin low.
                        pull reset pin Low, then High again.
                        pull 12vPin high.
                        the 'Display On' command is in the display_Init_seq()., so i need to toggle those pins before that happens.

                        i just tried only writing both of them LOW, but they both remain at 3.3V.
                        so i'm not controlling them at all, as it is.

                        i added #include <Gpio.h> in render.cpp.
                        i addedGpio gResetGpio;
                        int gResetPin = 31;
                        Gpio g12VGpio;
                        int g12VPin = 30;

                        underneath the extern "C" at line 45

                        and i have this: // hopefully set up pin P2_7 for reset of display
                        gResetGpio.open(gResetPin, Gpio::OUTPUT);
                        g12VGpio.open(g12VPin, Gpio::OUTPUT);
                        gResetGpio.write(0);
                        g12VGpio.write(0);
                        usleep(1000000);
                        gResetGpio.write(0);
                        printf("try turning on 12v now?\n");
                        usleep(10000000);
                        g12VGpio.write(0);

                        there for now, i was trying to use the repeat lines of write(0) to toggle them HIGH, obviously.

                        giuliomoro What happens in the destructor of Gpio is dependent on whether the pin was already "exported" before the program started.

                        no clue what that means, or how to make sure it gets exported.?

                          I guess it's because those pins by default are not set to GPIO but to UART. The document I linked earlier https://learn.bela.io/using-bela/technical-explainers/other-uses-of-gpio-pins/ mentions the issue of pinmuxing and goes through how to test pins from the command line before moving to C++.

                          Remork no clue what that means, or how to make sure it gets exported.?

                          I thought you had your pins staying high when the program ended, which could have been explained by the above, but actually it seems irrelevant now that I understood your problem better. "exporting" is sysfs GPIO jargon for "telling the kernel the pin should be available for user space to manipulate". "Unexporting" it would mean telling the kernel you don't need it anymore. On BelaMini all pins are exported at all times, so ... it doesn't really make a difference either. Just remember that if you want the pin to go low when the program exits gracefully, add a yourPin.write(0) just before returning from main().

                          i added
                          Gpio gResetGpio;
                          int gResetPin = 31;
                          Gpio g12VGpio;
                          int g12VPin = 30;

                          switched the order around of these, my colleague noticed that they were the other way around.
                          seems better.
                          so changed to

                          int gResetPin = 31;
                          Gpio gResetGpio;
                          int g12VPin = 30;
                          Gpio g12VGpio;

                          i tried it with the config-pin utility in Terminal, that worked fine..
                          weird thing was that using those pins as outputs is not listed as an option in config -l
                          but i could set them to output/hi/lo just fine.

                          right now setting the 1309 test project to run on boot seems to work.
                          i have no real idea why it works now, but stopped working before- i can only hope it stays this way.

                          now need to set it so it runs in the background. deja vu 🙂

                            Remork weird thing was that using those pins as outputs is not listed as

                            Any of the gpio modes will work for output . gpio is the shortest one and will do.