Merge pull request #203 from cyberman54/development
merge development v1.6.82
This commit is contained in:
58 files changed
+11716
-248
No files matched your search
@@ -41,6 +41,11 @@ function Decoder(bytes, port) {
|
||||
return decode(bytes, [uint8, uint8], ['rssi', 'beacon']);
|
||||
}
|
||||
|
||||
if (port === 7) {
|
||||
// BME680 sensor data
|
||||
return decode(bytes, [temperature, uint16, humidity, uint16], ['temperature', 'pressure', 'humidity', 'air']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +137,7 @@ var temperature = function (bytes) {
|
||||
if (isNegative) {
|
||||
t = -t;
|
||||
}
|
||||
return t / 1e2;
|
||||
return +(t / 100).toFixed(1);
|
||||
};
|
||||
temperature.BYTES = 2;
|
||||
|
||||
@@ -142,7 +147,7 @@ var humidity = function (bytes) {
|
||||
}
|
||||
|
||||
var h = bytesToInt(bytes);
|
||||
return h / 1e2;
|
||||
return +(h / 100).toFixed(1);
|
||||
};
|
||||
humidity.BYTES = 2;
|
||||
|
||||
|
||||
@@ -40,6 +40,14 @@ function Decoder(bytes, port) {
|
||||
decoded.rssi = bytes[i++];
|
||||
decoded.beacon = bytes[i++];
|
||||
}
|
||||
|
||||
if (port === 7) {
|
||||
var i = 0;
|
||||
decoded.temperature = ((bytes[i++] << 8) | bytes[i++]);
|
||||
decoded.pressure = ((bytes[i++] << 8) | bytes[i++]);
|
||||
decoded.humidity = ((bytes[i++] << 8) | bytes[i++]);
|
||||
decoded.air = ((bytes[i++] << 8) | bytes[i++]);
|
||||
}
|
||||
|
||||
return decoded;
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifdef HAS_BME
|
||||
|
||||
#include "bme680read.h"
|
||||
|
||||
// Local logging tag
|
||||
static const char TAG[] = "main";
|
||||
|
||||
#define SEALEVELPRESSURE_HPA (1013.25)
|
||||
|
||||
// I2C Bus interface
|
||||
Adafruit_BME680 bme;
|
||||
|
||||
bmeStatus_t bme_status;
|
||||
|
||||
void bme_init(void) {
|
||||
// initialize BME680 sensor using default i2c address 0x77
|
||||
if (bme.begin(HAS_BME)) {
|
||||
// Set up oversampling and filter initialization
|
||||
bme.setTemperatureOversampling(BME680_OS_8X);
|
||||
bme.setHumidityOversampling(BME680_OS_2X);
|
||||
bme.setPressureOversampling(BME680_OS_4X);
|
||||
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
|
||||
bme.setGasHeater(320, 150); // 320*C for 150 ms
|
||||
ESP_LOGI(TAG, "BME680 chip found and initialized");
|
||||
} else
|
||||
ESP_LOGE(TAG, "BME680 chip not found on i2c bus");
|
||||
}
|
||||
|
||||
bool bme_read(void) {
|
||||
bool ret = bme.performReading();
|
||||
if (ret) {
|
||||
// read current BME data and buffer in global struct
|
||||
bme_status.temperature = bme.temperature;
|
||||
bme_status.pressure = (uint16_t)(bme.pressure / 100.0); // convert Pa -> hPa
|
||||
bme_status.humidity = bme.humidity;
|
||||
bme_status.gas_resistance = (uint16_t)(bme.gas_resistance / 1000.0); // convert Ohm -> kOhm
|
||||
ESP_LOGI(TAG, "BME680 sensor data read success");
|
||||
} else {
|
||||
ESP_LOGI(TAG, "BME680 sensor read error");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // HAS_BME
|
||||
+1
-1
@@ -10,6 +10,6 @@ void readButton() {
|
||||
ESP_LOGI(TAG, "Button pressed");
|
||||
payload.reset();
|
||||
payload.addButton(0x01);
|
||||
SendData(BUTTONPORT);
|
||||
SendPayload(BUTTONPORT);
|
||||
}
|
||||
#endif
|
||||
+44
-18
@@ -3,12 +3,13 @@
|
||||
|
||||
// Basic config
|
||||
#include "cyclic.h"
|
||||
#include "rcommand.h"
|
||||
#include "spislave.h"
|
||||
|
||||
// Local logging tag
|
||||
static const char TAG[] = "main";
|
||||
|
||||
uint32_t userUTCTime; // Seconds since the UTC epoch
|
||||
unsigned long nextTimeSync = millis();
|
||||
|
||||
// do all housekeeping
|
||||
void doHousekeeping() {
|
||||
|
||||
@@ -19,7 +20,24 @@ void doHousekeeping() {
|
||||
if (cfg.runmode == 1)
|
||||
do_reset();
|
||||
|
||||
// task storage debugging //
|
||||
spi_housekeeping();
|
||||
lora_housekeeping();
|
||||
|
||||
// time sync once per TIME_SYNC_INTERVAL
|
||||
#ifdef TIME_SYNC_INTERVAL
|
||||
if (millis() >= nextTimeSync) {
|
||||
nextTimeSync = millis() + TIME_SYNC_INTERVAL *
|
||||
60000; // set up next time sync period
|
||||
do_timesync();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_BME
|
||||
// read BME280 sensor if present
|
||||
bme_read();
|
||||
#endif
|
||||
|
||||
// task storage debugging //
|
||||
ESP_LOGD(TAG, "Wifiloop %d bytes left",
|
||||
uxTaskGetStackHighWaterMark(wifiSwitchTask));
|
||||
ESP_LOGD(TAG, "IRQhandler %d bytes left",
|
||||
@@ -28,10 +46,9 @@ void doHousekeeping() {
|
||||
ESP_LOGD(TAG, "Gpsloop %d bytes left", uxTaskGetStackHighWaterMark(GpsTask));
|
||||
#endif
|
||||
|
||||
spi_housekeeping();
|
||||
|
||||
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
||||
ESP_LOGD(TAG, "LEDloop %d bytes left", uxTaskGetStackHighWaterMark(ledLoopTask));
|
||||
ESP_LOGD(TAG, "LEDloop %d bytes left",
|
||||
uxTaskGetStackHighWaterMark(ledLoopTask));
|
||||
#endif
|
||||
|
||||
// read battery voltage into global variable
|
||||
@@ -40,24 +57,13 @@ void doHousekeeping() {
|
||||
ESP_LOGI(TAG, "Measured Voltage: %dmV", batt_voltage);
|
||||
#endif
|
||||
|
||||
// sync time & date if we have valid gps time
|
||||
#ifdef HAS_GPS
|
||||
if (gps.time.isValid()) {
|
||||
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(),
|
||||
gps.date.day(), gps.date.month(), gps.date.year());
|
||||
ESP_LOGI(TAG, "Time synced to %02d:%02d:%02d", hour(), minute(), second());
|
||||
} else {
|
||||
ESP_LOGI(TAG, "No valid GPS time");
|
||||
}
|
||||
#endif
|
||||
|
||||
// check free memory
|
||||
if (esp_get_minimum_free_heap_size() <= MEM_LOW) {
|
||||
ESP_LOGI(TAG,
|
||||
"Memory full, counter cleared (heap low water mark = %d Bytes / "
|
||||
"free heap = %d bytes)",
|
||||
esp_get_minimum_free_heap_size(), ESP.getFreeHeap());
|
||||
SendData(COUNTERPORT); // send data before clearing counters
|
||||
SendPayload(COUNTERPORT); // send data before clearing counters
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
get_salt(); // get new salt for salting hashes
|
||||
|
||||
@@ -83,6 +89,26 @@ void reset_counters() {
|
||||
macs_ble = 0;
|
||||
}
|
||||
|
||||
void do_timesync() {
|
||||
#ifdef TIME_SYNC_INTERVAL
|
||||
// sync time & date if we have valid gps time
|
||||
#ifdef HAS_GPS
|
||||
if (gps.time.isValid()) {
|
||||
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(),
|
||||
gps.date.day(), gps.date.month(), gps.date.year());
|
||||
ESP_LOGI(TAG, "Time synced by GPS to %02d:%02d:%02d", hour(), minute(),
|
||||
second());
|
||||
return;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "No valid GPS time");
|
||||
}
|
||||
#endif // HAS_GPS
|
||||
// Schedule a network time request at the next possible time
|
||||
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
|
||||
ESP_LOGI(TAG, "Network time request scheduled");
|
||||
#endif // TIME_SYNC_INTERVAL
|
||||
} // do_timesync()
|
||||
|
||||
#ifndef VERBOSE
|
||||
int redirect_log(const char *fmt, va_list args) {
|
||||
// do nothing
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#define SPI_SCLK GPIO_NUM_18
|
||||
#define SPI_CS GPIO_NUM_5
|
||||
|
||||
#define HAS_BME 0x77 // BME680 sensor on I2C bus (SDA=4/SCL=15); comment out if not present
|
||||
|
||||
#define CFG_sx1276_radio 1 // select LoRa chip
|
||||
//#define CFG_sx1272_radio 1 // select LoRa chip
|
||||
#define BOARD_HAS_PSRAM // use if board has external PSRAM
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Hardware related definitions for Heltec LoRa-32 Board
|
||||
//#define HAS_BME 0x77 // BME680 sensor on I2C bus (SDI=21/SCL=22); comment out if not present
|
||||
|
||||
// Hardware related definitions for Heltec LoRa-32 Board
|
||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||
#define CFG_sx1276_radio 1
|
||||
|
||||
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board
|
||||
#define HAS_LED (25) // white LED on board
|
||||
#define HAS_BUTTON (0) // button "PROG" on board
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
// disable brownout detection (avoid unexpected reset on some boards)
|
||||
#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
||||
|
||||
#define HAS_BME 0x76 // BME680 sensor on I2C bus; comment out if not present
|
||||
|
||||
#define HAS_LED 13 // ESP32 GPIO12 (pin22) On Board LED
|
||||
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||
//#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
// This settings are for boards labeled v1.6 on pcb, NOT for v1.5 or older
|
||||
*/
|
||||
|
||||
#define HAS_BME 0x77 // BME680 sensor on I2C bus (SDI=21/SCL=22); comment out if not present
|
||||
|
||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
||||
|
||||
|
||||
+3
-3
@@ -35,8 +35,8 @@ void irqHandler(void *pvParameters) {
|
||||
doHousekeeping();
|
||||
|
||||
// is time to send the payload?
|
||||
if (InterruptStatus & SENDPAYLOAD_IRQ)
|
||||
sendPayload();
|
||||
if (InterruptStatus & SENDCOUNTER_IRQ)
|
||||
sendCounter();
|
||||
}
|
||||
vTaskDelete(NULL); // shoud never be reached
|
||||
}
|
||||
@@ -55,7 +55,7 @@ void IRAM_ATTR homeCycleIRQ() {
|
||||
}
|
||||
|
||||
void IRAM_ATTR SendCycleIRQ() {
|
||||
xTaskNotifyFromISR(irqHandlerTask, SENDPAYLOAD_IRQ, eSetBits, NULL);
|
||||
xTaskNotifyFromISR(irqHandlerTask, SENDCOUNTER_IRQ, eSetBits, NULL);
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -21,6 +21,9 @@
|
||||
|
||||
//#define LMIC_USE_INTERRUPTS
|
||||
|
||||
//time sync via LoRaWAN network, is not yet supported by TTN (LoRaWAN spec v1.0.3)
|
||||
#define LMIC_ENABLE_DeviceTimeReq 1
|
||||
|
||||
// 16 μs per tick
|
||||
// LMIC requires ticks to be 15.5μs - 100 μs long
|
||||
#define US_PER_OSTICK_EXPONENT 4
|
||||
@@ -38,7 +41,7 @@
|
||||
// enable more verbose output. Make sure that printf is actually
|
||||
// configured (e.g. on AVR it is not by default), otherwise using it can
|
||||
// cause crashing.
|
||||
//#define LMIC_DEBUG_LEVEL 1
|
||||
#define LMIC_DEBUG_LEVEL 0
|
||||
|
||||
// Enable this to allow using printf() to print to the given serial port
|
||||
// (or any other Print object). This can be easy for debugging. The
|
||||
|
||||
+40
-4
@@ -328,9 +328,9 @@ void lora_send(osjob_t *job) {
|
||||
// waiting for LoRa getting ready
|
||||
} else {
|
||||
if (xQueueReceive(LoraSendQueue, &SendBuffer, (TickType_t)0) == pdTRUE) {
|
||||
// SendBuffer gets struct MessageBuffer with next payload from queue
|
||||
// SendBuffer now filled with next payload from queue
|
||||
if (!LMIC_setTxData2(SendBuffer.MessagePort, SendBuffer.Message,
|
||||
SendBuffer.MessageSize, (cfg.countermode & 0x02))) {
|
||||
SendBuffer.MessageSize, (cfg.countermode & 0x02))) {
|
||||
ESP_LOGI(TAG, "%d byte(s) sent to LoRa", SendBuffer.MessageSize);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "could not send %d byte(s) to LoRa",
|
||||
@@ -384,12 +384,12 @@ esp_err_t lora_stack_init() {
|
||||
if (!LMIC_startJoining()) { // start joining
|
||||
ESP_LOGI(TAG, "Already joined");
|
||||
}
|
||||
|
||||
|
||||
return ESP_OK; // continue main program
|
||||
#endif
|
||||
}
|
||||
|
||||
void lora_enqueuedata(uint8_t messageType, MessageBuffer_t *message) {
|
||||
void lora_enqueuedata(MessageBuffer_t *message) {
|
||||
// enqueue message in LORA send queue
|
||||
#ifdef HAS_LORA
|
||||
BaseType_t ret =
|
||||
@@ -414,3 +414,39 @@ void lora_housekeeping(void) {
|
||||
// uxTaskGetStackHighWaterMark(LoraTask));
|
||||
#endif
|
||||
}
|
||||
|
||||
void user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||
int flagSuccess) {
|
||||
// Explicit conversion from void* to uint32_t* to avoid compiler errors
|
||||
uint32_t *pUserUTCTime = (uint32_t *)pVoidUserUTCTime;
|
||||
lmic_time_reference_t lmicTimeReference;
|
||||
|
||||
if (flagSuccess != 1) {
|
||||
ESP_LOGW(TAG, "LoRaWAN network did not answer time request");
|
||||
return;
|
||||
}
|
||||
|
||||
// Populate lmic_time_reference
|
||||
flagSuccess = LMIC_getNetworkTimeReference(&lmicTimeReference);
|
||||
if (flagSuccess != 1) {
|
||||
ESP_LOGW(TAG, "LoRaWAN time request failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// Update userUTCTime, considering the difference between the GPS and UTC
|
||||
// epoch, and the leap seconds
|
||||
*pUserUTCTime = lmicTimeReference.tNetwork + 315964800;
|
||||
// Current time, in ticks
|
||||
ostime_t ticksNow = os_getTime();
|
||||
// Time when the request was sent, in ticks
|
||||
ostime_t ticksRequestSent = lmicTimeReference.tLocal;
|
||||
// Add the delay between the instant the time was transmitted and
|
||||
// the current time
|
||||
uint32_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000;
|
||||
*pUserUTCTime += requestDelaySec;
|
||||
|
||||
// Update system time with time read from the network
|
||||
setTime(*pUserUTCTime);
|
||||
ESP_LOGI(TAG, "Time synced by LoRa network to %02d:%02d:%02d", hour(),
|
||||
minute(), second());
|
||||
}
|
||||
+1
-1
@@ -107,7 +107,7 @@ bool mac_add(uint8_t *paddr, int8_t rssi, bool sniff_type) {
|
||||
#endif
|
||||
payload.reset();
|
||||
payload.addAlarm(rssi, beaconID);
|
||||
SendData(BEACONPORT);
|
||||
SendPayload(BEACONPORT);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+8
-1
@@ -55,7 +55,8 @@ uint8_t volatile channel = 0; // channel rotation counter
|
||||
uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
|
||||
batt_voltage = 0; // globals for display
|
||||
|
||||
hw_timer_t *channelSwitch = NULL, *sendCycle = NULL, *homeCycle = NULL, *displaytimer = NULL; // irq tasks
|
||||
hw_timer_t *channelSwitch = NULL, *sendCycle = NULL, *homeCycle = NULL,
|
||||
*displaytimer = NULL; // irq tasks
|
||||
TaskHandle_t irqHandlerTask, wifiSwitchTask;
|
||||
|
||||
std::set<uint16_t> macs; // container holding unique MAC adress hashes
|
||||
@@ -157,6 +158,12 @@ void setup() {
|
||||
strcat_P(features, " GPS");
|
||||
#endif
|
||||
|
||||
// initialize gps
|
||||
#ifdef HAS_BME
|
||||
strcat_P(features, " BME");
|
||||
bme_init();
|
||||
#endif
|
||||
|
||||
// initialize LoRa
|
||||
#ifdef HAS_LORA
|
||||
strcat_P(features, " LORA");
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#define LPP1PORT 1 // Port for Cayenne LPP 1.0 dynamic sensor encoding
|
||||
#define LPP2PORT 2 // Port for Cayenne LPP 2.0 packed sensor encoding
|
||||
#define BEACONPORT 6 // Port on which device sends beacon alarms
|
||||
#define BMEPORT 7 // Port on which device sends BME680 sensor data
|
||||
|
||||
// Some hardware settings
|
||||
#define RGBLUMINOSITY 30 // RGB LED luminosity [default = 30%]
|
||||
@@ -72,5 +73,8 @@
|
||||
#define OTA_MIN_BATT 3600 // minimum battery level for OTA [millivolt]
|
||||
#define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds]
|
||||
|
||||
// setting for syncing time of node
|
||||
//#define TIME_SYNC_INTERVAL 60 // sync time each ... minutes [default = 60], comment out means off
|
||||
|
||||
// LMIC settings
|
||||
// moved to src/lmic_config.h
|
||||
+77
-9
@@ -93,6 +93,21 @@ void PayloadConvert::addGPS(gpsStatus_t value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void PayloadConvert::addBME(bmeStatus_t value) {
|
||||
#ifdef HAS_BME
|
||||
int16_t temperature = (int16_t)(value.temperature); // float -> int
|
||||
uint16_t humidity = (uint16_t)(value.humidity); // float -> int
|
||||
buffer[cursor++] = highByte(temperature);
|
||||
buffer[cursor++] = lowByte(temperature);
|
||||
buffer[cursor++] = highByte(value.pressure);
|
||||
buffer[cursor++] = lowByte(value.pressure);
|
||||
buffer[cursor++] = highByte(humidity);
|
||||
buffer[cursor++] = lowByte(humidity);
|
||||
buffer[cursor++] = highByte(value.gas_resistance);
|
||||
buffer[cursor++] = lowByte(value.gas_resistance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PayloadConvert::addButton(uint8_t value) {
|
||||
#ifdef HAS_BUTTON
|
||||
buffer[cursor++] = value;
|
||||
@@ -150,6 +165,15 @@ void PayloadConvert::addGPS(gpsStatus_t value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void PayloadConvert::addBME(bmeStatus_t value) {
|
||||
#ifdef HAS_BME
|
||||
writeTemperature(value.temperature);
|
||||
writeUint16(value.pressure);
|
||||
writeHumidity(value.humidity);
|
||||
writeUint16(value.gas_resistance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void PayloadConvert::addButton(uint8_t value) {
|
||||
#ifdef HAS_BUTTON
|
||||
writeUint8(value);
|
||||
@@ -217,8 +241,10 @@ void PayloadConvert::writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f,
|
||||
writeUint8(bitmap);
|
||||
}
|
||||
|
||||
/* ---------------- Cayenne LPP format ---------- */
|
||||
// http://community.mydevices.com/t/cayenne-lpp-2-0/7510
|
||||
/* ---------------- Cayenne LPP 2.0 format ---------- */
|
||||
// see specs http://community.mydevices.com/t/cayenne-lpp-2-0/7510
|
||||
// PAYLOAD_ENCODER == 3 -> Dynamic Sensor Payload, using channels -> FPort 1
|
||||
// PAYLOAD_ENCODER == 4 -> Packed Sensor Payload, not using channels -> FPort 2
|
||||
|
||||
#elif (PAYLOAD_ENCODER == 3 || PAYLOAD_ENCODER == 4)
|
||||
|
||||
@@ -226,13 +252,15 @@ void PayloadConvert::addCount(uint16_t value1, uint16_t value2) {
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_COUNT_WIFI_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_LUMINOSITY; // workaround, type meter not found?
|
||||
buffer[cursor++] =
|
||||
LPP_LUMINOSITY; // workaround since cayenne has no data type meter
|
||||
buffer[cursor++] = highByte(value1);
|
||||
buffer[cursor++] = lowByte(value1);
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_COUNT_BLE_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_LUMINOSITY; // workaround, type meter not found?
|
||||
buffer[cursor++] =
|
||||
LPP_LUMINOSITY; // workaround since cayenne has no data type meter
|
||||
buffer[cursor++] = highByte(value2);
|
||||
buffer[cursor++] = lowByte(value2);
|
||||
}
|
||||
@@ -269,9 +297,10 @@ void PayloadConvert::addStatus(uint16_t voltage, uint64_t uptime, float celsius,
|
||||
buffer[cursor++] = LPP_ANALOG_INPUT;
|
||||
buffer[cursor++] = highByte(volt);
|
||||
buffer[cursor++] = lowByte(volt);
|
||||
#endif
|
||||
#endif // HAS_BATTERY_PROBE
|
||||
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_TEMP_CHANNEL;
|
||||
buffer[cursor++] = LPP_TEMPERATURE_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_TEMPERATURE;
|
||||
buffer[cursor++] = highByte(temp);
|
||||
@@ -292,11 +321,50 @@ void PayloadConvert::addGPS(gpsStatus_t value) {
|
||||
buffer[cursor++] = (byte)((lat & 0x0000FF));
|
||||
buffer[cursor++] = (byte)((lon & 0xFF0000) >> 16);
|
||||
buffer[cursor++] = (byte)((lon & 0x00FF00) >> 8);
|
||||
buffer[cursor++] = (byte)((lon & 0x0000FF));
|
||||
buffer[cursor++] = (byte)(lon & 0x0000FF);
|
||||
buffer[cursor++] = (byte)((alt & 0xFF0000) >> 16);
|
||||
buffer[cursor++] = (byte)((alt & 0x00FF00) >> 8);
|
||||
buffer[cursor++] = (byte)((alt & 0x0000FF));
|
||||
buffer[cursor++] = (byte)(alt & 0x0000FF);
|
||||
#endif // HAS_GPS
|
||||
}
|
||||
|
||||
void PayloadConvert::addBME(bmeStatus_t value) {
|
||||
#ifdef HAS_BME
|
||||
|
||||
// data value conversions to meet cayenne data type definition
|
||||
// 0.1°C per bit => -3276,7 .. +3276,7 °C
|
||||
int16_t temperature = (int16_t)(value.temperature * 10.0);
|
||||
// 0.1 hPa per bit => 0 .. 6553,6 hPa
|
||||
uint16_t pressure = value.pressure * 10;
|
||||
// 0.5% per bit => 0 .. 128 %C
|
||||
uint8_t humidity = (uint8_t)(value.humidity * 2.0);
|
||||
// 0.01 Ohm per bit => 0 .. 655,36 Ohm
|
||||
uint16_t gas = value.gas_resistance * 100;
|
||||
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_TEMPERATURE_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_TEMPERATURE; // 2 bytes 0.1 °C Signed MSB
|
||||
buffer[cursor++] = highByte(temperature);
|
||||
buffer[cursor++] = lowByte(temperature);
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_BAROMETER_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_BAROMETER; // 2 bytes 0.1 hPa Unsigned MSB
|
||||
buffer[cursor++] = highByte(pressure);
|
||||
buffer[cursor++] = lowByte(pressure);
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_HUMIDITY_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_HUMIDITY; // 1 byte 0.5 % Unsigned
|
||||
buffer[cursor++] = humidity;
|
||||
#if (PAYLOAD_ENCODER == 3)
|
||||
buffer[cursor++] = LPP_GAS_CHANNEL;
|
||||
#endif
|
||||
buffer[cursor++] = LPP_ANALOG_INPUT; // 2 bytes 0.01 Signed
|
||||
buffer[cursor++] = highByte(gas);
|
||||
buffer[cursor++] = lowByte(gas);
|
||||
#endif // HAS_BME
|
||||
}
|
||||
|
||||
void PayloadConvert::addButton(uint8_t value) {
|
||||
@@ -306,7 +374,7 @@ void PayloadConvert::addButton(uint8_t value) {
|
||||
#endif
|
||||
buffer[cursor++] = LPP_DIGITAL_INPUT;
|
||||
buffer[cursor++] = value;
|
||||
#endif
|
||||
#endif // HAS_BUTTON
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
+16
-4
@@ -211,7 +211,7 @@ void get_config(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get device configuration");
|
||||
payload.reset();
|
||||
payload.addConfig(cfg);
|
||||
SendData(CONFIGPORT);
|
||||
SendPayload(CONFIGPORT);
|
||||
};
|
||||
|
||||
void get_status(uint8_t val[]) {
|
||||
@@ -225,7 +225,7 @@ void get_status(uint8_t val[]) {
|
||||
payload.addStatus(voltage, uptime() / 1000, temperatureRead(),
|
||||
ESP.getFreeHeap(), rtc_get_reset_reason(0),
|
||||
rtc_get_reset_reason(1));
|
||||
SendData(STATUSPORT);
|
||||
SendPayload(STATUSPORT);
|
||||
};
|
||||
|
||||
void get_gps(uint8_t val[]) {
|
||||
@@ -234,12 +234,23 @@ void get_gps(uint8_t val[]) {
|
||||
gps_read();
|
||||
payload.reset();
|
||||
payload.addGPS(gps_status);
|
||||
SendData(GPSPORT);
|
||||
SendPayload(GPSPORT);
|
||||
#else
|
||||
ESP_LOGW(TAG, "GPS function not supported");
|
||||
#endif
|
||||
};
|
||||
|
||||
void get_bme(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get bme680 sensor data");
|
||||
#ifdef HAS_BME
|
||||
payload.reset();
|
||||
payload.addBME(bme_status);
|
||||
SendPayload(BMEPORT);
|
||||
#else
|
||||
ESP_LOGW(TAG, "BME680 sensor not supported");
|
||||
#endif
|
||||
};
|
||||
|
||||
// assign previously defined functions to set of numeric remote commands
|
||||
// format: opcode, function, #bytes params,
|
||||
// flag (true = do make settings persistent / false = don't)
|
||||
@@ -255,7 +266,8 @@ cmd_t table[] = {
|
||||
{0x0f, set_wifiant, 1, true}, {0x10, set_rgblum, 1, true},
|
||||
{0x11, set_monitor, 1, true}, {0x12, set_beacon, 7, false},
|
||||
{0x80, get_config, 0, false}, {0x81, get_status, 0, false},
|
||||
{0x84, get_gps, 0, false}};
|
||||
{0x84, get_gps, 0, false}, {0x85, get_bme, 0, false},
|
||||
};
|
||||
|
||||
const uint8_t cmdtablesize =
|
||||
sizeof(table) / sizeof(table[0]); // number of commands in command table
|
||||
|
||||
+23
-14
@@ -2,9 +2,9 @@
|
||||
#include "senddata.h"
|
||||
|
||||
// put data to send in RTos Queues used for transmit over channels Lora and SPI
|
||||
void SendData(uint8_t port) {
|
||||
void SendPayload(uint8_t port) {
|
||||
|
||||
MessageBuffer_t SendBuffer;
|
||||
MessageBuffer_t SendBuffer; // contains MessageSize, MessagePort, Message[]
|
||||
|
||||
SendBuffer.MessageSize = payload.getSize();
|
||||
SendBuffer.MessagePort = PAYLOAD_ENCODER <= 2
|
||||
@@ -13,25 +13,26 @@ void SendData(uint8_t port) {
|
||||
memcpy(SendBuffer.Message, payload.getBuffer(), payload.getSize());
|
||||
|
||||
// enqueue message in device's send queues
|
||||
lora_enqueuedata(port, &SendBuffer);
|
||||
spi_enqueuedata(port, &SendBuffer);
|
||||
lora_enqueuedata(&SendBuffer);
|
||||
spi_enqueuedata(&SendBuffer);
|
||||
|
||||
// clear counter if not in cumulative counter mode
|
||||
if ((port == COUNTERPORT) && (cfg.countermode != 1)) {
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
get_salt(); // get new salt for salting hashes
|
||||
ESP_LOGI(TAG, "Counter cleared");
|
||||
}
|
||||
} // SendData
|
||||
} // SendPayload
|
||||
|
||||
// interrupt triggered function to prepare payload to send
|
||||
void sendPayload() {
|
||||
void sendCounter() {
|
||||
|
||||
// append counter data to payload
|
||||
payload.reset();
|
||||
payload.addCount(macs_wifi, cfg.blescan ? macs_ble : 0);
|
||||
// append GPS data, if present
|
||||
|
||||
// clear counter if not in cumulative counter mode
|
||||
if (cfg.countermode != 1) {
|
||||
reset_counters(); // clear macs container and reset all counters
|
||||
get_salt(); // get new salt for salting hashes
|
||||
ESP_LOGI(TAG, "Counter cleared");
|
||||
}
|
||||
|
||||
#ifdef HAS_GPS
|
||||
// show NMEA data in debug mode, useful for debugging GPS on board
|
||||
// connection
|
||||
@@ -49,8 +50,16 @@ void sendPayload() {
|
||||
ESP_LOGD(TAG, "No valid GPS position or GPS data mode disabled");
|
||||
}
|
||||
#endif
|
||||
SendData(COUNTERPORT);
|
||||
} // sendpayload()
|
||||
SendPayload(COUNTERPORT);
|
||||
|
||||
// if we have MEMS sensor, send sensor data in separate frame
|
||||
#ifdef HAS_BME
|
||||
payload.reset();
|
||||
payload.addBME(bme_status);
|
||||
SendPayload(BMEPORT);
|
||||
#endif
|
||||
|
||||
} // sendCounter()
|
||||
|
||||
void flushQueues() {
|
||||
lora_queuereset();
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ esp_err_t spi_init() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void spi_enqueuedata(uint8_t messageType, MessageBuffer_t *message) {
|
||||
void spi_enqueuedata(MessageBuffer_t *message) {
|
||||
// enqueue message in SPI send queue
|
||||
#ifdef HAS_SPI
|
||||
BaseType_t ret =
|
||||
|
||||
Reference in new issue
Block a user