diff --git a/.github/workflows/build_zephyr.yml b/.github/workflows/build_zephyr.yml index 6561a3a..f39aeac 100644 --- a/.github/workflows/build_zephyr.yml +++ b/.github/workflows/build_zephyr.yml @@ -13,7 +13,7 @@ on: BOARD: required: true type: string - default: aludel_mini_v1_sparkfun9160_ns + default: nrf9160dk/nrf9160/ns ARTIFACT: required: true type: boolean diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4049d5e..4e96ff2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: ZEPHYR_SDK: [0.16.3] - BOARD: ["nrf9160dk/nrf9160/ns","aludel_mini/nrf9160/ns","aludel_elixir/nrf9160/ns"] + BOARD: ["nrf9160dk/nrf9160/ns","aludel_elixir/nrf9160/ns"] uses: ./.github/workflows/build_zephyr.yml with: diff --git a/CMakeLists.txt b/CMakeLists.txt index 37c9730..abdd5ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,5 +17,3 @@ target_sources(app PRIVATE src/app_settings.c) target_sources(app PRIVATE src/app_state.c) target_sources(app PRIVATE src/app_sensors.c) target_sources(app PRIVATE src/qm30vt2.c) - -add_subdirectory_ifdef(CONFIG_ALUDEL_BATTERY_MONITOR src/battery_monitor) diff --git a/Kconfig b/Kconfig index 3af1157..da365e1 100644 --- a/Kconfig +++ b/Kconfig @@ -13,6 +13,4 @@ config DNS_SERVER1 endif # DNS_RESOLVER -rsource "src/battery_monitor/Kconfig" - source "Kconfig.zephyr" diff --git a/README.md b/README.md index 080b678..c072823 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ images](https://github.com/golioth/reference-design-modbus-vibration-monitor/rel - Nordic nRF9160-DK - Golioth Aludel Elixir -- Golioth Aludel Mini ### Additional Sensors/Components @@ -48,8 +47,8 @@ This app implements: ### Settings Service -The following settings should be set in the Device Settings menu of the -[Golioth Console](https://console.golioth.io). +The following settings should be set in [the Device Settings menu of the +Golioth Console](https://console.golioth.io/device-settings). - `LOOP_DELAY_S` Adjusts the delay between sensor readings. Set to an integer value @@ -59,8 +58,8 @@ The following settings should be set in the Device Settings menu of the ### Remote Procedure Call (RPC) Service -The following RPCs can be initiated in the Remote Procedure Call menu of -the [Golioth Console](https://console.golioth.io). +The following RPCs can be initiated in the Remote Procedure Call tab of +each device in the [Golioth Console](https://console.golioth.io). - `get_network_info` Query and return network information. @@ -327,7 +326,7 @@ these repositories from `west.yml` and remove the includes/function calls from the C code. - [golioth-zephyr-boards](https://github.com/golioth/golioth-zephyr-boards) - includes the board definitions for the Golioth Aludel-Mini + includes the board definitions for the Golioth Aludel-Elixir - [libostentus](https://github.com/golioth/libostentus) is a helper library for controlling the Ostentus ePaper faceplate - [zephyr-network-info](https://github.com/golioth/zephyr-network-info) diff --git a/boards/aludel_elixir_ns.conf b/boards/aludel_elixir_ns.conf index 15d5024..5cbf85f 100644 --- a/boards/aludel_elixir_ns.conf +++ b/boards/aludel_elixir_ns.conf @@ -2,50 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 # General config -CONFIG_HEAP_MEM_POOL_SIZE=4096 -CONFIG_NEWLIB_LIBC=y -CONFIG_CBPRINTF_FP_SUPPORT=y - -# Networking -CONFIG_NET_SOCKETS_OFFLOAD=y -CONFIG_NET_IPV6=y -CONFIG_NET_IPV6_NBR_CACHE=n -CONFIG_NET_IPV6_MLD=n - -# Increase native TLS socket implementation, so that it is chosen instead of -# offloaded nRF91 sockets -CONFIG_NET_SOCKETS_TLS_PRIORITY=35 - -# Modem library -CONFIG_NRF_MODEM_LIB=y - -# LTE connectivity with network connection manager -CONFIG_NRF_MODEM_LIB_NET_IF=y -CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START=y -CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n -CONFIG_NET_CONNECTION_MANAGER=y -CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 - -# Add Logs for LTE Link Handler -CONFIG_GOLIOTH_SAMPLE_NRF91_LTE_MONITOR=y - -# Disable options y-selected by NCS for no good reason -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED=n -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED=n - -# MbedTLS configuration to support p-384 curve. These options -# enable using the MbedTLS built-in support for operations not -# supported by the default nRF Oberon crypto backend -CONFIG_NORDIC_SECURITY_BACKEND=n -CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y - -# Add Network Info Support -CONFIG_MODEM_INFO=y - -# Generate MCUboot compatible images -CONFIG_BOOTLOADER_MCUBOOT=y - -# Use Golioth Ostentus Faceplate -CONFIG_LIB_OSTENTUS=y +CONFIG_ALUDEL_BATTERY_MONITOR=y +# Turn on regulator to power click headers CONFIG_REGULATOR=y diff --git a/boards/nrf9160dk_nrf9160_ns.conf b/boards/nrf9160dk_nrf9160_ns.conf deleted file mode 100644 index a7af8eb..0000000 --- a/boards/nrf9160dk_nrf9160_ns.conf +++ /dev/null @@ -1,46 +0,0 @@ -# Copyright (c) 2023-2024 Golioth, Inc. -# SPDX-License-Identifier: Apache-2.0 - -# General config -CONFIG_HEAP_MEM_POOL_SIZE=4096 -CONFIG_NEWLIB_LIBC=y -CONFIG_CBPRINTF_FP_SUPPORT=y - -# Networking -CONFIG_NET_SOCKETS_OFFLOAD=y -CONFIG_NET_IPV6=y -CONFIG_NET_IPV6_NBR_CACHE=n -CONFIG_NET_IPV6_MLD=n - -# Increase native TLS socket implementation, so that it is chosen instead of -# offloaded nRF91 sockets -CONFIG_NET_SOCKETS_TLS_PRIORITY=35 - -# Modem library -CONFIG_NRF_MODEM_LIB=y - -# LTE connectivity with network connection manager -CONFIG_NRF_MODEM_LIB_NET_IF=y -CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_START=y -CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n -CONFIG_NET_CONNECTION_MANAGER=y -CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 - -# Add Logs for LTE Link Handler -CONFIG_GOLIOTH_SAMPLE_NRF91_LTE_MONITOR=y - -# Disable options y-selected by NCS for no good reason -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED=n -CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED=n - -# MbedTLS configuration to support p-384 curve. These options -# enable using the MbedTLS built-in support for operations not -# supported by the default nRF Oberon crypto backend -CONFIG_NORDIC_SECURITY_BACKEND=n -CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y - -# Add Network Info Support -CONFIG_MODEM_INFO=y - -# Generate MCUboot compatible images -CONFIG_BOOTLOADER_MCUBOOT=y diff --git a/prj.conf b/prj.conf index 3d64a6f..ba53aef 100644 --- a/prj.conf +++ b/prj.conf @@ -25,10 +25,10 @@ CONFIG_ZVFS_OPEN_MAX=23 CONFIG_LOG_PROCESS_THREAD_STACK_SIZE=1536 CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=10240 -CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=2048 -CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=2048 CONFIG_NETWORKING=y CONFIG_NET_IPV4=y +CONFIG_COAP_EXTENDED_OPTIONS_LEN=y +CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=39 # Application CONFIG_MAIN_STACK_SIZE=4096 @@ -55,7 +55,7 @@ CONFIG_GOLIOTH_SAMPLE_SETTINGS_SHELL=y # Misc. CONFIG_JSON_LIBRARY=y -CONFIG_NETWORK_INFO=y + # Longer response length needed for network info CONFIG_GOLIOTH_RPC_MAX_RESPONSE_LEN=512 CONFIG_I2C=y diff --git a/boards/aludel_mini_nrf9160_ns.conf b/socs/nrf9160_ns.conf similarity index 82% rename from boards/aludel_mini_nrf9160_ns.conf rename to socs/nrf9160_ns.conf index 3cd1a5e..ab731cb 100644 --- a/boards/aludel_mini_nrf9160_ns.conf +++ b/socs/nrf9160_ns.conf @@ -1,6 +1,3 @@ -# Copyright (c) 2023-2024 Golioth, Inc. -# SPDX-License-Identifier: Apache-2.0 - # General config CONFIG_HEAP_MEM_POOL_SIZE=4096 CONFIG_NEWLIB_LIBC=y @@ -26,8 +23,8 @@ CONFIG_NRF_MODEM_LIB_NET_IF_AUTO_CONNECT=n CONFIG_NET_CONNECTION_MANAGER=y CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=1024 -# Add Logs for LTE Link Handler -CONFIG_GOLIOTH_SAMPLE_NRF91_LTE_MONITOR=y +# Increased sysworkq size, due to LTE connectivity +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 # Disable options y-selected by NCS for no good reason CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED=n @@ -39,11 +36,13 @@ CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED=n CONFIG_NORDIC_SECURITY_BACKEND=n CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y -# Battery Support -CONFIG_ALUDEL_BATTERY_MONITOR=y - -# Add Network Info Support -CONFIG_MODEM_INFO=y +# Configure Golioth SDK dependencies (for NCS) +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=2048 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=2048 # Generate MCUboot compatible images CONFIG_BOOTLOADER_MCUBOOT=y + +# Add Network Info Support +CONFIG_NETWORK_INFO=y +CONFIG_MODEM_INFO=y diff --git a/src/app_rpc.c b/src/app_rpc.c index d379eee..645daf9 100644 --- a/src/app_rpc.c +++ b/src/app_rpc.c @@ -12,7 +12,10 @@ LOG_MODULE_REGISTER(app_rpc, LOG_LEVEL_DBG); #include #include +#ifdef CONFIG_NETWORK_INFO #include +#endif + #include "app_rpc.h" static void reboot_work_handler(struct k_work *work) @@ -35,9 +38,9 @@ static enum golioth_rpc_status on_get_network_info(zcbor_state_t *request_params zcbor_state_t *response_detail_map, void *callback_arg) { - network_info_add_to_map(response_detail_map); - - return GOLIOTH_RPC_OK; + COND_CODE_1(CONFIG_NETWORK_INFO, + (network_info_add_to_map(response_detail_map); return GOLIOTH_RPC_OK;), + (return GOLIOTH_RPC_UNIMPLEMENTED);); } static enum golioth_rpc_status on_set_log_level(zcbor_state_t *request_params_array, @@ -86,8 +89,7 @@ static enum golioth_rpc_status on_set_log_level(zcbor_state_t *request_params_ar } static enum golioth_rpc_status on_reboot(zcbor_state_t *request_params_array, - zcbor_state_t *response_detail_map, - void *callback_arg) + zcbor_state_t *response_detail_map, void *callback_arg) { /* Use work queue so this RPC can return confirmation to Golioth */ k_work_submit(&reboot_work); diff --git a/src/app_sensors.c b/src/app_sensors.c index 1435b56..eba0b0d 100644 --- a/src/app_sensors.c +++ b/src/app_sensors.c @@ -24,7 +24,7 @@ static const struct device *o_dev = DEVICE_DT_GET_ANY(golioth_ostentus); #endif #ifdef CONFIG_ALUDEL_BATTERY_MONITOR -#include "battery_monitor/battery.h" +#include #endif #define ZEPHYR_USER_NODE DT_PATH(zephyr_user) diff --git a/src/battery_monitor/CMakeLists.txt b/src/battery_monitor/CMakeLists.txt deleted file mode 100644 index 6e003d0..0000000 --- a/src/battery_monitor/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2023 Golioth, Inc. -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources_ifdef(CONFIG_ALUDEL_BATTERY_MONITOR battery.c) - -zephyr_include_directories(include) diff --git a/src/battery_monitor/Kconfig b/src/battery_monitor/Kconfig deleted file mode 100644 index 442baca..0000000 --- a/src/battery_monitor/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# -# Copyright (C) 2023 Golioth, Inc. -# -# SPDX-License-Identifier: Apache-2.0 -# - -config ALUDEL_BATTERY_MONITOR - bool "Battery monitoring library for the Golioth Aludel-Mini" - select ADC - select ADC_ASYNC - select ADC_NRFX_SAADC - help - Build and link common code for the battery monitor. diff --git a/src/battery_monitor/battery.c b/src/battery_monitor/battery.c deleted file mode 100644 index e77180f..0000000 --- a/src/battery_monitor/battery.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (c) 2018-2019 Peter Bigot Consulting, LLC - * Copyright (c) 2019-2020 Nordic Semiconductor ASA - * Copyright (c) 2023 Golioth, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "battery_monitor/battery.h" -#include "../app_sensors.h" - -LOG_MODULE_REGISTER(battery, LOG_LEVEL_DBG); - -#define VBATT DT_PATH(vbatt) -#define ZEPHYR_USER DT_PATH(zephyr_user) - -/* Formatting string for sending battery JSON to Golioth */ -#define JSON_FMT "{\"batt_v\":%d.%03d,\"batt_lvl\":%d.%02d}" - -#define LABEL_BATTERY "Battery" - -#ifdef CONFIG_BOARD_THINGY52_NRF52832 -/* This board uses a divider that reduces max voltage to - * reference voltage (600 mV). - */ -#define BATTERY_ADC_GAIN ADC_GAIN_1 -#else -/* Other boards may use dividers that only reduce battery voltage to - * the maximum supported by the hardware (3.6 V) - */ -#define BATTERY_ADC_GAIN ADC_GAIN_1_6 -#endif - -char stream_endpoint[] = "battery"; - -char _batt_v_str[8] = "0.0 V"; -char _batt_lvl_str[5] = "none"; - -/* Battery values specific to the Aludel-mini */ -static const struct battery_level_point batt_levels[] = { - /* "Curve" here eyeballed from captured data for the [Adafruit - * 3.7v 2000 mAh](https://www.adafruit.com/product/2011) LIPO - * under full load that started with a charge of 3.96 V and - * dropped about linearly to 3.58 V over 15 hours. It then - * dropped rapidly to 3.10 V over one hour, at which point it - * stopped transmitting. - * - * Based on eyeball comparisons we'll say that 15/16 of life - * goes between 3.95 and 3.55 V, and 1/16 goes between 3.55 V - * and 3.1 V. - */ - - {10000, 3950}, - {625, 3550}, - {0, 3100}, -}; - -struct io_channel_config { - uint8_t channel; -}; - -struct divider_config { - struct io_channel_config io_channel; - struct gpio_dt_spec power_gpios; - /* output_ohm is used as a flag value: if it is nonzero then - * the battery is measured through a voltage divider; - * otherwise it is assumed to be directly connected to Vdd. - */ - uint32_t output_ohm; - uint32_t full_ohm; -}; - -static const struct divider_config divider_config = { -#if DT_NODE_HAS_STATUS(VBATT, okay) - /* clang-format off */ - .io_channel = { - DT_IO_CHANNELS_INPUT(VBATT), - }, /* clang-format on */ - .power_gpios = GPIO_DT_SPEC_GET_OR(VBATT, power_gpios, {}), - .output_ohm = DT_PROP(VBATT, output_ohms), - .full_ohm = DT_PROP(VBATT, full_ohms), -#else /* /vbatt exists */ - /* clang-format off */ - .io_channel = { - DT_IO_CHANNELS_INPUT(ZEPHYR_USER), - }, /* clang-format on */ -#endif /* /vbatt exists */ -}; - -struct divider_data { - const struct device *adc; - struct adc_channel_cfg adc_cfg; - struct adc_sequence adc_seq; - int16_t raw; -}; -static struct divider_data divider_data = { -#if DT_NODE_HAS_STATUS(VBATT, okay) - .adc = DEVICE_DT_GET(DT_IO_CHANNELS_CTLR(VBATT)), -#else - .adc = DEVICE_DT_GET(DT_IO_CHANNELS_CTLR(ZEPHYR_USER)), -#endif -}; - -static int divider_setup(void) -{ - const struct divider_config *cfg = ÷r_config; - const struct io_channel_config *iocp = &cfg->io_channel; - const struct gpio_dt_spec *gcp = &cfg->power_gpios; - struct divider_data *ddp = ÷r_data; - struct adc_sequence *asp = &ddp->adc_seq; - struct adc_channel_cfg *accp = &ddp->adc_cfg; - int rc; - - if (!device_is_ready(ddp->adc)) { - LOG_ERR("ADC device is not ready %s", ddp->adc->name); - return -ENOENT; - } - - if (gcp->port) { - if (!device_is_ready(gcp->port)) { - LOG_ERR("%s: device not ready", gcp->port->name); - return -ENOENT; - } - rc = gpio_pin_configure_dt(gcp, GPIO_OUTPUT_INACTIVE); - if (rc != 0) { - LOG_ERR("Failed to control feed %s.%u: %d", gcp->port->name, gcp->pin, rc); - return rc; - } - } - - *asp = (struct adc_sequence){ - .channels = BIT(0), - .buffer = &ddp->raw, - .buffer_size = sizeof(ddp->raw), - .oversampling = 4, - .calibrate = true, - }; - -#ifdef CONFIG_ADC_NRFX_SAADC - *accp = (struct adc_channel_cfg){ - .gain = BATTERY_ADC_GAIN, - .reference = ADC_REF_INTERNAL, - .acquisition_time = ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 40), - }; - - if (cfg->output_ohm != 0) { - accp->input_positive = SAADC_CH_PSELP_PSELP_AnalogInput0 + iocp->channel; - } else { - accp->input_positive = SAADC_CH_PSELP_PSELP_VDD; - } - - asp->resolution = 14; -#else /* CONFIG_ADC_var */ -#error Unsupported ADC -#endif /* CONFIG_ADC_var */ - - rc = adc_channel_setup(ddp->adc, accp); - if (rc) { - LOG_ERR("Failed to setup ADC for AIN%u: %d", iocp->channel, rc); - } else { - LOG_DBG("ADC setup for AIN%u complete", iocp->channel); - } - - return rc; -} - -static bool battery_ok; - -static int battery_setup(void) -{ - LOG_INF("Initializing battery measurement"); - - int rc = divider_setup(); - - battery_ok = (rc == 0); - if (rc) { - LOG_ERR("Battery measurement setup failed: %d", rc); - } - - return rc; -} - -SYS_INIT(battery_setup, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); - -int battery_measure_enable(bool enable) -{ - int rc = -ENOENT; - - if (battery_ok) { - const struct gpio_dt_spec *gcp = ÷r_config.power_gpios; - - rc = 0; - if (gcp->port) { - rc = gpio_pin_set_dt(gcp, enable); - } - } - return rc; -} - -int battery_sample(void) -{ - int rc = -ENOENT; - - if (battery_ok) { - struct divider_data *ddp = ÷r_data; - const struct divider_config *dcp = ÷r_config; - struct adc_sequence *sp = &ddp->adc_seq; - - rc = adc_read(ddp->adc, sp); - sp->calibrate = false; - if (rc == 0) { - int32_t val = ddp->raw; - - adc_raw_to_millivolts(adc_ref_internal(ddp->adc), ddp->adc_cfg.gain, - sp->resolution, &val); - - if (dcp->output_ohm != 0) { - rc = val * (uint64_t)dcp->full_ohm / dcp->output_ohm; - LOG_DBG("raw %u ~ %u mV => %d mV", ddp->raw, val, rc); - } else { - rc = val; - LOG_DBG("raw %u ~ %u mV", ddp->raw, val); - } - } - } - - return rc; -} - -unsigned int battery_level_pptt(unsigned int batt_mV, const struct battery_level_point *curve) -{ - const struct battery_level_point *pb = curve; - - if (batt_mV >= pb->lvl_mV) { - /* Measured voltage above highest point, cap at maximum. */ - return pb->lvl_pptt; - } - /* Go down to the last point at or below the measured voltage. */ - while ((pb->lvl_pptt > 0) && (batt_mV < pb->lvl_mV)) { - ++pb; - } - if (batt_mV < pb->lvl_mV) { - /* Below lowest point, cap at minimum */ - return pb->lvl_pptt; - } - - /* Linear interpolation between below and above points. */ - const struct battery_level_point *pa = pb - 1; - - return pb->lvl_pptt + - ((pa->lvl_pptt - pb->lvl_pptt) * (batt_mV - pb->lvl_mV) / (pa->lvl_mV - pb->lvl_mV)); -} - -int read_battery_data(struct battery_data *batt_data) -{ - - /* Turn on the voltage divider circuit */ - int err = battery_measure_enable(true); - - if (err) { - LOG_ERR("Failed to enable battery measurement power: %d", err); - return err; - } - - /* Read the battery voltage */ - int batt_mv = battery_sample(); - - if (batt_mv < 0) { - LOG_ERR("Failed to read battery voltage: %d", batt_mv); - return batt_mv; - } - - /* Turn off the voltage divider circuit */ - err = battery_measure_enable(false); - if (err) { - LOG_ERR("Failed to disable battery measurement power: %d", err); - return err; - } - - batt_data->battery_voltage_mv = batt_mv; - batt_data->battery_level_pptt = battery_level_pptt(batt_mv, batt_levels); - - return 0; -} - -char *get_batt_v_str(void) -{ - return _batt_v_str; -} - -char *get_batt_lvl_str(void) -{ - return _batt_lvl_str; -} - -void log_battery_data(void) -{ - LOG_INF("Battery measurement: voltage=%s, level=%s", get_batt_v_str(), get_batt_lvl_str()); -} - -static void async_error_handler(struct golioth_client *client, enum golioth_status status, - const struct golioth_coap_rsp_code *coap_rsp_code, const char *path, - void *arg) -{ - if (status != GOLIOTH_OK) { - LOG_ERR("Failed to stream battery data: %d", status); - return; - } -} - -int stream_battery_data(struct golioth_client *client, struct battery_data *batt_data) -{ - int err; - /* {"batt_v":X.XXX,"batt_lvl":XXX.XX} */ - char json_buf[35]; - - /* Send battery data to Golioth */ - snprintk(json_buf, sizeof(json_buf), JSON_FMT, batt_data->battery_voltage_mv / 1000, - batt_data->battery_voltage_mv % 1000, batt_data->battery_level_pptt / 100, - batt_data->battery_level_pptt % 100); - /* LOG_DBG("%s", json_buf); */ - - err = golioth_stream_set_async(client, stream_endpoint, GOLIOTH_CONTENT_TYPE_JSON, json_buf, - strlen(json_buf), async_error_handler, NULL); - if (err) { - LOG_ERR("Failed to send battery data to Golioth: %d", err); - } - - return 0; -} - -int read_and_report_battery(struct golioth_client *client) -{ - int err; - struct battery_data batt_data; - - err = read_battery_data(&batt_data); - if (err) { - LOG_ERR("Error reading battery data"); - return err; - } - - /* Format as global string for easy access */ - snprintk(_batt_v_str, sizeof(_batt_v_str), "%d.%03d V", batt_data.battery_voltage_mv / 1000, - batt_data.battery_voltage_mv % 1000); - snprintk(_batt_lvl_str, sizeof(_batt_lvl_str), "%d%%", batt_data.battery_level_pptt / 100); - - log_battery_data(); - - if (golioth_client_is_connected(client)) { - err = stream_battery_data(client, &batt_data); - if (err) { - LOG_ERR("Error streaming battery info"); - return err; - } - } else { - LOG_DBG("No connection available, skipping streaming battery info"); - } - - return 0; -} diff --git a/src/battery_monitor/include/battery_monitor/battery.h b/src/battery_monitor/include/battery_monitor/battery.h deleted file mode 100644 index 35680cb..0000000 --- a/src/battery_monitor/include/battery_monitor/battery.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2018-2019 Peter Bigot Consulting, LLC - * Copyright (c) 2023 Golioth, Inc. - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef APPLICATION_BATTERY_H_ -#define APPLICATION_BATTERY_H_ - -#include -#include -#include - -/** Enable or disable measurement of the battery voltage. - * - * @param enable true to enable, false to disable - * - * @return zero on success, or a negative error code. - */ -int battery_measure_enable(bool enable); - -/** Measure the battery voltage. - * - * @return the battery voltage in millivolts, or a negative error - * code. - */ -int battery_sample(void); - -/** A point in a battery discharge curve sequence. - * - * A discharge curve is defined as a sequence of these points, where - * the first point has #lvl_pptt set to 10000 and the last point has - * #lvl_pptt set to zero. Both #lvl_pptt and #lvl_mV should be - * monotonic decreasing within the sequence. - */ -struct battery_level_point { - /** Remaining life at #lvl_mV. */ - uint16_t lvl_pptt; - - /** Battery voltage at #lvl_pptt remaining life. */ - uint16_t lvl_mV; -}; - -/** Calculate the estimated battery level based on a measured voltage. - * - * @param batt_mV a measured battery voltage level. - * - * @param curve the discharge curve for the type of battery installed - * on the system. - * - * @return the estimated remaining capacity in parts per ten - * thousand. - */ -unsigned int battery_level_pptt(unsigned int batt_mV, const struct battery_level_point *curve); - -/** A battery voltage and level measurement. - * - * Battery voltage is in mV. - * Battery level is in parts per ten thousand. - */ -struct battery_data { - int battery_voltage_mv; - unsigned int battery_level_pptt; -}; - -/** - * @brief Get pointer to a string representation of the last read battery - * voltage. - * - * This string is generated each time read_and_report_battery() is called. - * - * @return Pointer to character array - */ -char *get_batt_v_str(void); - -/** - * @brief Get pointer to a string representation of the last read percentage - * level. If a level has not yet been read, this value will be `none`. - * - * This string is generated each time read_and_report_battery() is called. - * - * @return Pointer to character array - */ -char *get_batt_lvl_str(void); - -/** - * @brief Read the battery voltage and estimated level. - * - * @param battery_data pointer to a struct to read the battery data into. - * - * @return Error number or zero if successful. - */ -int read_battery_data(struct battery_data *batt_data); - -/** - * @brief Log the battery voltage and estimated level. - * - * @param battery_data battery data to log. - * - */ -void log_battery_data(void); - -/** - * @brief Stream battery data to Golioth. - * - * @param client Golioth client to use for the Stream API call - * @param battery_data battery data to stream to Golioth. - * - * @return Error number or zero if successful - */ -int stream_battery_data(struct golioth_client *client, struct battery_data *batt_data); - -/** - * @brief Read, log, stream, and display a battery measurement. - * - * @param client Golioth client to use for the Stream API call - * - * @return Error number or zero if successful - */ -int read_and_report_battery(struct golioth_client *client); - -#endif /* APPLICATION_BATTERY_H_ */ diff --git a/src/main.c b/src/main.c index ff3a9b4..d59b814 100644 --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,7 @@ LOG_MODULE_REGISTER(golioth_modbus_vibration_monitor, LOG_LEVEL_DBG); #include #include -#ifdef CONFIG_SOC_NRF9160 +#ifdef CONFIG_SOC_SERIES_NRF91X #include #endif #ifdef CONFIG_LIB_OSTENTUS @@ -28,7 +28,7 @@ LOG_MODULE_REGISTER(golioth_modbus_vibration_monitor, LOG_LEVEL_DBG); static const struct device *o_dev = DEVICE_DT_GET_ANY(golioth_ostentus); #endif #ifdef CONFIG_ALUDEL_BATTERY_MONITOR -#include "battery_monitor/battery.h" +#include #endif #include @@ -39,7 +39,7 @@ static const struct device *o_dev = DEVICE_DT_GET_ANY(golioth_ostentus); /* Current firmware version; update in VERSION */ static const char *_current_version = - STRINGIFY(APP_VERSION_MAJOR) "." STRINGIFY(APP_VERSION_MINOR) "." STRINGIFY(APP_PATCHLEVEL); + STRINGIFY(APP_VERSION_MAJOR) "." STRINGIFY(APP_VERSION_MINOR) "." STRINGIFY(APP_PATCHLEVEL); static struct golioth_client *client; K_SEM_DEFINE(connected, 0, 1); @@ -60,8 +60,7 @@ void wake_system_thread(void) k_wakeup(_system_thread); } -static void on_client_event(struct golioth_client *client, - enum golioth_client_event event, +static void on_client_event(struct golioth_client *client, enum golioth_client_event event, void *arg) { bool is_connected = (event == GOLIOTH_CLIENT_EVENT_CONNECTED); @@ -87,7 +86,6 @@ static void start_golioth_client(void) /* Initialize DFU components */ golioth_fw_update_init(client, _current_version); - /*** Call Golioth APIs for other services in dedicated app files ***/ /* Observe State service data */ @@ -103,7 +101,7 @@ static void start_golioth_client(void) app_rpc_register(client); } -#ifdef CONFIG_SOC_NRF9160 +#ifdef CONFIG_SOC_SERIES_NRF91X static void lte_handler(const struct lte_lc_evt *const evt) { @@ -123,7 +121,7 @@ static void lte_handler(const struct lte_lc_evt *const evt) } } -#endif /* CONFIG_SOC_NRF9160 */ +#endif /* CONFIG_SOC_SERIES_NRF91X */ #ifdef CONFIG_MODEM_INFO static void log_modem_firmware_version(void) @@ -156,10 +154,12 @@ void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t void golioth_connection_led_set(uint8_t state) { uint8_t pin_state = state ? 1 : 0; -#if DT_NODE_EXISTS(DT_ALIAS(golioth_led)) + ARG_UNUSED(pin_state); /* silence warning if no LED/Ostentus present */ + /* Turn on Golioth logo LED once connected */ - gpio_pin_set_dt(&golioth_led, pin_state); -#endif /* #if DT_NODE_EXISTS(DT_ALIAS(golioth_led)) */ + IF_ENABLED(DT_NODE_EXISTS(DT_ALIAS(golioth_led)), + (gpio_pin_set_dt(&golioth_led, pin_state);)); + /* Change the state of the Golioth LED on Ostentus */ IF_ENABLED(CONFIG_LIB_OSTENTUS, (ostentus_led_golioth_set(o_dev, pin_state);)); } @@ -209,7 +209,7 @@ int main(void) } #endif /* #if DT_NODE_EXISTS(DT_ALIAS(golioth_led)) */ -#ifdef CONFIG_SOC_NRF9160 +#ifdef CONFIG_SOC_SERIES_NRF91X /* Start LTE asynchronously if the nRF9160 is used. * Golioth Client will start automatically when LTE connects */ @@ -230,7 +230,7 @@ int main(void) /* Block until connected to Golioth */ k_sem_take(&connected, K_FOREVER); -#endif /* CONFIG_SOC_NRF9160 */ +#endif /* CONFIG_SOC_SERIES_NRF91X */ /* Set up user button */ err = gpio_pin_configure_dt(&user_btn, GPIO_INPUT); diff --git a/west.yml b/west.yml index 93c41ef..a09e7ee 100644 --- a/west.yml +++ b/west.yml @@ -7,7 +7,7 @@ manifest: projects: - name: golioth path: modules/lib/golioth-firmware-sdk - revision: v0.17.0 + revision: v0.18.0 url: https://github.com/golioth/golioth-firmware-sdk.git west-commands: scripts/west-commands.yml submodules: true @@ -47,5 +47,10 @@ manifest: revision: v1.2.0 url: https://github.com/golioth/zephyr-network-info + - name: Golioth Battery Monitor + path: deps/modules/lib/battery-monitor + revision: v1.0.0 + url: https://github.com/golioth/battery-monitor + self: path: app