Help with piezo midi drum using CD4051 [solved]

Hi,

I apologize if I have made a duplicate post, but I’ve been searching for something similar and couldn’t find one. I am new to Arduino and electronics in general. I am trying to make a midi drum based on schematic and sketch I found here:

htp://www.youtube.com/watch?v=LW8UZjsuBS0

First I tested with a single piezo, connected to A0 on the Arduino. I use Serial_MIDI_Converter_V2D, loopMIDI and Battery 4 for sampling and it worked.

Mine needs only 8 inputs right now, so I used a single CD4051 chip to multiplex the inputs and modified the code accordingly. I built the circuit on a perfboard with only one piezo disc connected. But when I uploaded the sketch, all the notes are played on Battery, even though I didn’t hit the piezo.

I wrote the sketch below to test the circuit, attached a single piezo on pin 1 of the CD4051:

int r0 = 0;
int r1 = 0;
int r2 = 0;
int multiplex[8];

void setup()
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  Serial.begin(9600);
}
void loop()
{
  for(int count=0; count <= 7; count++)
  {
    r2 = bitRead(count,0);
    r1 = bitRead(count,1);
    r0 = bitRead(count,2);
    digitalWrite(2, r0);
    digitalWrite(3, r1);
    digitalWrite(4, r2);
    multiplex[count] = analogRead(0);
    Serial.println(multiplex[count]);
    delay(2000);
  }
  Serial.println();
}

And the output I get on the serial monitor is attached below(without hitting the piezo disc). I also attached a picture of the schematic I found (modified based on mine).

Can anyone please help me with my mistakes.

Reading.jpg

built the circuit on a perfboard with only one piezo disc connected.

You must not leave inputs to the multiplexer unconnected. If you want to only have one sensor wired up you must wire all the other pins to ground, otherwise the floating channels pick up interference and can give you any value, as you have found.

For more on floating inputs see:-
http://www.thebox.myzen.co.uk/Tutorial/Inputs.html

Hi Mike,

Thanks for the reply. I will try that tonight and let you know.

Hi Mike,

I attached all the piezos as u suggested and it seems to be working.

But now I have another problem. Once I hit one piezo, other notes are also triggered. This seems random as I couldn't get any specific pattern. Sometimes many other notes are triggered and sometimes, only one other note is triggered.

Can you help me further with this. Thanks in advance.

Mike, I ran the test code again (with all 8 piezos connected) and the result I got on the serial monitor is as below(attached picture):

2.jpg

Once I hit one piezo, other notes are also triggered.

Yes this can happen, it is called cross talk. That is one channel affects another. This is mainly due to the very high load impedance, ( that 1M resistor ) sadly there is no sure fire fix.

A lot of it comes down to layout and decoupling. You need a 0.1uF capacitor between power and ground on the multiplexer chip.
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

Then try putting a pull up resistor directly on the analogue input, start with 1M and see if it improves things.
The problem is that once you start loading the inputs with lower resistor values to improve the cross talk you also reduce the sensitivity.

On the software side you could try increasing the threshold value.
Do a test, print out all the analogue value readings when you detect a hit and you will probably see that the phantom ones are lower, try and take that out with the threshold value.

The other thing is you could try a short delay, say 10mS between writing to the data select pins and starting an analogue conversion.

Good luck

I don't have any 0.1uf nearby. Found a 0.47uf from an old cassette player and tested with this instead, but i have the same result. So I'm looking for the 0.1uf (its very difficult to find parts here).

Regarding the pullup resistor, I don't exactly know how to wire that. I googled pullup/down resistors but couldn't find one that looks like mine (sorry, total noob)

A pull up resistor goes from the pin to the 5V line.

The capacitor has to be a ceramic type, other types will not do. These are normally brown.

Given your lack of access to components you might be better off just using the six inputs directly instead of using a multiplexer.

Just came back from a repair shop with some 0.1ufs, will try it again once i get back from work.

Given your lack of access to components you might be better off just using the six inputs directly instead of using a multiplexer.

With only six inputs, I would have to leave maybe a cymbal and a tom. It feels like I'm so close to give up now and with your help, I hope I'll make it

Attached the cap and pullup resistor but I get the same result

Ran the test sketch (without hitting any piezo) and the serial monitor output is:

1012
754
267
155
219
270
187
643

Ran the test sketch (without hitting any piezo) and the serial monitor output is:

That sounds like you have a wiring error, that is a typical result from a floating input.
Check the connections and then post a photo, resized to no more than 1000pixels wide of your wiring.

I’ve attached the pictures, top and bottom. Its a bit messy so I labelled it a bit:

Red - 5v
Black - Ground
Green - Select pins (top one is connected to Pin2, middle to Pin3, bottom to Pin4)
Blue - Analog In

Its a bit messy so I labelled it a bit:

No very nice construction well done.

However I am a bit concerned with the input wiring. Assuming those white two pin connectors are where the sensors go, is not the resistor and diode supposed to be across the sensor not in series with it?

Assuming those white two pin connectors are where the sensors go

Yes, they are.

is not the resistor and diode supposed to be across the sensor not in series with it?

Facepalm. Thanks for pointing that out. I will work on it tomorrow as its getting late here. Will be back once I'm done

Still no luck. I attached pictures of the new wiring

Hey Mike,

I realized I inserted some of the piezo connectors the wrong way. Changed it and raised the threshold from 100 to 200 and the drum seems to work fine now except for a little hiccup.

When hitting any piezo, the eighth pad (note 39 on the PadNote array) always goes off. Hope you can understand what I’m trying to say.

Here’s the code I’m using. I modified this a bit to suit my need, and I don’t understand all of them yet (like the PinPlayTime array etc) :sweat_smile:

unsigned char PadNote[8] = {30,34,26,24,33,31,29,39};
unsigned char status;
int PadCutOff[8] = {100,100,100,200,100,100,100,100};   //not using this right now
int MaxPlayTime[8] = {25,25,25,25,25,25,25,25};        
#define  midichannel 0;                 
boolean activePad[8] = {0,0,0,0,0,0,0,0};      
int PinPlayTime[8] = {0,0,0,0,0,0,0,0};             
boolean VelocityFlag  = true;
int pin = 0;
int hitavg = 0;
int pad = 0;
int r0 = 0;
int r1 = 0;
int r2 = 0;
int count = 0;
int multiplex[8];

void setup() 
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  Serial.begin(115200);
}

void loop(){

  readSensors(0);
  checkSensors(0);
}
void readSensors (int analogPin) {
  for(count=0; count <= 7; count++)
  {
    r2 = bitRead(count,0);
    r1 = bitRead(count,1);
    r0 = bitRead(count,2);
    digitalWrite(2, r0);
    digitalWrite(3, r1);
    digitalWrite(4, r2);
    multiplex[count] = analogRead(analogPin);
  }
}
  
void checkSensors (int analogPin)
{
  for(int pin=0; pin <=7; pin++)
  {
    hitavg = multiplex[pin];
    pad=pin;
   
    if(hitavg > 200)
    {
      if((activePad[pad] == false))
      {
        hitavg = map(hitavg,0,1023,50,127);
        MIDI_TX(144,PadNote[pad],hitavg);
        delay(5);
        MIDI_TX(144,PadNote[pad],0);
        PinPlayTime[pad] = 0;
        activePad[pad] = true;
      }
      else
      {
        PinPlayTime[pad] = PinPlayTime[pad] + 1;
      }
    }
    
    else if((activePad[pad] == true))
    {
      PinPlayTime[pad] = PinPlayTime[pad] + 1;
      if(PinPlayTime[pad] > MaxPlayTime[pad])
      {
       activePad[pad] = false;
       MIDI_TX(144,PadNote[pad],0);
     }
    }
  }
}

void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY) {
  status = MESSAGE + midichannel;
  Serial.write(status);
  Serial.write(PITCH);
  Serial.write(VELOCITY);
}

Hi Mike,

I raised the threshold for the eighth pad from 200 to 250 and its working now.

Attached the code below for other users:

unsigned char PadNote[8] = {30,34,26,24,33,31,29,39};
unsigned char status;
int PadCutOff[8] = {200,200,200,200,200,200,200,250};
int MaxPlayTime[8] = {25,25,25,25,25,25,25,25};        
#define  midichannel 0;                 
boolean activePad[8] = {0,0,0,0,0,0,0,0};      
int PinPlayTime[8] = {0,0,0,0,0,0,0,0};             
boolean VelocityFlag  = true;
int pin = 0;
int hitavg = 0;
int pad = 0;
int r0 = 0;
int r1 = 0;
int r2 = 0;
int count = 0;
int multiplex[8];

void setup() 
{
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  Serial.begin(115200);
}

void loop(){

  readSensors(1);
  checkSensors(1);
}
void readSensors (int analogPin) {
  for(count=0; count <= 7; count++)
  {
    r2 = bitRead(count,0);
    r1 = bitRead(count,1);
    r0 = bitRead(count,2);
    digitalWrite(2, r0);
    digitalWrite(3, r1);
    digitalWrite(4, r2);
    multiplex[count] = analogRead(analogPin);
  }
}
  
void checkSensors (int analogPin)
{
  for(int pin=0; pin <=7; pin++)
  {
    hitavg = multiplex[pin];
    pad=pin;
   
    if(hitavg > 200)
    {
      if((activePad[pad] == false))
      {
        hitavg = map(hitavg,0,1023,50,127);
        MIDI_TX(144,PadNote[pad],hitavg);
        delay(5);
        MIDI_TX(144,PadNote[pad],0);
        PinPlayTime[pad] = 0;
        activePad[pad] = true;
      }
      else
      {
        PinPlayTime[pad] = PinPlayTime[pad] + 1;
      }
    }
    
    else if((activePad[pad] == true))
    {
      PinPlayTime[pad] = PinPlayTime[pad] + 1;
      if(PinPlayTime[pad] > MaxPlayTime[pad])
      {
       activePad[pad] = false;
       MIDI_TX(144,PadNote[pad],0);
     }
    }
  }
}

void MIDI_TX(unsigned char MESSAGE, unsigned char PITCH, unsigned char VELOCITY) {
  status = MESSAGE + midichannel;
  Serial.write(status);
  Serial.write(PITCH);
  Serial.write(VELOCITY);
}

I will flag this thread as SOLVED now. Thank you for your time and input on my project.

Well done, glad you made it.

Hi!

I'm doing just the same project, the same schematic and one multiplexer.

I ask you, can you make some new scheme to implement it I ?. I have read the whole conversation and I still have not understood, what the capacitor for example.

I have the same code that sent the man in the video but I feel the same, some inputs affect others.

¿Can you help me? I appreciate it.

Greetings.

Please can I help to me I like make 12priso midi drum if u can please give me arduino chord and diaggram thanks​:heart::heart: