I have built two devices to record sensor data and communicate with each other using NRF24L01+ Trancievers.
One of them is only a sensor and a radio. The other has an LCD screen, RTC and an SD Card.
The following code will only let the SD card or the NRF function, but will not switch between the two during program operation.
With this code, if I remove only the SD card's MISO wire, the NRF functions properly and transmits the humidity value from one device to the other. If I reconnect the MISO wire the device no longer recieves data from the other, but it does write to the SD file correctly.
I have seen numerous posts about this which indicate this is a flaw in the IDE's SD library and that using the SDFat library should solve the problem on its own. I have done this, there is still something missing in my code that is preventing the two from toggling back and forth.
There is also the hardware solution of using a tri-state buffer, but I am hoping there is a software option here.
Can anyone reccomend a fix?
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "DS3231.h"
#include <LiquidCrystal.h>
#include <SdFat.h>
#define SD_CS 45
#define RF_CE 48
#define RF_CSN 47
#define RF_SS 53
RTClib RTC;
Adafruit_BME280 bme; // I2C
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
RF24 radio(RF_CE, RF_CSN);
SdFat SD;
const byte thisSlaveAddress[5] = {'R','x','A','A','A'};
bool RFON = false;
bool newData = false;
int dataReceived;
int adc_key_in;
unsigned long ReportMillis;
unsigned long ReportInterval = 30000;
int Temp;
int Z1Hum;
int Z2Hum;
int ExtHum = 0;
//===========
void setup() {
Serial.begin(9600);
//SPI PIN MODES
pinMode(RF_SS, OUTPUT);
pinMode(SD_CS, OUTPUT);
lcd.begin(16, 2);
Serial.println("LCD Start");
//BME Sensor
bool status;
status = bme.begin(0x76);
if (!status) {
Serial.println("BME Fail");
}else{
Serial.println("BME Start");
}
SDStart();
RFStart();
}
void loop() {
if (RFON == false) RFStart();
if (millis() - ReportMillis > ReportInterval){
SDStart();
RecordReport();
RFON = false;
ReportMillis = millis();
}
TestDisplay();
MonitorTempHum();
ReadRadio();
RadioData();
}
void ReadRadio() {
if (radio.available()) {
radio.read( &dataReceived, sizeof(dataReceived));
newData = true;
}
}
void RadioData() {
if (newData == true) {
newData = false;
Z2Hum = dataReceived;
}
}
void RecordReport(){
DateTime LogNow = RTC.now();
int Year = LogNow.year();
int Month = LogNow.month();
int Day = LogNow.day();
int Hour = LogNow.hour();
int Minute = LogNow.minute();
File DRLog = SD.open("DRLog.csv", FILE_WRITE);
if (DRLog) {
DRLog.print(Year);
DRLog.print(',');
DRLog.print(Month);
DRLog.print(',');
DRLog.print(Day);
DRLog.print(',');
DRLog.print(Hour);
DRLog.print(',');
DRLog.print(Minute);
DRLog.print(',');
DRLog.print(Temp);
DRLog.print(',');
DRLog.print(Z1Hum);
DRLog.print(',');
DRLog.print(Z2Hum);
DRLog.print(',');
DRLog.print(ExtHum);
DRLog.println();
DRLog.close();
Serial.print("Report Recorded-");
Serial.print(Hour);
Serial.print(":");
Serial.println(Minute);
}else{
Serial.println("SD Write Failed");
}}
void RFStart(){
radio.begin();
radio.setPALevel(RF24_PA_MIN);
radio.setDataRate( RF24_250KBPS );
radio.openReadingPipe(1, thisSlaveAddress);
radio.startListening();
Serial.println("RF Start");
RFON = true;
}
void SDStart(){
if (!SD.begin(SD_CS)) {
Serial.println("SD Fail");
return;
}
Serial.println("SD Start");
}