Dear all,
I've got a MEGA2560 with a Sensor Shield V2.0 board. I will be using this as a remote data collector. The data will be locally stored on a SD-card and will also be transmitted to home base via an nRF24L01.
I've got two boards both using the SPI protocol: A SD-card (http://arduino-info.wikispaces.com/SD-Cards) which is connected to the SD-card connector on the Sensor Shield board.
And I also got a nRF24L01 TX board connected to the same MISO, MOSI and SCK pins but also on pin 8 and 7. 7= CE and 8= CSN
Both, SD-card and nRF24L01, boards work individually but refuse to work together.
When I call the specific function I open the function with digitalWrite(CSSD, LOW); and close the function with digitalWrite(CSSD, HIGH);
Eg:
void Radio() {
digitalWrite(CSTX, LOW);
radio.write(&LDRValue, 2); // Second parameter specifies amount of bytes, long = 2 bytes, float = 4 bytes
radio.write(&TempOffice, 4);
digitalWrite(CSTX, HIGH);
You would expect by doing this that the SPI will then be ready to open up another function and read the data from that. However, that's not the case.
I also got an RTC (DS3231) and an LCD (4 x 2) connected via I2C to the MEGA and when I try to run as is then the clock stops working and also the Serial Monitor.
I am aware that the SPI uses common MOSI, MISO and CLK lines but uses different CS pins for each application.
Can somebody tell me where I went wrong? I've kind of given up by spending more then 8 hours on this.
Here is my code:
/* TEMPERATURE DATA LOGGER, 19-02-2018@Luc De Pauw */
/*---( LIBRARIES )---*/
#include <OneWire.h> /*DS18B20*/
#include <DallasTemperature.h> /*DS18B20*/
#include <Wire.h> /*RTC DS3231*/
#include "Sodaq_DS3231.h" /*RTC DS3231*/
#include <LiquidCrystal_I2C.h> /*LCD*/
#include <SD.h> /*SD-card*/
#include "Timer.h" /*Timer*/
#include <SPI.h> /*nRF24L01*/
#include <RF24.h> /*nRF24L01*/
/*---( DECLARE OBJECTS )---*/
/*LCD*/ // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol //Set the pins on the I2C chip used for LCD connections:
/*LCD*/ LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //Set the LCD I2C address to 0x20 or 0x27, determined by A0, A1 and A2
/*DS18B20*/ OneWire oneWire(2); //Data wire is plugged into pin 2 on the Arduino
/*DS18B20*/ DallasTemperature tempSensors(&oneWire); //Pass our oneWire reference to Dallas Temperature.
/*DS18B20*/ DeviceAddress TempSensor0 = { 0x28, 0x2D, 0x68, 0x4D, 0x05, 0x00, 0x00, 0x85 }; //Insert unique 128 bit address of sensor
/*SD-card*/ const int CSSD = 53; // Chip Selct SD card,Also for nRF24L01 as it uses the shared SPI-bus
/*nRF24L01*/ RF24 radio(7, 8); // CE, CSN= Chip Select Not
const int CSTX = 8;
/*nRF24L01*/ byte addresses[][6] = {"0"}; //Identify the transmitting and receiving bit
/*---( DECLARE VARIABLES )----*/
/*DS18B20*/ float TempOffice;
/*DS18B20*/ float MaxTemp1;
/*DS18B20*/ float MinTemp1 = 50;
/*LDR*/ long LDRValue;
/*RTC DS3231*/ char TimeBuffer[19] = "";
/*Timer*/ Timer timer;
void setup(){
/*Serial Monitor*/Serial.begin(9600); //Start serial port
SPI.begin();
/*LCD*/ lcd.begin(20,4); //Initialize the lcd for 20 chars 4 lines
/*RTC DS3231*/ rtc.begin(); //Start the RTC library code
/*DS18B20*/ tempSensors.begin(); //Start the OneWire library
/*DS18B20*/ tempSensors.setResolution(TempSensor0, 11); //Set the resolution to 11 bit (Can be 9 to 12 bits .. lower is faster but less accurate)
/*SD-card*/ Serial.print("Initializing SD card...");
/*SD-card*/ pinMode(CSSD, OUTPUT); //Make sure that the default chip select pin is set to output, even if you don't use it:
/*SD-card*/ if (!SD.begin(CSSD)) { //See if the card is present and can be initialized:
/*SD-card*/ Serial.println("Card failed, or not present");}
/*SD-card*/ Serial.println("Card initialized.");
/*Timer*/ timer.every(5000, SerMon); //Write every 5 seconds to the SerialMonitor
/*Timer*/ timer.every(30000, WriteToSD); //Write every 30 seconds to the SD-card
pinMode(CSTX, OUTPUT);
/*nRF24L01*/ radio.begin(); // Initiate the radio object
/*nRF24L01*/ radio.setChannel(124); // 0 to 124, frequencies between 2.4 and 2.5 Ghz in chunks of 100 MHz. Use a channel unlikely to be used by Wifi, Microwave ovens etc
/*nRF24L01*/ radio.setPALevel(RF24_PA_MIN); // Set the transmit power to lowest available to prevent power supply related issues, can also be set to MAX
/*nRF24L01*/ radio.setDataRate(RF24_2MBPS); // Set the speed of the transmission to the quickest available, can be set to 250KB or 1MBPS to increase range
/*nRF24L01*/ radio.openWritingPipe(addresses[0]); // Open a writing and reading pipe on each radio, with opposite addresses
/*nRF24L01*/ radio.openReadingPipe(1, addresses[0]);
}
void loop(){
timer.update();
Clock();
ReadTemp();
MaxTemp();
MinTemp();
LDR();
LCDPrint();
Radio();
//SerMon(); // No need to call as this is done by the timer
//WriteToSD(); // No need to call as this is done by the timer
}
void Clock(){
DateTime now = rtc.now(); //Read the current date-time from the RTC
sprintf(TimeBuffer, "%04d-%02d-%02d %02d:%02d:%02d", now.year(), now.month(), now.date(), now.hour(), now.minute(), now.second());
}
/
void ReadTemp(){
tempSensors.requestTemperatures(); // Send the command to get temperatures
TempOffice = tempSensors.getTempC(TempSensor0);
}
void MaxTemp(){
if (TempOffice > MaxTemp1) {
MaxTemp1 = TempOffice; }
}
void MinTemp(){
if (TempOffice < MinTemp1) {
MinTemp1 = TempOffice; }
}
void LDR() {
LDRValue = analogRead(A0);
}
void LCDPrint(){
lcd.setCursor(0,0); //Start at character 0 on line 0
lcd.print("CurrentTemp= "); lcd.print(TempOffice,1); lcd.print(" C");
lcd.setCursor(0,1);
lcd.print("MaxTemp= "); lcd.setCursor(13,1); lcd.print(MaxTemp1,1); lcd.print(" C");
lcd.setCursor(0,2);
lcd.print("MinTemp= "); lcd.setCursor(13,2); lcd.print(MinTemp1,1); lcd.print(" C");
lcd.setCursor(0,3);
lcd.print(TimeBuffer);
}
void Radio() {
digitalWrite(CSTX, LOW);
radio.write(&LDRValue, 2); // Second parameter specifies amount of bytes, long = 2 bytes, float = 4 bytes
radio.write(&TempOffice, 4);
digitalWrite(CSTX, HIGH);
}
void SerMon(){ //Every 5 seconds writes data to serial monitor, activated by timer
Serial.print("Writing data to Serial: ");
Serial.print("TempOffice= "); Serial.print(TempOffice,1); Serial.print("°C |");
Serial.print(" MAX= "); Serial.print(MaxTemp1, 1); Serial.print("°C |");
Serial.print(" MIN= "); Serial.print(MinTemp1, 1); Serial.print("°C |");
Serial.print(" LDR= "); Serial.println(LDRValue, 1);
}
void WriteToSD(){ //Every 30 seconds writes data to SD-card and to serial monitor, activated by timer
digitalWrite(CSSD, LOW);
// digitalWrite(chipSelect, LOW); // Chip Select pin must be low before the Slave is recognised
File dataFile = SD.open("datalog.txt", FILE_WRITE); //Open the file. Only one file can be open at a time, so you have to close this one before opening another
if (dataFile) { //If the file is available, write to it:
dataFile.print(TimeBuffer); dataFile.print(", "); dataFile.print(TempOffice, 1); dataFile.print(", "); dataFile.print(MaxTemp1, 1);
dataFile.print(", "); dataFile.print(MinTemp1, 1); dataFile.print(", "); dataFile.println(LDRValue, 0);
dataFile.close();}
else { //If the file isn't open, pop up an error
Serial.println("Error opening datalog.txt");}
//Also print confirmation and data to Serial Monitor
Serial.print("To SD-card: "); Serial.print("TempOffice= "); Serial.print(TempOffice,1); Serial.print("°C |");
Serial.print(" MAX= "); Serial.print(MaxTemp1, 1); Serial.print("°C |");
Serial.print(" MIN= "); Serial.print(MinTemp1, 1); Serial.print("°C |");
Serial.print(" LDR= "); Serial.println(LDRValue, 1);
digitalWrite(CSSD, HIGH);
}