Hi,
You can use the serial port to detect water and send an SMS if water was detected. It can also be modified to just read a single switch.
Hardware (just two wires):
All you need is to attach two wires to TX and RX of your router (tested with Asus WL-500gP v1 and a FTDI 3.3 V serial to USB converter cable), remove the insulation at the end of the cable. If the cables touch, data can be send from TX to RX, if the cables are not connected (no water, open switch) no data can be received at the RX-pin.
Safety warning:
Ensure that the cables will not touch other voltage levels (mains for instance!). The router might get damaged or you may get electrocuted!
How it verx:
The TTL level serial ports of routers and many USB level shifter are quite sensitive. If there is some resistance between the TX and RX line, data can be send out at the TX pin and detected at the RX pin. Also, you do not have to care for the voltage level of the serial port, since TX will transmit with a compatible voltage to RX.
Tested with:
- Asus Wl-500gP.
- FTDI USB 3.3 V level shifter cable.
tsender.sh (copy this to /usr/bin/tsender.sh)
#!/bin/sh
################################################################################
#
# Little hack to use a serial port as water detection or switch input.
#
# Hardware....: Just a pair of cable attached to TX and RX
#
# How it works: A string is send out at TX. After sending the RX-buffer is read.
# If it contains the same string, well then there is conductive
# connection betweem TX and RX.
# Tested with.: Asus WL-500gP v1 embedded router hardware
#
# Author......: (c) 2007, 2008, 2009 Tom Stoeveken
#
# ToDo........: - write a C program, integrate with OpenWRT
# - investigate if the bit error rate and resistance correlate
#
################################################################################
# copy a string from $1 to $2 and pause
while true; do
echo "$1" > "$2"
usleep 100000
done
treceiver.sh (copy this to /usr/bin/treceiver.sh)
#!/bin/sh
################################################################################
#
# Little hack to use a serial port as water detection or switch input.
#
# Hardware....: Just a pair of cable attached to TX and RX
#
# How it works: A string is send out at TX. After sending the RX-buffer is read.
# If it contains the same string, well then there is conductive
# connection betweem TX and RX.
# Tested with.: Asus WL-500gP v1 embedded router hardware
#
# Author......: (c) 2007, 2008, 2009 Tom Stoeveken
#
# ToDo........: - write a C program, integrate with OpenWRT
# - investigate if the bit error rate and resistance correlate
#
################################################################################
# it was necessary to find the right pid to kill in case no data arrives
# at the input buffer, otherwise this script hangs forever
{ usleep 400000 ; kill $$; } </dev/null &
KILLERPID="$!"
# read from RX buffer
head -n 1 "$1" &
HEADPID="$!"
usleep 200000
kill "$KILLERPID" 2>/dev/null
kill "$HEADPID" 2>/dev/null
handymeldung_wasser.sh
#!/bin/sh
################################################################################
#
# Little hack to use a serial port as water detection or switch input.
#
# Hardware....: Just a pair of cable attached to TX and RX
#
# How it works: A string is send out at TX. After sending the RX-buffer is read.
# If it contains the same string, well then there is conductive
# connection betweem TX and RX.
# Tested with.: Asus WL-500gP v1 embedded router hardware
#
# Author......: (c) 2007, 2008, 2009 Tom Stoeveken
#
# ToDo........: - write a C program, integrate with OpenWRT
# - investigate if the bit error rate and resistance correlate
#
################################################################################
MYPID="$(echo "$$")"
#trap "rm /tmp/handy_wassermeldung.pid; exit 0" 0 1 2
if [ -f /tmp/handy_wassermeldung.pid ]; then
OTHERPID="$(cat /tmp/handy_wassermeldung.pid)"
if [ "$OTHERPID" != "$MYPID" ]; then
logger "ueberzeahlige Wassermeldung verworfen (MYPID: $MYPID, OTHERPID: $OTHERPID)"
exit 0
fi
fi
echo "$MYPID" > /tmp/handy_wassermeldung.pid
#echo "Wassereinbruch im Keller." | gnokii --config /etc/gnokiirc --sendsms +491234567
logger "Wassermeldung von PID $MYPID"
sleep 60
logger "Wassermeldung wieder freigegeben durch PID $MYPID"
rm /tmp/handy_wassermeldung.pid
The main script, copy it to /usr/bin/waterdetection.sh
#!/bin/sh
################################################################################
#
# Little hack to use a serial port as water detection or switch input.
#
# Hardware....: Just a pair of cable attached to TX and RX
#
# How it works: A string is send out at TX. After sending the RX-buffer is read.
# If it contains the same string, well then there is conductive
# connection betweem TX and RX.
# Tested with.: Asus WL-500gP v1 embedded router hardware
#
# Author......: (c) 2007, 2008, 2009 Tom Stoeveken
#
# ToDo........: - write a C program, integrate with OpenWRT
# - investigate if the bit error rate and resistance correlate
#
################################################################################
# configure the serial port here
SERIALPORT="/dev/ttyS1"
# set a baudrate, I went for a quite slow baudrate
BAUDRATE=9600
# PID of the sender, since we start it, we also have to stop it afterwards
SPID=-1
trap 'kill "$SPID"; exit' 0 1 2
# flash LED for each try
led() {
echo $1 > /proc/diag/led/power
}
# configure the serial port
configure() {
# configure BAUDRATE, 8N1
stty -F "$SERIALPORT" $BAUDRATE clocal cread cs8 -cstopb parenb parodd -echo -crtscts -onlcr
}
# check if we could read our own message without errors
receiver() {
RECV="$(treceiver.sh "$SERIALPORT")"
if [ "$RECV" = "$1" ]; then
water
else
led 1
usleep 2000
led 0
sleep 2
echo "no water detected"
fi
}
# if there was water detected, this function will be called
water() {
for i in $(seq 0 5); do
led 1
usleep 30000
led 0
usleep 30000
done
echo "water detected"
# here i send an SMS if there was water detected
./handymeldung_wasser.sh &
}
# main loop
configure
while true; do
TEXT="1234567890"
led 0
if [ "$SPID" = "-1" ]; then
configure
tsender.sh "$TEXT" "$SERIALPORT" &
SPID="$!"
fi
configure
receiver "$TEXT"
usleep 300000
done
The "usleep" binary is part of busybox, so enable it with "make menuconfig". The SMS is send with "gnokii", the setup and configuration is not described here. I provided a Makefile for gnokii a while ago and it is now part of OpenWRT.
Modify the scripts according to your needs and hardware. At one stage either I or someone keen enough to code it in C, C++ might provide a package for OpenWRT. This is quite experimental code, but it proved to work for several month now.
Viel Spass,
Tom