Skip to content

Commit

Permalink
Timestamp in metrics; vsys measurement support; voltage, heap, and rs…
Browse files Browse the repository at this point in the history
…si metrics (#1)

* Add timestamp of measurement to metrics

* Add support for heap, rssi, and battery voltage

* Also tweak the headers handler to avoid a concat
  • Loading branch information
gcochard authored Apr 7, 2023
1 parent fcee904 commit ab0fa07
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 18 deletions.
109 changes: 93 additions & 16 deletions arduino-bsec-wifi.ino
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,57 @@ static uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE];
/* Gas estimate names will be according to the configuration classes used */
const String gasName[] = { "Field Air", "Hand sanitizer", "Undefined 3", "Undefined 4"};

/**
* Battery measurement support!
* Mostly taken directly from https://github.com/raspberrypi/pico-examples/pull/326
* Seems to work even within an HTTP request handler!
*/
#include "pico/cyw43_arch.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"
#include "pico/cyw43_arch/arch_threadsafe_background.h" //to get access to void cyw43_thread_enter(void); and void cyw43_thread_exit(void);
#ifndef CYW43_WL_GPIO2
#define CYW43_WL_GPIO2 2 //this is not defined in pico_w.h
#endif
const float VSYS_CONVERSION_FACTOR = 3 * 3.3f / (1 << 12);
//Set GPIO29 back to settings for wifi usage (shared pin with ADC3, so settings are changed when activating ADC3)
void SetGPIO29WifiStatus(){
gpio_set_function(29, GPIO_FUNC_PIO1); //7
gpio_pull_down(29);
gpio_set_slew_rate(29, GPIO_SLEW_RATE_FAST); //1
gpio_set_drive_strength(29, GPIO_DRIVE_STRENGTH_12MA); //3
}

float measureVsys(){
//WL_GPIO2, IP VBUS sense - high if VBUS is present, else low
uint vbus = cyw43_arch_gpio_get(CYW43_WL_GPIO2);
if(vbus == 0){
// low, on battery, measure voltage
print("on battery!");
} else {
print("on USB!");
}

// first let's prevent the wifi background thread from processing...
cyw43_thread_enter();

//initialize and select ADC3/GPIO29
adc_gpio_init(29);
adc_select_input(3);

//Read ADC3, result is 1/3 of VSYS, so we still need to multiply the conversion factor with 3 to get the input voltage
uint16_t adc3 = adc_read();
float vsys = adc3 * VSYS_CONVERSION_FACTOR;

// return gp29 to its previous state
SetGPIO29WifiStatus();
cyw43_thread_exit();
return vsys;
}
/**
* End battery measurement code
*/

WiFiServer server(80);

#ifdef TLS
Expand Down Expand Up @@ -195,11 +246,22 @@ void connectToWifi(){
WiFi.begin(ssid, pass);
}
}

// set the RTC using NTP
NTP.begin("pool.ntp.org", "time.nist.gov");
NTP.waitSet();
time_t now = time(nullptr);
struct tm timeinfo;
gmtime_r(&now, &timeinfo);
print("Current time: ");
print(asctime(&timeinfo));
char buf[20];
ltoa(now, buf, 10);
println(String(" (") + buf + ")");
}

typedef struct
{
unsigned long timestamp;
float raw_temp;
float raw_pressure;
float raw_humidity;
Expand Down Expand Up @@ -673,6 +735,7 @@ void newDataCallback(const bme68xData data, const bsecOutputs outputs, Bsec2 bse

void commitLast() {
memcpy(&committedOutput, &lastOutput, sizeof(bsec_outputs_t));
committedOutput.timestamp = time(nullptr);
}

void updateDisplay()
Expand Down Expand Up @@ -855,12 +918,12 @@ void printHead(WiFiClient &client, int statusCode, String contentType) {
client.println();
}

String metric(String key, int val, String location) {
return key + "{group=\"environment\", location=\""+location+"\"} " + val + "\n";
String metric(String key, int val, String location, String timestamp) {
return key + "{group=\"environment\", location=\""+location+"\"} " + val + " " + timestamp +"000\n";
}

String metric(String key, float val, String location) {
return key + "{group=\"environment\", location=\""+location+"\"} " + val + "\n";
String metric(String key, float val, String location, String timestamp) {
return key + "{group=\"environment\", location=\""+location+"\"} " + val + " " + timestamp + "000\n";
}

bool processOneRequest(WiFiClient &client){
Expand Down Expand Up @@ -987,17 +1050,31 @@ bool processOneRequest(WiFiClient &client){
printHead(client, 500, "text/plain");
} else {
printHead(client, 200, "text/plain");
client.print(metric("rawtemp", committedOutput.raw_temp, metricLocation));
client.print(metric("pressure", committedOutput.raw_pressure, metricLocation));
client.print(metric("rawhumidity", committedOutput.raw_humidity, metricLocation));
client.print(metric("rawgas", committedOutput.raw_gas, metricLocation));
client.print(metric("aqi", committedOutput.air_quality, metricLocation));
client.print(metric("aqi_accuracy", committedOutput.air_quality_accuracy, metricLocation));
client.print(metric("temperatureF", committedOutput.comp_temp, metricLocation));
client.print(metric("humidity", committedOutput.comp_humidity, metricLocation));
client.print(metric("static_aqi", committedOutput.static_air_quality, metricLocation));
client.print(metric("eco2", committedOutput.eco2, metricLocation));
client.print(metric("tvoc", committedOutput.voc, metricLocation));
char buf[20];
// use timestamp of the last full read for the sensor metrics
ltoa(committedOutput.timestamp, buf, 10);
String ts = String(buf);
client.print(metric("rawtemp", committedOutput.raw_temp, metricLocation, ts));
client.print(metric("pressure", committedOutput.raw_pressure, metricLocation, ts));
client.print(metric("rawhumidity", committedOutput.raw_humidity, metricLocation, ts));
client.print(metric("rawgas", committedOutput.raw_gas, metricLocation, ts));
client.print(metric("aqi", committedOutput.air_quality, metricLocation, ts));
client.print(metric("aqi_accuracy", committedOutput.air_quality_accuracy, metricLocation, ts));
client.print(metric("temperatureF", committedOutput.comp_temp, metricLocation, ts));
client.print(metric("humidity", committedOutput.comp_humidity, metricLocation, ts));
client.print(metric("static_aqi", committedOutput.static_air_quality, metricLocation, ts));
client.print(metric("eco2", committedOutput.eco2, metricLocation, ts));
client.print(metric("tvoc", committedOutput.voc, metricLocation, ts));
// and grab a fresh timestamp for the board metrics as they're measured right now
ltoa(time(nullptr), buf, 10);
ts = String(buf);
int rssi = WiFi.RSSI();
client.print(metric("heap_free", rp2040.getFreeHeap(), metricLocation, ts));
client.print(metric("heap_used", rp2040.getUsedHeap(), metricLocation, ts));
client.print(metric("wifi_rssi", rssi, metricLocation, ts));

// why not tempt fate and do a vsys measurement during a request handler?
client.print(metric("vsys_voltage", measureVsys(), metricLocation, ts));
}
} else if(req.getPath() == "/wifi") {
// output the current SSID
Expand Down
4 changes: 2 additions & 2 deletions request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ Request::Request(String &in, bool serial){
headerCount = 0;
if(hasSerial) Serial.println("Parsing headers...");
while(tmp.indexOf('\n') && headerCount < 20 && tmp.length()){
headers_arr[headerCount] = new String;
headers_arr[headerCount]->concat(tmp.substring(0,tmp.indexOf('\n')));
headers_arr[headerCount] = new String(tmp.substring(0, tmp.indexOf('\n')));
//headers_arr[headerCount]->concat(tmp.substring(0,tmp.indexOf('\n')));
tmp = tmp.substring(tmp.indexOf('\n')+1);
headerCount++;
}
Expand Down

0 comments on commit ab0fa07

Please sign in to comment.