Input for Audio Shield

Status
Not open for further replies.
Hi all,

First of all my congrats for this massive forum full of interesting projects!
I have a pretty dumb question to ask but looking all over the forum and internet I was not able to find the answer...

I want to listen an I2C sensor. I have already managed all the connections and I can read the value that I want to send to the audio shield.
My question is: there is a way to send the data from my sensor directly as output?

My configuration now is the following:
Untitled.png

Right now i'm using buffer option, but this cause first of all a delay and also a weird sound.

Can you help me?
I'm a newbie in sound generation and I'm stuck at this point!
 
Last edited:
Is a LIS3DH accelerometer, I want to use it as a mic in a special application.
For understand how it sounds I want to stream a single axis value out from the headphones through the Audio Shield.
 
I'm having some difficulty understanding how accelerometer data should be audio. Can you explain this?

Weird sound makes sense, if data that is not audio is run through digital to analog conversion, the result is often... "static" or " noise" .

I can only guess that you wish to translate the accelerometer data into a synthesized tone...and that would indeed require a few cpu cycles.
 
The vibration captured by an accellerometer is like a piezo signal generated by pickup or a microphone.
I'm saying so because I've tried to "hear" an analog accelerometer (output through a level adapter and preamp). I would like to do the same but with a digital one, but I'm obtaining only a weird metallic noise.

My problem now is that is not clear how I can stream a value straight out from the audio shield. Using the buffer is creating a weird metallic sound, even using filters.

Have you ever tried to stream as output a variable generated by the sketch?
 
I believe I understand what you're trying to do.

From your configuration information I assume the output you are getting from the accelerometer is analog and being received by the ADC1 object.

Based on your configuration, it appears to me that the output of the audio shield is simply converting what it has been given. If this is not what you expect, then it is possible that the sensor does not output an " audio - like " signal in the manner of a piezoelectric pickup.
 
Sorry the image can lead to misunderstanding. My sensor is the "QUEUE1" because I'm getting the raw data and then use it for fill a buffer.
The ADC is for something else, that is not used now.

Here attached my sketch!
 

Attachments

  • accsensfusion_v1_beta.ino
    1.8 KB · Views: 65
The digital output of the sensor is not audio data. The audio shield is attempting to convert data that is no longer analogous to a pickup. This is why you are hearing a "metallic" noise.
 
I can ensure you that the analog accelerometer works fine and is audible, because the sound is vibration, is the same concept as the MEMS Mic.
There are even studies about using the smartphone accellerometers as mics, and NASA is using the same sensor for "hear" the health of the Mars rover.

The metallic sound I guees is related to the buffer filling, for sure I coded it wrong, because is not circular: looks like that the sound is refreshing every X milliseconds and it is not continous, therefore I have this Phaser sound.

The question is: I have an int variable and I want to stream it out via the Audio Shield. How should I do it? I must use the queue object or there is something else?
 
I have read your code. I have read the datasheet for the sensor.

Once again, the audio shield is playing what you are sending it. What you are sending it may not be what you wish for it to be.

There are numerous possibilities as to why. Data transmission rates via i2c could be quantizing the data. Perhaps try increasing the i2c clock rate from default.
 
That's done in the initialization of the wire library, which in this case that's happening in the adafruit library.

Looking into that, I'm not *seeing* a call to 400khz for the wire library...

This is done by Wire.setClock(400000); and while it may be there... I don't see it.
Try adding the line to your setup
 
I've tried as suggested but without luck. The I2C now is 400Khz and the sensor can read up to 5Khz.
I've looked the output of the headphone jack with the oscilloscope and looks like that I have only the positive edge of the wave, cutting all the negative, and also I have an half second response time.

The output of the sensor is this one:
Untitled.jpg

If this will be my output, I should hear an humm, or something similar. Maybe a buzz. Not a metallic slow refreshed sound... Am I right?

Here is after I tap on the table:
Untitled.jpg

I really don't know what is wrong.
 
I'm not sure but it may be that something in between is taking processor time, possibly in the sensor library, which is trying to provide service to all potential uses.

You might have better results in writing "bare metal" code to access the specific register in the sensor as fast as possible with no other tasks in between the read and write.

I can't speak to possible interference in the queue object as I honestly have never looked at that code. There is however a lot of things going on in the sensor library that you may not require for your use.

Hopefully someone else with more coding skill decides to speak up here.
 
@theczar1987
A few few remarks concerning your code:

The queue is 128 words(samples) long, not 256!

In your code the queue1.playBuffer() command is executed once per loop/sample. It should only be executed once every 128 samples.

You need to read your sensor at the same sample rate as the audio lib.
 
It can be, but is something in between the raw data acquisition and the streaming. Because the plot looks to me quite accurate, is not losing samples.
Thanks anyway for the quick answers and for the help man! I appreciate that!
 
@theczar1987
A few few remarks concerning your code:

The queue is 128 words(samples) long, not 256!

In your code the queue1.playBuffer() command is executed once per loop/sample. It should only be executed once every 128 samples.

You need to read your sensor at the same sample rate as the audio lib.

Thanks Neurofun!
I've moved the queue1.playBuffer() like this:
Code:
 sens_fusion_out = ((lis.x * GAIN_X) + (lis.y * GAIN_Y) + (lis.z * GAIN_Z));
  Serial.print("OUTPUT: "); Serial.println(sens_fusion_out);
  Serial.println();

  //sine1.frequency(sens_fusion_out);
  
  uint16_t *temp = queue1.getBuffer();
  bufr[i] = sens_fusion_out;
  /*Serial.print("BUFFER: "); Serial.print(bufr[i]);*/ Serial.print("   BUFFER COUNT: "); Serial.println(i);
  i++;
    
  memcpy(temp, &bufr, 256);

  if(i > 256){
    Serial.println("PLAY!");
    queue1.playBuffer();
    i = 0;
  }

But now is not playing nothing.
About the sync between the audio lib and the sensor lib I'm totally agree with you, but in theory the slowest should not prevail?
Thanks a lot to everybody!
 
THANKS NEUROFUN!

Now I'm superclose to the effect that I want obtain but the audio starts only if I open the serial monitor...
Why is doing so?
 
while (!Serial)

( I think it's relatively safe to comment out that whole line it's there to halt execution until you open the serial monitor)
 
OK, I´m with you concerning using the accelerometer as acoustic Sensor (in fact it is an old concept: keyword vector-sensor)

Assume you tell the LIS3DH to sample at 5.376 kHz then you should retrieve the data with the same velocity. As you read x,y,z your "fetch rate" should be 3time higher, right?
Also you should reprogram the audio card for the same data rate instead 44.1 kHz 3x5.376 kHz or using an interpolating filter.

Not sure if you have access to SPI mode, but you were indicating I2C, so you should program the accel acquisition to be slaved to LIS3DH, which is running in free continuous mode.

as soon you fill a audio buffer, you must issue a global update of the Audio engine.
 
It's still unclear to me how this is going to work. The clocking and update period of the Audio library's objects is ~44.1 KSamples/s. In this instance that period is set by the AudioOutputI2S object which is the only one present that can have update_responsibility.

There is no way your I2C sensor can maintain that sample rate (and even if it could, the I2C sampling is asynchronous to the Audio library's sampling). So, you're starving the AudioOutputI2S object for input. The result has to be some type of distortion. You'd have to rewrite the AudioOutputI2S object whose clocking is based on the F_CPU. But I still don't know how you'd synch it with the I2C sampling.

The whole thing doesn't seem to be thought out very well.
 
It's still unclear to me how this is going to work. The clocking and update period of the Audio library's objects is ~44.1 KSamples/s. In this instance that period is set by the AudioOutputI2S object which is the only one present that can have update_responsibility.

There is no way your I2C sensor can maintain that sample rate (and even if it could, the I2C sampling is asynchronous to the Audio library's sampling). So, you're starving the AudioOutputI2S object for input. The result has to be some type of distortion. You'd have to rewrite the AudioOutputI2S object whose clocking is based on the F_CPU. But I still don't know how you'd synch it with the I2C sampling.

The whole thing doesn't seem to be thought out very well.

That is the nice thing on Teensy, nearly everything is possible.
e.g.: you can easily write an audio object that controls the update rate, or modify the sampling rate of I2S chips.
The question that I2C sampling is not synchronous to Audio library sampling is void, as input data can be buffered and audio library can be modified or augmented.
I´m not saying it is a beginner´s job, but IMHO, it can be done.
 
The question that I2C sampling is not synchronous to Audio library sampling is void, as input data can be buffered and audio library can be modified or augmented.
I didn't say that the input/output sampling needs to be Phase synchronous. As you stated, that's easily handled with a FIFO buffer. But, the sampling rate at the input (i.e. from the I2C device) must be exactly Frequency synchronous to the sampling rate at the output (i.e. to the I2S DAC). Otherwise, the buffer will either overrun or underrun.

I'm just not sure how you would go about achieving uniform sampling from the I2C at EXACTLY the same rate as your sending samples to the I2S.

You might fix that with a re sampling algorithm. Or, you could get the two rates "close enough" with the buffering problems. Either solution would probably produce artifacts and I don't find either very satisfying.
 
I didn't say that the input/output sampling needs to be Phase synchronous. As you stated, that's easily handled with a FIFO buffer. But, the sampling rate at the input (i.e. from the I2C device) must be exactly Frequency synchronous to the sampling rate at the output (i.e. to the I2S DAC). Otherwise, the buffer will either overrun or underrun.

I'm just not sure how you would go about achieving uniform sampling from the I2C at EXACTLY the same rate as your sending samples to the I2S.

You might fix that with a re sampling algorithm. Or, you could get the two rates "close enough" with the buffering problems. Either solution would probably produce artifacts and I don't find either very satisfying.

I hate when I reread my posts, find errors, and the window has closed on being able to edit it:

I didn't say that the input/output sampling needs to be Phase synchronous. As you stated, that's easily handled with a FIFO buffer. But, the sampling rate at the input (i.e. from the I2C device) must be exactly Frequency synchronous to the sampling rate at the output (i.e. to the I2S DAC). Otherwise, the buffer will either overrun or underrun.

I'm just not sure how you would go about achieving uniform sampling from the I2C at EXACTLY the same rate as you're sending samples to the I2S.

You might fix that with a re sampling algorithm. Or, you could get the two rates "close enough" and live with the buffering problems. Either solution would probably produce artifacts and I don't find either very satisfying.
 
Status
Not open for further replies.
Back
Top