Hi,

I've added a push button to my Pepper for front panel access to the Bela Button.
I'd like to be able to loop through my Csound projects, but I'm having trouble getting it to function as desired.
I've followed the instructions from https://learn.bela.io/using-bela/bela-techniques/running-projects-on-boot/ and have currently got two projects loop_a_project and loop_b_project.
loop_a_project starts correctly on boot, but when I hit the button, I no longer get sound from Pepper, but loop_b_project doesn' t appear to start.

Here is some messages I caught from journalctl:

Mar 22 18:47:34 bela stdbuf[251]: Button pressed, quitting
Mar 22 18:47:34 bela kernel: rtdm_pruss_irq_close
Mar 22 18:47:34 bela stdbuf[202]: Click detected -- no action

Broadcast message from root@bela (somewhere) (Wed Mar 22 18:47:49 2023):

Bela button held, restarting

Mar 22 18:47:49 bela stdbuf[202]: Bela button held, running /opt/Bela/local/bela_button_hold.sh

Note that I've changed the hold behaviour to reboot instead of shutdown.

I checked the bela_startup.service after having pressed the button, it looks like it's continuing to run:

root@bela:/lib/systemd/system# systemctl status bela_startup.service
 bela_startup.service - Run Bela at boot
   Loaded: loaded (/lib/systemd/system/bela_startup.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2016-11-03 17:16:50 UTC; 5min ago
 Main PID: 249 (bela_startup.sh)
    Tasks: 11 (limit: 4915)
   CGroup: /system.slice/bela_startup.service
           ├─249 /bin/bash /opt/Bela/bela_startup.sh
           ├─279 /usr/bin/make -C /root/Bela PROJECT=loop_a_morphing_wavefolder CL= runonly
           ├─443 /bin/sh -c sync& cd /root/Bela/projects/loop_a_morphing_wavefolder && bash -c 'belacsound --csd=/root/Bela/projects/loop_a_morphing_wavefolde
           ├─445 bash -c belacsound --csd=/root/Bela/projects/loop_a_morphing_wavefolder/_main.csd  2>&1
           └─452 belacsound --csd=/root/Bela/projects/loop_a_morphing_wavefolder/_main.csd

Nov 03 17:16:55 bela stdbuf[249]: [commit: ea6cd697190d99414f8097b385c1b0e4d61fdb04]
Nov 03 17:16:55 bela stdbuf[249]: libsndfile-1.0.27
Nov 03 17:16:55 bela stdbuf[249]: sr = 44100.0, kr = 2756.250, ksmps = 16
Nov 03 17:16:55 bela stdbuf[249]: 0dBFS level = 1.0, A4 tuning = 440.0
Nov 03 17:16:57 bela stdbuf[249]: audio buffered in 256 sample-frame blocks
Nov 03 17:16:57 bela stdbuf[249]: SECTION 1:
Nov 03 17:16:57 bela stdbuf[249]: Initialising spinlock...
Nov 03 17:16:57 bela stdbuf[249]: Starting realtime mode queue: 0xb533d010 thread: 0x16e0890
Nov 03 17:16:57 bela stdbuf[249]: Underrun detected: 12 blocks dropped
Nov 03 17:17:47 bela stdbuf[249]: Button pressed, quitting

I also tried adjusting the csound launch command to belacsound --stop-button-pin 115 but after a quick look through the code I'm not sure that particular plumbing is hooked up.

Any ideas what's going on or what to look at next to further debug?

Cheers

It turns out it's a combination of factors. A csound program doesn't seem to be exiting properly when the button is pressed (ouch, needs further investigation) and when running all loop_* programs on boot, the settings from the project settings do not get applied. In the process of testing this (and half an afternoon) I also came up with a workflow that will work for you, so a good workaround is the following:

The hard work

  • update your Bela code to the dev branch. This contains two changes I just pushed:
    • a fix and an improvement to bela-cape-btn
    • a new command-line option for Bela: --disabled-digital-pins <mask> so you can disable individual pins *
  • get on the board via ssh and open the file /lib/systemd/system/bela_button.service for editing
    • Here you will see this line:
      ExecStart=/usr/bin/stdbuf -oL -eL /usr/local/bin/bela-cape-btn --pin 115  --delay 10 --monitor-click 0 --verbose --hold-press-timeout-ms 2000
    • change the pin 115 to the pin corresponding to the button you want to use to stop the running project. The pin values corresponding to the Pepper buttons should be (left to right): 89, 87, 88, 86 (or at least I think, according to the cross-referencing of this, this and this.
    • change it to remove --monitor-click 0 and add in its place --click "make --no-print-directory -C /root/Bela stoprunning" (careful with the quotes)
    • add --pressed 1 to inform it to use 0 as unpressed and 1 as pressed value (default is reverse)
    • remove the --hold /opt/Bela/bela_button_hold.sh option, because triggering that by mistake would shut down the board. You may re-instate that later when everything else works OK. Or replace it with a dummy "echo HOLD" so you see it happening but it doesn't shut the board down under you ass.
    • remove --verbose which is verbose and --delay 10 which is legacy
    • all in all, you should have something like this (using Pepper's leftmost button):
      ExecStart=/usr/bin/stdbuf -oL -eL /usr/local/bin/bela-cape-btn --pin 89 --hold "echo HOLD" --hold-press-timeout-ms 2000 --pressed 1 --click "make --no-print-directory -C /root/Bela stoprunning"
      (this will print HOLD when you hold press the button but it won't do anything beyond that)
  • in the IDE, add the following command-line option to your Bela program: --disabled-digital-channels <bitmask> where the actual argument you pass is a bitmask to ignore some of the Bela digital pins. The numbering here is in terms of Bela digital pins. So, left-to-right the buttons would be: 15,14,13,12. The corresponding bitmasks would be 0x8000, 0x4000, 0x2000, 0x1000. For the leftmost button I am testing with, use --disabled-digital-channels 0x8000. This will make it so that when you start or stop the Bela program, the corresponding pin is left untouched so that it doesn't interfere with the bela-cape-btn program running in the background.

Note: if you are a non-Pepper csound user and want to simply use The Button on the cape to stop the running program, do the above leaving --pin 115 in place but you also need to add --stop-button-pin=-1 to your command line options, either in the project settings or in /root/.bela/belaconfig as explained below.

First test:

  • reload the systemd script, restart it and monitor it:
    systemctl daemon-reload
    systemctl restart bela_button
    journalctl -fu bela_button
  • you should get a log, whose last line is similar to:
    Mar 22 23:17:19 bela stdbuf[6628]: Monitoring pin `89` (edge), will execute `make --no-print-directory -C /root/Bela stoprunning` on click and `echo HOLD` on hold (>2000ms). Button is pressed when pin is HIGH...
  • press the button. This will run the make stoprunning command. As there is no Bela program running, every time you press it you should get something like:
    Mar 22 23:17:48 bela stdbuf[6628]: No process to kill
  • now start the Bela program with the command-line-option specified above. Pressing the button should now yield:
    Mar 22 23:18:41 bela stdbuf[6628]: Killing old Bela process 6788
    and the Bela program should stop.
  • leaving the bela-cape-btn program running, verify that if you restart the Bela program several times, you can stop it again and again with the button (if you didn't set the --disabled-digital-channels option correctly, you would see that it would work only the first time).

Make it work:

If everything went fine so far, there is one more step to get this to work for your use case: with programs running on boot in a loop, command-line options from the program are not observed (UOPS), so you can use global command line options to work around that (and also so you don't have to remember to set them for each new project you add to your loop_*:

  • mkdir -p /root/.bela
  • then put in /root/.bela/belaconfig the following line:
    CL=--disabled-digital-channels 0x8000
    NOTE: these command line options will be applied by default in all programs, unless you specify a different entry for --disabled-digital-channels in your program and you are running that program from the IDE
  • hopefully now you should be able to start your csound (or whatever) programs in a loop and have it work OK

BONUS STEPS:

As you can see, you have a lot of options to control the effect of the button in the bela-cape-btn program. At this point you can do one of two things:

  • re-instate the old --hold /opt/Bela/bela_button_hold.sh option. Behaviour would be like:
    • short-press: program stops
    • long-press: graceful shutdown
  • however, if you do need all 4 buttons for your performance, you could decide to, instead, have bela-cape-btn ignore the short presses (clicks) and only act when a long press is detected. Behaviour would be like:
    • short-press: nothing, you can use these in your performance *
    • long-press: stop current project (and go to next project)
      This leaves you without an option to do a graceful shutdown, but maybe we are grown ups and there is no need for that unless you are writing files to disk ... (and by default with Pepper you have no graceful shutdown button exposed).

Well I guess you have enough details now to try something out.

* Perhaps misleadingly, but intentionally, channels disabled with --disabled-digital-channels can still be used as inputs from within the Bela program (well, in most cases at least (i.e.: when at least one other channel from the same GPIO bank has been enabled, which is always the case if you disable only one channel at the time)).

G'day Giulio,

Thanks for all the details, it certainly gave me enough to try some things out. As I'm using all of Pepper's buttons in my patch and wanted to make sure I could use the bela cape button that I'd broken out to the front panel I didn't follow your instructions to the letter. Also, it's a PITA to remove and reinstall in the rack, so I'm trying to avoid having to update/flash or what have you. Anyway I think it's mostly working now - here's how I went about it.

I created a short script, similar to /opt/Bela/bela_button_hold.sh called /opt/Bela/bela_button_click.sh that contained make stoprunning command:

#!/bin/bash                                                                                                                           
#this file is executed when the button on the Bela cape is pressed momentarily                                                        
                                                                                                                                      
CUSTOM_FILE=/opt/Bela/local/`basename $0`                                                                                             
[ -f $CUSTOM_FILE ] &&\                                                                                                               
{                                                                                                                                     
        echo "Bela button clicked, running $CUSTOM_FILE"                                                                              
        $CUSTOM_FILE                                                                                                                  
        exit                                                                                                                          
}                                                                                                                                     
echo Bela button clicked, stopping current project                                                                                    
make --no-print-directory -C /root/Bela stoprunning           

Then, I updated /lib/systemd/system/bela_button.service as such:

[Unit]                                                                                                                                
Description=Monitor the Bela cape button                                                                                              
After=networking-online.target                                                                                                        
                                                                                                                                      
[Service]                                                                                                                             
Type=simple                                                                                                                           
ExecStart=/usr/bin/stdbuf -oL -eL /usr/local/bin/bela-cape-btn --pin 115 --click /opt/Bela/bela_button_click.sh --hold /opt/Bela/bela_button_hold.sh --delay 20 --monitor-click 1                                                                                           
Environment=HOME=/root                                                                                                                

[Install]                                                                                                                             
WantedBy=default.target

Finally, I had to intercept the button press to stop csound from eating it, so I changed the /root/Bela/Makefile csound command to:

RUN_COMMAND?=bash -c 'belacsound --stop-button-pin -1 --csd=$(CSOUND_FILE) $(COMMAND_LINE_OPTIONS) 2>&1'                              

And with that, I can cycle between the two csound patches I currently have running on the board with the bela button, thanks!

Might be problematic if I mix and match engines in my projects, but for now they're all csound.

Can you spot any foreseeable problems doing it this way?

Cheers

    jaradical Might be problematic if I mix and match engines in my projects, but for now they're all csound.

    that's where the global command line options in /root/.bela/belaconfig can come in handy: those are obeyed by all programs.

    jaradical Can you spot any foreseeable problems doing it this way?

    That looks OK. Note that if you ever start a program without --stop-button-pin -1, it will break the edge detection of bela-cape-btn and you'll have to restart it. Another reason to have that set in the global command line options instead of per-program or per-language.

    jaradical Finally, I had to intercept the button press to stop csound from eating it,

    Yup, I just added a note to the previous post to clarify that.

    jaradical Also, it's a PITA to remove and reinstall in the rack, so I'm trying to avoid having to update/flash or what have you.

    Yeah, I was not suggesting reflashing, but doing an update to the dev branch through the IDE (https://learn.bela.io/using-bela/bela-techniques/updating-bela/). That would even give you csound 6.18 if you don't have it already.