Arduino Micro + nRF8001 + MicroSD

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
mxstrand
 
Posts: 1
Joined: Thu Jun 12, 2014 3:17 pm

Arduino Micro + nRF8001 + MicroSD

Post by mxstrand »

Hello - I've got an Arduino Micro wired up to an nRF8001 and a MicroSD card reader/breakout board.

Each peripheral runs sketches correctly on its own.

As both peripherals are SPI devices, they share the SCK (clock), MISO, and MOSI pins. No other pins are shared.

My intention is to pass a string from an iPhone client via BLE and write that string into a .txt file.

However, my sketch seems to fail as I try to initiate both devices in the setup. Particularly, the SD.open function won't fire. All logging stops in the serial once that code block hits. If I comment it out, things progress appropriately, but I need that SD file object available in my loop.

Here's the full sketch:

Thank you very much for any help/guidance.

Code: Select all

#include <SPI.h>
#include <SD.h> // MicroSD
#include "Adafruit_BLE_UART.h"

File myFile;

// Connect CLK/MISO/MOSI to hardware SPI
// e.g. On UNO & compatible: CLK = 13, MISO = 12, MOSI = 11
#define ADAFRUITBLE_REQ 10
#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);


// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;

// change this to match your SD shield or module;
// Arduino Ethernet shield: pin 4
// Adafruit SD shields and modules: pin 10
// Sparkfun SD shield: pin 8
const int chipSelect = 8; 

/**************************************************************************/
/*!
    Configure the Arduino and start advertising with the radio
*/
/**************************************************************************/
void setup(void)
{ 
  Serial.begin(9600);
  // Serial1.begin(9600);
  while(!Serial); // Leonardo/Micro should wait for serial init
  
  Serial.print("\nInitializing 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); // pin setup for SD card
  
  // we'll use the initialization code from the utility libraries
  // since we're just testing if the card is working!
  while (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
  } 
  
  // print the type of card
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");
  }

  // Now we will try to open the 'volume'/'partition' - it should be FAT16 or FAT32
  if (!volume.init(card)) {
    Serial.println("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("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
  
  // FILE CREATION
  myFile = SD.open("datalog.txt", FILE_WRITE);
  // if the file is available, write to it:
  if (SD.open("datalog.txt", FILE_WRITE)) {
        myFile.println("in the file open success block");
        // print to the serial port too:
        Serial.println("data logged to SD");
  
  // if the file isn't open, pop up an error:
  }
  else {
        Serial.println("File Error datalog.txt");
  } 
  myFile.close(); // always close after an open.
  
  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("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  
  //Serial.println("\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);
  
  Serial.println(F("Adafruit Bluefruit Low Energy nRF8001 Print echo demo"));
  BTLEserial.begin();
}

/**************************************************************************/
/*!
    Constantly checks for new events on the nRF8001
*/
/**************************************************************************/
aci_evt_opcode_t laststatus = ACI_EVT_DISCONNECTED;

void loop()
{
  // Serial.println(F("In the loop"));

  // Tell the nRF8001 to do whatever it should be working on.
  BTLEserial.pollACI();
  
  if(myFile) {
    Serial.println(F("myFile still Exists"));
  }

  // 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()) {
      Serial.print("* "); 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);
      
      delay(2000); // wait for file creation
      // if the file opened okay, write to it:
      if (myFile) {
        Serial.print("Writing to test.txt...");
        myFile.println(c);
    	// close the file:
        myFile.close();
        Serial.println("done.");
      } else {
        // if the file didn't open, print an error:
        Serial.println("error opening .txt file");
      }
    }

    // Next up, see if we have any data to get from the Serial console

    if (Serial.available()) {
      // Read a line from Serial
      Serial.setTimeout(100); // 100 millisecond timeout
      String s = Serial.readString();

      // We need to convert the line to bytes, no more than 20 at this time
      uint8_t sendbuffer[20];
      s.getBytes(sendbuffer, 20);
      char sendbuffersize = min(20, s.length());

      Serial.print(F("\n* Sending -> \"")); Serial.print((char *)sendbuffer); Serial.println("\"");

      // write the data
      BTLEserial.write(sendbuffer, sendbuffersize);
    }
  }
}

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Arduino Micro + nRF8001 + MicroSD

Post by adafruit_support_mike »

You may be seeing memory overflow or fragmentation problems. The String class chews up a lot of free memory.

Try wrapping all your literal strings in the F() macro and see if that helps.

m_drunk
 
Posts: 10
Joined: Wed Oct 29, 2014 5:44 pm

Re: Arduino Micro + nRF8001 + MicroSD

Post by m_drunk »

I've noticed a trend with using the nRF8001 with a lot of other SPI libraries. The MCP2515 (canbus) and the SD card reader (with SD.h, I assume) you're speaking of working fine together on the same bus, as well as several other SPI modules I have no trouble with. But once you introduce this particular SPI flavor that the nrf8001 uses, everything comes to a screaming halt. So my question is, what makes this guy different from just about every other SPI implementation that we've seen? Gonna post this everywhere I find that the situation is applicable.

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Arduino Micro + nRF8001 + MicroSD

Post by adafruit_support_mike »

This thread has been inactive for six months. Please continue in the other thread where you posted the same comment:

http://forums.adafruit.com/viewtopic.php?f=25&t=53879

Locked
Please be positive and constructive with your questions and comments.

Return to “Other Arduino products from Adafruit”