3 months later

Hi,

Nice project! Completely the helping hand/connection I was looking for - great!

But I tried to run your code with the Bela Mini and i got the following error:

Building project...
Building render.cpp...
Makefile:433: recipe for target '/root/Bela/projects/TouchTest/build/render.o' failed
Build finished
In file render.cpp: no matching function for call to 'libpd_float' column: 3, line: 780
/root/Bela/projects/TouchTest/render.cpp:780:3: error: no matching function for call to 'libpd_float'
                libpd_float("sensorValue", (float)i, (float)sensorValue[i]);
                ^~~~~~~~~~~
/usr/local/include/libpd/z_libpd.h:46:12: note: candidate function not viable: requires 2 arguments, but 3 were provided
EXTERN int libpd_float(const char *recv, float x);
           ^
1 error generated.
make: *** [/root/Bela/projects/TouchTest/build/render.o] Error 1
root@bela ~/Bela#

Any ideas? Insights?

Thanks!
Dywen

this line

libpd_float("sensorValue", (float)i, (float)sensorValue[i]);

would have never compiled: libpd_float() only takes two arguments. @luiszayas ? Also, it is not safe to call libpd_float() from a separate thread.

"your code", is indeed the code of @luiszayas

If he can follow this up - great.
If not, I'm trying to get a grip on the relationship between the Bela Ide, MPR121 sensor and library AND Pure Data
---> in render.cpp of the example code, this is mentioned
// This array holds the continuous sensor values
int sensorValue[NUM_TOUCH_PINS];

---> How can this be "seen" by Pure Data?

I will compare the libraries..
Ciaaoo
Dywen

    dywen ---> How can this be "seen" by Pure Data?

    It is being sent (or attempted to be sent) to Pd via libpd_float("sensorValue", (float)i, (float)sensorValue[i]);. This is aiming to send a message to a receiver [receive sensorValue] in the Pd patch.

    Hey,

    This I understand - but I don't know how to fix it - as indeed libpd_float only takes two arguments.

    :-/
    greetz,
    Dywen

    you can look at the whole libpd messaging API here:
    https://github.com/libpd/libpd/wiki/libpd#sending-messages-to-pd

    You could use libpd_start_message(), libpd_add_float(), libpd_add_float(), libpd_finish_list() in this order. However, as I mentioned above, sending messages to libpd from a different thread is not safe. I think it may be ok for libpd_float(), but it surely is not for the list option I just illustrated.
    The easiest way would probably be something like

    libpd_float("sensorIndex", (float)i);
    libpd_float("sensorValue", (float)sensorValue[i]);

    and then having two separate receivers ([r sensorIndex] and [r sensorValue])

    Although the proper way is to move the message sending to the render() function. Given that the sensorValue variable is global, you can just remove the libpd_float() from readMPR121() and add these lines to render():

    for(int i = 0; i < NUM_TOUCH_PINS; i++) {
      libpd_float("sensorIndex", (float)i);
      libpd_float("sensorValue", (float)sensorValue[i]);
    }

    there is still a race condition there, but hopefully it will be fine.

    Alternatively, replace the two libpd_float() above with the list-based approach described above: it is now safe to use the list approach because you are doing that from within the audio thread.

      Hi,

      I adapted the code in render.cpp, that splits up the 'libpd_float()'

      And I changed the Pd patch (simplified it)

      alt text

      When compiling, I get this:

      Build finished
      Running project...
      Running Pd 0.48-0
      This project requires the number of inputs and the number of outputs to be the same
      Couldn't initialise audio rendering
      Error: unable to initialise audio
      Makefile:524: recipe for target 'runide' failed
      make: *** [runide] Error 255
      

      I'm out of my depth here - barely understanding the libpd documentation :-/

      greetz
      dywen

      Aha, logical!! BelaMini has no analog out

      :-)

      My values are scrambled now - but that's one layer of bugs scraped off!! yeay!

      alt text

      Not - yet - workable as you can see.

      that's actually expected: [route] strips off the first element of the message. In your case you have a message with only one element, so it just "forwards" a bang.

      Ok, back to Pure Data and knowing how that works :-)
      Two questions::

      ---> I'm trying to find out what pure Data gets from the MPR121 via render.cpp
      I managed to print this

       rt_printf("%d ", sensorValue[i]); 

      :-D
      --> so the MPR121 gives values from 0 (state of not touched) to 110 approximately
      I need an object in pd that does not send bangs (like [route] does) but a construction that works with a threshold (when the value is higher than 30, button is pressed, play sound)
      Any ideas? - I think I know about an object, but I don't know how it deals with the array of 12 numbers..

      ---> Render.cpp does not want to print rt_printf("%d ", sensorIndex); (commented out in the following code snippet)
      Is this because sensorIndex is just a very local variable?
      is it ignored?
      Is it a problem (seems not to be the case..)

      // Auxiliary task to read the I2C board
      void readMPR121(void*)
      {
      	for(int i = 0; i < NUM_TOUCH_PINS; i++) {
      		sensorValue[i] = -(mpr121.filteredData(i) - mpr121.baselineData(i));
      		sensorValue[i] -= threshold;
      		if(sensorValue[i] < 0)
      			sensorValue[i] = 0;
      		libpd_float("sensorIndex", (float)i);
      		//rt_printf("%d ", sensorIndex[i]); //error: use of undeclared identifier 'sensorIndex'
      		libpd_float("sensorValue", (float)sensorValue[i]);
      #ifdef DEBUG_MPR121
      		rt_printf("%d ", sensorValue[i]); //prints the values of the sensor when DEBUG_MPR121 is define at beginning of programme
      #endif
      	}
      #ifdef DEBUG_MPR121
      	rt_printf("\n");
      #endif
      	
      // You can use this to read binary on/off touch state more easily
      //rt_printf("Touched: %x\n", mpr121.touched());
      }
      

      Full render.cpp file is here:
      https://framabin.org/p/?6facff6f6e1a593b#XZ1pyi4ED24QQQ+dUT9aEfZh+IzhXY58XUYzLIHQw8E=

      And, thanks - you made my day!
      greetz,
      dywen

        dywen ---> Render.cpp does not want to print rt_printf("%d ", sensorIndex); (commented out in the following code snippet)

        there is no variable called sensorIndex. In fact the value you are sending to the "sensorIndex" receiver in Pd is simply i.

        dywen I need an object in pd that does not send bangs (like [route] does) but a construction that works with a threshold (when the value is higher than 30, button is pressed, play sound)

        could be

        [r sensorValue]
        |
        [> 30]
        |
        [select 1]
        |
        [somethingThatPlaysSound]

        ?

        Hi,

        Ok, I made a testpatch to simulate the sensor (as i don't know another way (yet) to get the data from the sensor into pd via Bela).

        When the slider is at 0, the MPR121 sensor is not touched
        I have put the threshhold at 30, because sometimes proximity and not touch is detected - to be changed at will.
        alt text
        https://framabin.org/p/?d2e0eebe6a1f043c#MmaUCw4CZUU2L08AwD32Dg3Dk9TRG5KXQgW0jfMwYmU=

        This is my translation to Pd&Bela
        And it works! For the moment for pin0 on the MPR121

        alt text

        Pd code:
        https://framabin.org/p/?95c0a2a50f7b1d1e#Q/+/6HwTwCfmfEvZSmI2ypZMmmiIJsCBGK0I36f9FqE=

        Lovely..
        Now figure out how to get the 8 values from the MPR121 chip
        (by doing [r sensorValue 0 1 2 3 4 5 6 7] ? - after lunch..)

        Greetz,
        Dywen

          dywen Now figure out how to get the 8 values from the MPR121 chip
          (by doing [r sensorValue 0 1 2 3 4 5 6 7] ? - after lunch..)

          send a list!
          e.g.:

          	        libpd_start_message(8);
                          for(int n = 0; n < 8; ++n)
                              libpd_add_float(sensorValue[n]);
          		libpd_finish_list("sensorValue");

            Of course!
            But Pure data still sees them as one

            alt text

            They bang together
            When I touch the 0 of MPR121 both values get printed - when I touch the 1 of MPR121 it's the same.
            I should be able to pour sensorValue into an array (but a pd array is not the same as an array in C..)

            The extra argument (0 or 1) to [r sensorValue] is ignored I believe.

            Print straight out of the receiver:

            [r sensorValue]
            |
            [print]

            and you will see that they come in as a list. However, when you go into [> ], only the first element is considered.

            So try this

            [r sensorValue]
            |
            [unpack f f f f f f f f ]
            |  |  |  |  |  |  |  | 
            each of these is one of your values.