Electron breathes cyan but nothing happens

Hi All,

I’m trying to troubleshoot an issue with my Electrons in which the onboard LED breathes cyan as if everything was working fine, but the code doesn’t seem to run. I put a println in the setup() but when this problem occurs (which is intermittent) it doesn’t come out on the console. The Electron has attached to it: two I2C sensors, an SPI SD card reader, and 2 RGB 1050 LEDs.

My guess is that SYSTEM_THREAD(ENABLED); might be causing this, but am unsure of how to confirm this and how to get around it.

Suggestions or similar experiences are very much appreciated.

Thanks!

EDIT: posted code below

    // ENABLE MULTI THRADING
    SYSTEM_THREAD(ENABLED);
    
    #include "KaiMMA8452Q/KaiMMA8452Q.h"
    #include "math.h"
    #include "SdFat/SdFat.h"
    
    int16_t AcX,AcY,AcZ;
    
    MMA8452Q accel; // Default MMA8452Q object create. (Address = 0x1D)
    
    FuelGauge fuel; // object that gets battery data
    
    int I2C_ADDRESS = 0x77;  // bmp180 sensor address
    
    const unsigned char oversampling_setting = 2; //oversampling for measurement
    const unsigned char pressure_conversiontime[4] = {
    	5, 8, 14, 26
    };                 // delays for oversampling settings 0, 1, 2 and 3
    
    // sensor registers from the BOSCH BMP085 datasheet
    int ac1;
    int ac2;
    int ac3;
    unsigned int ac4;
    unsigned int ac5;
    unsigned int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;
    
    // variables to keep the values
    int temperature = 0;
    long pressure = 0;
    
    // led pins
    int greenLED1 = B0;
    int redLED1 = B1;
    int blueLED1 = B2;
    int greenLED2 = B3;
    int redLED2 = D2;
    int blueLED2 = D3;
    
    // sd card vars
    const int chipSelect = A2;
    SdFat sd;
    File root;
    File dataFile;
    
    // read temperature and pressure from sensor
    void readSensor() {
    	int ut= readUT();
    	long up = readUP();
    	long x1, x2, x3, b3, b5, b6, p;
    	unsigned long b4, b7;
    
    	//calculate true temperature
    	x1 = ((long)ut - ac6) * ac5 >> 15;
    	x2 = ((long) mc << 11) / (x1 + md);
    	b5 = x1 + x2;
    	temperature = (b5 + 8) >> 4;
    
    	// calculate true pressure
    	b6 = b5 - 4000;
    	x1 = (b2 * (b6 * b6 >> 12)) >> 11;
    	x2 = ac2 * b6 >> 11;
    	x3 = x1 + x2;
    	b3 = (((int32_t) ac1 * 4 + x3)<<oversampling_setting + 2) >> 2;
    	x1 = ac3 * b6 >> 13;
    	x2 = (b1 * (b6 * b6 >> 12)) >> 16;
    	x3 = ((x1 + x2) + 2) >> 2;
    	b4 = (ac4 * (uint32_t) (x3 + 32768)) >> 15;
    	b7 = ((uint32_t) up - b3) * (50000 >> oversampling_setting);
    	p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
    
    	x1 = (p >> 8) * (p >> 8);
    	x1 = (x1 * 3038) >> 16;
    	x2 = (-7357 * p) >> 16;
    	pressure = p + ((x1 + x2 + 3791) >> 4);
    }
    
    // read uncompensated temperature value
    unsigned int readUT() {
    	writeRegister(0xf4,0x2e);
    	delay(5); // the datasheet suggests 4.5 ms
    	return readIntRegister(0xf6);
    }
    
    // read uncompensated pressure value
    long readUP() {
    	writeRegister(0xf4,0x34+(oversampling_setting<<6));
    	delay(pressure_conversiontime[oversampling_setting]);
    
    	unsigned char msb, lsb, xlsb;
    	Wire.beginTransmission(I2C_ADDRESS);
    	Wire.write(0xf6); // register to read
    	Wire.endTransmission();
    	delay(2);
    	Wire.requestFrom(I2C_ADDRESS, 3); // request three bytes
    	while(!Wire.available()) {
    		Particle.process();
    		delay(2); // wait until data available
    	}
    	msb = Wire.read();
    	while(!Wire.available()) {
    		Particle.process();
    		delay(2); // wait until data available
    	}
    	lsb |= Wire.read();
    	while(!Wire.available()) {
    		Particle.process();
    		delay(2); // wait until data available
    	}
    	xlsb |= Wire.read();
    	return (((long)msb<<16) | ((long)lsb<<8) | ((long)xlsb)) >>(8-oversampling_setting);
    }
    
    void  getCalibrationData() {
    	ac1 = readIntRegister(0xAA);
    	ac2 = readIntRegister(0xAC);
    	ac3 = readIntRegister(0xAE);
    	ac4 = readIntRegister(0xB0);
    	ac5 = readIntRegister(0xB2);
    	ac6 = readIntRegister(0xB4);
    	b1 = readIntRegister(0xB6);
    	b2 = readIntRegister(0xB8);
    	mb = readIntRegister(0xBA);
    	mc = readIntRegister(0xBC);
    	md = readIntRegister(0xBE);
    }
    
    void writeRegister(unsigned char r, unsigned char v)
    {
    	Wire.beginTransmission(I2C_ADDRESS);
    	Wire.write(r);
    	Wire.write(v);
    	Wire.endTransmission();
    }
    
    // read a 16 bit register
    int readIntRegister(unsigned char r)
    {
    	unsigned char msb, lsb;
    	Wire.beginTransmission(I2C_ADDRESS);
    	Wire.write(r); // register to read
    	Wire.endTransmission();
    	delay(2);
    	Wire.requestFrom(I2C_ADDRESS, 2); // request two bytes
    	while(!Wire.available()) {
    		Particle.process();
    		delay(2);
    	} // wait until data available
    	msb = Wire.read();
    	while(!Wire.available()) {
    		Particle.process();
    		delay(2);
    	} // wait until data available
    	lsb = Wire.read();
    	return (((int)msb<<8) | ((int)lsb));
    }
    
    const int maxAvgCount = 4;
    float AcXAvg = 0; float AcYAvg = 0; float AcZAvg = 0; long pAvg = 0; float vectorSumAvg = 0;
    float adjAcXAvg = 0; float adjAcYAvg = 0; float adjAcZAvg = 0; long adjPAvg = 0; // float adjVectorSum = 0;
    float AcXArray[maxAvgCount]; float AcYArray[maxAvgCount]; float AcZArray[maxAvgCount];
    long pArray[maxAvgCount];
    float vectorSumArray[maxAvgCount];
    float adjAcXArray[maxAvgCount]; float adjAcYArray[maxAvgCount]; float adjAcZArray[maxAvgCount];
    long adjPArray[maxAvgCount];
    int avgCount = 0;
    bool firstAvg = false;
    void smoothData(float ax, float ay, float az) {     // , float gx, float gy, float gz) {
    	if (avgCount < maxAvgCount && firstAvg == false) {
    		// add the first values to arrays
    		if (avgCount < maxAvgCount) {
    			AcXArray[avgCount] = ax;
    			AcYArray[avgCount] = ay;
    			AcZArray[avgCount] = az;
    			pArray[avgCount] = pressure;
    			vectorSumArray[avgCount] = sqrt(pow(ax, 2) + pow(ay, 2) + pow(az, 2));
    		}
    		avgCount++;
    	}
    
    	if (avgCount == maxAvgCount && firstAvg == false) { // calculate rolling average
    		for (int i=0; i < avgCount; i++) {
    			if (i == 0) {
    				AcXAvg = AcXArray[i];
    				AcYAvg = AcYArray[i];
    				AcZAvg = AcZArray[i];
    				pAvg = pArray[i];
    				vectorSumAvg = vectorSumArray[i];
    			} else {
    				AcXAvg = AcXAvg + AcXArray[i];
    				AcYAvg = AcYAvg + AcYArray[i];
    				AcZAvg = AcZAvg + AcZArray[i];
    				pAvg = pAvg + pArray[i];
    				vectorSumAvg = vectorSumAvg + vectorSumArray[i];
    			}
    		}
    
    		// not checking for division by zero
    		AcXAvg = AcXAvg/avgCount;
    		AcYAvg = AcYAvg/avgCount;
    		AcZAvg = AcZAvg/avgCount;
    		pAvg = pAvg/avgCount;
    		vectorSumAvg = vectorSumAvg/avgCount;
    
    		firstAvg = true;
    	}
    	else if (avgCount == maxAvgCount && firstAvg == true) {
    		// shift values in original arrays and add newest to end
    		float tempAcXArray[avgCount]; float tempAcYArray[avgCount]; float tempAcZArray[avgCount];
    		float tempPArray[avgCount];
    		float tempVectorSumArray[avgCount];
    		for (int i = 0; i < avgCount; i++) {
    			if (i < maxAvgCount - 1) {
    				tempAcXArray[i] = AcXArray[i+1];
    				tempAcYArray[i] = AcYArray[i+1];
    				tempAcZArray[i] = AcZArray[i+1];
    				tempPArray[i] = pArray[i+1];
    				tempVectorSumArray[i] = vectorSumArray[i+1];
    			} else {
    				tempAcXArray[i] = ax;
    				tempAcYArray[i] = ay;
    				tempAcZArray[i] = az;
    				tempPArray[i] = pressure;
    				tempVectorSumArray[i] = sqrt(pow(ax, 2) + pow(ay, 2) + pow(az, 2));
    			}
    		}
    
    		for (int i = 0; i < avgCount; i++) {
    			AcXArray[i] = tempAcXArray[i];
    			AcYArray[i] = tempAcYArray[i];
    			AcZArray[i] = tempAcZArray[i];
    			pArray[i] = tempPArray[i];
    			vectorSumArray[i] = tempVectorSumArray[i];
    		}
    
    		// recalculate averages
    		// sum values in temp arrays
    		for (int i = 0; i < avgCount; i++) {
    			if (i == 0) {
    				AcXAvg = AcXArray[i];
    				AcYAvg = AcYArray[i];
    				AcZAvg = AcZArray[i];
    				pAvg = pArray[i];
    				vectorSumAvg = vectorSumArray[i];
    			} else {
    				AcXAvg = AcXAvg + AcXArray[i];
    				AcYAvg = AcYAvg + AcYArray[i];
    				AcZAvg = AcZAvg + AcZArray[i];
    				pAvg = pAvg + pArray[i];
    				vectorSumAvg = vectorSumAvg + vectorSumArray[i];
    			}
    		}
    
    		// not checking for division by zero
    		AcXAvg = AcXAvg/avgCount;
    		AcYAvg = AcYAvg/avgCount;
    		AcZAvg = AcZAvg/avgCount;
    		pAvg = pAvg/avgCount;
    		vectorSumAvg = vectorSumAvg/avgCount;
    
    		// calculate adjusted values and store in adjArrays
    		for (int i = 0; i < avgCount; i++) {
    			// check if addition or subtraction is needed
    			if (AcXArray[i] >= 0 && AcXAvg >= 0) {
    				adjAcXArray[i] = abs(AcXArray[i] - AcXAvg);
    			} else {
    				adjAcXArray[i] = AcXArray[i] - AcXAvg;
    			}
    			if (AcYArray[i] >= 0 && AcYAvg >= 0) {
    				adjAcYArray[i] = abs(AcYArray[i] - AcYAvg);
    			} else {
    				adjAcYArray[i] = AcYArray[i] - AcYAvg;
    			}
    			if (AcZArray[i] >= 0 && AcZAvg >= 0) {
    				adjAcZArray[i] = abs(AcZArray[i] - AcZAvg);
    			} else {
    				adjAcZArray[i] = AcZArray[i] - AcZAvg;
    			}
    			if (pArray[i] >= 0 && pAvg >= 0) {
    				adjPArray[i] = abs(pArray[i] - pAvg);
    			} else {
    				adjPArray[i] = pArray[i] - pAvg;
    			}
    		}
    
    		// calculate adjusted averages
    		for (int i=0; i < avgCount; i++) {
    			if (i == 0) {
    				adjAcXAvg = adjAcXArray[i];
    				adjAcYAvg = adjAcYArray[i];
    				adjAcZAvg = adjAcZArray[i];
    				adjPAvg = adjPArray[i];
    			} else {
    				adjAcXAvg = adjAcXAvg + adjAcXArray[i];
    				adjAcYAvg = adjAcYAvg + adjAcYArray[i];
    				adjAcZAvg = adjAcZAvg + adjAcZArray[i];
    				adjPAvg = adjPAvg + adjPArray[i];
    			}
    		}
    
    		adjAcXAvg = adjAcXAvg/avgCount;
    		adjAcYAvg = adjAcYAvg/avgCount;
    		adjAcZAvg = adjAcZAvg/avgCount;
    		adjPAvg = adjPAvg/avgCount;
    
    		detectWave(adjAcXAvg, adjAcYAvg, adjAcZAvg);
    	}
    }
    
    int waveHappened = 0;
    int eventsRequired = 6;
    int waveCountX = 0;
    int waveCountY = 0;
    int waveCountZ = 0;
    bool firstEventDetected = false;
    bool lastEventOverThresh = false;
    unsigned long lastEventTime;
    long minEventTime = 200;
    long maxEventTime = 6000;
    long maxWaveTime = 7000;
    int aThresh = 220;
    void detectWave(float axAvg, float ayAvg, float azAvg) {
    	// check for wave event
    	squeezeDetect(adjPAvg);
    }
    
    void logWave(){
    	sdLogEvent(String("0," + Time.timeStr()));
    	pubLiveData(String("0," + Time.timeStr()));
    	Serial.print("Wave: "); Serial.println(Time.timeStr());
    }
    
    // set timer to block squeezeEvents from happening too quick of succession
    unsigned long lastSqueezeEventTime;
    long nextSqueezeAllowedIn = 4000;
    int squeezeThresh = 250;
    long squeezeStartedAt;
    int squeezeEventDetected = 0;
    void squeezeDetect(long p) {
    	// look for squeeze event
    	tapDetect();
    }
    
    void logSqueeze(){
    	sdLogEvent(String("1," + Time.timeStr()));
    	pubLiveData(String("1," + Time.timeStr()));
    	Serial.print("Squeeze: "); Serial.println(Time.timeStr());
    }
    
    int tap = 0;
    void tapDetect() {
    	tap = accel.readTap();
    	if (tap > 0 && waveCountX < eventsRequired && waveCountY < eventsRequired && waveCountZ < eventsRequired) {
    		logTap();
    		tapOutput(1);
    		waveCountX = 0;
    		waveCountY = 0;
    		waveCountZ = 0;
    	}
    }
    
    void logTap(){
    	sdLogEvent(String("2," + Time.timeStr()));
    	pubLiveData(String("2," + Time.timeStr()));
    	Serial.print("Tap: "); Serial.println(Time.timeStr());
    }
    
    void tapOutput(int c) {
    	int cnt = 0;
    	while(cnt < c) {
    		for (int i = 0; i <= 200; i++) {
    			analogWrite(blueLED1, i);
    			analogWrite(blueLED2, i);
    			delay(7);
    		}
    		for (int i = 200; i >= 0; i--) {
    			analogWrite(blueLED1, i);
    			analogWrite(blueLED2, i);
    			delay(7);
    		}
    		cnt++;
    	}
    }
    
    void squeezeOutput(int c) {
    	int cnt = 0;
    	while(cnt < c) {
    		for (int i = 0; i <= 200; i++) {
    			analogWrite(redLED1, i);
    			analogWrite(redLED2, i);
    			delay(7);
    		}
    		for (int i = 200; i >= 0; i--) {
    			analogWrite(redLED1, i);
    			analogWrite(redLED2, i);
    			delay(7);
    		}
    		cnt++;
    	}
    }
    
    void waveOutput (int c) {
    	int cnt = 0;
    	while(cnt < c) {
    		for (int i = 0; i <= 200; i++) {
    			// analogWrite(redLED, i);
    			analogWrite(greenLED1, i);
    			analogWrite(greenLED2, i);
    			delay(7);
    		}
    		for (int i = 200; i >= 0; i--) {
    			analogWrite(greenLED1, i);
    			analogWrite(greenLED2, i);
    			delay(7);
    		}
    		cnt++;
    	}
    }
    
    char msgType;
    char msgID;
    void getAlertFromOtherBlink(const char *event, const char *data) {
    
    	sdLogEvent(data);
    
    	char* saveptr;  // pointer that will store strtok_r place in the string it's parsing LOCALLY instead of globally like strtok
    	char* copy = strndup(data, strlen(data));  // strndup instead of strdup because it's safe to know exactly how much data to allocate
    	int message = atoi(strtok_r(copy, ",", &saveptr));  // strtok_r instead of strtok because it uses a local pointer instead of a global
    	char* id = strtok_r(NULL, ",", &saveptr);  // strtok_r instead of strtok because it uses a local pointer instead of a global
    	char cpyoftnow[25];  // standard length of a ISO timestamp from Time.timeStr();
    	snprintf(cpyoftnow, sizeof(cpyoftnow), "%s", (const char*)Time.timeStr());  //snprintf instead of strcpy because it knows exactly how many characters to copy over and includes Null termination
    	char buffer[strlen(id) + strlen(cpyoftnow) + 2];  // create a buffer that's the length of the id, timestamp, and 2 more spaces for a comma and NULL terminator
    	snprintf(buffer, sizeof(buffer), "%s,%s", id, cpyoftnow);  //snprintf instead of strcpy because it knows exactly how many characters to copy over and includes Null termination​
    	Particle.publish("topicname", buffer, 60, PRIVATE);
    	free(copy);
    
    	if (message == 0) {
    		waveOutput(3);
    	} else if (message == 1) {
    		squeezeOutput(3);
    	} else if (message == 2) {
    		tapOutput(3);
    	}
    }
    
    int fallHappened = 0;
    int impactHappened = 0;
    const int fallThreshold = 350;
    const int vSumThresh = 2000;
    void detectFall(float ax, float ay, float az) {
    	float vectorSum = sqrt(pow(ax, 2) + pow(ay, 2) + pow(az, 2));
    	if (vectorSum < fallThreshold) {
    		fallHappened = 1;
    		impactHappened = 0;
    		logFall();
    	} else if (fallHappened == 1 && vectorSum > vSumThresh) {
    		impactHappened = 1;
    		fallHappened = 0;
    		logImpact();
    	} else {
    		fallHappened = 0;
    		impactHappened = 0;
    	}
    }
    
    void logFall(){
    	sdLogEvent(String("3," + Time.timeStr()));
    	Serial.print("Fall: "); Serial.println(Time.timeStr());
    }
    
    void logImpact(){
    	sdLogEvent(String("4," + Time.timeStr()));
    	Serial.print("Impact: "); Serial.println(Time.timeStr());
    }
    
    unsigned int inMotion = 0;
    unsigned int motionThreshold = 1080;
    unsigned long motionStartMillis = 0;
    unsigned long motionLatencyMillis = 1000;
    void detectMotion(float ax, float ay, float az){
    	long millisDiff = millis() - motionStartMillis;
    
    	if (inMotion == 0 && vectorSumAvg > motionThreshold && motionStartMillis == 0 && millisDiff > motionLatencyMillis) {
    		motionStartMillis = millis();
    		logMotion("5,");
    		inMotion = 1;
    	} else if (inMotion == 1 && vectorSumAvg < motionThreshold && motionStartMillis > 0 && millisDiff > motionLatencyMillis) {
    		motionStartMillis = 0;
    		logMotion("6,");
    		inMotion = 0;
    	} else if (inMotion == 1 && vectorSumAvg > motionThreshold && millisDiff < motionLatencyMillis) {
    		motionStartMillis = millis();
    	}
    }
    
    void logMotion(String m){
    	sdLogEvent(String(m + Time.timeStr()));
    	Serial.print(m); Serial.println(Time.timeStr());
    }
    
    int lastOrientation = 0;
    bool firstOrientationLogged = false;
    void logOrientation() {
    	// is the current orientation the same as the last
    	int currentOrientation = accel.readPL();
    	if (firstOrientationLogged == false) {
    		lastOrientation = currentOrientation;
    		firstOrientationLogged = true;
    	} else if (firstOrientationLogged == true && lastOrientation != currentOrientation) {
    		sdLogEvent(String("7," + String(currentOrientation) + "," + Time.timeStr()));
    		Serial.print("Orientation changed to "); Serial.print(currentOrientation); Serial.print(": "); Serial.println(Time.timeStr());
    		lastOrientation = currentOrientation;
    	}
    }
    
    const float maxCharge = 77.0;
    const float minCharge = 10.0;
    float lastBatteryPercentage = 0.0;
    bool battLow = false;
    bool battFull = false;
    bool chargingBatt = false;
    void checkBattery() {
    	float batteryPercentage = fuel.getSoC();
    	if (batteryPercentage >= lastBatteryPercentage) {
    		chargingBatt = true;
    	} else if (batteryPercentage < lastBatteryPercentage) {
    		chargingBatt = false;
    	}
    
    	if (batteryPercentage > maxCharge) {
    		battFull = true;
    		battLow = false;
    	} else if (batteryPercentage <= minCharge) {
    		battLow = true;
    		battFull = false;
    	} else if (batteryPercentage < maxCharge && batteryPercentage > minCharge) {
    		battLow = false;
    		battFull = false;
    	}
    
    	lastBatteryPercentage = batteryPercentage;
    }
    
    void logBattery(){
    	float batteryPercentage = fuel.getSoC();
    	float voltage = fuel.getVCell();
    	String ds = String(String(batteryPercentage) + "," + String(voltage) + "," + Time.timeStr());
    	sdLogEvent(ds);
    	pubBattData(ds);
    	Serial.print(batteryPercentage); Serial.print("%,"); Serial.print(voltage); Serial.print(",");  Serial.println(Time.timeStr());
    }
    
    int lastNetStatus = 0;
    void logNetStatus(){
    	int netStatus = Cellular.ready();
    	if (lastNetStatus == 1 && netStatus == 0) {
    		// if it was connected but isn't now
    		lastNetStatus = 0;
    		sdLogEvent(String("8," + Time.timeStr()));
    		Serial.print("Network Disconnected: "); Serial.println(Time.timeStr());
    	} else if (lastNetStatus == 0 && netStatus == 1) {
    		// if it was NOT connected but is now
    		lastNetStatus = 1;
    		sdLogEvent(String("9," + Time.timeStr()));
    	}
    }
    
    // id the last file in dir and return it, or open a new one if its size is over the limit
    unsigned long maxFileSize = 1000000;     // in bytes 1000000 = 1mb
    void readDirectory() {
    	root.rewindDirectory();
    	String fExt = ".txt";
    	int fileCounter = 0;
    	unsigned long lastFileSize = 0;
    	String lastFileName;
    
    	while (true) {
    		File f = root.openNextFile();
    		if (!f && fileCounter == 0) { // there are no files present at all
    			f.close();
    			String fileIndex = String(fileCounter);
    			String fileName = String(fileIndex + fExt);
    			dataFile = sd.open(fileName, FILE_WRITE);
    			// Serial.print("no files present. new file name: "); dataFile.printName(); Serial.println();
    			break;
    		} else if (!f && fileCounter > 0 && lastFileSize > maxFileSize) { // no more files, the last file is too big to open
    			f.close();
    			String fileIndex = String(fileCounter);
    			String fileName = String(fileIndex + fExt);
    			dataFile = sd.open(fileName, FILE_WRITE);
    			// Serial.print("no more files to count and last file too big to open. new file name: "); dataFile.printName(); Serial.println();
    			break;
    		} else if (!f && fileCounter > 0 && lastFileSize < maxFileSize) { // no more files, the last file is small enough to open
    			String fniString = String(fileCounter - 1);
    			String fileName = String(fniString + fExt);
    			f.close();
    			dataFile = sd.open(fileName, FILE_WRITE);
    			// Serial.print("lastFileSize: "); Serial.println(lastFileSize);
    			// Serial.print("last file was small enough to use again. file name: "); Serial.println(fileName);
    			break;
    		} else {
    			fileCounter++;
    			lastFileSize = f.size();
    		}
    	}
    }
    
    bool battMessageSent = false;
    bool receivedBattNotification = false;
    void pubBattData (String dataString) {
    	Particle.publish("topicname", dataString, PRIVATE);
    	Serial.println("publishing battdata...");
    }
    
    bool eventMessageSent = false;
    bool receivedEventNotification = false;
    void pubLiveData(String dataString) {
    	Particle.publish("topicname", dataString, PRIVATE);
    	Serial.println("publishing live event data...");
    }
    
    void sdLogEvent(String dataString) {
    	// if the file is available, write to it:
    	if (dataFile) {
    		dataFile.println(dataString);
    		dataFile.flush();
    	} else {
    		Serial.print("error opening "); Serial.println(dataFile.printName());
    	}
    }
    
    void setup() {
    	Serial.println("test");
    	pinMode(greenLED1, OUTPUT);
    	pinMode(redLED1, OUTPUT);
    	pinMode(blueLED1, OUTPUT);
    	pinMode(greenLED2, OUTPUT);
    	pinMode(redLED2, OUTPUT);
    	pinMode(blueLED2, OUTPUT);
    
    	Serial.begin(9600);
    	while (!Serial) {
    		; // wait for serial port to connect. Needed for native USB port only
    	}
    	accel.begin(SCALE_2G, ODR_800); // Init and customize the FSR and ODR
    	accel.setupTap(0x2F, 0x2F, 0x2F, 0x1E, 0x32, 0xC8);
    	accel.setupPL();
    	getCalibrationData();
    	lastSqueezeEventTime = millis();
    
    	String sysId = System.deviceID();
    	String topicName = String("topicname/" + sysId);
    	Particle.subscribe(topicName, getAlertFromOtherBlink, MY_DEVICES); // subscribes to the M2X server response from other Blink
    	Particle.publish("topicname", "restart", PRIVATE);
    
    	Serial.print("Initializing SD card...");
    	// see if the card is present and can be initialized:
    	if (!sd.begin(chipSelect)) {
    		Serial.println("Card failed, or not present");
    		return;
    	}
    	Serial.println("card initialized.");
    	root = sd.open("/");
    	readDirectory();
    }
    
    bool msgToSend = 0;
    bool battLowLedOn = false;
    unsigned long previousMillis = 0;
    const long interval = 300000;
    void loop() {
    	if (accel.available()) {
    		accel.read(); // Update acceleromter data
    		AcX = accel.x;
    		AcY = accel.y;
    		AcZ = accel.z;
    	}
    
    	if (dataFile.size() > maxFileSize) {
    		readDirectory();
    	}
    
    	readSensor();
    	smoothData(AcX, AcY, AcZ);
    	detectFall(AcX, AcY, AcZ);
    	detectMotion(AcX, AcY, AcZ);
    	logOrientation();
    	logNetStatus();
    
    	unsigned long currentMillis = millis();
    	if (currentMillis - previousMillis >= interval) {
    		logBattery();
    		previousMillis = currentMillis;
    	}
    
    	checkBattery();
    	delay(25);
    }

@khansen, can you post your code?

added it to the original post. i tried to pare it down some and left out some of the code that’s just processing data.

@khansen, you Serial.println() before you Serial.begin()! On the photon this is not an issue because the Serial object is already started by the system firmware. However, I suggest fixing the order. Also, you may, for testing purposes, change the while(!Serial) to while(!Serial.available()) Particle.process(); so that the code will wait for you to hit a key before continuing. Try that to see what prints. Another potential problem is the return; in your SD initialization code. This command will cause a return from “setup()” back to the system firmware which will then run loop()! You may want to consider replacing it with while(1) Particle.process(); to prevent further code execution.

BTW, you set some bool variables to “zero” others to “false”. You may want to stick to the true or false convention. :grinning:

1 Like

Thanks for the tips! Made the change on the return in setup().

I should have also pointed out earlier that all of this code worked w/o this issue previously. This is a relatively new problem (since just before Turkey Day), and more importantly it’s an intermittent problem. Sometimes it’s an issue, but not every time the device is turned on or reset.