diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 179 |
1 files changed, 171 insertions, 8 deletions
@@ -25,6 +25,67 @@ #include "certificates.h" +#include <nrf9160.h> +#include <stdio.h> +#include <string.h> +#include <zephyr/drivers/adc.h> + +struct device *adc_dev; +uint8_t sensors_enabled = 0xff; // bit 0 - PIR, bit 1 - HAL, bit 2 - temperature, bit 3 - gas + +#include <hal/nrf_saadc.h> +#define ADC_DEVICE_NAME DT_NODELABEL(adc) +#define ADC_RESOLUTION 10 +#define ADC_GAIN ADC_GAIN_1_2 +#define ADC_REFERENCE ADC_REF_INTERNAL +#define ADC_ACQUISITION_TIME ADC_ACQ_TIME(ADC_ACQ_TIME_MICROSECONDS, 10) + +static const struct adc_channel_cfg adc_temp_channel_cfg = { + .gain = ADC_GAIN, + .reference = ADC_REFERENCE, + .acquisition_time = ADC_ACQUISITION_TIME, + .channel_id = 4, +#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS) + .input_positive = 5, +#endif +}; + +static const struct adc_channel_cfg adc_gas_channel_cfg = { + .gain = ADC_GAIN, + .reference = ADC_REFERENCE, + .acquisition_time = ADC_ACQUISITION_TIME, + .channel_id = 5, +#if defined(CONFIG_ADC_CONFIGURABLE_INPUTS) + .input_positive = 6, +#endif +}; + + +static int16_t adc_sample(uint8_t idx) +{ + int ret; + int16_t temp; //mV + + if(idx > 1) return -1; + + const struct adc_sequence sequence = { + .channels = BIT(idx + 4), // choose AIN4 on AIN5 + .buffer = &temp, // only single value, make to pointer to simulate array + .buffer_size = sizeof(temp), + .resolution = ADC_RESOLUTION, + }; + + if (!adc_dev) { + return -1; + } + + ret = adc_read(adc_dev, &sequence); + + temp = (temp * 6) / 5; // simple aproximation of 0-1023 range to 0-1200 mV range + + return temp; +} + LOG_MODULE_REGISTER(mqtt_simple, CONFIG_MQTT_SIMPLE_LOG_LEVEL); /* Buffers for MQTT client. */ @@ -87,16 +148,16 @@ static void data_print(uint8_t *prefix, uint8_t *data, size_t len) LOG_INF("%s%s", (char *)prefix, (char *)buf); } -/**@brief Function to publish data on the configured topic +/**@brief Function to publish data on a topic */ -static int data_publish(struct mqtt_client *c, enum mqtt_qos qos, +static int data_publish(struct mqtt_client *c, enum mqtt_qos qos, const char *topic, uint8_t *data, size_t len) { struct mqtt_publish_param param; param.message.topic.qos = qos; - param.message.topic.topic.utf8 = CONFIG_MQTT_PUB_TOPIC; - param.message.topic.topic.size = strlen(CONFIG_MQTT_PUB_TOPIC); + param.message.topic.topic.utf8 = topic; + param.message.topic.topic.size = strlen(topic); param.message.payload.data = data; param.message.payload.len = len; param.message_id = sys_rand32_get(); @@ -211,8 +272,14 @@ void mqtt_evt_handler(struct mqtt_client *const c, if (err >= 0) { data_print("Received: ", payload_buf, p->message.payload.len); + + // for both way communication demonstration: ox turn on led x, [any other char]x turns off led x + if(p->message.payload.len >= 2 && payload_buf[1] >= '0' && payload_buf[1] <= '3') { + dk_set_led(payload_buf[1] - 48, payload_buf[0] == 'o'); + } + /* Echo back received data */ - data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, + data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, "nrf/echo", payload_buf, p->message.payload.len); } else if (err == -EMSGSIZE) { LOG_ERR("Received payload (%d bytes) is larger than the payload buffer " @@ -434,19 +501,56 @@ static int fds_init(struct mqtt_client *c) #if defined(CONFIG_DK_LIBRARY) static void button_handler(uint32_t button_states, uint32_t has_changed) { + // After inicializtion pressed button and active switch make sensor disabled + if(sensors_enabled == 0xff) { + sensors_enabled = (~button_states) & 0xf; // mask only 4 real buttons + } + if (has_changed & button_states & BIT(CONFIG_BUTTON_EVENT_BTN_NUM - 1)) { int ret; ret = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, - CONFIG_BUTTON_EVENT_PUBLISH_MSG, - sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG)-1); + "nrf/button", + "1 pressed", + 9); + if (ret) { + LOG_ERR("Publish failed: %d", ret); + } + } + + if ((has_changed & BIT(4)) && (sensors_enabled & BIT(0))) { + int ret; + + dk_set_led(0, button_states & BIT(4)); + + ret = data_publish(&client, + MQTT_QOS_1_AT_LEAST_ONCE, + "nrf/pir", + (button_states & BIT(4))? "1":"0", + 1); + if (ret) { + LOG_ERR("Publish failed: %d", ret); + } + } + + if (has_changed & BIT(5) && (sensors_enabled & BIT(1))) { + int ret; + + dk_set_led(1, button_states & BIT(5)); + + ret = data_publish(&client, + MQTT_QOS_1_AT_LEAST_ONCE, + "nrf/magnet", + (has_changed & BIT(5))? "1":"0", + 1); if (ret) { LOG_ERR("Publish failed: %d", ret); } } } + #endif static int shell_mqtt_publish(const struct shell *shell, size_t argc, char **argv) @@ -458,6 +562,7 @@ static int shell_mqtt_publish(const struct shell *shell, size_t argc, char **arg ret = data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, + CONFIG_MQTT_PUB_TOPIC, CONFIG_BUTTON_EVENT_PUBLISH_MSG, sizeof(CONFIG_BUTTON_EVENT_PUBLISH_MSG) - 1); if (ret) { @@ -512,7 +617,10 @@ static int modem_configure(void) void main(void) { int err; - uint32_t connect_attempt = 0; + uint32_t connect_attempt = 0, last_measurement = 0; + + uint16_t adcval = 0; + uint8_t buf[10]; LOG_INF("The MQTT simple sample started"); @@ -541,6 +649,23 @@ void main(void) #if defined(CONFIG_DK_LIBRARY) dk_buttons_init(button_handler); + dk_leds_init(); + + adc_dev = DEVICE_DT_GET(ADC_DEVICE_NAME); + + if (!adc_dev) { + printk("device_get_binding ADC failed\n"); + while(1); + } + err = adc_channel_setup(adc_dev, &adc_temp_channel_cfg); + if (err) { + printk("Error in adc setup: %d\n", err); + } + + err = adc_channel_setup(adc_dev, &adc_gas_channel_cfg); + if (err) { + printk("Error in adc setup: %d\n", err); + } #endif do_connect: @@ -561,6 +686,11 @@ do_connect: return; } + // One second blink with all led to inform abot + dk_set_leds(0b1111); + k_msleep(1000); + dk_set_leds(0b1111); + while (1) { err = poll(&fds, 1, mqtt_keepalive_time_left(&client)); if (err < 0) { @@ -591,6 +721,39 @@ do_connect: LOG_ERR("POLLNVAL"); break; } + + if(last_measurement < (NRF_RTC1->COUNTER) || last_measurement + 1000000 > (NRF_RTC1->COUNTER)) + { + last_measurement = (NRF_RTC1->COUNTER); + if (sensors_enabled & BIT(2)) { //enabled temperature + // Sample AIN4 - LM35 + adcval = adc_sample(0); + printk("Temp: %d mV\n", adcval); + + if(adcval > 280) { // 26 deg C + snprintf(buf, 10, "%d", adcval); + data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, "nrf/temp", buf, strlen(buf)); + dk_set_led(2, 1); + k_msleep(1000); + } + else dk_set_led(2, 0); + } + + if (sensors_enabled & BIT(3)) { // enabled gas + // Sample AIN5 - gas sensor + adcval = adc_sample(1); + printk("Gas: %d mV %d\n", adcval, sensors_enabled); + + if(adcval > 200) { // reliable limit got by testing + snprintf(buf, 10, "%d", adcval); + data_publish(&client, MQTT_QOS_1_AT_LEAST_ONCE, "nrf/gas", buf, strlen(buf)); + dk_set_led(3, 1); + k_msleep(1000); + } + else dk_set_led(3, 0); + } + } + } LOG_INF("Disconnecting MQTT client..."); |
