-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
163 additions
and
0 deletions.
There are no files selected for viewing
163 changes: 163 additions & 0 deletions
163
examples/Example7_PowerControl/Example7_PowerControl.ino
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
|
||
} |