Help with multiple knock Sensors across 4 Analog pins...

Hi folks,

First post here - I'm currently in the process of putting together a small controller which features 4 Piezo mics. The sensors are going to Analog pins 0 - 3, but I cannot seem to separate them into 4 separate 'knocks'

I've tried a couple of templates I found on this forum, but these seem to be sensor arrays, and don't really help me too much. I'm pretty good with a soldering iron, but I'm very new to coding. I have been trying to expand on the example 'Knock' sketch below, but I don't know which lines of code may need to be duplicated for the additional sensors...

// these constants won't change:
const int ledPin = 13;      // LED connected to digital pin 13
const int knockSensor = A0; // the piezo is connected to analog pin 0
const int threshold = 100;  // threshold value to decide when the detected sound is a knock or not


// these variables will change:
int sensorReading = 0;      // variable to store the value read from the sensor pin
int ledState = LOW;         // variable used to store the last LED status, to toggle the light

void setup() {
 pinMode(ledPin, OUTPUT); // declare the ledPin as as OUTPUT
 Serial.begin(9600);       // use the serial port
}

void loop() {
 // read the sensor and store it in the variable sensorReading:
 sensorReading = analogRead(knockSensor);

 // if the sensor reading is greater than the threshold:
 if (sensorReading >= threshold) {
   // toggle the status of the ledPin:
   ledState = !ledState;
   // update the LED pin itself:
   digitalWrite(ledPin, ledState);
   // send the string "Knock!" back to the computer, followed by newline
   Serial.println("Knock!");
 }
 delay(100);  //
}

Appreciate any and all suggestions and links. I don't actually need LEDs or anything else at the moment - just concentrating on the inputs.

Cheers
Luke

I've tried a couple of templates I found on this forum,

Let's see what you tried and tell us what problems you had.

these seem to be sensor arrays

Without knowing exactly what you are doing using arrays does sound like a good idea.

Thanks for the quick response...

The Pure Data patch I wrote, which previously worked with a couple of pots and photolenses, has 4 'inlets'. Each Piezo should relate to one of these. At the moment, all 4 sensors are being picked up by the first inlet, with the other 3 not giving any signal.

Picture below of that part of the patch, in case my description reads as nonsense...

The array code I experimented with, and is the one currently loaded to the Arduino is as follows:

const int ledPin = 13;
const int knockSensor[4] = { A0, A1, A2, A3 };
const int threshold = 100;

int sensorReading[4] = {0, 0, 0, 0};
int ledState = LOW;

void setup()
{
  pinMode(ledPin, OUTPUT);
  Serial.begin(115200);     
}

void loop()
{
  int minThres = 0;
  int maxThres = 200;

  for (int i = 0; i < 4; i++)
  {
    
    sensorReading[i] = analogRead(knockSensor[i]);
    sensorReading[i] = analogRead(knockSensor[i]);

    if (sensorReading[i] >= threshold)
    {
      ledState = !ledState;
      digitalWrite(ledPin, ledState);
      Serial.println(sensorReading[i]);
    }
  }
    // delay ()
}

You declared:int sensorReading[4] = {0, 0, 0, 0};but you read:sensorReading = analogRead(knockSensor);It sould be:sensorReading[i] = analogRead(knockSensor);
Work from there. How would you know which knock sensor triggered the led? there is a lot of fun comming up for you.

Jacques

My bad, didn't use the Code function - Now corrected. @jbellavance - the code suggestion you gave me is actually what I have been using, apparently...

Don't go around and change your posts. Anyone who tries to learn things reading the forum will sure be confused.

The modify option should ony be used to correct minor errors, like misspelling and the same.

Jacques

Noted. I figured it was better I was clear, than more people offer up their time trying to correct some code which is already correct (to some degree).

I'll be more careful in future. Thanks!

How are thesensors mounted and how far apart are they ?

I note that your code does not indicate which sensor has been triggered

UKHeliBob:
I note that your code does not indicate which sensor has been triggered

Yeah, I think that's what I need to fix and I don't really know which bit of code to address...

Oh and the sensors are mounted to separate surfaces about half an inch apart.

I don't really know which bit of code to address...

If you only have one LED, then how about flashing it a different number of times depending on which sensor is triggered ? Write a function to flash the LED and pass the for loop index as a parameter. For a quick/dirty test use delay() when flashing the LEDs even though that will block the code for a while.

Or simply print the for loop index when you detect a knock.

Sorry - I've not been entirely clear. I'm not actually firing an LED - I'm trying to pick up the 4 separate sensors in Max/PD. I left the LED code in there as a starting point if I want to add LEDs later (feel free to tell me this is bad coding admin)

PD and Max are both able to pick up the sensors, but perhaps because I used a template script, that's the reason they're not able to determine separate signals?

Looks like you'll also need to Serial.print(i) (or Serial.println(i))

Serial.print(i);
Serial.println(sensorReading[i]);

PD and Max are both able to pick up the sensors, but perhaps because I used a template script, that's the reason they're not able to determine separate signals?

What are PD and Max (whatever they are) expecting to receive and by what method ?

UKHeliBob:
What are PD and Max (whatever they are) expecting to receive and by what method ?

PD - Pure Data
Max - Max MSP

Both are visual programming environments - Ultimately, I'll be using the little device I've built to control a virtual instrument (synth) that I've been asked to do the Sound Design for... Max and Pure Data are used as the 'interface' between the raw sensor data, and the midi data required by the software environments, smoothing the data and converting it to something more usable.

I'm trying to feed 4 inputs from the 4 analog pins (0-3) into PD/Max via Serial port. At present, the array code I posted (up there somewhere) is recognised, however, in my Pure Data patch (which has 4 'inlets' for the various analog pins) is only picking up data on one inlet - all 4 sensors are picked up here, when there should be 1 per inlet. This leads me to think that there is something missing in my Arduino code which will enable Pure Data (or MaxMSP) to read 4 separate lines of data.

The Pure Data patch is correct - I've had it working previously with a few analog inputs (Pots and lenses). One thing I have not tried is amending that Arduino code (for the pots) to recognise Knock sensors, so I'll try that now and if it fails, paste the code up.

Thanks again to anyone who's popped their head in and tried to help me unravel this!

I'm trying to feed 4 inputs from the 4 analog pins (0-3) into PD/Max via Serial port

What format are they expecting to receive, bearing in mind that the serial link can only pass one byte at a time with a maximum value of 255

Just the unfiltered numerical data from the pins - I can convert it to what I need in my patch (that's kinda what Max and PD are really good at)...

Or another, perhaps better way to look at it - the numerical data that one can see in the Arduino serial monitor - that is what I want to receive, only I figured there must be a way to separate the data being received on analog pins 0-3, into 4 distinct streams of data, or at least some kind of note in the Arduino code which allows me to separate them out in another software program.

It may be unobtainable, but it seemed kind of simple from what I had read prior to trying it. I'm ok with it not working like that, if anybody has suggestions on ways to get the desired effect (would a multiplexer help? - I'm planning on expanding the instrument anyway once this prototype somewhat does what it should)

Just the unfiltered numerical data from the pins

So, if analogRead() returns say 1012, how is that transmitted ?

UKHeliBob:
So, if analogRead() returns say 1012, how is that transmitted ?

Previously, when doing a similar thing with potentiometers, when the serial monitor read 1012, that was the value received into Pure Data - I'll be perfectly honest and say I don't understand the mechanics of getting that information between the two, other than having a very basic understanding of a serial port.

I have had a fiddle with the code and managed to split it into the 4 separate data paths but each time I try and add some kind of threshold for each analogRead, it's all errors...

If the sensor reading has to reach a threshold before it triggers a knock!, I think that will resolve the issue of which sensor is being triggered at any given time.

int knockSensor = A0;
int AnalogVal = 0; 
int knockSensor2 = A1;
int AnalogVal2 = 0; 
int knockSensor3 = A2;
int AnalogVal3 = 0; 
int knockSensor4 = A3;
int AnalogVal4 = 0; 

void setup() //
{
  
  Serial.begin(115200); 
}
void loop () 
{
  AnalogVal = analogRead(knockSensor); 
  AnalogVal2 = analogRead(knockSensor);
  AnalogVal3 = analogRead(knockSensor); 
  AnalogVal4 = analogRead(knockSensor);

  Serial.print(AnalogVal); 
  Serial.print("knock!"); 
  Serial.print(AnalogVal2); 
  Serial.print("knock!"); 
  Serial.print(AnalogVal3); 
  Serial.print("knock!"); 
  Serial.print(AnalogVal4); 
  Serial.print("knock!"); 

  Serial.print("knock!"); 
  Serial.println(); 
  delay(100); //
}

FYI - Because I started chopping away at another Example sketch, the output has been changed to knock! but I don't think this makes a difference in what I'm trying to achieve, at least not at this stage... Just getting the analogRead() to work properly (as per my above reply) would make my week.

  AnalogVal = analogRead(knockSensor);
  AnalogVal2 = analogRead(knockSensor);
  AnalogVal3 = analogRead(knockSensor);
  AnalogVal4 = analogRead(knockSensor);

This reads the same analogue input 4 times into 4 different variables. Did you mean to do this and if so, why ? Weren't you using an array of sensor pins in previous versions of the program ?

each time I try and add some kind of threshold for each analogRead, it's all errors...

Please post what you tried and the errors that it produced