These are the changes you made to the core/default_libpd_render.cpp
file:
diff --git a/core/default_libpd_render.cpp b/other.cpp
index ac789c65..5590dd5a 100644
--- a/core/default_libpd_render.cpp
+++ b/other.cpp
@@ -1,3 +1,4 @@
+
/*
* Default render file for Bela projects running Pd patches
* using libpd.
@@ -11,12 +12,14 @@
extern "C" {
#include <libpd/s_stuff.h>
};
-#include <libraries/UdpServer/UdpServer.h>
-#include <libraries/Midi/Midi.h>
-#include <libraries/Scope/Scope.h>
+#include <UdpServer.h>
+#include <Midi.h>
+#include <Scope.h>
#include <string>
#include <sstream>
#include <algorithm>
+#include <stdlib.h>
+#include <PulseIn.h>
enum { minFirstDigitalChannel = 10 };
static unsigned int gAnalogChannelsInUse;
@@ -31,6 +34,24 @@ static unsigned int gFirstDigitalChannel;
static unsigned int gLibpdDigitalChannelOffset;
static unsigned int gFirstScopeChannel;
+PulseIn pulseIn;
+PulseIn pulseIn2;
+Scope scope;
+int gTriggerInterval = 1323; // how often to send out a trigger. 2646 samples are 60ms
+int gMinPulseLength = 7; //to avoid spurious readings
+float gRescale = 58; // taken from the datasheet
+unsigned int gTriggerDigitalOutChannel = 0; //channel to be connected to the module's TRIGGER (digital) pin
+unsigned int gTriggerDigitalOutChannel2 = 2;
+unsigned int gEchoDigitalInPin = 1; //channel to be connected to the modules's ECHO pin (digital pin 1) - check the pin diagram in the IDE
+unsigned int gEchoDigitalInPin2 = 3;
+int gTriggerCount = 0;
+int gTriggerCount2 = 0;
+int gPrintfCount = 0;
+int gPrintfCount2 = 0;
+float* gScopeOut;
+void* gPatch;
+bool gDigitalEnabled = 0;
+
void Bela_userSettings(BelaInitSettings *settings)
{
settings->uniformSampleRate = 1;
@@ -295,13 +316,18 @@ void fdLoop(void* arg){
}
#endif /* PD_THREADED_IO */
-Scope scope;
-float* gScopeOut;
-void* gPatch;
-bool gDigitalEnabled = 0;
-
bool setup(BelaContext *context, void *userData)
{
+ // Set the mode of digital pins
+ pinMode(context, 0, gTriggerDigitalOutChannel, OUTPUT); //sending TRIGGER from digital out
+ pulseIn.init(context, gEchoDigitalInPin, HIGH); //detect HIGH pulses on this pin
+ pinMode(context, 0, gTriggerDigitalOutChannel2, OUTPUT); //sending TRIGGER from digital out
+ pulseIn2.init(context, gEchoDigitalInPin2, HIGH); //detect HIGH pulses on this pin
+ if(context->analogInChannels != 8){
+ fprintf(stderr, "This project has to be run with 8 analog channels\n");
+ return false;
+ }
+
// Check Pd's version
int major, minor, bugfix;
sys_getversion(&major, &minor, &bugfix);
@@ -328,7 +354,7 @@ bool setup(BelaContext *context, void *userData)
//gMidiPortNames.push_back("hw:0,0,0");
//gMidiPortNames.push_back("hw:1,0,1");
- scope.setup(gScopeChannelsInUse, context->audioSampleRate);
+ scope.setup(2, 44100);
gScopeOut = new float[gScopeChannelsInUse];
// Check first of all if the patch file exists. Will actually open it later.
@@ -466,6 +492,65 @@ bool setup(BelaContext *context, void *userData)
void render(BelaContext *context, void *userData)
{
+ for(unsigned int n = 0; n<context->digitalFrames; n++){
+ gTriggerCount++;
+ if(gTriggerCount == gTriggerInterval){
+ gTriggerCount = 0;
+ digitalWriteOnce(context, n, gTriggerDigitalOutChannel, HIGH); //write the status to the trig pin
+ } else {
+ digitalWriteOnce(context, n, gTriggerDigitalOutChannel, LOW); //write the status to the trig pin
+ }
+ int pulseLength = pulseIn.hasPulsed(context, n); // will return the pulse duration(in samples) if a pulse just ended
+ float duration = 1e6 * pulseLength / context->digitalSampleRate; // pulse duration in microseconds
+ static float distance = 0;
+ if(pulseLength >= gMinPulseLength){
+ static int count = 0;
+ // rescaling according to the datasheet
+ distance = duration / gRescale;
+ libpd_float("distance1", distance);
+ libpd_bang("foo");
+ //rt_printf("Sending distance to pd\n");
+ if(count > 5000){ // we do not want to print the value every time we read it
+ rt_printf("pulseLength: %d, distance: %fcm\n", pulseLength, distance);
+ count -= 5000;
+ }
+ ++count;
+
+ }
+ // Logging to the scope the pulse inputs (gEchoDigitalInPin) and the distance
+ scope.log(digitalRead(context, n, gEchoDigitalInPin), distance/100);
+
+ }
+
+ for(unsigned int n = 0; n<context->digitalFrames; n++){
+ gTriggerCount2++;
+ if(gTriggerCount2 == gTriggerInterval){
+ gTriggerCount2 = 0;
+ digitalWriteOnce(context, n, gTriggerDigitalOutChannel2, HIGH); //write the status to the trig pin
+ } else {
+ digitalWriteOnce(context, n, gTriggerDigitalOutChannel2, LOW); //write the status to the trig pin
+ }
+ int pulseLength = pulseIn2.hasPulsed(context, n); // will return the pulse duration(in samples) if a pulse just ended
+ float duration = 1e6 * pulseLength / context->digitalSampleRate; // pulse duration in microseconds
+ static float distance2 = 0;
+ if(pulseLength >= gMinPulseLength){
+ static int count = 0;
+ // rescaling according to the datasheet
+ distance2 = duration / gRescale;
+ libpd_float("distance2", distance2);
+ libpd_bang("foo");
+ //rt_printf("Sending distance2 to pd\n");
+ if(count > 5000){ // we do not want to print the value every time we read it
+ rt_printf("pulseLength: %d, distance2: %fcm\n", pulseLength, distance2);
+ count -= 5000;
+ }
+ ++count;
+
+ }
+ // Logging to the scope the pulse2 inputs (gEchoDigitalInPin2) and the distance2
+ scope.log(digitalRead(context, n, gEchoDigitalInPin2), distance2/100);
+ }
+
int num;
#ifdef PARSE_MIDI
for(unsigned int port = 0; port < midi.size(); ++port){
@@ -636,14 +721,6 @@ void render(BelaContext *context, void *userData)
dcm.processOutput(&context->digital[digitalFrameBase], gLibpdBlockSize);
}
- // scope output
- for (j = 0, p0 = gOutBuf; j < gLibpdBlockSize; ++j, ++p0) {
- for (k = 0, p1 = p0 + gLibpdBlockSize * gFirstScopeChannel; k < gScopeChannelsInUse; k++, p1 += gLibpdBlockSize) {
- gScopeOut[k] = *p1;
- }
- scope.log(gScopeOut[0], gScopeOut[1], gScopeOut[2], gScopeOut[3]);
- }
-
// audio output
for(int n = 0; n < context->audioOutChannels; ++n)
{
@@ -675,3 +752,4 @@ void cleanup(BelaContext *context, void *userData)
libpd_closefile(gPatch);
delete [] gScopeOut;
}
this looks like it should work (although it could be made much more compact).
One mistake you are doing is that you are logging to the scope
twice. You are only supposed to call log()
once per sample. In this case your scope output is going to be mostly unusable, but this shouldn't prevent the rest of the core from working correctly.
So, to apply my earlier suggestion of "enabling only one of the two sensors at a time" in the code, you shall do what follows:
- to enable only the sensor on channels 0 and 1:
- comment out the following lines from setup():
pinMode(context, 0, gTriggerDigitalOutChannel2, OUTPUT); //sending TRIGGER from digital out pulseIn2.init(context, gEchoDigitalInPin2, HIGH); //detect HIGH pulses on this pin
- and the whole second
for(unsigned int n = 0; n<context->digitalFrames; n++)
block fromrender()
.
- comment out the following lines from setup():
- to enable only the sensor on channels 2 and 3:
- comment out these lines from
setup()
:pinMode(context, 0, gTriggerDigitalOutChannel, OUTPUT); //sending TRIGGER from digital out pulseIn.init(context, gEchoDigitalInPin, HIGH); //detect HIGH pulses on this pin
- and the whole first
for(unsigned int n = 0; n<context->digitalFrames; n++)
block fromrender()
.
- comment out these lines from
Testing:
- connect only sensor on channels 0/1, enable only it (as above). Verify it works
- connect both sensors. Don't change the code. Verify that the one on 0/1 still works
- connect only sensor on channels 2/3, enable only it (as above). Verify it works
- connect both sensors. Don't change the code. Verify that the one on 2/3 one still works
If 2. and 4. fail, then it's most likely a problem of power supply. If all pass, then it's most likely a problem of code.