Skip to content

Commit

Permalink
Add new Power Control example
Browse files Browse the repository at this point in the history
  • Loading branch information
rayozzie committed Mar 4, 2022
1 parent 07799cf commit c6648e5
Showing 1 changed file with 163 additions and 0 deletions.
163 changes: 163 additions & 0 deletions examples/Example7_PowerControl/Example7_PowerControl.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
//
// Copyright 2022 Blues Inc. All rights reserved.
// Use of this source code is governed by licenses granted by the
// copyright holder including that found in the LICENSE file.
//
// This example contains the complete source for the Sensor Tutorial at dev.blues.io
// https://dev.blues.io/build/tutorials/sensor-tutorial/notecarrier-af/esp32/arduino-wiring/
//
// This tutorial requires a Notecarrier-F (or equivalently-wired carrier board) designed
// enable the Notecard's ATTN pin to control a host MCU's power supply.
//

#include <Notecard.h>
#include <Wire.h>

// Parameters for this example
#define notehubProductUID "com.your_company.your_name:your_project" // if you're your_name@your_company.com
#define notehubUploadPeriodMins 10
#define hostSleepSeconds 60

// Arduino serial debug monitor port definitions
#define serialDebug Serial

// Notecard I2C port definitions
Notecard notecard;

// When the Notecard puts the host MCU to sleep, it enables the host to save 'state' inside the
// notecard while it's asleep, and to retrieve this state when it awakens. These are several
// 'segments' of state that may individually be saved.
struct {
int cycles;
} globalState;
const char globalSegmentID[] = "GLOB";

struct {
int measurements;
} tempSensorState;
const char tempSensorSegmentID[] = "TEMP";

struct {
int measurements;
} voltSensorState;
const char voltSensorSegmentID[] = "VOLT";

// One-time Arduino initialization
void setup()
{

// Arduino IDE requires a delay to move the serial port over
// from programming the MCU to the debug monitor.
delay(2500);
serialDebug.begin(115200);
notecard.setDebugOutputStream(serialDebug);

// Initialize the physical I2C I/O channel to the Notecard
Wire.begin();
notecard.begin();

// Determine whether or not this is a 'clean boot', or if we're
// restarting after having been put to sleep by the Notecard.
NotePayloadDesc payload;
bool retrieved = NotePayloadRetrieveAfterSleep(&payload);

// If the payload was successfully retrieved, attempt to restore state from the payload
if (retrieved) {

// Restore the various state data structures
retrieved &= NotePayloadGetSegment(&payload, globalSegmentID, &globalState, sizeof(globalState));
retrieved &= NotePayloadGetSegment(&payload, tempSensorSegmentID, &tempSensorState, sizeof(tempSensorState));
retrieved &= NotePayloadGetSegment(&payload, voltSensorSegmentID, &voltSensorState, sizeof(voltSensorState));

// We're done with the payload, so we can free it
NotePayloadFree(&payload);

}

// If this is our first time through, initialize the Notecard and state
if (!retrieved) {

// Initialize operating state
memset(&globalState, 0, sizeof(globalState));
memset(&tempSensorState, 0, sizeof(tempSensorState));
memset(&voltSensorState, 0, sizeof(voltSensorState));

// Initialize the Notecard
J *req = NoteNewRequest("hub.set");
JAddStringToObject(req, "product", notehubProductUID);
JAddStringToObject(req, "mode", "periodic");
JAddNumberToObject(req, "outbound", notehubUploadPeriodMins);
NoteRequest(req);

// Because many devs will be using oscilloscopes or joulescopes to closely examine power
// consumption, it can be helpful during development to provide a stable and repeatable
// power consumption environment. In the Notecard's default configuration, the
// accelerometer is 'on'. As such, when debugging, devs may see tiny little blips from
// time to time on the scope. These little blips are caused by accelerometer interrupt
// processing, when developers accidentally tap the notecard or carrier. As such,
// to help during development and measurement, this request disables the accelerometer.
req = NoteNewRequest("card.motion.mode");
JAddBoolToObject(req, "stop", true);
NoteRequest(req);

}

}

void loop()
{

// Bump the number of cycles
globalState.cycles++;

// Simulation of a device taking a measurement of a temperature sensor. Because we
// don't have an actual external hardware sensor in this example, we're just retrieving
// the internal surface temperature of the Notecard.
double currentTemperature = 0.0;
J *rsp = NoteRequestResponse(NoteNewRequest("card.temp"));
if (rsp != NULL) {
currentTemperature = JGetNumber(rsp, "value");
NoteDeleteResponse(rsp);
tempSensorState.measurements++;
}

// Simulation of a device taking a measurement of a voltage sensor. Because we
// don't have an actual external hardware sensor in this example, we're just retrieving
// the battery voltage being supplied to the Notecard.
double currentVoltage = 0.0;
rsp = NoteRequestResponse(NoteNewRequest("card.voltage"));
if (rsp != NULL) {
currentVoltage = JGetNumber(rsp, "value");
NoteDeleteResponse(rsp);
voltSensorState.measurements++;
}

// Add a note to the Notecard containing the sensor readings
J *req = NoteNewRequest("note.add");
if (req != NULL) {
JAddStringToObject(req, "file", "example.qo");
J *body = JCreateObject();
if (body != NULL) {
JAddNumberToObject(body, "cycles", globalState.cycles);
JAddNumberToObject(body, "temperature", currentTemperature);
JAddNumberToObject(body, "temperature_measurements", tempSensorState.measurements);
JAddNumberToObject(body, "voltage", currentVoltage);
JAddNumberToObject(body, "voltage_measurements", voltSensorState.measurements);
JAddItemToObject(req, "body", body);
}
NoteRequest(req);
}

// Put ourselves back to sleep for a fixed period of time
NotePayloadDesc payload = {0, 0, 0};
NotePayloadAddSegment(&payload, globalSegmentID, &globalState, sizeof(globalState));
NotePayloadAddSegment(&payload, voltSensorSegmentID, &voltSensorState, sizeof(voltSensorState));
NotePayloadAddSegment(&payload, tempSensorSegmentID, &tempSensorState, sizeof(tempSensorState));
NotePayloadSaveAndSleep(&payload, hostSleepSeconds, NULL);

// We should never return here, because the Notecard put us to sleep. If we do
// get here, it's because the Notecarrier was configured to supply power to this
// host MCU without being switched by the ATTN pin.
delay(15000);

}

0 comments on commit c6648e5

Please sign in to comment.