Devin MuiAaron HuangJesse Liang
Published © MIT

nowo's ark

An inexpensive flood detection system for developing countries.

EasyWork in progress24 hours529
nowo's ark

Things used in this project

Hardware components

ELEGOO UNO R3 Board ATmega328P ATMEGA16U2 with USB Cable
ELEGOO UNO R3 Board ATmega328P ATMEGA16U2 with USB Cable
×1
ELEGOO UNO R3 Project Complete Starter Kit
ELEGOO UNO R3 Project Complete Starter Kit
×1
Pushbutton switch 12mm
SparkFun Pushbutton switch 12mm
×1
LED (generic)
LED (generic)
×1
Resistor 100 ohm
Resistor 100 ohm
×1
Breadboard (generic)
Breadboard (generic)
×1
PVC Pipe
×1

Software apps and online services

Google Cloud

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)
Handsaw

Story

Read more

Custom parts and enclosures

Lid STL

Support

Support STL

Clip

Clip STL

Disk

Disk STL

Lid

Schematics

screen_shot_2019-05-26_at_1_13_47_am_M1RLvOlwFu.png

Fritzing

Code

app.js

JavaScript
var express = require('express')
var mongoose = require('mongoose')
var secrets = require('./secrets.js')

mongoose.Promise = require('bluebird')

var twilio = require('twilio')
var client = new twilio(secrets.accountId, secrets.authToken)

var opt = {
	useNewUrlParser: true,
	useFindAndModify: false
}

mongoose.connect('mongodb://localhost/nowo', opt)
mongoose.set('useCreateIndex', true)

var subscriptionSchema = mongoose.Schema({
	number: String,
	location: {
		longitude: Number,
		latitude: Number,
		address: String
	}
}, {
	timestamps: true
})

var deviceSchema = mongoose.Schema({
	location: {
		longitude: Number,
		latitude: Number
	}
}, {
	timestamps: true
})

var dataSchema = mongoose.Schema({
	location: {
		longitude: Number,
		latitude: Number
	},
	device: {
		type: mongoose.Schema.Types.ObjectId,
		ref: 'Device'
	}
}, {
	timestamps: true
})

var Subscription = mongoose.model('Subscription', subscriptionSchema)
var Device = mongoose.model('Device', deviceSchema)
var Data = mongoose.model('Data', dataSchema)

var app = express()

app.use(express.json())
app.use(express.urlencoded({ extended: false }))

app.post('/subscribe', function(req, res){
	Subscription.findOne({ number: req.body.From }, function(err, subscription){
		if(err) res.json({
			status: 'fail',
			data: err
		})

		// twilio automatically manages the stop/start functionality for us
		if(subscription) {
			client.messages.create({
				body: 'You have already subscribed to the flood detection system. Send STOP if you would like to stop receiving flood alerts.',
				to: req.body.From,
				from: secrets.number
			})
			.then(function(){
				res.json({
					status: 'fail',
					data: 'subscriber already exists!'
				})
			})
		} else { // necessary else statements bc of node's async nature
			new Subscription({
				number: req.body.From
			}).save(function(err){
				client.messages.create({
					body: 'You have subscribed to the flood detection system! Send STOP if you would like to stop receiving flood alerts.',
					to: req.body.From,
					from: secrets.number
				})
				.then(function(){
					res.json({
						status: 'success',
						data: 'subscribed'
					})
				})
			})
		}
	})
})

app.post('/data', function(req, res){
	Subscription.find({}, function(err, subscriptions){
		if(err) res.json({
			status: 'fail',
			data: err
		})

		for(var subscription of subscriptions){
			console.log(subscription)
			client.messages.create({
				body: 'A flood has been detected! Please evacuate quickly! Send STOP if you would like to stop receiving flood alerts.',
				to: subscription.number,
				from: secrets.number
			})
		}

		res.json({
			status: 'success',
			data: 'subscribers notified'
		})
	})
})

app.listen(3000, function(){
	console.log('listening on port 3000')
})

hardware.ino

Arduino
const int buttonPin = 8;
int startMillis;
int currentMillis;
int timer = 3000;
const int ledPin = 9;

void setup() {
  Serial.begin(9600);
  Serial.println("serial started");
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT);
  startMillis = 0;
}

void loop() {
    currentMillis = millis();
    
    if(currentMillis - startMillis > timer){
      if(digitalRead(buttonPin)){
        Serial.println("on");
        startMillis = currentMillis;
        digitalWrite(ledPin, HIGH);
      } else {
        digitalWrite(ledPin, LOW);
      }
    }
}

controller.py

Python
import requests
import serial
import traceback

from time import sleep

# establish serial connection with arduino
ser = serial.Serial('/dev/cu.usbmodem141401', 9600)
url = "http://localhost:3000/data"

while True:
	try:
		line = ser.readline()
		if 'on' in line:
			print('flood detected!')
			r = requests.post(url, data={'status': True })
			sleep(3)

	except:
		traceback.print_exc()

GitHub

Credits

Devin Mui

Devin Mui

3 projects • 5 followers
Wrote code instead of going to prom. From SF.
Aaron Huang

Aaron Huang

2 projects • 0 followers
Jesse Liang

Jesse Liang

1 project • 1 follower
Self-taught programmer. Hackathon hacker. From San Francisco, but attending UCSD.

Comments