Jay Freedly
Published

Storm Drain Defender

A storm drain grate mountable sensor that monitors and alerts you when your storm drain is not functioning properly.

72
Storm Drain Defender

Things used in this project

Hardware components

AVR IoT Mini Cellular Board
Microchip AVR IoT Mini Cellular Board
×1
JSN-SR04T Integrated Ultrasonic Distance Measuring Sensor Transducer Module Waterproof
×1
Rechargeable Battery, 3.7 V
Rechargeable Battery, 3.7 V
×1

Software apps and online services

Arduino IDE
Arduino IDE
Microsoft Azure
Microsoft Azure
Microsoft Azure Iot Hub Microsoft IoT Explorer
PuTTy - serial terminal

Story

Read more

Schematics

Board Diagram

Code

Distance sensing and Azure IoT Hub Upload

Arduino
This code assumes you have followed the Provision.ino example sketch from the AVR_IoT-Cellular library examples to generate the DeviceID and add a device to the Azure IoT Hub.
#include <Arduino.h>
#include <ecc608.h>
#include <log.h>
#include <lte.h>
#include <mqtt_client.h>


//Specifies trigger and echo pin on 
const int trigPin = PIN_PA7; // Labeled D12 on board
const int echoPin = PIN_PB5; //Labeled D10 on board

//Configures board for MQTT data transfer using the stored IoT Hub credentials used in the Provision.ino sketch
const char MQTT_PUB_TOPIC_FMT[] PROGMEM = "devices/%s/messages/events/";
const char MQTT_SUB_TOPIC_FMT[] PROGMEM = "devices/%s/messages/devicebound/#";

static char mqtt_sub_topic[128];
static char mqtt_pub_topic[128];

static volatile bool got_message_event = false;
static char message_topic[384];
static volatile uint16_t message_length = 0;

static void onReceive(const char* topic,
                      const uint16_t length,
                      __attribute__((unused)) const int32_t id) {
    strcpy(message_topic, topic);
    message_length = length;

    got_message_event = true;
}

bool initTopics() {
    ATCA_STATUS status = ECC608.begin();

    if (status != ATCA_SUCCESS) {
        Log.errorf(F("Failed to initialize ECC, error code: %X\r\n"), status);
        return false;
    }

    // Find the device ID and set the publish and subscription topics
    uint8_t device_id[128];
    size_t device_id_length = sizeof(device_id);

    status =
        ECC608.readProvisionItem(AZURE_DEVICE_ID, device_id, &device_id_length);

    if (status != ATCA_SUCCESS) {
        Log.errorf(F("Could not retrieve device ID from the ECC, error code: "
                     "%X. Please provision the device with the provision "
                     "example sketch.\r\n"),
                   status);
        return false;
    }

    sprintf_P(mqtt_sub_topic, MQTT_SUB_TOPIC_FMT, device_id);
    sprintf_P(mqtt_pub_topic, MQTT_PUB_TOPIC_FMT, device_id);

    return true;
}

void setup() {
  Log.begin(115200);
  Log.info(F("Starting MQTT for Azure example\r\n"));

    if (!initTopics()) {
        Log.error(F("Unable to initialize the MQTT topics. Stopping..."));
        while (1) {}
    }

    if (!Lte.begin()) {
        Log.error(F("Failed to connect to operator"));
        while (1) {}
    }

    // Attempt to connect to Azure
    if (MqttClient.beginAzure()) {
        MqttClient.subscribe(mqtt_sub_topic);
        MqttClient.onReceive(onReceive);
    } else {
        while (1) {}
    }

  Serial3.begin(115200);
  pinConfigure(trigPin, PIN_DIR_OUTPUT);
  pinConfigure(echoPin, PIN_DIR_INPUT | PIN_PULLUP_ON);
}

void loop() {

  digitalWrite(trigPin, LOW);
  delayMicroseconds(5);

  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  long duration = pulseIn(echoPin, HIGH);
  long distance = duration * 0.034 / 2;

  Serial3.print("Distance:");
  Serial3.println(distance);

  String message_to_publish = String("height: " + String(distance) + "}");

  const bool published_successfully =
    MqttClient.publish(mqtt_pub_topic, message_to_publish.c_str());

  if (published_successfully) {
      Log.info(F("Published message"));
  } else {
      Log.error(F("Failed to publish\r\n"));
  }

  if (got_message_event) {

    String message = MqttClient.readMessage(message_topic,message_length);
    
            // Read message will return an empty string if there were no new
            // messages, so anything other than that means that there were a
            // new message
            if (message != "") {
                Log.infof(F("Got new message: %s\r\n"), message.c_str());
            }

            got_message_event = false;
        }

        delay(60000);   //delays for one minute before next read
}

Credits

Jay Freedly

Jay Freedly

1 project • 1 follower

Comments