Hi, I'm attempting something and running into some trouble. I have an micro SD card breakout (the type you can give 5V inputs) and an nRF24L01 antenna. I've gotten both working separately, but now I want to combine them. What I want to do is, read some data off the SD card, then send it to another Arduino with the nRF, and repeat. I'm using a 5V/16MHz Arduino Pro Mini, and I'm selecting the right board/processor/port in the IDE. I have another totally separate circuit that acts as the receiver, which I'm positive is working correctly, as I'll show below. Since I know both the nRF and SD cards can be power hungry, I'm powering everything with an external breadboard power stick, which should be able to supply enough current. There is a 3.3V rail for the nRF, and a 5V for both the Pro Mini and SD breakout.
I've done some reading on multiple SPI devices on the same Arduino, and I think I understand the concept. Basically, you connect both SPI devices to the same MOSI/MISO/SCK pins, but then you have a "chip select" pin for each device, and it seems like chip select pins are usually active low, meaning I have to keep those pins high to keep them off.
All correct so far?
Basically, I'm following this pic:
from this link: https://www.dorkbotpdx.org/blog/paul/better_spi_bus_design_in_3_steps
So I've written to the SD card successfully using the SD library (in one sketch), and I've been able to send info over the nRF to another Arduino (in another sketch), but I can't seem to get them to work at the same time.
Here's a broad overview of what I'm doing (I posted the code below, but this is just to explain it): I made some enable/disable functions for both the SD and RF, where I set their respective chip select pins (3 and 8 ) to low/high (respectively). Then, in the main loop, I have it enable the SD card, open/write/close it, then disable it, then delay for a couple seconds, then enable the nRF, send an integer, disable it, and repeat. I'm not actually using the SS pin as a chipselect pin, but I know you need to set it to output and high, so I've done that too (it's pin 10 on the Pro Mini). I've also added a couple LEDs that should show you when each SPI device is enabled.
Here's my code, trying to do the above:
#include <SPI.h>
#include "RF24.h"
#include <SD.h>
/****************** User Config ***************************/
/*** Set this radio as radio number 0 or 1 ***/
bool radioNumber = 1;
/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7,8);
/**********************************************************/
byte addresses[][6] = {"1Node","2Node"};
unsigned long counter = 1;
const int SLAVESELECTPIN_SD = 3;
const int SLAVESELECTPIN_RF = 8;
const int LEDPIN_SD = 5;
const int LEDPIN_RF = 2;
const int SS_pin = 10;
File myFile;
void enableRF(){
digitalWrite(SLAVESELECTPIN_RF, LOW);
digitalWrite(LEDPIN_RF, HIGH);
Serial.println("Enabling RF...");
}
void disableRF(){
digitalWrite(SLAVESELECTPIN_RF, HIGH);
digitalWrite(LEDPIN_RF, LOW);
Serial.println("Disabling RF...");
}
void enableSD(){
digitalWrite(SLAVESELECTPIN_SD, LOW);
digitalWrite(LEDPIN_SD, HIGH);
Serial.println("Enabling SD...");
}
void disableSD(){
digitalWrite(SLAVESELECTPIN_SD, HIGH);
digitalWrite(LEDPIN_SD, LOW);
Serial.println("Disabling SD...");
}
void setup() {
pinMode(SS_pin, OUTPUT);
pinMode(LEDPIN_SD, OUTPUT);
pinMode(LEDPIN_RF, OUTPUT);
digitalWrite(SS_pin, HIGH);
digitalWrite(LEDPIN_SD, LOW);
digitalWrite(LEDPIN_RF, LOW);
pinMode(SLAVESELECTPIN_SD, OUTPUT);
pinMode(SLAVESELECTPIN_RF, OUTPUT);
disableRF();
disableSD();
Serial.begin(9600);
// enableRF();
radio.begin();
// Set the PA Level low to prevent power supply related issues since this is a
// getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
radio.setPALevel(RF24_PA_HIGH);
radio.setDataRate(RF24_250KBPS);
// Open a writing and reading pipe on each radio, with opposite addresses
if(radioNumber){
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]);
}else{
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1,addresses[1]);
}
// disableRF();
Serial.print("Initializing SD card...");
if (!SD.begin(SLAVESELECTPIN_SD)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
disableSD();
}
void loop() {
int delayms = 4000;
delay(delayms);
enableSD();
Serial.println("Writing to SD...");
myFile = SD.open("test.txt", FILE_WRITE);
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing 1, 2, 3.");
// close the file:
myFile.close();
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
disableSD();
delay(delayms);
enableRF();
delay(50);
Serial.print("Sending over RF...");
unsigned long msg = counter;
radio.write(&msg, sizeof(unsigned long) );
Serial.print("Sent ");
Serial.println(msg);
disableRF();
counter++;
} // Loop
When I upload and run it, here's the serial output:
Initializing SD card...initialization done.
Writing to test.txt...done.
Disabling SD...
Enabling SD...
Writing to SD...
Writing to test.txt...done.
Disabling SD...
Enabling RF...
Sending over RF...Sent 1
Disabling RF...
Enabling SD...
Writing to SD...
Writing to test.txt...done.
Disabling SD...
Enabling RF...
Sending over RF...Sent 2
(It writes to the SD card before the loop starts, so that's why there are two at the beginning.)
However, I'm getting nothing on the receiver Arduino/nRF.
Now, here's a clue... if I remove the SD card and breakout, and leave everything else exactly the same, and restart the sketch... the nRF successfully sends!
Initializing SD card...initialization failed!
Enabling SD...
Writing to SD...
error opening test.txt
Disabling SD...
Enabling RF...
Sending over RF...Sent 1
Disabling RF...
Enabling SD...
Writing to SD...
error opening test.txt
Disabling SD...
Enabling RF...
Sending over RF...Sent 2
Disabling RF...
And it appears on the other Arduino.
So it's pretty clear that one is interfering with the other, and it seems like the SD card takes precedence when they're both there. I also hope these two cases (SD module in, SD module out) demonstrate that my wiring is correct, because the SD card works in the first case, the nRF works in the second.
This document (warning, pdf) http://www.diyembedded.com/tutorials/nrf24l01_0/nrf24l01_tutorial_0.pdf says, regarding the nRF's CSN pin:
The third pin is CSN, which stands for chip select not. This is the enable pin for
the SPI bus, and it is active low (hence the “not” in the name). You always want to keep
this pin high except when you are sending the device an SPI command or getting data on
the SPI bus from the chip.
However, I really don't know what's making the nRF not work when the SD card is in there. If I had to guess, I'd say that one of the chip select pins isn't working correctly, or my enable/disable functions are doing something redundant (for example, maybe when you do radio.write(), it automatically makes the nRF CSN pin go low, so I don't need to manually, or it would mess it up or something.
Is there something simple I'm missing? I think it's almost there. Thanks in advance.