Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Chamal Ayesh Wickramanayaka
Published © MIT

Flood Water Disaster Warning System

Annually, lot of people suffer by flood water around the world. Sometime people do not know until the flood water hit their region. The lack

IntermediateWork in progress10 hours879

Things used in this project

Story

Read more

Schematics

Wiring diagram of Artemis and the sensors

Wiring diagram of Artemis and the sensors

Connect with IoT gateway (ESP8266)

The diagram illustrates how to connect Artemis with ESP8266 for serial communication.

Code

SparkFun Artimis ATP with BME280

Arduino
#include <stdint.h>
#include "SparkFunBME280.h"
#include <SoftwareSerial.h>
#include "Wire.h"
#include "SPI.h"
#include "SparkFun_VCNL4040_Arduino_Library.h"
#include <SFE_MicroOLED.h>

#define PIN_RESET 9  
#define DC_JUMPER 1

BME280 mySensor;
VCNL4040 proximitySensor;
MicroOLED oled(PIN_RESET, DC_JUMPER);
SoftwareSerial esp8266(9,10);

void setup() {
    mySensor.settings.commInterface = I2C_MODE;
    mySensor.settings.I2CAddress = 0x77;
    mySensor.settings.runMode = 3;
    mySensor.settings.tStandby = 0;
    mySensor.settings.filter = 0;
    mySensor.settings.tempOverSample = 1;
    mySensor.settings.pressOverSample = 1;
    mySensor.settings.humidOverSample = 1;
    Serial.begin(9600);
    esp8266.begin(9600);
    Serial.print("Starting BME280... result of .begin(): 0x");
    Serial.println(mySensor.begin(), HEX);
    Wire.begin();
    if (proximitySensor.begin() == false)
    {
      Serial.println("Device not found. Please check wiring.");
      while (1);
    }
    oled.begin(); 
    oled.clear(ALL);
    oled.display(); 
    delay(1000);  
    oled.clear(PAGE);
}

void loop() {
  oled.clear(PAGE);
  oled.setFontType(0.25);
  oled.setCursor(0,0);
  oled.print(String(mySensor.readTempC()) + "C");
  oled.setCursor(0,10);
  oled.print(String(mySensor.readFloatHumidity()) + "%");
  oled.setCursor(0,20);
  oled.print(String(round(mySensor.readFloatPressure())) + "kPa");
  oled.setCursor(0,30);
  oled.print(String(mySensor.readFloatAltitudeMeters()) + "m");
  unsigned int proxValue = proximitySensor.getProximity(); 
  delay(10);
  oled.setCursor(0,40);
  oled.print(String(proxValue));
  oled.display();
  esp8266.print(proxValue);
  esp8266.print(",");
  esp8266.print(mySensor.readTempC());
  esp8266.print(",");
  esp8266.print(mySensor.readFloatHumidity());
  esp8266.print(",");
  esp8266.print(round(mySensor.readFloatPressure()));
  esp8266.print("\r\n");
  delay(1000);
}

ESP8266 code for receiving and sending sensor data to web socket.

Arduino
#include <WebSocketsClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti WiFiMulti;
WebSocketsClient webSocket;
bool isConnected = false;
int SENSOR_ID = 1;
String distance = "0";
String temp = "0";
String humidity = "0";
String bp = "0";
int rain = 0;
int light = 0;
String incomingByte = "";
int i1, i2, i3, i4;

void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
    switch(type) {
        case WStype_DISCONNECTED:
            isConnected = false;
            break;
        case WStype_CONNECTED:
            {
                isConnected = true;
                webSocket.sendTXT("5");
            }
            break;
        case WStype_TEXT:
            break;
        case WStype_BIN:
            hexdump(payload, length);
            break;
    }

}

void setup() {
    Serial.begin(9600);   
    for(uint8_t t = 4; t > 0; t--) {
      delay(1000);
    }
    WiFiMulti.addAP("SSID", "password");
    while(WiFiMulti.run() != WL_CONNECTED) {
        delay(100);
    }
    webSocket.beginSocketIO("web-socket-ip", port);
    webSocket.onEvent(webSocketEvent);
}

void loop() {
    webSocket.loop();
    if(isConnected) 
    {
      if(Serial.available()>0){
        incomingByte = Serial.readStringUntil('\r\n');
        Serial.println(incomingByte);
        i1 = incomingByte.indexOf(",");
        distance = incomingByte.substring(0,i1);
        i2 = incomingByte.indexOf(",", i1+1);
        temp = incomingByte.substring(i1+1, i2);
        i3 = incomingByte.indexOf(",", i2+1);
        humidity = incomingByte.substring(i2+1, i3);
        i4 = incomingByte.indexOf(",", i3+1);
        bp = incomingByte.substring(i3+1);
        rain = 1;
        light = 1;
        webSocket.sendTXT("42[\"beacon\",{\"id\":" + String(SENSOR_ID) + ",\"name\":\"deduru oya\",\"value\":" + distance + ",\"temp\":" + temp + ",\"humidity\":" + humidity + ",\"rain\":" + String(rain) + ",\"air\":" + bp + ",\"light\":" + String(light) +"}]");
      }
    }
}

Inference Engine Rain Fall Prediction

Arduino
Included inference engine related code to previous code. There are some additional files are needed to run this sketch. The entire project is in github.
/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

#include <TensorFlowLite.h>
#include "main_functions.h"
#include "constants.h"
#include "output_handler.h"
#include "sine_model_data.h"
#include "tensorflow/lite/experimental/micro/kernels/all_ops_resolver.h"
#include "tensorflow/lite/experimental/micro/micro_error_reporter.h"
#include "tensorflow/lite/experimental/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "tensorflow/lite/version.h"

namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output = nullptr;
int inference_count = 0;
constexpr int kTensorArenaSize = 2 * 1024;
uint8_t tensor_arena[kTensorArenaSize];
}

#include <stdint.h>
#include "SparkFunBME280.h"
#include <SoftwareSerial.h>
#include "Wire.h"
#include "SPI.h"
#include "SparkFun_VCNL4040_Arduino_Library.h"
#include <SFE_MicroOLED.h>

#define PIN_RESET 9  
#define DC_JUMPER 1

BME280 mySensor;
VCNL4040 proximitySensor;
MicroOLED oled(PIN_RESET, DC_JUMPER);
SoftwareSerial esp8266(9,10);

String proxValue;
String temp;
String humidity;
String bp;
float rain;
String alt;

void setup() {
  // ML setup
  static tflite::MicroErrorReporter micro_error_reporter;
  error_reporter = &micro_error_reporter;
  model = tflite::GetModel(g_sine_model_data);
  if (model->version() != TFLITE_SCHEMA_VERSION) {
    error_reporter->Report(
        "Model provided is schema version %d not equal "
        "to supported version %d.",
        model->version(), TFLITE_SCHEMA_VERSION);
    return;
  }
  static tflite::ops::micro::AllOpsResolver resolver;
  static tflite::MicroInterpreter static_interpreter(
      model, resolver, tensor_arena, kTensorArenaSize, error_reporter);
  interpreter = &static_interpreter;
  TfLiteStatus allocate_status = interpreter->AllocateTensors();
  if (allocate_status != kTfLiteOk) {
    error_reporter->Report("AllocateTensors() failed");
    return;
  }
  input = interpreter->input(0);
  output = interpreter->output(0);
  inference_count = 0;

  // Sensor setup
  mySensor.settings.commInterface = I2C_MODE;
  mySensor.settings.I2CAddress = 0x77;
  mySensor.settings.runMode = 3;
  mySensor.settings.tStandby = 0;
  mySensor.settings.filter = 0;
  mySensor.settings.tempOverSample = 1;
  mySensor.settings.pressOverSample = 1;
  mySensor.settings.humidOverSample = 1;
  Serial.begin(9600);
  esp8266.begin(9600);
  Serial.print("Starting BME280... result of .begin(): 0x");
  Serial.println(mySensor.begin(), HEX);
  Wire.begin();
  if (proximitySensor.begin() == false)
  {
    Serial.println("Device not found. Please check wiring.");
    while (1);
  }
  // Initialize display
  oled.begin(); 
  oled.clear(ALL);
  oled.display(); 
  delay(1000);  
  oled.clear(PAGE);
}

void loop() {
  // Clear display
  oled.clear(PAGE);
  oled.setFontType(0.25);
  oled.setCursor(0,0);

  proxValue = String(proximitySensor.getProximity()); 
  temp = String(mySensor.readTempC());
  humidity = String(mySensor.readFloatHumidity());
  bp = String(round(mySensor.readFloatPressure()));
  alt = String(mySensor.readFloatAltitudeMeters());

  // Do the inference
  rain = inference(temp.toInt(), humidity.toInt(), bp.toInt());
  
  // Display sensor data
  oled.print(temp + "C");
  oled.setCursor(0,10);
  oled.print(humidity + "%");
  oled.setCursor(0,20);
  oled.print(bp + "kPa");
  //oled.setCursor(0,30);
  //oled.print(alt + "m");
  //oled.setCursor(0,30);
  //oled.print(proxValue);
  oled.setCursor(0,30);
  oled.print("Rain prob.: ");
  oled.setCursor(0,40);
  oled.print(String(rain) + "%");
  oled.display();
  // Send values to ESP8266 IoT gateway
  esp8266.print(proxValue);
  esp8266.print(",");
  esp8266.print(mySensor.readTempC());
  esp8266.print(",");
  esp8266.print(mySensor.readFloatHumidity());
  esp8266.print(",");
  esp8266.print(round(mySensor.readFloatPressure()));
  esp8266.print("\r\n");
  delay(1000);
}

float inference(int x, int y, int z){
  input->data.f[0] = x;
  input->data.f[1] = y;
  input->data.f[2] = z;
  TfLiteStatus invoke_status = interpreter->Invoke();
  if (invoke_status != kTfLiteOk) {
    error_reporter->Report("Invoke failed...");
    return 0;
  }
  float y_val = output->data.f[0];
  return y_val/100;
}

Credits

Chamal Ayesh Wickramanayaka
23 projects • 25 followers
Experienced software engineer with a passion for AI, IoT, and innovation, continuously seeking to learn and embrace new technologies.

Comments