We are living with my father, 96 years old. He sometimes forgets to close the tap water because he is hard of hearing. So water sometimes continues to flow for about 4 hours or more in the sink. When we received our water bill at the end of the month, we are surprised at the high water bill and want to reduce the water charges. As this solution, I built Water Flow Detection System to stop the water using an AI to reduce the water charges.
2. How I am Trying to Solve It?The Water Flow Detection System works using QuickFeather Development Kit and SensiML AI Software to analyze the tap water status and alarm the tap water running by the onboard LED and the piezo speaker.
The external microphone detects the sound of water flow. Its microphone mounted on the water pipe extends from QuickFeather Development Kit with a cable. QuickFeather Development Kit connects with Raspberry Pi by USB cable and sends the received sound data to Raspberry Pi. After detecting the sound, Raspberry Pi creates a CSV file importable by SensiML DataCaptureLab of SensiML AI software.
SensiML DataCaptureLab captures the sound data using importing a CSV file and labels it. After that, SensiML Analytics Studio of SensiML AI software builds a machine learning model for detecting tap water running. Next, the SensiML Analytics Studio generates a knowledge pack from that model.
After flashing the generated knowledge pack into QuickFeather Development Kit, depending on the detection results of the tap water running, the Water Flow Detection System built on QuickFeather Development Kit notifies using the onboard LED and a piezo speaker as follows:
- When detected tap water stop, the onboard LED lights up green.
- When detected running tap water, the onboard LED lights up blue.
- When detected for more than 8-sec tap water running, the piezo speaker sounds with the onboard LED lights up red.
(1) Circuit Schematic
Here is Circuit Schematic made with KiCad. QuickFeather Development Kit connects, using the I2C interface, ADS1015 Module wired to MAX4466 Mic. QuickFeather Development Kit also connects Raspberry pi through CP2102 USB to TTL, and Piezo Speaker through GPIO.
(2) Assemble It
Components on the breadboard include QuickFeather Development Kit, ADS1015 Module, MAX4466 Mic, Piezo Speaker, and CP2102 USB to TTL, assembled as follows.
The program code on QuickFeather Development Kit bases qf_ssi_ai_app on Quickfeather Simple Streaming Interface AI Application Project. Additionally, the program code on Raspberry Pi works for collecting the sound data from QuickFeather Development Kit. Those source codes show in ’https://github.com/tomosoft-jp/detectionsystem.‘
4.1 ADS1015 Sensor CodeAD converter “ADS1015” code based on “SparkFun ADS1015 Arduino Library” for Arduino modifies following the steps below. The generated code places in the folder “qf_ssi_ai_app/src.”
(1) Add the header file as follows.
”SparkFun_ADS1015_Arduino_Library.c”
…
#include "Fw_global_config.h"
#include "FreeRTOS.h"
#include "task.h"
extern "C" void HAL_DelayUSec(uint32_t usecs);
…
”SparkFun_ADS1015_Arduino_Library.h“
…
#else
// tomo #include "WProgram.h"
#include "Wire.h"
#endif
…
(2) Add “delay” function as follows.
”SparkFun_ADS1015_Arduino_Library.c”
…
void delay(unsigned long ms)
{
HAL_DelayUSec(ms*1000);
}
…
(3) Change data type in ”SparkFun_ADS1015_Arduino_Library.c” and ”SparkFun_ADS1015_Arduino_Library.h” as follows.
boolean → bool
byte → uint8_t
(4) Comment out the following data type in”SparkFun_ADS1015_Arduino_Library.h.”
Stream
4.2 Data Collection CodeData Collection Code builds and runs the project to work at data collection mode.
(1) Change to data collection mode by the following macro.
”sensor_ssss.h”
…
/* Settings for the sensor processing modes, Enable only one of these mode */
#define SENSOR_SSSS_RECOG_ENABLED 0 /* Enable SensiML recognition */
#define SENSOR_SSSS_LIVESTREAM_ENABLED 1 /* Enable live-streaming for data collection */
…
(2) Change sensor sample rate to 250 and number of channels to 1 as follows.
sensor_ssss.h”
…
#define SENSOR_SSSS_SAMPLE_RATE_HZ (250) // sensor sample rate per channel in Hz
#define SENSOR_SSSS_CHANNELS_PER_SAMPLE ( 1) // Number of channels
#define SENSOR_SSSS_LATENCY (20) // process samples every 20ms
…
(3) Update code “sensor_ssss.cpp” for using ADS1015 Module as follows.
- Add a class instance of the ADS1015 and include file “SparkFun_ADS1015_Arduino_Library.h.”
- Update the string value definition of “json_string_sensor_config.”
- Add the function “begin” and “setSampleRate” into the function “sensor_ssss_configure.”
- Change the data block pointer in the function “sensor_ssss_acquisition_buffer_ready.”
"sensor_ssss.cpp”
…
#include "SparkFun_ADS1015_Arduino_Library.h" //**tomo
…
ADS1015 qorc_ssi_adc ; //**tomo
const char json_string_sensor_config[] = \
"{"\
"\"sample_rate\":250,"\
"\"samples_per_packet\":2,"\
"\"column_location\":{"\
" \"Sound\":0"\
"}"\
"}\r\n" ;
void sensor_ssss_configure(void)
{
…
//**tomo
uint8_t ret = qorc_ssi_adc.begin();
qorc_ssi_adc.setSampleRate(sensor_ssss_config.rate_hz);
/*--- END of User modifiable section ---*/
int sensor_ssss_acquisition_buffer_ready()
{
…
//**tomo
int16_t adc_data = qorc_ssi_adc.getSingleEnded(3);
int16_t *p_adc_data = (int16_t *)p_dest;
*p_adc_data ++= adc_data;
p_dest += 2; // advance datablock pointer to retrieve and store next sensor data
…
4.3 Data Recognition CodeData Recognition Code builds and runs the project to work at data recognition mode.
(1) Replace the recognition model folder "knowledgepack_project" downloaded in "Download model of SensiML Analytics Studio" with the contents of the folder "water_stop_app / knowledgepack."
(2) Change to data collection mode by the following macro.
”sensor_ssss.h”
…
/* Settings for the sensor processing modes, Enable only one of these mode */
#define SENSOR_SSSS_RECOG_ENABLED 1 /* Enable SensiML recognition */
#define SENSOR_SSSS_LIVESTREAM_ENABLED 0 /* Enable live-streaming for data collection */
…
(3) The onboard LED lights up green when detected tap water stops in switch case 2. The tap water is running in switch case 1. The piezo speaker sounds with the onboard LED red when detected for more than 8-sec tap water is running. Otherwise, the onboard LED lights up blue.
” sml_output.c”
…
kb_get_feature_vector(model, sensor_ssss_ai_fv_arr, &sensor_ssss_ai_fv_len);
//**tomo
//dbg_str_now();
switch((int)classification){
case 1:
if(wateralarm < WATERTIMER){
wateralarm ++;
HAL_GPIO_Write(GPIO_5, 0); //green LED
HAL_GPIO_Write(GPIO_6, 0); //red LED
HAL_GPIO_Write(GPIO_4, 1); //blue LED
}
else{
HAL_GPIO_Write(GPIO_5, 0); //green LED
HAL_GPIO_Write(GPIO_4, 0); //blue LED
HAL_GPIO_Write(GPIO_6, 1); //red LED
HAL_GPIO_Write(GPIO_2, sensor_rate_debug_gpio_val);
sensor_rate_debug_gpio_val ^= 1;
}
break;
case 2:
wateralarm = 0;
HAL_GPIO_Write(GPIO_6, 0); //red LED
HAL_GPIO_Write(GPIO_4, 0); //blue LED
HAL_GPIO_Write(GPIO_5, 1); //green LED
break;
default:
wateralarm = 0;
break;
}
count = snprintf(sensor_ssss_ai_result_buf, buflen, "{\"ModelNumber\":%d,\"Classification\":%d,\"FeatureLength\":%d,\"FeatureVector\":[",(int)model,(int)classification, (int)sensor_ssss_ai_fv_len);
…
4.4 Sound Data Save Code
Sound Data Save Code on Raspberry Pi receives the sound data from QuickFeather Development Kit after sending the string “connect” by USB. After receiving 5000 sound data, its code starts to make a CSV file that SensiML DataCaptureLab can read.
”ssiloger.py”
import serial
import struct
import datetime
datasize = 2 * 250 * 20
databuf = [0] * datasize
def main():
ser = serial.Serial('/dev/ttyUSB0', 460800)
# datasize = 10
print(datasize)
ser.write(str.encode('connect'))
for num in range(datasize):
while True:
if ser.in_waiting > 0:
break
recv_data = ser.read(1)
databuf[num] = int.from_bytes(recv_data, 'big')
# print("{0}".format(databuf[num]))
# print("********")
filename = 'log/soundlog' + datetime.datetime.now().strftime('%Y%m%d%H%M%S') + '.csv'
with open(filename, "wb") as f:
f.write(str.encode("Sound\n"))
for num in range(0, datasize, 2):
data = databuf[num] + (databuf[num + 1] << 8)
# print("{0}".format(data))
f.write(str.encode("{0}\n".format(data)))
if __name__ == '__main__':
main()
5. Capturing Sound DataSensiML DataCaptureLab captures the sound data using a CSV file.
5.1 Attach MAX4466 Mic to the tapMAX4466 Mic mounted on the water pipe is connected to QuickFeather Development Kit by wire. QuickFeather Development Kit receives the sound data detected by MAX4466 Mic and sends it to Raspberry Pi 4 through CP2102 USB to TTL.
After opening the project and click the “Switch Modes” on the center, capture mode uses by clicking the “Capture” button.
(1) The Data Capture Lab imports ADS1015 Module Plugins via the following SSF files.
“dcl_import.ssf”
…
{
"max_throughput": 0,
"name": "ADC",
"part": "ADS1015",
"sample_rates": [
128,
250,
490,
920,
1600,
2400,
3300
],
"is_default": false,
"sensors": [
{
"column_count": 1,
"is_default": true,
"column_suffixes": [
""
],
"type": "Analog Channel"
}
],
"sensor_id": 1184532964,
"can_live_stream": true
}
…
(2) Click the menu “File,” “Import Files,” “CSV Files…” and select the CSV files created by Raspberry Pi 4.
(3) Click the “Import” button.
(4) To open the raw sensor data files you have captured, use the “Project Explorer”. This can be found in the upper left-hand corner of the DataCaptureLab.
SensiML DataCaptureLab labels the sound data. After opening the project, click “Switch Modes,” and Label Explorer mode is open after selecting the “Label Explorer” button.
(1) Click “Add Labels” to create new event labels “flow” and “stop”.
(2) Identify the event of interest in the graph. To do this, move the mouse onto the graph of the sound data and right-click + drag your mouse over the area that you want to label as an event. This will place a new segment in the file..
(3) After creating the segment, label this segment ”flow” by clicking the “Edit” button.
SensiML Analytics Studio builds a machine learning model for detecting tap water running.
(1) Set the following data after clicking the left side menu “Prepare Data,” and click the “SAVE” button.
- Query: myquery
- Session: Session 1
- Label: Label
- Metadata: segment_uuid
- Plot: Segment
(2) Set the following data after clicking the left side menu “Build Mode,” and click the “Optimize” button.
- Pipeline: mypipeline
- Window Size: 250
- Optimization Metric: f1-score
SensiML Analytics Studio generates a knowledge pack from that model.
(1) Set the following data after clicking the left side menu “Download Mode,” and click the “DOWNLOAD” button.
- HW Platform: QuickFeather 1.7.0
- Target OS: FreeRTOS
- Format: Library
- Data Source: Sensor 1
- Output: Simple Streaming
Use the flash programming procedure to flash the binary including the Knowledge Pack to QuickFeather Development Kit and reset the board to start running program code. Here is a video of the Water Flow Detection system running on QuickFeather Development Kit.
Comments