STM32 Read mic value (MP34DT05-A) from I2S DMA - stm32

I want to read MEMS microphone (MP34DT05-A) value (in ASCII) from STM32F107 board. I'm using I2S to communicate with the microphone.
What I did:
I tried simple reading with HAL_I2S_Receive_DMA(&hi2s3, i2sbuffer, 100); which uint16_t i2sbuffer[256]; and the result is random character (E⸮h2FI⸮g⸮⸮F⸮⸮⸮).
I'm using PDM_Filter from pdm2pcm_glo.h (STM32_Audio\Addons\PDM library):
HAL_I2S_Receive_DMA(&hi2s3, pdm_buff, 16);
PDM_Filter(&cbuff[0], &pcm_buff[0], &PDM1_filter_handler);
and the result still random character (d⸮⸮l⸮巳⸮N#⸮&6⸮4q٣⸮#⸮d⸮ɻ&⸮}⸮).
Should I need conversion for the data? Or I did something wrong?

A PDM microphone does not output ASCII!
The PDM microphone outputs a sequence of 1-bit values.
The function PDM_Filter converts it to PCM, which is a sequence of 16-bit values, still in binary.
To print the 16 bit sequence as text, you would need to do something like:
printf("%hi,", pcm_buff[0]);
printf("%hi,", pcm_buff[1]);
...
but obviously you can use a loop.

Related

Transmitting I2S mic data over UART in STM32

I have interfaced I2S mic (ICS-43434) with STM32f401RET6 board.
I have wired it correctly, now just trying to test the mic by passing the data through UART to my pc. Hoping someone can point me in the correct direction.
I have tried passing straight to the UART transmit. However I think I may need some datahandling - I am receiving from the UART, but sometimes just 0 or other times just gibberish which is not from the Mic as it still transmits even when i disconnect the mic.
I2S mic is receiving data in 24 bits in 32 bit frame, the last 8 bits are junk. The protocol is Big Endian, I am thinking that the HAL library handles this, however I am not completely sure.
uint16_t data;
while (1)
{
/*USER CODE END WHILE */
HAL_StatusTypeDef result= HAL_I2S_Receive(&hi2s1,&data,2,100);
HAL_UART_Transmit(&huart3,&data,2,100);
/*USER CODE BEGIN 3 */
}
/*USER CODE END 3 */
What did I miss?

How computers can receive data quickly?

In computer networks, we are trying to increase the transmission speed of data. Since data is nothing but electrical signals. How these electric signals can be converted into bits so quickly? This conversion is done by ADC - DAC. We can’t control the speed of computation of ADC then how can we translate the electric signals to bits so quickly. Next, Is this ADC integrated in our computer chipset?
Also, does it mean that every peripheral has ADC. For example, NIC card will have ADC. Is the information carried in the LAN cable like CAT 5, 6 are analog in nature?
You clock bits in by detecting a rising edge on a signal wired up to one of the pins of your chip. Then the rise lasts for a certain period of time, but only a fraction of a millisecond. There's a bit of tolerance so sender and receiver don't have to be exactly synchronised. The chip then transfers the bit to a buffer in very low level code. When it has a byte, slightly higher level code transfers the byte to another buffer, then the next level is user level - we have a stream of input bytes.
Whilst the wire is of course analogue, that is not analogue to digital conversion. Analogue to digital conversion is where we measure the signal, quantise it, then create a binary representation in place value notation.

serial communication beteen arduino and MATLAB

I'm currently working on my final year study project , i'm using arduino due and the ultrasonic sensors which are placed on a wheelchair to make an autonomous one.
so my problem is that i'm reading the distances from the sensors and i need to send them tomatlab simulink to use them in the fuzzy logic controller block but i can't because what i'm sending in the serial monitor from ardiuno is something like "
#distance1#distance2#...#distance10# " which is a string type,so how can i get the data (distances) using serial port to use them in matlab simulink.
Do i have to change the arduino code or should i use some block in simulink?
any response might be helpfull
You need to parse the input, based on the delimiter, and decide you often you should sample the sensor.
You want your input to be split at the hash. You should use something like:
str = input; % from arduino buffer
delimiter = "#";
C = strsplit(str,delimiter)
C = int(C) % type case to an int
You probably should read every 5th signal based on the frequency of the sensor. If the sensor takes 100 measures per second you probably only need 20 to be processed. This looks like:
C = C[1:5:end]
Maybe...
Processing the signal you might want to use error std from the data sheet of the sensor somewhere. Parse the input probably either before it gets passed into simulink, or as one of the first blocks. It is kind of up to you (I don't know if there is a best practise).
I hope that helped!
The docs for str split is here:
http://au.mathworks.com/help/matlab/ref/strsplit.html

Receiving the right value when transmitting .dat file using FM radio

I am new to GNU Radio and I'm trying to transmit a value using it and the USRP B210 board.
I used Matlab to convert the value 0.121 to wav format then convert the wav file to .dat file using audio_to_file example in GNU Radio.
When I transmit the .dat file using the B210 and GNU Radio, I received a wav file but when I read the wav using matlab function (audioread()) I get a different value.
P.S.
Sample rate for the converted .dat file was 44100 Hz and 16 bits per sample.
The receiver and transmitter sampling rate is 400K Hz.
I used fm_tx4.py example from the GNU Radio package for my transmitter.
I used uhd_nbfm_receiver.grc for the receiver.
If you're wondering why your received signal doesn't have the same amplitude as your sent signal, you're not getting the very basics of radio communications: as there is no digital line between your transmitter and your receiver, power can go anywhere, and how much reaches the receiver depends on a lot of factors, including gain, antennas, distance, matching...
There will be a lot more things that are different on the RX side than they were on the TX side: Your reception has not been time-synchronized, so you might see a phase shift. You don't mention whether the receiver is the same, a clock-synchronized or an clock-independent B210, which means you have the general case, where no two physical clocks can be identical (yes, that's impossible, but you can reduce errors), so you'll generally see some frequency offset, too.
I recommend reading up a bit on basic radio comm theory, I often recommend GNU Radio's pictured introduction, and GNU Radio's suggested Reading Page. Michael Ossmann gets some recognition for his courses, too, so you should definitely have a look at them.
Also, all your data->Wav->transmit conversion is totally unnecessary. Matlabs fread/fwrite functions can read/store the native machine float format that GNU Radio's file_sink/file_source can store/read. See the FAQ entry.

Playing sound in Matlab at +30dB

As far as I know when I load wav files to matlab with command:
song = wavread('file.wav');
array song have elements with values from -1 to 1. This file (and hardware) is prepared to be played with 80dB. I need to add +30dB to achieve 110dB.
I do +10dB by multiplying by sqrt(10), so to get +30dB I do:
song = song*10*sqrt(10); which is the same as
song = song*sqrt(10)*sqrt(10)*sqrt(10);
Now values of array song have much greater values than -1 to 1 and I hear distorted sound.
Is it because of this values greater than <-1,1> or quality of my speakers/headphones?
The distortion is because your values are exceeding +/-1. The float values are converted to ADC counts, which are either +/-32768 (for a 16-bit ADC) or +/-8388608 (for a right-justified 24-bit ADC) or +/-2147483648 (for a left-justfied 24-bit ADC). For a 16-bit ADC, this is usually accomplished by an operation like adcSample = (short int)(32768.0*floatSample); in C. If floatSample is > +1 or < -1 this will cause wraparound in the short int cast, which is the distortion you hear. The cast is necessary because the ADC expects 16-bit digital samples.
You will need to adjust your amplifier/speaker settings to get the sound level you desire.
Conversely, you could create a copy of your file, lower it by 30 dB, adjust your amplifier/speakers to play the new file at 80 dB, then play the original file at the same amp/speaker settings. This will cause the original file to be played at 110 dB.
As Paul R noted in his comment, I am guessing here that you are using dB as shorthand for dB SPL when referring to the actual analog sound level produced by the full signal chain.