I’ve been trying to troubleshoot my brand spankin’ new Spark Core for probably 4 hours now, and I think I’ve narrowed down one of the issues. It will work for basic examples like the LED blink or my own tests with the CLI serial monitor, but every time I flash one of the SD-Card-Library examples (like cardinfo or read/write), the core will go into breathing cyan mode but be listed as “offline” whenever I check the spark list via the CLI.
The only way to get it back online is to then do a manual setup, but sometimes I can’t even get the mode to change to “listening” (flashing blue), so I have to go into DFU mode and reinstall updates/patches before I can setup the wifi again through the CLI.
Is this a problem with the SD library? With my firmware? With my CLI? Wisdom much appreciated! (P.S. Note that I am a beginner - I just started using the terminal heavily yesterday and downloading things like homebrew and Xcode (I had some help at a makerspace for that part ;))
For sure! This is literally a copy-paste from the SD card library example:
/*
SD card test
This example shows how use the utility libraries on which the'
SD library is based in order to get info about your SD card.
Very useful for testing a card when you're not sure whether its working or not.
The circuit:
* SD card attached to SPI bus as follows:
Refer to "libraries/SdFat/Sd2Card_config.h"
created 28 Mar 2011
by Limor Fried
modified 16 Mar 2011
by Tom Igoe
modified for Maple(STM32 micros)/libmaple
17 Mar 2012
by dinau
*/
// include the SD library:
#include "application.h"
#include "sd-card-library/sd-card-library.h"
// set up variables using the SD utility library functions:
Sd2Card card;
SdVolume volume;
SdFile root;
// SOFTWARE SPI pin configuration - modify as required
// The default pins are the same as HARDWARE SPI
const uint8_t chipSelect = A2; // Also used for HARDWARE SPI setup
const uint8_t mosiPin = A5;
const uint8_t misoPin = A4;
const uint8_t clockPin = A3;
void setup()
{
Serial.begin(115200);
while (!Serial.available());
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!
// Initialize HARDWARE SPI with user defined chipSelect
if (!card.init(SPI_HALF_SPEED, chipSelect)) {
// Initialize SOFTWARE SPI (uncomment and comment out above line to use)
// if (!card.init(mosiPin, misoPin, clockPin, 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?");
return;
} else {
Serial.println("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("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();
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);
}
void loop(void) {
}
Sadly, I’ve never gotten any serial output from the SD example. I do wonder if I am opening up the serial monitor too late? It’s a bit tricky to get the timing for exactly when it’s been sent over - unless that’s not actually how these things work.
One update.
I’m currently trying to manually setup my core again in order to test some other apps, and I keep running into this issue: whenever I go through “spark setup”, I can make it through to putting in my wifi credentials successfully, but it won’t make it through claiming. I am able to see the “breathing cyan” (as indicated by:
Done! Your core should now restart.
Please wait until your core is breathing cyan and then press ENTER
but when I press the ENTER, the following happens:
========================================
Claiming your core
Failed to claim core, server said [ 'Device is not connected' ]
Please wait until your core is breathing cyan and then press ENTER
Failed to claim core, server said [ 'Device is not connected' ]
Please wait until your core is breathing cyan and then press ENTER
Failed to claim core, server said [ 'Device is not connected' ]
Please wait until your core is breathing cyan and then press ENTER
I have a feeling you’re getting stuck on the second line of code in setup():
while (!Serial.available());
Unless I’m wrong, you are sitting in a loop, waiting for data to be received on the core side, but you aren’t sending any data, so it just sits there.
Try commenting out that line, and maybe put in a “delay(2000);” instead, to give yourself about 2 seconds to connect to serial after it is setup (so put it after Serial.begin).
You are likely losing your Spark Core connection because the while loop is blocking, so WiFi can’t talk to the cloud.
void setup()
{
Serial.begin(115200);
// Blocking loop waiting for incoming serial data, not sure why this is here.
//while (!Serial.available());
delay(2000); // give yourself 2 seconds to connect to serial
...
DANG @jerrytron, good catch! I completely missed that and was focused on the SD stuff. You are spot on about being stuck in the loop and losing the cloud connection. Normally, a similar line (while (!Serial.available()) SPARK_WAN_Loop(); )is used to allow a user to open their serial terminal and hit a key so they don’t miss any output. The SPARK_WAN_Loop() part keeps the cloud connection alive.
That absolutely worked! Finally seeing files in my terminal! Thank you so much for that catch, I was really starting to wonder if there was a hardware issue - glad to know it was just a funny bit of code. Gonna test around to make sure there aren’t any other weird connectivity/claiming issues, but I’m hoping this fixes everything.
Thanks! Ah yeah, I’ve seen that while loop before. Couldn’t remember the ‘why’ of it, just saw the problem. Thanks for the enhanced version of the loop and explanation!