i have begun with arduino programming a few weeks ago and last few days i am struggling with SPI.
I am trying to read data from digital microphone ADMP441 (24 bits
via SPI with my arduino.
I sniff communication (look at att jpeg) and it look like that data are generated but i am not able to read them and check them e.g. via serial [ Serial.println(in); ] i get value 0 all the time.
this is my code: #include <SPI.h> // include the SPI library
const byte slaveSelectPin = 10; // digital pin 10 for /CS
void setup() {
I don't think you are communicating with that IC correctly. Here is the online datasheet:
Take a look at page 9. The communication requires 64 bits (8 bytes). The first 4 bytes are for the left channel, and the second 4 bytes are for the right channel, depending on the state of the WS line. The WS line is not the CS line. It should be a separate line. The CS line is not connected to the IC, only the WS line. The WS line should be LOW for the first 4 bytes and HIGH for the second 4 bytes.
edit: And how the IC responds depends on the state of the L/R line. If the L/R line is LOW, it responds during the WS line LOW (first 4 bytes), and if it is HIGH, it responds during the WS line HIGH (second 4 bytes).
If the slaveSelectPin (D10) is connected to the WS line of the IC, I would try this:
thnx for your quick replies. I have to admit, i cannot really simulate I2S via SPI.
I researched timing again and I have decided to make it up in the other way.
SPI.setBitOrder(MSBFIRST); << needs to go after SPI.begin();
SPI.setDataMode(SPI_MODE0); << needs to go after SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV4); << needs to go after SPI.begin();
SPI.begin();
At the same time, those are the default settings, so likely it didn't really hurt the effort.
Trying to do I2C with SPI pins is not the best.
maybe ARDUINO is a bit slow for SPI interface. I am begginer in this area, so Its only my idea.
Does anybody have a clue about some implementation SPI for the board ?
I did not notice the SPI mode was incorrect. You should use mode 3. Clock HIGH and pulsed LOW, capturing data on the rising edge.
SPI.setDataMode(SPI_MODE3);
edit: It may still be OK with MODE0 according to the timing. Print the values returned from these SPI.transfer() calls to see how the data is transferred.
You must do an extra "shift left one bit" to align those bits into a 24 bit value.
I would stick with mode 0 after examining the SPI timing. The SCK line should be LOW when the WS line goes LOW. That is mode 0. The timing diagram was a bit misleading at first glance.
I would try this code. It builds a long variable using the byte values returned in my suggested code above. It shifts left 8 bit places three times, then shifts right 7 bit places once. It will be a 24 bit value in a 32 bit variable.
Thank you very much for hints. But I wasnt successful. :~
Look at output from sniffer.
I used lower SCK freq., cos due to microphone datasheet max. SCK is 3.2 MHz, now is SPI running on 2 MHz.
I have noticed SD output (level H) lasts only 25 ns, isnt it too little ? because I got only 0 values from SpiRead all the time.
(for test i put log. 1 to MISO pin and got 1111...., so code is OK. )
I have generated TEST ouput from ARDU and log. 1 lasted 500 ns.
Are you using a logic level translator between the Arduino and the ADMP441? According to the datasheet, the max input to any pin on that device is 3.3v.
For this moment I have to stop my experiment cos i destroy my ADMP441 =( (today i have a bad day). The other one doesnt work at all. So I will have to order new one.
NOTE: I dont have logic level trans., I have Crowduino model, which can be switched to 3.3V power mode, so i can try it then (with new ADMP441) with this setting.