Particle Argon Saving to micro SD

I have a particle argon connected to a PIR sensor which works correctly with the code :

int PIR_SENSOR_OUTPUT_PIN = 8; 
int warm_up;

void setup() {
  pinMode(PIR_SENSOR_OUTPUT_PIN, INPUT);
  Serial.begin(9600); /* Define baud rate for serial communication */
  delay(20000); /* Power On Warm Up Delay */
  Particle.subscribe("hook-response/motion", myHandler, MY_DEVICES);
}

void myHandler(const char *event, const char *data) {
    // Handle the integration response  
}

void loop() {
  int sensor_output;
  sensor_output = digitalRead(PIR_SENSOR_OUTPUT_PIN);
  Serial.print(sensor_output);
  if(sensor_output == 1) {
    Particle.publish("motion", String(sensor_output), PRIVATE);}
  else if (sensor_output ==0){
    Particle.publish("motion",String(sensor_output), PRIVATE);}
  delay(1000);
}

I have purchased a sparkfun breakout board and micro SD card (128gb) and am now trying to flash a code that allows it to save to the micro SD.

Has anyone been successful with saving to an SD card?

Welcome to the community :+1:

Yes. Have you tried the SDFat library?

For your code above, I’d suggest you move the Particle.subscribe() instruction before the delay().
Anything that needs to be registered with the cloud needs to be registered within a few seconds after the connectino got established.
You can even preemptively register so that the device OS will register with the cloud ASAP.

Yes though I am having major issues getting the code to work correctly. Its not saving to my SD card.
Thanks for the response.

#include "Particle.h"
#include "SdFat.h"
#include "SdCardLogHandlerRK.h"
// Pick an SPI configuration.
// See SPI configuration section below (comments are for photon).
#define SPI_CONFIGURATION 0
//------------------------------------------------------------------------------
// Setup SPI configuration.
#if SPI_CONFIGURATION == 0
// Primary SPI with DMA
// SCK => A3, MISO => A4, MOSI => A5, SS => A2 (default)
SdFat sd;
const uint8_t chipSelect = SS;
#elif SPI_CONFIGURATION == 1
// Secondary SPI with DMA
// SCK => D4, MISO => D3, MOSI => D2, SS => D1
SdFat sd(1);
const uint8_t chipSelect = D1;
#elif SPI_CONFIGURATION == 2
// Primary SPI with Arduino SPI library style byte I/O.
// SCK => A3, MISO => A4, MOSI => A5, SS => A2 (default)
SdFatLibSpi sd;
const uint8_t chipSelect = SS;
#elif SPI_CONFIGURATION == 3
// Software SPI.  Use any digital pins.
// MISO => D5, MOSI => D6, SCK => D7, SS => D0
SdFatSoftSpi<D5, D6, D7> sd;
const uint8_t chipSelect = D0;
#endif  // SPI_CONFIGURATION
//------------------------------------------------------------------------------

int PIR_SENSOR_OUTPUT_PIN = 8; 
int warm_up;

void setup() {
  pinMode(PIR_SENSOR_OUTPUT_PIN, INPUT);
  Serial.begin(9600); /* Define baud rate for serial communication */
  delay(20000); /* Power On Warm Up Delay */
  Particle.subscribe("hook-response/motion", myHandler, MY_DEVICES);
}

void myHandler(const char *event, const char *data) {
    // Handle the integration response

  File myFile;
  Serial.begin(9600);
  // Wait for USB Serial 
  while (!Serial) {
    SysCall::yield();
  }
  
  Serial.println("Type any character to start");
  while (Serial.read() <= 0) {
    SysCall::yield();
  }

  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // Change to SPI_FULL_SPEED for more performance.
  if (!sd.begin(chipSelect, SPI_FULL_SPEED)) {
    sd.initErrorHalt();
  }

  // open the file for write at end like the "Native SD library"
  if (!myFile.open("datacollector.txt", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening datacollector.txt for write failed");
  }
  // if the file opened okay, write to it:
  Serial.print("Writing to datacollector.txt...");
  myFile.println("datacollector 1, 2, 3.");
  myFile.printf("fileSize: 128", myFile.fileSize());
  
  // close the file:
  myFile.close();
  Serial.println("done.");

  // re-open the file for reading:
  if (!myFile.open("datacollector.txt", O_READ)) {
    sd.errorHalt("opening datacollector.txt for read failed");  
 
    Serial.println("datacollector.txt content:"); 
  }   
}

void loop() {
  int sensor_output;
  sensor_output = digitalRead(PIR_SENSOR_OUTPUT_PIN);
  Serial.print(sensor_output);
  if(sensor_output == 1) {
    Particle.publish("motion", String(sensor_output), PRIVATE);}
  else if (sensor_output ==0){
    Particle.publish("motion",String(sensor_output), PRIVATE);}
  delay(1000);
}

How have you wired the card reader?
On the Argon you wouldn’t use the A# pins mentioned in the respective comments but the SCK, MI and MO pins as labeled on the board.
For clarity you may also want to do away with the configuration blocks that don’t apply to your case.

And when posting code, please use the Preformatted text feature image for better readability.

2 Likes

Will do, thank you.

Device SPI Name SD Reader Color
A2 SS /CS Yellow
A3 SCK SCK Orange
A4 MISO DO Blue
A5 MOSI DI Green
3V3 VCC Red
GND GND Black
CD

I have the micro SD (128gb) inserted with the sparkfun breakout board. I soldered the wires to the breakout board and connected to the argon via breadboard

@NA20, as @ScruffR pointed out, on the Argon, the connections should be:

Device SPI Name SD Reader Color
A2 SS /CS Yellow
SCK (D13) SCK SCK Orange
MI (D11) MISO DO Blue
MO (D12) MOSI DI Green
3V3 VCC Red
GND GND Black
CD
3 Likes

@NA20,

Welcome to the community. You are getting some great advice from @ScruffR and @peekay123 so I hope your SD card implementation will be running soon.

I wanted to provide an alternative which I have used on many projects, using the SparkFun OpenLog. I know this is not the track you are on but I wanted to make sure you knew there is another way.

Here are some of the advantages of this approach:

  1. It uses less pins than a SPI device and is easily implemented.
  2. You can simply Serial1.println() to the SD card and create data that is easily imported into Excel as a .CSV file
  3. You can remove and replace the SD card without disturbing or having to power down the Argon

I was concerned about increased power consumption but the OpenLog uses only about 2mA while idle.

This is not as robust or integrated an approach as the path you are on. But I wanted to let you know about another approach.

Chip

2 Likes

@chipmc Thank you very much, I’ll definitely look into that approach as well.

1 Like

@chipmc @NA20

Also, don’t forget we now have access to the 2MB memory chip on the Gen3 Devices now using the LittleFS library that became functional in the latest 2.0 firmware.

It’s really 1MB of storage due to the wear leveling in LittleFS, but that’s still a good amount of data for logs.

2 Likes