Multiplexing Analog Teensy (Piezo trigger notes)

Status
Not open for further replies.

Deadp1xels

Well-known member
Code:
int muxPinA = 0;
int muxPinB= 1;
int muxPinC =2;
int muxPinD =3;
int analogReadPin(0);

const int midiChannel =1;

// Sets pot smoothing tolerances
int sensorTolerance =16;
int ccTolerance = 2;

int cAmount = 2; int cc4knob[2] = {61,62}; //CC1, CC2, CC3 ...

//example for 16 knobs:
//int cc4knob[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};

int ccValue[8]; // Value of the knob (MIDI CC range: [0,127]
int sensorValue[8]; // value from the analog input (Analogue Input range [0,1023])

// Sets inital values for bitReads
int r0 = 0;
int r1 = 0;
int r2 = 0;
int r3 = 0;

void setup()
{
pinMode(muxPinA, OUTPUT);
pinMode(muxPinB, OUTPUT);
pinMode(muxPinC, OUTPUT);
pinMode(muxPinD, OUTPUT);

pinMode (analogReadPin, INPUT);
Serial.begin(9600);
}


void loop()
{
for (int i = 0; i < cAmount; i++)
{
// Loads values into "r" variables
r0 = bitRead(i,0);
r1 = bitRead(i,1);
r2 = bitRead(i,2);
r3 = bitRead(i,3);

// Writes bits to each pin, based on "r"
digitalWrite(muxPinA, r0);
digitalWrite(muxPinB, r1);
digitalWrite(muxPinC, r2);
digitalWrite(muxPinD, r3);

int newSensorValue = analogRead(analogReadPin);

// Smoothing
if (abs(newSensorValue - sensorValue[i]) > sensorTolerance) 
{
sensorValue[i] = newSensorValue;
int newCCValue = sensorValue[i] / 8; // Divides value by 8 for MIDI (0-127)

if (abs(newCCValue - ccValue[i]) > ccTolerance)
{
ccValue[i] = newCCValue;
usbMIDI.sendNoteOn(ccValue[i], newCCValue, midiChannel); // Sends USB MIDI
delay(10);

} 
} 
} 
}

I'm navigating away from my button to play notes, and moving to piezos to allow for velocity aswell

I have my piezos wired in parrelel with a 1Mohm resistor positive going to input of a 74HC4076E Multiplexer

This is a piece of code i had and modified for a while ready for when i dove head first into multiplexing

Ideally i want 12 piezos playing one octave with velocity control

Currently the two piezos i have trigger the same note and are ULTRA sensitive, to the point they trigger a note 5-6 times a second at alternating velocity

Any ideas?
 
Last edited:
Ok i suddenly realized the code was for a different project and was completely wrong for giving me decent piezo response

Code:
void setup()
{
pinMode(0, OUTPUT); // s0
pinMode(1, OUTPUT); // s1
pinMode(2, OUTPUT); // s2
pinMode(3, OUTPUT); // s2

Serial.begin(9600);
}

void loop()
{
digitalWrite(0, LOW);
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);

int readInZero = analogRead(3)/8; 
if(readInZero>=80){
  usbMIDI.sendNoteOn(61,readInZero,1);
  delay(50);
  Serial.println(readInZero); 
}
{
digitalWrite(0, HIGH);
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);

int readInOne = analogRead(3)/8; 
if(readInOne>=80){
  usbMIDI.sendNoteOn(62,readInOne,1);
  delay(50);
  Serial.println(readInOne); //use the result
}

}
}

This is the new code

I have two piezos in parrelel with 1M Ohm resistors going into pins 0 and 1 of a CD74HC4067E Multiplexer

Both notes are playing nicely, minor multiple triggers if i really push it but won't be an issue in my application

Once i press or tap the piezo to trigger it above the Threshold level the note plays but continues to ring....

I can make a video if it helps, anyone had any issue like this??
 
I don't see any usbMIDI.sendNoteOff() in your code. For every note you turn on, you need to turn it off sometime later.
 
So it works but my piezo is still being temperamental

My instinct is telling me coding won't solve my issue anymore

I'm not really sure where to go from here swap the resistor for a lower value and bang in a Zener to limit my voltage

bit frustrating this is the last yet most crucial part of my build, it's just not giving he response I want

I know piezo a aren't easy to work with but this is ridiculous, I guess I'm going to have to work at conditioning the signal before the ADC
 
OK, first things first--if you can borrow an oscilloscope or make one of the sound card o-scopes, your life will be much easier doing any piezo work.

You may find out:
- that your problems are solved by a simple flip of the piezo (if the main pulse is going negative)
- that the surface the piezo is attached to is causing "ringing"
- that the adjacent transducer is causing false triggering
- that the voltage induced by the piezo is glitching the main supply and resetting the Teensy
- some other problem in the analog domain like picking up 60 Hz (everything is an antenna)

I had to build an AVR based drum trigger in two weeks once, and (though it is crufty in my eyes now) these are some tricks I used:

- isolated the triggers with fabric and/or neoprene

- used twisted pair for the transducer wires (several benefits: isolation, inherent capacitance damped pulse, neatness, less stress on piezos)

- For signal conditioning, I used a resistor voltage divider and a small (.0001 uF, perhaps smaller) capacitor. The divider values I chose by looking at the maximum voltage on the scope I could obtain by thwacking the piezo and dividing it down into just above the safe range. I got brief spikes to 30V or so on the greeting card piezos I used. The capacitor (one leg on ground) damped it further and seemed to stretch out the short pulse a little so the A/D worked better.

- since I had lots of AVR pins free, I tied the transducers (post-conditioning) to both an analog and a digital input pin, then looked for the hits as transitions on the digital pins, which was obviously waaaaay faster. If I got a hit, I switched over to the analog pin to read the value. I think I actually sent the MIDI channel and note on while I was waiting for the velocity. This approach may be overkill given the speed of the A/D but it worked for me.

Good luck! Let us know how it goes.
 
This is alot of fantastic information guys thank you!

My first guess was getting my hands on a scope, unfortunately i tried to get a free scope offered from a friends recently but it never came through
I've been trying to get a serial scope working but i'm not really sure how to interface it with my serial monitor :rolleyes:

Alot of what you mentioned leaves me thinking actually

During my NoteOn and NoteOff i get some some odd value of around 0-4 looping on and off, my note does'nt trigger but its still sending the value of 4

I should probably mount the piezos under the conditions i require for the final product, its going to be in a glove so the added material will add an extra parameter to adjust to.

slightly concerned about my circuit size, to condition one signal it won't take alot but i'm going to have to do it for 12 piezos :confused:


Edit:
Ordering components now, little daunting about what I see on your circuit the op amp seems fine this is we're my theory comes into practice.

Still waiting on smaller piezos to turn up anyway, the ones I'm using are too big for my glove :)

I'll keep you posted
 
Last edited:
Well seems my order didn't go through due to card errors and its been blocked till i can get it fixed :confused:

Back to using what i have to solve this issue guess theres no solution by just using resistors zeners and a few varying caps is there? :p

I see some videos on youtube that seem to achieve the same thing but no luck :confused:

I'm getting closer though!!

Code:
int t;
int THRESHOLD = 40;

void setup()
{
pinMode(0, OUTPUT); 
pinMode(1, OUTPUT); 
pinMode(2, OUTPUT); 
pinMode(3, OUTPUT); 

Serial.begin(9600);
}

void loop()
{
digitalWrite(0, LOW);
digitalWrite(1, LOW);
digitalWrite(2, LOW);
digitalWrite(3, LOW);

int readInZero = analogRead(3)/8; 
int Velocity = analogRead(3)/8;

if(readInZero>=THRESHOLD){
   t++;
   usbMIDI.sendNoteOn(61,Velocity,1);
   delay(t);
  usbMIDI.sendNoteOff(61,Velocity,1);
}
}

I get my piezo sending values when i take my finger off which is one of the biggest issues

Im working on finding an oscope to use
 
The LM324A is one of the cheapest and most widely used opamps (probably because it's so cheap....) Looks like you can get just one from Digikey for only $0.41.
 
Back to using what i have to solve this issue guess theres no solution by just using resistors zeners and a few varying caps is there?

I get my piezo sending values when i take my finger off which is one of the biggest issues

Im working on finding an oscope to use


*** if you are triggering when you take your finger off then you need to flip your piezo leads (or the piezo, if easier) and test things a bit more before you read on or try anything else. You could be done already! ***

My circuit was all passive parts: gnd---Piezo---R1---Input pin--R2--gnd

1) That didn't work? OK! In the above text-tastic circuit R1 makes a voltage divider with R2. Since we are not sure what high voltage spike your piezo can crank out, I'd keep R2 at 1K and start with R1 at 10K with change to 4.7K if you don't see enough voltage at the Input pin. A lot depends on your set-up and piezo size.

2) As I mentioned, I put a small cap in parallel with R2. It may not even be needed but seemed to help dampen/stretch the pulse for my situation. Small: .001 ufd range but it's not science.

Again, you are probably soooooo close. I think flipping the piezo leads is not 100% equivalent to flipping the piezo, but try the easy thing first.
 
Since you mentioned Zeners, these guys seem to be doing their signal conditioning with just a single 1Mohm resistor and a 5.1V Zener to keep things from exceeding 5.1V: http://spikenzielabs.com/SpikenzieLabs/DrumKitKit.html and http://spikenzielabs.com/SpikenzieLabs/dkkai.html

Bonus: they have some code to scrutinize.


Lastly: Since you are stymied on the o-scope, you can just acquire/print a set of A/D values to judge the waveform that the Teensy is seeing. You can then judge whether it is too small or is clipping and adjust R1 in the previous message smaller or larger to compensate--something like:

void loop()
{
int readInZero = analogRead(3)/8;

if(readInZero>=THRESHOLD){
Serial.println(readInZero);
delay(2); ' may need to change this variable or delay micros depending on how fast the pulse is
}


Good luck!
 
Hey guys

Its not the price, I actually had a £30 (45-50$?) order in with op-amps and extra nick nacks but the card was blocked due to suspected fraudlent activity so there investigating and getting back to me.

Managed to dig out a handful of caps from a older collection of gear got some
100uf 16v Smoothing
10uf 63v smoothing
0.1uf By-pass/Decoupling
1uf 35v Tantalum Bead Cap

I have no idea why i have them... but i do

I'll try the suggestions, i do appreciate them!

In the mean time i got an old crystal display working with teensy in about 10 minutes which is a bonus

Little bit weighty i could do with something smaller :p
 
Hey guys

Its not the price, I actually had a £30 (45-50$?) order in with op-amps and extra nick nacks but the card was blocked due to suspected fraudlent activity so there investigating and getting back to me.

Managed to dig out a handful of caps from a older collection of gear got some
100uf 16v Smoothing
10uf 63v smoothing
0.1uf By-pass/Decoupling
1uf 35v Tantalum Bead Cap

I have no idea why i have them... but i do

I'll try the suggestions, i do appreciate them!

In the mean time i got an old crystal display working with teensy in about 10 minutes which is a bonus

Little bit weighty i could do with something smaller :p

Well after a bit of tinkering here and there.... I'm VERY CLOSE!

its just going to take alot of tweaking and tinkering to get it perfect when i intergrate into my glove but it seems.... SEEMS to be working much better no false triggers note rings when its greater than threshold and turns off when its less than a threshold

I initially flipped the piezo cables then went with just flipping the entire piezo, put a 5.1v zener in parralel and a 0.1uF cap in hope i can smooth the value off

Its working just needs some fiddling
 
Well after a bit of tinkering here and there.... I'm VERY CLOSE!

its just going to take alot of tweaking and tinkering to get it perfect when i intergrate into my glove but it seems.... SEEMS to be working much better no false triggers note rings when its greater than threshold and turns off when its less than a threshold

I initially flipped the piezo cables then went with just flipping the entire piezo, put a 5.1v zener in parralel and a 0.1uF cap in hope i can smooth the value off

Its working just needs some fiddling

Hi there,

Im trying to get a piezo code working for triggering a kick drum for live shows.

Any chance of helping me out ? :D
 
Sorry .. my bad ..:eek:

Id like to use a piezo (stuck to the bass drum) to send midi notes (velocity sensitive) through to Ableton Live using a digital pin on my teensy ++2

I managed to get the piezo to work with this code :



Code:
int const numDigPins = 40; // number of digital pins to send note values
int currentDig[numDigPins];
int digitalpin[] = {
 0,1,2,3,4,5,41,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,
}; // which digital pins to use for sending note values

int digitalpitch[] = {
51,50,49,48,
55,54,53,52,
59,58,57,56,
63,62,61,60,

64,65,66,67,68,69,
70,71,72,73,74,75,
76,77,78,79,80,81,
82,83,84,85,86,87}; // which midi notes to send from the digital pins selected above
int digInput[numDigPins];

// the MIDI channel number to send messages
const int channel = 1;

void setup() {
  
pinMode(PIN_D6, OUTPUT);
  
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(41, INPUT_PULLUP);  
  pinMode(7, INPUT_PULLUP);
  pinMode(8, INPUT_PULLUP);
  pinMode(9, INPUT_PULLUP);
  pinMode(10, INPUT_PULLUP);
  pinMode(11, INPUT_PULLUP);
  pinMode(12, INPUT_PULLUP);
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
  pinMode(15, INPUT_PULLUP);
  pinMode(16, INPUT_PULLUP);
  pinMode(17, INPUT_PULLUP);
  pinMode(18, INPUT_PULLUP);
  pinMode(19, INPUT_PULLUP);
  pinMode(20, INPUT_PULLUP);
  pinMode(21, INPUT_PULLUP);
  pinMode(22, INPUT_PULLUP);
  pinMode(23, INPUT_PULLUP);
  pinMode(24, INPUT_PULLUP);
  pinMode(25, INPUT_PULLUP);
  pinMode(26, INPUT_PULLUP);
  pinMode(27, INPUT_PULLUP);
  pinMode(28, INPUT_PULLUP);
  pinMode(29, INPUT_PULLUP);
  pinMode(30, INPUT_PULLUP);
  pinMode(31, INPUT_PULLUP);
  pinMode(32, INPUT_PULLUP);
  pinMode(33, INPUT_PULLUP);
  pinMode(34, INPUT_PULLUP);
  pinMode(35, INPUT_PULLUP);
  pinMode(36, INPUT_PULLUP);
  pinMode(37, INPUT_PULLUP);
  pinMode(38, INPUT_PULLUP);
  pinMode(39, INPUT_PULLUP);
  pinMode(40, INPUT_PULLUP);
 
 // Serial.begin(38400);

}

void loop() {
  

// digital pins sending notes
  for (int i = 0; i < numDigPins; i++) {
    if (digitalRead(digitalpin[i]) == 1 && currentDig[i] == 0) {
      usbMIDI.sendNoteOff(digitalpitch[i], 100, channel); 
      currentDig[i] = 1;
    }  
    if (digitalRead(digitalpin[i]) == 0  && currentDig[i] == 1) {
      usbMIDI.sendNoteOn(digitalpitch[i], 100, channel);
      currentDig[i] = 0;
    }  
  }
 


      
  }
  
  while (usbMIDI.read()); // read and discard any incoming MIDI messages
  delay(25); 
}

But the velocity is set to 100 no matter how hard or soft i hit it..
 
You're going to need to use analogRead(), and perhaps some analog circuitry to capture the peak, to detect how hard the drum is hit.
 
You're going to need to use analogRead(), and perhaps some analog circuitry to capture the peak, to detect how hard the drum is hit.

Hey thank you for the reply ... Much appreciated.

That's the code I'm looking for. Do i use normal code for say a potentiometer, and an analog pin for this ?

What is analog circuitry ?
 
Status
Not open for further replies.
Back
Top