summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c179
1 files changed, 171 insertions, 8 deletions
diff --git a/src/main.c b/src/main.c
index 570c01d..15af38b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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...");