• Hardware
  • Communication between 2 Bela Mini

As anybody achived to communicate between 2 Bela Mini with the USB A port? And what bit rate can be achived by that? Would there be a faster way to communicate between the 2 Bela Mini? Thank you!

you can connect one BelaMini's USB micro to the USB-A on the other one, however you'll need to change the IP addresses and DHCP range on the one that is connected via USB-micro so that ti it uses IPs different from the default, or the other one may be confused. Here's a summary of how those IP addresses work right now https://learn.bela.io/using-bela/technical-explainers/ip-addresses/

That's assuming you are looking for a ethernet-over-USB connection. You could leverage the MIDI connection instead and that wouldn't require much setup. The "host" one will see the other one as a regular USB midi device (probably hw:1,0,0), while the "device" one will see the other as it would see a host via the USB gadget driver, so at hw:0,0,0

In terms of bandwidth, that's a USB-2.0 High Speed connection, so that's the upper limit. Actual throughput will depend on packet size and CPU usage among other things.

Hi there! Thank you so much for your answer! If I've already done the IP config, is there an example project I could base on to do the USB A to USB Micro communication? Or is it just a basic Serial communication? Also, why the USB A to USB A would not work, I'm really curious about that! Thank you so much for your time!

    USB-A to USB-A ... In USB 2.0 you always need one host and one device. You may make it work USB-A to USB-A because you could configure it in software one as a host and one as a device, in defiance of what the connector would suggest ... but then you'd need to find a rare USB-A plug to USB-A plug cable with data lines ...

    FelixDoyon Or is it just a basic Serial communication?

    If you've set up the IPs, then use the network interface , sending UDP messages back and forth. Use the UdpClient / UdpServer classes.

    Something like

    // to send
    #include <libraries/UdpClient/UdpClient.h>
    
    UdpClient client;
    
    // in setup() 
    client.setup(port, ip_address);
    
    // from a non-realtime thread:
    client.send(buf, size);
    // to receive
    #include <libraries/UdpServer/UdpServer.h>
    
    UdpServer server;
    
    // in setup()
    server.setup(port);
    
    // from a non-realtime thread:
    uint8_t buf[maxLen];
    int ret = server.waitUntilReady(timeout)
    if (-1 == ret) {
      // handle error
    } else if (1 == ret) {
      // receive one packet
      int len = server.read(buf, maxLen false);
      if(len < 0) {
        // handle error
      } else {
         printf("From %s:%d received %d bytes: ", server.getLastRecvAddr(), server.getLastRecvPort(), len);
         for(int n = 0; n < len; ++n)
           printf("%d", buf[len]);
         printf("\n");
      }
    }

    Hi there!
    As I understand, neither USB and UDP would be good choice for my application, as I need a full duplex communication, but with exactly the same amount of data in each direction (and idealy with the same processing power used on both Bela). Basicly, I'm trying to test different codec with 2 distinct Bela mini and with real time audio data.
    So, what do you think would be the better way to communicate? I thought about UART, but I think it would not be fast enough. Do you think it would be possible to use like a Ethernet connector on Bela Mini, with or without a librarie? Thank you for your time!

    I don't see why UDP over USB network wouldn't work. Read and write from both ends.

    24 days later

    Hi there! I've been working on my problem recently. I can't use UDP because the final project requires two Bela Mini boards on two separate computers. Since I ideally need to transfer raw, live audio (32 bits * 48kHz = 1.6 Mbps), UART isn't fast enough to handle this speed (I tested it, and there's over 80% transmission error).

    The solution I currently have in mind is to use SPI, but that means I'll need to simulate a slave device. To handle this speed, I would also need to use the PRU, which seems quite complex.

    So, do you think there's a better solution than SPI with one of the Bela Minis as a simulated slave? If not, I've seen the example on GitHub, SPI-PRU, but the code seems complicated. Is there a specific file in the repository that I could use as a reference? Or do you have any recommendations on this? I've also tried using Linux SPI commands, like IOCTL, but I couldn't get it to work for simulating a slave. Do you think this approach could still work?

    Thank you, and have a nice day!

      See the example Communications/SPI. With that you can do bidirectional transmissions. Theoretically you can transport 48 Mbps , but in practice signal quality may limit you to something closer to 12 MB/s when the cable between the boards is short enough.

      FelixDoyon live audio (32 bits * 48kHz = 1.6 Mbps), UART isn't fast enough to handle this speed (I tested it, and there's over 80% transmission error).

      If you convert your audio to int16 and use the sampling rate that Bela is using (44.1kHz), you would need 16*44100 = 705600 bits per second, which may work better. Not sure how you made your test, but it seems that the maximum baudrate you can set is 3.6864Mbaud, so you should be able to comfortably transmit the data you require even transmitting floats.

      FelixDoyon I've been working on my problem recently. I can't use UDP because the final project requires two Bela Mini boards on two separate computers.

      I think you should be able to set one of the two USB-A ports to operate as a USB device while the USB-micro also operates as a device, so that you can connect a single board to two different hosts. Then you'd need a rare USB-A plug to USB-A plug cable which also transmits data - or attach wires directly to the USB pins on P1 - and you could plug one Mini at the same time to the host computer and to the other Mini.

      Thank you for your answer!
      When you say you can convert the audio in to int16, is there a particular way to do so? or it's just that it will work if you cast it to int16 directly from the value of audioRead and cast it back to float when you want to use audioWrite?à
      I also have a USB A to USB A cable with data. What would I need to do to make a serial bus between the 2?
      Thank you and have a nice day?

        FelixDoyon is there a particular way to do so? or it's just that it will work if you cast it to int16

        Need to make a int16_t array and then multiply your floats by 32768. A + 0.5f for rounding and a bit of clipping to avoid overflow. E.g.:

          myintarray[n]  = int16_t(constrain(myfloatarray[n] * 32768 + 0.5f, -32768, 32767));
          10 days later

          Thank you for all your time!
          I've ordered a USB A to give it a try. The manufacturer says it as the data lines. I was wondering then if it's still a Serial communication like the UART in the code (creating a Serial object). Also, instead of /ttyS4, wich one will I have to use?
          Thank you!

          giuliomoro

          7 days later

          OK the first thing to do is test the cable. Have you got an SD card reader on your computer?

            OK try the following:

            • make a backup of your SD card and/or projects
            • boot Bela, access it via ssh and edit file /opt/Bela/bela_gadget.sh, replace the line
              ls /sys/class/udc/ > UDC with ls /sys/class/udc/ | head -n1 > UDC
            • power off Bela, remove the SD card and place it in your laptop
            • the BELABOOT partition appears on your computer, open the file uEnv.txt in a text editor (e.g.: sublime, vim, nano, whatever, don't use Word or TextEdit).
            • after the line that starts with uboot_overlay_addr3=, add another line: uboot_overlay_addr4=/lib/firmware/PB-USB1-PERIPHERAL.dtbo
            • save the file and quit the editor. Use the OS's "safely remove" feature before you unplug the SD card.
            • put the SD card on Bela and boot it, connected only with the USB micro cable
            • access Bela via ssh
            • create file /opt/Bela/usb1_network.sh with the following content:
              #!/bin/bash
              
              HOST_OS=mac # use 'mac' for ncm or 'win' for RNDIS
              
              cd /sys/kernel/config/usb_gadget/
              mkdir g2 && cd g2
              
              echo 0x1d6b > idVendor  # Linux Foundation
              echo 0x0104 > idProduct # Multifunction Composite Gadget
              echo 0x0102 > bcdDevice # v1.0.2
              echo 0x0200 > bcdUSB    # USB 2.0
              
              mkdir -p strings/0x409
              echo "__bela2__" > strings/0x409/serialnumber
              echo "Augmented Instruments Ltd" > strings/0x409/manufacturer
              echo "Bela2" > strings/0x409/product
              
              # Two USB-network drivers: one for Windows, one for macOS, only one will be enabled below
              FUNC_RNDIS=functions/rndis.usb0
              mkdir -p $FUNC_RNDIS                    # network, Windows compatible
              mkdir -p functions/ncm.usb0             # network, macOS compatible
              
              mkdir -p os_desc
              echo 1 > os_desc/use
              echo 0xbc > os_desc/b_vendor_code
              echo MSFT100 > os_desc/qw_sign
              
              /opt/Bela/bela_mac.sh || true
              # using cpsw_0 and cpsw_3 that are unused by /opt/Bela/bela_gadget.sh
              if [ $HOST_OS == win ]; then
              	cat /etc/cpsw_0_mac > $FUNC_RNDIS/host_addr || true
              	cat /etc/cpsw_3_mac > $FUNC_RNDIS/dev_addr || true
              else
              	cat /etc/cpsw_0_mac > functions/ncm.usb0/host_addr || true
              	cat /etc/cpsw_3_mac > functions/ncm.usb0/dev_addr || true
              fi
              
              mkdir -p $FUNC_RNDIS/os_desc/interface.rndis
              echo RNDIS > $FUNC_RNDIS/os_desc/interface.rndis/compatible_id
              echo 5162001 > $FUNC_RNDIS/os_desc/interface.rndis/sub_compatible_id
              # The below are needed starting from kernel 4.14: the defaults have reverted to 2/6/0,
              # which no longer works with Windows or HoRNDIS
              echo ef > $FUNC_RNDIS/class
              echo 04 > $FUNC_RNDIS/subclass
              echo 01 > $FUNC_RNDIS/protocol
              
              mkdir -p configs/c.1
              echo 500 > configs/c.1/MaxPower
              if [ $HOST_OS == win ]; then
              	ln -s $FUNC_RNDIS configs/c.1/ # this needs to be loaded first in order to work on Windows
              else
              	ln -s functions/ncm.usb0 configs/c.1/
              fi
              
              udevadm settle -t 5 || :
              echo musb-hdrc.1 > UDC
              
              echo "" > /var/lib/dhcp/dhcpd.leases
            • if you are using Windows, replace HOST_OS=mac with HOST_OS=win. Either should work for Linux
            • make it executable: chmod +x /opt/Bela/usb1_network.sh
            • edit file /etc/dhcp/dhcpd.conf and add these three lines close to the lines that do the same for 192.168.7.0 and 192.168.6.0
              subnet 192.168.8.0 netmask 255.255.255.0 {
                      range 192.168.8.1;
              }
            • edit file /etc/network/interfaces and at the bottom of the file add:
              auto usb2
              iface usb2 inet static
                  address 192.168.8.2
                  netmask 255.255.255.0
                  network 192.168.8.0
            • reboot Bela, connected only with the USB micro cable.
            • get back onto Bela and execute /opt/Bela/usb1_network.sh
            • run ifup usb2
            • run dmesg -w and leave it running in the terminal
            • moment of truth: connect the USB-A to USB-A cable to the same computer where you are currently connected over micro USB
              • does a new network show up on the host?
              • does anything appear in the terminal window where the process is running?
              • can you connect to the Bela IDE on 192.168.8.2?

            Even if this is successful, do not yet connect the two USB cables to two different computers, get back for more details.

              I might have done someting wrong because my computer does'nt detect the partition when I plug in. I can't either connect via SSH. Should I flash the image on the SD card? If so, is there a way to save my project before, just by accesing the partition directly from the SD card without the Bela?

              giuliomoro

              giuliomoro reboot Bela, connected only with the USB micro cable.
              get back onto Bela and execute /opt/Bela/usb1_network.sh

              At this step, it doesn't show up

              Can you get the sd card back in your laptop and show the content of uEnv.txt in there?

              OK, try commenting out the addr4 line again and put it back in and reboot?