Arduino Nano - Problem with storing data in SD card and sending via Bluetooth

Hi,

I have attached mainCode.ino and few pictures showing the problem.

The idea is to have a piece of code that save data from a sensor into a SD card and transfer it via Bluetooth when the Bluetooth is available. So this basic code is trying to check that.

I tested the Bluetooth in a separate code and it is working properly. SD card code also works well when there is no Bluetooth activation. But SD card does not work when Bluetooth is also included in the code.

I constantly get this error for the SD card. "Error opening text.txt"

It might be to do with the error of lack of space or working the SD.h and SPI.h together.

Any idea how to fix this?

Regards,
BeeZee

mainCode.ino (5.78 KB)

CircuitDesign-sdCard-BlueTooth.pdf (347 KB)

BeeZee:
It might be to do with the error of lack of space or working the SD.h and SPI.h together.

Lack a space for what?

SD.h and SPI.h most definitely work together and are actually need for the Ethernet+SD card shield and the SD card shield that I have.

I am not interested in clicking on code in an attached file.
If you don't know how to post code properly, I suggest you read the sticky on how to do so at the very top of the main forum.

.

BeeZee:
It might be to do with the error of lack of space or working the SD.h and SPI.h together.

It probably isn't either of them. It could be pin conflict.

You will be amazed how many people insist on using software serial on the SPI pins for buetooth and then find grief when they want to put an SPI device, as one would expect, on the same pins.

That's a rough guess. Post your code in the kosher manner, and you will probably get a better one.

I am using Arduino Nano and I have OpenLog SD card with NRF8001 Bluetooth. I have written a code based on the examples have been available for the SD card and the Bluetooth module. I want to store data in SD card and then transmit it. At the moment the code I have written has some issues.

  • I can store data in SD card and read it but Bluetooth does not work.
  • If I comment the part related to reading data from SD card and creating a file then the Bluetooth works.

I have added the screenshot of the SERIAL PRINT. The connections are correct as SD card and Bluetooth work fine individually and only dont work if they are called at the same time like the attached code.

Can you please let me know why the status of the Bluetooth does not change when SD card is active and reading?

Here is main part of the code:

#include <SPI.h>
#include "Adafruit_BLE_UART.h"
#include <SoftwareSerial.h>
/*********************************BLUETOOTH*****************************************/
#define ADAFRUITBLE_REQ 6
#define ADAFRUITBLE_RDY 2     // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 9

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
SoftwareSerial OpenLog(4, 3); //Soft TX on 4, Soft RX out on 3
//SoftwareSerial(rxPin, txPin)

int resetOpenLog = 5; //This pin resets OpenLog. Connect pin 5 to pin GRN on OpenLog.
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

//int statLED = 13;

float dummyVoltage = 3.50; //This just shows to to write variables to OpenLog

void setup() {                
  //pinMode(statLED, OUTPUT);
  Serial.begin(9600);

  setupOpenLog(); //Resets logger and waits for the '<' I'm alive character
  Serial.println("OpenLog online");
  Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Print echo demo"));
  BTLEserial.begin();
}
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;
void loop() {

/**********************************************************************************************************/ /*Creat a name for files*/
  randomSeed(analogRead(A0)); //Use the analog pins for a good seed value
  int fileNumber = random(999); //Select a random file #, 0 to 999
  char fileName[12]; //Max file name length is "12345678.123" (12 characters)
  sprintf(fileName, "log%03d.txt", fileNumber);

  gotoCommandMode(); //Puts OpenLog in command mode
  createFile(fileName); //Creates a new file called log###.txt where ### is random

  Serial.print("Random file created: ");
  Serial.println(fileName);

 /********************************************************************************************************/ /*Write something to OpenLog*/
  OpenLog.println("Hi there! How are you today?");
  OpenLog.print("Voltage: ");
  OpenLog.println(dummyVoltage);
  dummyVoltage++;
  OpenLog.print("Voltage: ");
  OpenLog.println(dummyVoltage);

  Serial.println("Text written to file");
  Serial.println("Reading file contents:");
  Serial.println();

  /************************************************************************************************************/ /*Now let's read back*/
  gotoCommandMode(); //Puts OpenLog in command mode
  readFile(fileName); //This dumps the contents of a given file to the serial terminal

  /*************************************************************************************************************/ /*Now let's read more about the SD card*/
  //readDisk(); //Check the size and stats of the SD card

  Serial.println();
  Serial.println("File read complete");
   BTLEserial.pollACI();
  Serial.println("Yay bluetooth!");
   //Ask what is our current status
  aci_evt_opcode_t status = BTLEserial.getState();
  // If the status changed....
  Serial.println(status);
  Serial.println(BTLEserial.getState());
  Serial.println(laststatus);
  if (status != laststatus) {
    Serial.print("We are here in the loop.");
    // print it out!
    if (status == ACI_EVT_DEVICE_STARTED) {
        Serial.println(F("* Advertising started"));
    }
    if (status == ACI_EVT_CONNECTED) {
        Serial.println(F("* Connected!"));
    }
    if (status == ACI_EVT_DISCONNECTED) {
        Serial.println(F("* Disconnected or advertising timed out"));
    }
    // OK set the last status change to this one
    laststatus = status;
  }

  if (status == ACI_EVT_CONNECTED) {
    Serial.print("We are here.");
    // Lets see if there's any data for us!
    if (BTLEserial.available()) {
      BTLEserial.print(2); // LOOK AT HOW TO SEND PACKETS OF 20 BYTES.
      // only send data if we type something first.
      Serial.print(F("* ")); Serial.print(BTLEserial.available()); Serial.println(F(" bytes available from BTLE"));
    }
    // OK while we still have something to read, get a character and print it out
    while (BTLEserial.available()) {
      char c = BTLEserial.read();
      Serial.print(c);
      OpenLog.println(c); // This stores from Bluetooth to SD card
    }
  }
   Serial.print("done");
}

Thanks,
Bee

Possibly pin conflict - particularly if Bluetooth is on software serial. Post your code in the proper manner. The pictures aren't worth a cracker.

I have added the screenshot of the SERIAL PRINT.

You took a picture of text? Why? Far simpler to copy and paste the text!

Hi,

I do not understand your point can you please explain it.

Bee

This is the first part of the code:

/*******************************************SD CARD and Bluetooth*******************************/

#include <SD.h>
#include <SPI.h>
#include "Adafruit_BLE_UART.h"
const uint8_t chipSelect = 10;


 // This version uses the internal data queing so you can treat it like Serial (kinda)!
/*********************************BLUETOOTH*****************************************/
#define ADAFRUITBLE_REQ 6
#define ADAFRUITBLE_RDY 2     // This should be an interrupt pin, on Uno thats #2 or #3
#define ADAFRUITBLE_RST 9

Adafruit_BLE_UART BTLEserial = Adafruit_BLE_UART(ADAFRUITBLE_REQ, ADAFRUITBLE_RDY, ADAFRUITBLE_RST);

Then the SD card reading is here:

void setup()
{
  Serial.begin(9600);
  /*******************************************SD CARD*******************************/
  Serial.print(F("Initializing SD card..."));
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
  // Note that even if it's not used as the CS pin, the hardware SS pin 
  // (10 on most Arduino boards, 53 on the Mega) must be left as an output 
  // or the SD library functions will not work. 
  
  pinMode(chipSelect, OUTPUT);
  //check_sd_card();
  // digitalWrite(6, HIGH);

  uint8_t sdInitialised;
  sdInitialised = SD.begin(10);
  Serial.println(F("Output from initialisation:"));
  Serial.println(sdInitialised);
  if (!sdInitialised) {
    Serial.println(F("initialization failed!"));
    return;
  }
  Serial.println(F("initialization done AGAIN."));

  
  write_to_sd_card();
 
   /*********************************BLUETOOTH*****************************************/
  // while(!Serial); //
    Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Print echo demo"));

  // BTLEserial.setDeviceName("NEWNAME"); /* 7 characters max! */

  BTLEserial.begin(); 
}
  /*********************************BLUETOOTH*****************************************/

//aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;   
void loop()
{
  // Tell the nRF8001 to do whatever it should be working on. give it some time to process.
  BTLEserial.pollACI();

  // Ask what is our current status
  aci_evt_opcode_t status = BTLEserial.getState();
  // If the status changed....
  if (status != laststatus) {
    // print it out!
    if (status == ACI_EVT_DEVICE_STARTED) {
        Serial.println(F("* Advertising started"));
    }
    if (status == ACI_EVT_CONNECTED) {
        Serial.println(F("* Connected!"));
    }
    if (status == ACI_EVT_DISCONNECTED) {
        Serial.println(F("* Disconnected or advertising timed out"));
    }
    // OK set the last status change to this one
    laststatus = status;
  }

  if (status == ACI_EVT_CONNECTED) {
    // Lets see if there's any data for us!
    if (BTLEserial.available()) {
      int valueOne = 2;
      BTLEserial.print(valueOne); // LOOK AT HOW TO SEND PACKETS OF 20 BYTES.
      // only send data if we type something first.
      Serial.print(F("* ")); Serial.print(BTLEserial.available()); Serial.println(F(" bytes available from BTLE"));
    }
    // OK while we still have something to read, get a character and print it out
    while (BTLEserial.available()) {
      char c = BTLEserial.read();
      Serial.print(c);
    }
  }
}

The functions are:

void check_sd_card(){
  Sd2Card card;
  SdVolume volume;
  SdFile root; 
  //Serial.print("\nInitializing SD card...");
  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println(F("initialization failed. Things to check:"));
    Serial.println(F("* is a card inserted?"));
    Serial.println(F("* is your wiring correct?"));
    Serial.println(F("* did you change the chipSelect pin to match your shield or module?"));
    return;
  } else {
    Serial.println(F("Wiring is correct and a card is present."));
  }

  // print the type of card
  //Serial.print("\nCard type: ");
  switch (card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println(F("SD1"));
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println(F("SD2"));
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println(F("SDHC"));
      break;
    default:
      Serial.println(F("Unknown"));
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println(F("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card"));
    return;
  }


  // print the type and size of the first FAT-type volume
  uint32_t volumesize;
  Serial.print(F("\nVolume type is FAT"));
  Serial.println(volume.fatType(), DEC);
  Serial.println();

  volumesize = volume.blocksPerCluster();    // clusters are collections of blocks
  volumesize *= volume.clusterCount();       // we'll have a lot of clusters
  volumesize *= 512;                            // SD card blocks are always 512 bytes
  Serial.print(F("Volume size (bytes): "));
  Serial.println(volumesize);

  Serial.println(F("\nFiles found on the card (name, date and size in bytes): "));
  root.openRoot(volume);

  // list all files in the card with date and size
  root.ls(LS_R | LS_DATE | LS_SIZE);
  root.close();  
}

void write_to_sd_card(){
  File myFile;  
   // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open(F("test.txt"), FILE_WRITE);
  // if the file opened okay, write to it:
  if (myFile) {
    Serial.print(F("Writing to test.txt..."));
    myFile.println(F("testing 1, 2, 5."));
  // close the file:
    myFile.close();
    Serial.println(F("done."));
  } else {
    // if the file didn't open, print an error:
    Serial.println(F("error opening test.txt"));
  }
}

I hope this is OK.

Bee

Threads merged.

SoftwareSerial OpenLog(4, 3); //Soft TX on 4, Soft RX out on 3
and
  // On the Ethernet Shield, CS is pin 4. It's set as an output by default.

The code is a convoluted mess but, if you are using pin 4 as CS, as is common, that is the conflict. If not, what is that line doing in the code?