Go Down

Topic: Piezo MIDI Drums (Read 4294 times) previous topic - next topic

rikardo

Hi I could use some help.
I have simple MIDI drums based on piezo sensors. I use this code:

int piezo1 = A0;
int piezo2 = A2;
int piezo3 = A4;
int piezo4 = A6;
int piezo5 = A8;
int threshold = 500; 
int sensorReading = 0;
int val,oldcas;

void setup() {

 
  pinMode(piezo1, INPUT);
  pinMode(piezo2, INPUT);
  pinMode(piezo3, INPUT);
  pinMode(piezo4, INPUT);
  pinMode(piezo5, INPUT);
  Serial.begin(57600);     

}

void loop() {

  //////////////////CRASH////////////////

  sensorReading = analogRead(piezo5);

  if( sensorReading > threshold ) {
    oldcas = millis()+5;
    while(analogRead(piezo5) > threshold)
    {
      if(millis()==oldcas)
      {
        val = analogRead(piezo5) / 8;
      }
    }
   
    MidiTX(144, 1, val);
    MidiTX(128, 1, val);
  }
 
  //////////R-TOM////////////////////
 
    sensorReading = analogRead(piezo4);

  if( sensorReading > threshold ) {
    oldcas = millis()+5;
    while(analogRead(piezo4) > threshold)
    {
      if(millis()==oldcas)
      {
        val = analogRead(piezo4) / 8;
      }
    }
   
    MidiTX(144, 2, val);
    MidiTX(128, 2, val);
  }
 
  ///////////////SNARE////////////////
 
    sensorReading = analogRead(piezo3);

  if( sensorReading > threshold ) {
    oldcas = millis()+5;
    while(analogRead(piezo3) > threshold)
    {
      if(millis()==oldcas)
      {
        val = analogRead(piezo3) / 8;
      }
    }
   
    MidiTX(144, 3, val);
    MidiTX(128, 3, val);
  }
 
  ///////////////L-TOM/////////////
 
    sensorReading = analogRead(piezo2);

  if( sensorReading > threshold ) {
    oldcas = millis()+5;
    while(analogRead(piezo2) > threshold)
    {
      if(millis()==oldcas)
      {
        val = analogRead(piezo2) / 8;
      }
    }
   
    MidiTX(144, 4, val);
    MidiTX(128, 4, val);
  }
 
  //////////////HI-HIT/////////////////
 
 
    sensorReading = analogRead(piezo1);

  if( sensorReading > threshold ) {
    oldcas = millis()+5;
    while(analogRead(piezo1) > threshold)
    {
      if(millis()==oldcas)
      {
        val = analogRead(piezo1) / 8;
      }
    }
   
    MidiTX(144, 5, val);
    MidiTX(128, 5, val);
  }
}

void MidiTX(unsigned char StatusByte, unsigned char Note, unsigned char Val)
{
  Serial.write(StatusByte);
  Serial.write(Note);
  Serial.write(Val);
}

with virtual MIDI port loopbe1 , Serial - MIDI converter V2D (by Mark Demers - Spikenzielab.com) and Battery 3 as sample player. but audio from battery is delayed. I tryed another SW with Battery 3 ( Maple Virtual Midi Cable as virtual midi port and Hairless MIDI<->Serial Bridge as converter ) but ther is still delay.

where is problem??

marco_c

#1
Apr 23, 2013, 09:49 pm Last Edit: Apr 23, 2013, 09:52 pm by marco_c Reason: 1
I have tried to simplify the code to make it easier to debug. I have created a function that does everything your code was repeating once to avoid cut an paste and make things more consistent.

Code: [Select]
#define  MAX_PIEZO  5

uint8_t piezo[MAX_PIEZO] = { A0, A2, A4, A6, A8 };
uint8_t drumType[MAX_PIEZO] = { 5, 4, 3, 2, 1 };

const int threshold = 500;  

void setup()
{
 for (uint8_t i=0; i<MAX_PIEZO; i++)
   pinMode(piezo[i], INPUT);

 Serial.begin(57600);      
}

void MidiTX(unsigned char StatusByte, unsigned char Note, unsigned char Val)
{
 Serial.write(StatusByte);
 Serial.write(Note);
 Serial.write(Val);
}

void ProcessPiezo(uint8_t p)
{
 uint16_t sensorReading = analogRead(piezo[p]);
 uint16_t  val;

 if (sensorReading > threshold)
 {
   uint32_t oldcas = millis() + 5;
   
   // this part of the code looks complex
   // explain what you are trying to do?
   while (analogRead(piezo[p]) > threshold)
   {
     if (millis() >= oldcas)
     {
       val = analogRead(piezo[p]) / 8;
     }
   }
   
   MidiTX(144, drumType[p], val);
   MidiTX(128, drumType[p], val);
 }
}

void loop()
{
 for (uint8_t i=0; i<MAX_PIEZO; i++)
   ProcessPiezo(i);
}


So the question is what do you mean by delay? How long? milliseconds, seconds, minutes?

There is a 5ms delay built into you code when you detect a value > threshold, but I imagine that you don't mean that.
Your code also used int for a millis() value instead of unsigned long, so I changed that. In some cases that could have caused delays until the counter wrapped around again.

Try what is there now, verify that you still have a problem and then give us more details.

You can also try to capture the output using the serial monitor on the computer (avoid all the MIDI) and if the message is there instantaneously, you knoew the delay is after that in the MIDI software chain on the PC.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

rikardo

#2
Apr 24, 2013, 05:14 pm Last Edit: Apr 24, 2013, 05:30 pm by rikardo Reason: 1
by delay I mean time between hitting the drum pad and sound from PC.
yep, I tryed serial monitor and problem seems to be in MIDI chain in PC
and it cannot be fixed easy i think :D I tryed combinaton of more SW but nothig worked :/

thanks anyway :)

and one more problem, why it doesnt work with two midi msg at the same time? when i hit 2 pads simultaneously, plays only one or none.

marco_c

Quote
why it doesnt work with two midi msg at the same time?


Probably because of the 5ms delay waiting for the dignal. If you hit botrh at the same time one will be registered and the other has probably disappeared by the time you have finished checking and sent the messge out the port.

To fix this you would have to rewrite the functions without delay statements. One approach may be to just remove the delay you have now and just see if that works better.
Arduino libraries http://arduinocode.codeplex.com
Parola for Arduino http://parola.codeplex.com

lordcpx

Hey, i've created an alternative to MIDI, using only USB connection for a Homemade electronic drums. Check it out:

http://www.youtube.com/watch?v=sc2j7o7XtIQ

Go Up