How manage multiples modules with SPI?


I’m a recent Arduino’s user. I’m French, and perhaps not a English master…
I’m trying to build a weather station.

I’m using a UNO-smd-R2 with a Sparkfun SD-shield and a barometric pressure captor MPL115A1.
The both compoments use the SPI. They are running perfectly, but when try to gather the both, SD-shield and MPL115A1, this last one is inactive, sending false values.

My outline is this following:

           D13  D12  D11  D10  D9  D8    D7   D6   D5    D4   D3   D2
MPL115A1   SCK  SDO  SDI  ___  SDN  ___  ___  ___  ___  CS_  ___  ___ 
SD-Shield  CLK  MISO MOSI___  ___  CS    ___  ___  ___  ___  ___  ___

I decided to avoid the pin 10 which is the internal ChipSelect from de ArduinoBoard. I don’t know if it’s a good choice or good understanding? I understood the ArduinoBoard must stay the master shield…
In my scketch, I delcared the chipselects PINs, D4 and D8 in Output for the initialization : digitalWrite(CS_PIN, output);. When I want to control and read the MPL115A1, I switch the SD-shield chipselect on a High level : digitalWrite(CS_PIN, high)

I had the scketch in the attachment, if someone can help me to understand, find the good way or my mistakes, I will be so grateful.

And sorry again if my English translation is not so well…

Moderator edit: [code][/code] tags added. (Nick Gammon)

SecondStep.ino (12.4 KB)

You do not need to disable the SD SPI. It is handled by the SD library transfer routines. Your sketch does the same here:

unsigned int readRegister(byte thisRegister) {
    byte result = 0;
    // select only the MPL115A1
    digitalWrite(MPL115A1_SELECT_PIN, LOW);

// you shouldn't do this
//    digitalWrite(SD_CS_PIN, HIGH);
    // send the request
    SPI.transfer(thisRegister | MPL115A1_READ_MASK);
    result = SPI.transfer(0x00);
    // deselect the MPL115A1
    digitalWrite(MPL115A1_SELECT_PIN, HIGH);

// you shouldn't do this
//    digitalWrite(SD_CS_PIN, LOW);
    return result;  

writeRegister() is the same. All you need to do is insure both are disabled at the end of your setup function. Leave those pins alone once in loop().

edit: I modified the code to fit traditional slave select pin settings. Each library takes care of its own.


Thanks for your advices.
I used it, but the MPL115A1 didn’t work. I was frustrated, and I decided (I don’t know why) to play with the chip select from the serial monitor. When I withdraw the connection from the D4 (CS MPL115A) the measurement changed. The values were not correct, but different. Also, I decided to withdraw the VCC pin (3,3V) just to know if the sensor was shutdown or enable…

It’s just unbelievable, it’s running perfectly now!!! without vcc!!! ??? I don’t know why…

I’m going to read again and precisely the datasheets…

I added some pix in the attachment.

I’m wondering if my alunimun support is not the reason of this malfunction? perhaps that create an electric connection between the different boards… I’ll inform you about my research…

Thanks so much.

I wouldn't do that. Running it without VCC is running the chip off parasitic power derived from the data lines. That won't be good for it. Solve the problem instead.

I agree with SurferTim. Fiddling with the CS for the SD card in the readRegister function is completely the wrong place for it. Leave those lines out.

If you look at their diagram on page 10 of the datasheet, I would not be lowering and raising CS for the barometer for each reading.

Put the CS stuff around all this:

    writeRegister(0x24, 0x00);      // Start Both Conversions
    //writeRegister(0x20, 0x00);    // Start Pressure Conversion
    //writeRegister(0x22, 0x00);    // Start temperature conversion
    delay(2);                       // Max wait time is 1ms, typ 0.8ms
    // Read pressure
    uiPH = readRegister(PRESH);
    uiPL = readRegister(PRESL);
    uiTH = readRegister(TEMPH);
    uiTL = readRegister(TEMPL);

And don't change it in writeRegister or readRegister. Of course all that could be simplified now:

    digitalWrite(MPL115A1_SELECT_PIN, LOW);
    SPI.transfer (0x24 & MPL115A1_WRITE_MASK);
    SPI.transfer (0x00);
    digitalWrite(MPL115A1_SELECT_PIN, HIGH);
    delay(1);                       // Max wait time is 1ms, typ 0.8ms
    digitalWrite(MPL115A1_SELECT_PIN, LOW);
    SPI.transfer (PRESH | MPL115A1_READ_MASK);
    uiPH = SPI.transfer (0x00);
    SPI.transfer (PRESL | MPL115A1_READ_MASK);
    uiPL = SPI.transfer (0x00);
    SPI.transfer (TEMPH | MPL115A1_READ_MASK);
    uiTH = SPI.transfer (0x00);
    SPI.transfer (TEMPL | MPL115A1_READ_MASK);
    uiTL = SPI.transfer (0x00);
    digitalWrite(MPL115A1_SELECT_PIN, HIGH);

Tip: Might be nice to have a define for 0x24, since you have ones for all the others. :slight_smile:

Also, I decided to withdraw the VCC pin (3,3V) just to know if the sensor was shutdown or enable...

Why not run it at 5V to be compatible with the Arduino?


thanks so much Nick.

I completly agree with you, and i stoped really quickly to run without vcc yesterday.
I need to use your advices for my scketch but I think having found the gulty...

With Vcc=5V all captors run correctly. At the beginning I decided to use the better voltage for the MLP115A1 and the SHT15. 3,3V was the better level to reduce the consuption. But now, when I control the voltage, I find 4,3V!!! and it's also the same voltage on the SD-shield and the Arduino Board. I know that 3,3V is using by the SD-card, and in fact I have some regularly problems to establish the communication with the card...

In brief, in think the regulator 3,3V on the Arduino board is defective... that can explain all events...

What do you think about my supposition? I have also some doubts about the SD-shield...

Have a good weekend.

From the Uno hardware reference:

3V3. A 3.3 volt supply generated by the on-board regulator. Maximum current draw is 50 mA.

The Mega is the same.

Are you using more than 50ma on those devices?

For me I'm really far from this treshold...

From the different datasheets, the consumption of the both captors is really weak: MPL115A1(10µA Max) & SHT15(25µA Max).
About the SD-shield Sparkfun, I don't know.
For me the current level is not the problem, at the beginning I used the project directly on the USB plug. Now, I'm using a new 9V battery, just to avoid a degradation on my computer...

Currently, my project is running correctly, but I need to use the 5V.

In brief, in think the regulator 3,3V on the Arduino board is defective... that can explain all events...

Try measuring the 3.3V pin with nothing connected. I doubt it is defective.

Of course, without sensors, the arduino board and the SD-shield offer exactly 3,3V!!!
When I reconnect my captors on the pin 3,3V, the voltage rise to 4,3V.
I remember previous Mr Gammon's replie, I've probably a parasitic power which is derived from the data lines... But, is it dangerous? With the 5V source, the running looks completely normal...

I've a another problem now.
I made a test during this weekend. I ordered a measurement per minute and the 9V battery worked only during 5 hours!!! I'm going to use the shutdown on the MLP115A1, after each measurement, the SHT15 is switch on sleeping mode. Finally I would like to reduce the consumption from the Arduino board. Do you know how can I do?