Serial communication, relative slow?

Hey People, i am making a Drum machine.

And i use Piezo sensor as the drum sensor, and that works great. My problem is that when i hit the drum the sound is a little slower than my hit on the drum :)

I am almost sure that the problem is in the serial communication? But how slow can it be?

You can see my code as following, and see if something is slowing it down? :)

Thanks :)

int sensorPin = 8; int ledPin = 13; int sensorValue = 0; long time = 0;

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

void loop() { sensorValue = analogRead(sensorPin);

//Serial.println(sensorValue);

if (sensorValue > 50 && millis() - time > 40) { digitalWrite(ledPin, HIGH); Serial.write(2); time = millis(); } else { digitalWrite(ledPin, LOW); }

delayMicroseconds(1000);

}

Does sending 64 bytes (instead of one byte) make a difference?

Why does the sending of serial data depend on time? Why are you inducing a delay with delayMicroseconds?

BTW: millis() returns an unsigned long, not a long.

delayMicroseconds(1000);

In that time, you could have transmitted 11 characters.

Slow?
Let’s see…

void loop() {

sensorValue = analogRead(sensorPin);

100 microseconds

 if (sensorValue > 50 && millis() - time > 40) {

+40 miliseconds

delayMicroseconds(1000);

+1 milisecond

= ~41 miliseconds

Freq = 1/0.041 = 24Hz
Nyquist will say this is good to sample a signal <12Hz

Good grave drum :wink:

Delete that time controller, analogRead will limit you to 10Khz by itself.

Oh, a personal question: Why a “Serial.write(2)”? Is it a special number?

Thanks for the fast replying :-)

I am almost sure, that the slowness is in the serial connection..

It is not in the "if millis" because i see the slowness only when the drum was hit and, that would mean only from serial.write(2); to the sound is playing :-)

2 is just a random number i choose ;)

MIDI runs at less than a third this bit-rate. Don't hear too many complaints about MIDI latency.

Oh! Just a sensor! I think I missed :P You mean, then, that it has high latency.... ok, ok :)

@Stampeho: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1290356102/1#1

What patch are you using for drum sound? Maybe the attack phase is so wide.

And delete time=millis() in setup()

I need the millis() in the if(), else my drum "hits" several times becausce then sensor is beyond my treeshold for a longer time that it takes the arduino to run a loop:-(

but i will try to do some of you ideas when i am home from work :-)

btw, i am sorry about my english ;)

And Yes, "Latency" is the word that i was looking for :)

But i have to let the millis() function be there, in the if(); Else does my concept of the whole program, not work :o

This is the best i can do to remove anything:

int sensorPin = 8; int ledPin = 13; int sensorValue = 0; long time = 0;

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

void loop() { sensorValue = analogRead(sensorPin);

if (sensorValue > 50 && millis() - time > 40) { digitalWrite(ledPin, HIGH); Serial.write(2); time = millis(); } else { digitalWrite(ledPin, LOW); }

}

It is a very small latency, but you can feel it when you hit the drum yourself, you can feel/hear the sound is a little late, but still so much that you cant play drums on it. Its a little frustrating when i know all works perfect, the sensor, the arduino code and my java code (on computer). But that stupid latency ...

I hope you can help me, or if i have to delete that millis(); what should i then use?

And "alfonso.nishikawa", i'm not sure that i understand this "What patch are you using for drum sound? Maybe the attack phase is so wide."

As I said:

And delete time=millis() in setup()

and in the last of your post, you deleted it. Very good :)

And now the important question: What drum patch are you using? Do you have the .wav file? The patch is the ripped sound signal :)

Yes i have that :) But i have been cutting it in the beginning (with Audacity), so nothing at the beginning of the wave is "no sound" :)

But here it is http://dl.dropbox.com/u/4696460/SNARE2.wav

How is the "computer part"? Programming language? Sourcecode?

As you see, the SNARE2.wav starts "on a top" :)

I found out that Java openAL was a fast way to play a sample, so we used that: Here is the souce:

import gnu.io.CommPort; import gnu.io.CommPortIdentifier;

import java.io.IOException; import java.io.InputStream;

import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.UnsupportedAudioFileException;

public class playSound {

private CommPortIdentifier comm; private CommPort port; private InputStream os; private DrumAudioPlayer drumPlayer = null;

public playSound() { drumPlayer = new DrumAudioPlayer(); try { comm = CommPortIdentifier.getPortIdentifier("COM12"); port = comm.open("playSound", 30); os = port.getInputStream(); port.setInputBufferSize(1); System.out.println("Connection!"); spilLyden(); os.close(); port.close(); } catch (Exception e) { e.printStackTrace(); } }

public void spilLyden() throws IOException, LineUnavailableException, UnsupportedAudioFileException, InterruptedException { int count=0;

while(true) { if (os.available() > 0) { int foobar = os.read(); //System.out.println(foobar); if (foobar == 2) { System.out.println(count++ + " Bam!"); drumPlayer.snare(); } } Thread.sleep(1); } }

public static void main(String[] args) { new playSound(); }

}

THAT WAS THE MAIN CODE

AND this is the tread which create the sound, and dont ask about that, because i dont know anything about that piece of code:

import net.java.games.joal.; import net.java.games.joal.util.; import java.io.*; import java.nio.ByteBuffer;

public class DrumAudioPlayer {

static AL al = ALFactory.getAL();

// Buffers hold sound data. static int[] buffer = new int[1]; //static IntBuffer[] buffer = new IntBuffer[1];

// Sources are points emitting sound. static int[] source = new int[1];

// Position of the source sound.q static float[] sourcePos = { 0.0f, 0.0f, 0.0f };

// Velocity of the source sound. static float[] sourceVel = { 0.0f, 0.0f, 0.0f };

// Position of the listener. static float[] listenerPos = { 0.0f, 0.0f, 0.0f };

// Velocity of the listener. static float[] listenerVel = { 0.0f, 0.0f, 0.0f };

// Orientation of the listener. (first 3 elements are "at", second 3 are "up") static float[] listenerOri = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };

static int LoadALData() {

// variables to load into

int[] format = new int[1]; int[] size = new int[1]; ByteBuffer[] data = new ByteBuffer[1]; int[] freq = new int[1]; int[] loop = new int[1];

// Load wav data into a buffer. al.alGenBuffers(1, buffer, 0); if (al.alGetError() != AL.AL_NO_ERROR) return AL.AL_FALSE;

ALut.alutLoadWAVFile("SNARE2.wav", format, data, size, freq, loop); al.alBufferData(buffer[0], format[0], data[0], size[0], freq[0]); //ALut.alutUnloadWAV(format[0],data[0],size[0],freq[0]);

// Bind buffer with a source. al.alGenSources(1, source, 0);

if (al.alGetError() != AL.AL_NO_ERROR) return AL.AL_FALSE;

al.alSourcei (source[0], AL.AL_BUFFER, buffer[0] ); al.alSourcef (source[0], AL.AL_PITCH, 1.0f ); al.alSourcef (source[0], AL.AL_GAIN, 1.0f ); al.alSourcefv(source[0], AL.AL_POSITION, sourcePos, 0); al.alSourcefv(source[0], AL.AL_VELOCITY, sourceVel, 0); al.alSourcei (source[0], AL.AL_LOOPING, loop[0] );

// Do another error check and return. if(al.alGetError() == AL.AL_NO_ERROR) return AL.AL_TRUE;

return AL.AL_FALSE; }

static void setListenerValues() { al.alListenerfv(AL.AL_POSITION, listenerPos, 0); al.alListenerfv(AL.AL_VELOCITY, listenerVel, 0); al.alListenerfv(AL.AL_ORIENTATION, listenerOri, 0); }

static void killALData() { al.alDeleteBuffers(1, buffer, 0); al.alDeleteSources(1, source, 0); ALut.alutExit(); }

public void snare() { al.alSourcePlay(source[0]);

}

public void stop() { al.alSourceStop(source[0]); }

public DrumAudioPlayer() { // Initialize OpenAL and clear the error bit.

ALut.alutInit(); al.alGetError();

// Load the wav data. if (LoadALData() == AL.AL_FALSE) return;

setListenerValues();

// Setup an exit procedure.

Runtime runtime = Runtime.getRuntime(); runtime.addShutdownHook( new Thread( new Runnable() { public void run() { killALData(); } } ) ); } }