Electron: Collect data every minute, publish it every 15 minutes - with sleep. Better way to do this?

Latest working…

Particle IDE Share

//////////////////////////////////////////////////////////////////////////////////////////////////////
//     THIS SKETCH IS TO GATHER READINGS FROM SENSORS, IN THIS CASE THE BNO055, ADS1115, AND        //
//     MCP9808, AT A USER SET TIME INTERVAL (SET IN SECONDS) TO THEN BE PUBLISHED OUT ONCE THE      //
//     DESIRED NUMBER OF SAMPLES HAS BEEN OBTAINED.                                                 //
//     DURING THIS, IF AN EVENT IS TRIGGERED - A STATE WHERE IF ANY ONE OF THE SENSOR'S VALUE       //
//     DIFFERS MORE THEN THE LAST FOUR VALUES AVERAGED TOGETHER + SENSOR ALERT SETPOINT             //
//     (sensor_alert_thrshld[X]), THE SENSOR SAMPLE TIME INTERVAL IS CHANGED UNTIL THE DEFINED      //
//     NUMBER OF PUBLISHED ALERT EVENTS HAS OCCURRED.                                               //
//     CONFIGURABLE SETTINGS ARE BELOW, UNDER *USER CONFIGURABLE PARAMETERS*			    //
//												    //
//	Following components are used:								    //
//	   -Pololu #2562, 5V Step-Up Voltage Regulator, https://www.pololu.com/product/2562/   	    //
//	    (100k onboard pullup removed, replaced with external 10k pulldown) 			    //
//	   -ADS1115 16-Bit ADC - 4 Channel, https://www.adafruit.com/product/1085		    //
//	   -MCP9808 High Accuracy I2C Temperature Sensor, https://www.adafruit.com/product/1782	    //
//	   -BNO055 9-DOF Absolute Orientation IMU Fusion, https://www.adafruit.com/product/2472	    //
//////////////////////////////////////////////////////////////////////////////////////////////////////

#include "Particle.h"
#include "particle-BNO055.h"
#include <Wire.h>
#include <ADS1115.h>
#include "MCP9808.h"
#include <math.h>

SYSTEM_MODE(AUTOMATIC)
SYSTEM_THREAD(ENABLED)

ADS1115 ads;
MCP9808 mcp = MCP9808();
Adafruit_BNO055 bno = Adafruit_BNO055(55);

///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ BEGIN USER CONFIGURABLE PARAMETERS \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

// SAMPLE & PUBLISH SETTINGS //
int norm_smpl_intvl = 60;	// SAMPLE INTERVAL, HOW MANY SECONDS TO WAIT BETWEEN EACH
const int rnds_to_publish = 5;	// WAIT UNTIL x NUMBER OF SAMPLES ARE GATHERED TO BURST PUBLISH
int do_publish = 1;		// PERFORM PARTICLE.PUBLISH EVENTS

// SENSOR REPORT CONFIG
const int no_of_sensors = 8; 	// THE NUMBER OF SENSOR READINGS TO COLLECT PER SAMPLE
// 				                   ▼ THE LENGTH OF EACH SENSOR'S VALUE
int sensorlen[no_of_sensors] = {4, 4, 4, 4, 3, 3, 3, 3};

// ALAERT SETTING //
int alert_smpl_intvl = 10;	 // ALERT SAMPLE INTERVAL, HOW MANY SECONDS TO WAIT BETWEEN EACH
const int alrt_publish_rnds = 2; // WHILE IN SENSOR ALERT - HOW MANY COMPLETE PUBLISH CYCLES TO LOOP THROUGH
// 					                           ▼ SET ARRAY FOR SENSOR ALERT
int sensor_alert_thrshld[no_of_sensors] = {999, 999, 999, 999, 2, 15, 15, 15};

// POWER SETTINGS //
int solar_opt = 0;		// SOLAR OPTIMIZATION, 0 = SOLAR OPT OFF, 5 = 5V SOLAR PANEL, 6 = 6V SOLAR PANEL
int enable_wop = 0;		// ENABLE WAKE-ON-PING
int sleep = 1;			// SLEEP MODE ON = 1 / SLEEP MODE OFF = 0
int sleep_wait = 1;		// TIME TO WAIT AFTER PUBLISH TO FALL ASLEEP
int secs_less_intrvl_sleep = 0; // ADDITIONAL SECONDS TO DELAY FROM SAMPLE INTERVAL FOR SLEEP TIME, 5 SECONDS ARE ALREADY SUBTRACTED
int app_watchdog = 360000;	// APPLICATION WATCHDOG TIME TRIGGER IS MS - SLEEP TIME SHOULD NOT BE COUNTED

///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ END USER CONFIGURABLE PARAMETERS \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

// DECLARE ITEMS USED AND SET INITIAL PARAMETERS
int alert_sample_qty = ((rnds_to_publish * alrt_publish_rnds) + 1); // HOW MANY SENSOR SAMPLES TO TAKE WHILE IN EVENT/ALERT MODE
float storage[(rnds_to_publish + 1)][no_of_sensors];	// DIMENSION THE STORAGE CONTAINER ARRAY
int current_smpl_intvl = norm_smpl_intvl;		// SET CURRENT SAMPLE INTERVAL TO NORMAL SAMPLE INTERVAL AS ABOVE
char fullpublish[500];					// CONTAINS THE STRING TO BE PUBLISHED
char fullpub_temp1[16];					// TEMPORARY HOLDING STRING USED FOR FULLPUBLISH EVENT
int alrt_ckng_tmp = 0;					// USED AS A TEMP CONTAINER IN SENSOR ALERT CHECKING
int w = 0;						// THE NUMBER OF SAMPLES TO GATHER
int x = 0;						// THE NUMBER OF SAMPLES COUNTER
int xa = 0;						// THE NUMBER OF SAMPLES COUNTER in ALERT STATE
int y = 0;						// THE SAMPLE PER COUNT GATHERED
int smpls_performed = 0;				// COUNTER FOF ALL SAMPLES PERFORMED
int sensor_event_chk = 0;				// SENSOR SAMPLE EVENT CHECK
int sensor_hist_depth = 0;				// SENSOR SAMPLE EVENT CHECK DEPTH
int alert_cycl_mark = 0;				// CYCLE MARK BASED ON 'smpls_performed' TO CONTINUE ALERT REPORTING
int t2 = 0;						// EQUALS TIME(0) + norm_smpl_intvl, USED TO DETERMINE WHEN TO TAKE SAMPLE
int alrt_state_chng = 0;				// CHANGE IN ALERT STATE FLAG
float sensor_value[no_of_sensors][7];			// DIMENSION THE SENSOR VALUE ARRAY
int vcell;						// BATTERY INFO
int vsoc;						// BATTERY INFO
int a = 0;						// GP TIMER USE
int published_norm1_or_alert2 = 0;			// TYPE OF PUBLISH LAST PERFORMED
int sla = 0;						// USED IN CREATION OF PREAMBLE
int led1 = D7;						// ONBOARD BLUE LED
int volt5 = D6;						// 5V STEP-UP VOLTAGE REGULATOR ON/OFF CONTROL (SAME CONTROL AS LED) 
int16_t adc0, adc1, adc2, adc3;				// IMU
float adcx0, adcx1, adcx2, adcx3;			// IMU
int sleeptime = 0;					// SLEEP DURATION
// END OF DECLARATIONS AND INITIAL PARAMETERS

void i2cWake()
{
	//WAKE UP i2c DEVICES
	digitalWrite(volt5, HIGH);			// TURN ON 5 VOLT REGULATOR
	ads.setMode(MODE_CONTIN);			// SET ADC SAMPLING MODE AS CONTINUOUS
	mcp.setPowerMode(MCP9808_CONTINUOUS);		// SET TEMP SENSOR MODE AS CONTINUOUS 
	Wire.beginTransmission(0x28);			// TURN IMU ON
	Wire.write(0x3E);				// TURN IMU ON
	Wire.write(0x00);				// TURN IMU ON
	Wire.endTransmission();				// TURN IMU ON
}

void i2cSleep()
{
	//PUT i2c DEVICES TO SUSPEND
	ads.setMode(MODE_SINGLE);			// SET ADC SAMPLING MODE AS CONTINUOUS
	mcp.setPowerMode(MCP9808_LOW_POWER);		// SET TEMP SENSOR MODE AS CONTINUOUS
	Wire.beginTransmission(0x28);			// TURN IMU ON
	Wire.write(0x3E);				// TURN IMU ON
	Wire.write(0x02);				// TURN IMU ON
	Wire.endTransmission();				// TURN IMU ON
	digitalWrite(volt5, LOW);			// TURN OFF 5 VOLT REGULATOR
}

void preamble()
{
	// PUT PREAMBLE ON DATA
	fullpub_temp1[0] = 0;
	fullpublish[0] = 0;

	snprintf(fullpub_temp1, sizeof(fullpub_temp1), "%d%d", alrt_state_chng, no_of_sensors);
	strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1);

	for (sla = 0; sla < no_of_sensors; sla++)
	{
		snprintf(fullpub_temp1, sizeof(fullpub_temp1), "%d", sensorlen[sla]);
		strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1);
	}
}

void fullpublishout()
{
	Particle.publish("a", fullpublish, 60, PRIVATE, NO_ACK); // PARTICLE.PUBLISH EVENT ! ! ! !

	digitalWrite(led1, HIGH);

	for (uint32_t ms = millis(); millis() - ms < 500; Particle.process())
		;
	digitalWrite(led1, LOW);
}

void setup()
{
	Serial.begin(9600);

	pinMode(led1, OUTPUT);
	pinMode(volt5, OUTPUT);

	digitalWrite(volt5, HIGH);

	// SOLAR SETTINGS //
	if (solar_opt)
	{
		PMIC pmic; //INITIALIZE THE PMIC CLASS TO CALL THE POWER MANAGEMENT FUNCTIONS BELOW

		pmic.setChargeCurrent(0, 0, 1, 0, 0, 0); //SET CHARGING CURRENT TO 1024MA (512 + 512 OFFSET)

		if (solar_opt == 5)
			pmic.setInputVoltageLimit(4840); //SET THE LOWEST INPUT VOLTAGE TO 4.84 VOLTS, FOR 5V SOLAR PANEL

		if (solar_opt == 6)
			pmic.setInputVoltageLimit(5080); //SET THE LOWEST INPUT VOLTAGE TO 5.08 VOLTS, FOR 6V SOLAR PANEL
	}

	Wire.begin(); // INITIALIZE I2C
	for (uint32_t ms = millis(); millis() - ms < 500;)
		;

	bno.begin(); // INITIALIZE IMU
	for (uint32_t ms = millis(); millis() - ms < 500;)
		;

	bno.setExtCrystalUse(true);
	ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS); // (ADDR = GND)
	ads.setGain(GAIN_TWOTHIRDS);	// 2/3x gain +/- 6.144V  1 bit = 0.1875mV
	ads.setMode(MODE_CONTIN);	// ads.setMode(MODE_CONTIN) = Continuous conversion mode - ads.setMode(MODE_SINGLE); Power-down single-shot mode (default)
	ads.setRate(RATE_128);		// 128SPS (default) 8,16,32,64,128,250,475,860
	ads.setOSMode(OSMODE_SINGLE);	// Set to start a single-conversion
	ads.begin();
	mcp.setResolution(MCP9808_SLOWEST);

	i2cWake();
}

ApplicationWatchdog wd(app_watchdog, System.reset);

void loop()
{
	FuelGauge fuel;

	if (a == 0 && fuel.getSoC() > 20)
	{
		if (enable_wop)
			Cellular.command("AT+URING=1\r\n");

		for (uint32_t ms = millis(); millis() - ms < 1000; Particle.process())
			Particle.publish("a", "9 - DEVICE ONLINE!", 60, PRIVATE, NO_ACK); // LET SERVER KNOW ONLINE!

		digitalWrite(led1, HIGH);

		for (uint32_t ms = millis(); millis() - ms < 1000; Particle.process())
			;

		digitalWrite(led1, LOW);
		a = 2;
	}

	if (fuel.getSoC() < 20) //LOW BATTERY DEEP SLEEP
	{
		if (a != 0)
			Particle.publish("a", "9 - DEVICE SHUTTING DOWN, BATTERY SoC < 20!", 60, PRIVATE, NO_ACK); // LET SERVER KNOW WE ARE GOING TO SLEEP

		for (uint32_t ms = millis(); millis() - ms < 5000; Particle.process()) //EXTRA TIME BEFORE DEEP SLEEP
			;

		System.sleep(SLEEP_MODE_DEEP, 7200); // SLEEP 2 HOURS IF SoC < 20
	}

	///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ START SENSOR VALUE GATHERING \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

	// SENSOR VALUES GO INTO THE sensor_value[X][0] ARRAY WHERE 'X' IS THE SENSOR NUMBER
	// sensor_value[1][0] = SENSOR 1, SENSOR VALUE
	// sensor_value[1][1-4] = SENSOR 1, HISTORICAL SENSOR VALUES
	// sensor_value[1][5] = SENSOR 1, HISTORICAL SENSOR VALUE AVERAGE OF ALL FOUR

	adc0 = ads.Measure_SingleEnded(0); //ADS1115 VOLTAGE READING 1
	adcx0 = ((0.1875 * adc0) / 1000);
	sensor_value[0][0] = adcx0;

	adc1 = ads.Measure_SingleEnded(1); //ADS1115 VOLTAGE READING 2
	adcx1 = ((0.1875 * adc1) / 1000);
	sensor_value[1][0] = adcx1;

	adc2 = ads.Measure_SingleEnded(2); //ADS1115 VOLTAGE READING 3
	adcx2 = ((0.1875 * adc2) / 1000);
	sensor_value[2][0] = adcx2;

	adc3 = ads.Measure_SingleEnded(3); //ADS1115 VOLTAGE READING 4
	adcx3 = ((0.1875 * adc3) / 1000);
	sensor_value[3][0] = adcx3;

	int tempget = fabs(10 * mcp.getTemperature()); //MCP9808 TEMP READING
	sensor_value[4][0] = tempget;

	sensors_event_t event; //BNO055 SAMPLE GATHERING
	bno.getEvent(&event);

	float orx = event.orientation.x; // BNO055 ORIENTATION X
	// MAKE ORX RELATIVE TO 180'
	int orxt1 = int(orx) - 180;
	orxt1 = abs((orxt1 + 180) % 360 - 180);
	int orxt2 = 180 - int(orx);
	orxt2 = abs((orxt2 + 180) % 360 - 180);
	if (orxt1 > orxt2)
		sensor_value[5][0] = float(orxt2);
	else
		sensor_value[5][0] = float(orxt1);

	float ory = event.orientation.y; // BNO055 ORIENTATION Y
	ory = ory + 180;
	sensor_value[6][0] = ory;

	float orz = event.orientation.z; // BNO055 ORIENTATION Z
	orz = orz + 180;
	sensor_value[7][0] = orz;

	///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ END SENSOR VALUE GATHERING \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

	///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/GATHER, EVENT CHECK, AND PUBLISH \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

	//-- ALERT CHECK --
	if (sensor_hist_depth == 4)
	{
		sensor_hist_depth = 1;
	}
	else
	{
		sensor_hist_depth++;
	}
	// CYCLE THROUGH 1 - 4 FOR HISTORY / AVERAGING
	for (w = 0; w < no_of_sensors; w++)
	{
		sensor_value[w][5] = ((sensor_value[w][1] + sensor_value[w][2] + sensor_value[w][3] + sensor_value[w][4]) / 4);
		sensor_value[w][sensor_hist_depth] = sensor_value[w][0];

		if (smpls_performed > 4)
		{
			alrt_ckng_tmp = fabs(sensor_value[w][0] - sensor_value[w][5]);
			sensor_value[w][6] = alrt_ckng_tmp;

			if (alrt_ckng_tmp > sensor_alert_thrshld[w])
			{
				Serial.printf("OOS Sensor %d, ", w);
				Serial.printlnf("Diff: %d, Threshold: %d.", alrt_ckng_tmp, sensor_alert_thrshld[w]);

				if (alrt_state_chng != 2)
				{
					alrt_state_chng = 1; // SIGNIFIES FRESH CHANGE INTO ALERT STATE SO PUBLISHER WILL PUBLISH STORAGE AND THEN START ALERT REPORTING
				}

				alert_cycl_mark = smpls_performed + alert_sample_qty;
			}
		}
	}
	//-- END OF ALERT CHECK

	//-- START SAMPLING TIME CHECK --
	if (Time.now() >= t2)
	{
		for (w = 0; w < no_of_sensors; w++)
		{
			storage[x][w] = sensor_value[w][0];
		} //PLACE SENSOR VALUES IN STORAGE ARRAY
		x++;

		t2 = Time.now() + current_smpl_intvl;

		if (alert_cycl_mark > smpls_performed)
		{
			Serial.println("!");
			published_norm1_or_alert2 = 2;
		}
		else
		{
			Serial.println(".");
			published_norm1_or_alert2 = 1;
		}

		smpls_performed++;

		if (smpls_performed > alert_cycl_mark)
			current_smpl_intvl = norm_smpl_intvl;

		wd.checkin(); // SOFTWARE WATCHDOG CHECK-IN

		if (alert_cycl_mark == (smpls_performed + 1))
			alrt_state_chng = 3;
	}
	//-- END SAMPLING TIME CHECK --

	//-- BEGIN ALERT STATE PUBLISH FLUSH --
	if ((alrt_state_chng == 3) || (alrt_state_chng == 1))
	{
		preamble();
		for (xa = 0; xa < x; xa++)
		{
			for (y = 0; y < no_of_sensors; y++)
			{
				if (y < 4)
				{ //THIS IS TO LET THE FIRST FOUR READINGS HAVE TWO DECIMAL PLACES
					snprintf(fullpub_temp1, sizeof(fullpub_temp1), "%0*.2f", sensorlen[y], storage[xa][y]);
				}
				else
				{
					snprintf(fullpub_temp1, sizeof(fullpub_temp1), "%0*.0f", sensorlen[y], storage[xa][y]);
				}
				strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1); // better to check the boundaries
			}
		} // BUILT FULLPUBLISH STRING
		x = 0;
		xa = 0;

		FuelGauge fuel; // GET BATTERY INFO
		fullpub_temp1[0] = 0;

		snprintf(fullpub_temp1, sizeof(fullpub_temp1), "E%d%d%dT%ld", current_smpl_intvl, ((int)(fuel.getVCell() * 100)), ((int)(fuel.getSoC() * 100)), (t2 - Time.now())); // ADDING SAMPLE RATE, BATTERY INFO
		strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1);

		Serial.println(fullpublish);
		Serial.printf("ASP: The size of published string is %d bytes. \n", strlen(fullpublish));

		if (do_publish)
			fullpublishout();

		if (alrt_state_chng == 1)
		{
			current_smpl_intvl = alert_smpl_intvl;
			t2 = Time.now() + current_smpl_intvl;
		}

		if (alrt_state_chng == 3)
		{
			alrt_state_chng = 0;
			current_smpl_intvl = norm_smpl_intvl;
			t2 = Time.now() + current_smpl_intvl;
		}

		//-- SEND OUT SYSTEM NOTE TO ALERT OOS AND FOR ON THE SPOT SENSOR VALUE REPORTING
		if (alrt_state_chng == 1)
		{
			fullpub_temp1[0] = 0;
			fullpublish[0] = 0;

			snprintf(fullpub_temp1, sizeof(fullpub_temp1), "9 - OOS: ");
			strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1);

			for (y = 0; y < no_of_sensors; y++)
			{
				if (y < 4)
				{ //THIS IS TO LET THE FIRST FOUR READINGS HAVE TWO DECIMAL PLACES
					snprintf(fullpub_temp1, sizeof(fullpub_temp1), "  '%0*.2f'%s%.0f>%d", sensorlen[y], sensor_value[y][0], ((sensor_value[y][6] > sensor_alert_thrshld[y]) ? "▲" : ":"), sensor_value[y][6], sensor_alert_thrshld[y]);
				}
				else
				{
					snprintf(fullpub_temp1, sizeof(fullpub_temp1), "  '%0*.0f'%s%.0f>%d", sensorlen[y], sensor_value[y][0], ((sensor_value[y][6] > sensor_alert_thrshld[y]) ? "▲" : ":"), sensor_value[y][6], sensor_alert_thrshld[y]);
				}
				strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1); // better to check the boundaries
			}

			FuelGauge fuel; // GET BATTERY INFO

			fullpub_temp1[0] = 0;

			Serial.println(fullpublish);
			Serial.printf("The size of published string is %d bytes. \n", strlen(fullpublish));

			if (do_publish)
				fullpublishout();

			alrt_state_chng = 2;
		}
		//-- END SEND OUT SYSTEM NOTE TO ALERT OOS
	}
	//-- END ALERT STATE PUBLISH FLUSH --

	else

	//-- START NORMAL CHECK AND PUBLISH --
	{
		if (x == rnds_to_publish)
		{
			preamble();
			for (x = 0; x < rnds_to_publish; x++)
			{
				for (y = 0; y < no_of_sensors; y++)
				{
					if (y < 4)
					{ //THIS IS TO LET THE FIRST FOUR READINGS HAVE TWO DECIMAL PLACES
						snprintf(fullpub_temp1, sizeof(fullpub_temp1), "%0*.2f", sensorlen[y], storage[x][y]);
					}
					else
					{
						snprintf(fullpub_temp1, sizeof(fullpub_temp1), "%0*.0f", sensorlen[y], storage[x][y]);
					}
					strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1); // better to check the boundaries
				}
			} // BUILT FULLPUBLISH STRING
			x = 0;
			FuelGauge fuel; // GET BATTERY INFO
			fullpub_temp1[0] = 0;

			snprintf(fullpub_temp1, sizeof(fullpub_temp1), "E%d%d%dT%ld", current_smpl_intvl, ((int)(fuel.getVCell() * 100)), ((int)(fuel.getSoC() * 100)), (t2 - Time.now())); // ADDING SAMPLE RATE, BATTERY INFO
			strncat(fullpublish, fullpub_temp1, sizeof(fullpublish) - strlen(fullpublish) - 1);

			Serial.println(fullpublish);
			Serial.printf("The size of published string is %d bytes. \n", strlen(fullpublish));

			if (do_publish)
				fullpublishout();

			fullpublish[0] = 0; // CLEAR THE FULLPUBLISH STRING
		}
		//-- END SAMPLES TAKEN CHECK AND PUBLISH --
	}

	//-- BEDTIME CHECK --
	if (sleep == 1)
	{
		if (published_norm1_or_alert2 == 1 && norm_smpl_intvl > 23 && t2 >= (Time.now() + sleep_wait))
			sleeptime = (((norm_smpl_intvl - secs_less_intrvl_sleep) - sleep_wait) - 5);

		if (published_norm1_or_alert2 == 2 && alert_smpl_intvl > 23 && t2 >= (Time.now() + sleep_wait))
			sleeptime = (((alert_smpl_intvl - secs_less_intrvl_sleep) - sleep_wait) - 5);

		if (enable_wop == 1 && sleeptime)
		{
			i2cSleep();
			System.sleep({RI_UC, BTN}, {RISING, FALLING}, sleeptime, SLEEP_NETWORK_STANDBY);
			i2cWake();
			Cellular.command("AT+URING=0\r\n");
			Cellular.command("AT+URING=1\r\n");
		}

		if (enable_wop == 0 && sleeptime)
		{
			i2cSleep();
			System.sleep(BTN, FALLING, sleeptime, SLEEP_NETWORK_STANDBY);
			i2cWake();
		}

		sleeptime = 0;
		published_norm1_or_alert2 = 0;
	}
	//-- END BEDTIME CHECK --

	///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ END GATHER, EVENT CHECK, AND PUBLISH \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
	for (uint32_t ms = millis(); millis() - ms < 700;)
		;
}