ECE 4180 Final Project
Field Programmable Water Array (FPWA)
Introduction
This notebook details the design and implementation of a programmable water curtain. The idea was inspired by a Cirque du Soleil show that implemented a waterfall onstage as shown in the video below. Our design uses an mbed microcontroller and an array of solenoids to create artistic effects in water flow. The user is able to choose the pattern of water flow.
Components
Our design uses the following parts:
- mbed Microcontroller (LPC1768)
- Uxcell a14092600ux0438 Open Frame Actuator Linear Mini Push Pull Solenoid
- I2C Capacitive Touchpad
- 3-D printed water reservoir and plugs
3-D printed water reservoir.
Design
Water flow out of the water reservoir is controlled by plugs that allow water to flow in desired patterns. The plugs are attached to solenoids that pull the plugs away from their resting position to allow the release of water. The mbed sends control signals to the MOSFETS that drive the solenoids.
The capacitive touchpad allows users to determine the desired patter of water flow. Touchpad keys 9-12 select pre-dfined bit patterns while keys 1-8 correspond to individual solenoids that can be used to implement any desired pattern.
Flow diagram of design with all components.
3-D printed reservoir with openings sealed by 3-D printed plugs and fitted solenoids.
Wiring
mbed | Component | Pin |
---|---|---|
p9 | Touch Keypad | SDA |
p10 | Touch Keypad | SCL |
p26 | Touch Keypad | IRQ |
Vout | Touch Keypad | Vcc |
p13 - p20 | MOSFET | JP2-Control |
Power | MOSFET | Solenoid |
---|---|---|
gnd | JP2-gnd | |
5V | JP2-RAW | |
JP1-1 | Solenoid | |
JP1-2 | Solenoid |
Entire circuit setup.
Code
main.cpp
#include <vector> #include "mbed.h" #include "mpr121.h" // Create the interrupt receiver object on pin 26 InterruptIn interrupt(p26); I2C i2c(p9, p10); BusOut solenoids(p13,p14,p15,p16,p17,p18,p19,p20); Mpr121 mpr121(&i2c, Mpr121::ADD_VSS); volatile int value = 0; float waittime = 1.0; // Key hit/release interrupt routine void fallInterrupt() { value = mpr121.read(0x00); value += mpr121.read(0x01)<<8; } // Function for Bernoulli distribution to control water flow pattern vector<bool> f(double p, int n){ vector<bool> my_vector; for(int i = 0; i<n; ++i){ my_vector.push_back((rand() %100 < 100*p)); } return my_vector; } int main() { // setting up the interrupt interrupt.mode(PullUp); wait(.01); interrupt.fall(&fallInterrupt); while (1) { // individual solenoid control solenoids[7]= value & 0x01; solenoids[6]=(value>>1) & 0x01; solenoids[5]=(value>>2) & 0x01; solenoids[4]=(value>>3) & 0x01; solenoids[3]=(value>>4) & 0x01; solenoids[2]=(value>>5) & 0x01; solenoids[1]=(value>>6) & 0x01; solenoids[0]=(value>>7) & 0x01; if ((value>>8) & 0x01) { // pattern 1 solenoids[0] = 1; wait(waittime); solenoids[1] = 1; wait(waittime); solenoids[2] = 1; wait(waittime); solenoids[3] = 1; wait(waittime); solenoids[4] = 1; wait(waittime); solenoids[5] = 1; wait(waittime); solenoids[6] = 1; wait(waittime); solenoids[7] = 1; wait(waittime); solenoids[7] = 0; wait(waittime); solenoids[6] = 0; wait(waittime); solenoids[5] = 0; wait(waittime); solenoids[4] = 0; wait(waittime); solenoids[3] = 0; wait(waittime); solenoids[2] = 0; wait(waittime); solenoids[1] = 0; wait(waittime); solenoids[0] = 0; wait(waittime); // end of pattern 1 } if ((value>>9) & 0x01) { // pattern 2 solenoids[0] = 1; solenoids[7] = 1; wait(waittime); solenoids[1] = 1; solenoids[6] = 1; wait(waittime); solenoids[2] = 1; solenoids[5] = 1; wait(waittime); solenoids[3] = 1; solenoids[4] = 1; wait(waittime); solenoids[0] = 0; solenoids[7] = 0; wait(waittime); solenoids[1] = 0; solenoids[6] = 0; wait(waittime); solenoids[2] = 0; solenoids[5] = 0; wait(waittime); solenoids[3] = 0; solenoids[4] = 0; wait(waittime); // end of pattern 2 } if ((value>>10) & 0x01) { // pattern 3 solenoids[0] = 1; solenoids[1] = 1; solenoids[2] = 1; solenoids[3] = 1; solenoids[4] = 1; solenoids[5] = 1; solenoids[6] = 1; solenoids[7] = 1; wait(waittime); solenoids[0] = 0; wait(waittime); solenoids[7] = 0; wait(waittime); solenoids[1] = 0; wait(waittime); solenoids[6] = 0; wait(waittime); solenoids[2] = 0; wait(waittime); solenoids[5] = 0; wait(waittime); solenoids[3] = 0; wait(waittime); solenoids[4] = 0; wait(waittime); // end of pattern 3 } if ((value>>11) & 0x01) { // pattern 4 solenoids[0] = 1; wait(waittime); solenoids[0] = 0; solenoids[1] = 1; wait(waittime); solenoids[1] = 0; solenoids[2] = 1; wait(waittime); solenoids[2] = 0; solenoids[3] = 1; wait(waittime); solenoids[3] = 0; solenoids[4] = 1; wait(waittime); solenoids[4] = 0; solenoids[5] = 1; wait(waittime); solenoids[5] = 0; solenoids[6] = 1; wait(waittime); solenoids[6] = 0; solenoids[7] = 1; wait(waittime); solenoids[7] = 0; // end of pattern 4 } } }
Video
Demonstration of water curtain working with capacitive touch-pad inputs and pre-programmed pattern.
Results
In this project, we demonstrated mbed's capability to interface between hardware inputs and outputs. The inputs to the program are used to control the output water pattern.
We encountered challenges in managing water flow out of the reservoir without leaking. We tried several designs in configuring the solenoid with the plug to stop water flow as seen below. The final design uses rubber-tipped plugs held in place by rubber bands to minimize the leaking. Additionally, it was challenging to ensure that the water flowing out did not interact with any of the electronic components. We took extra caution to ensure that water did not harm any of the electronic devices.
Future work to build on this current design includes stopping all water leakage and adding additional user features. For example, playing music in-sync to the water pattern and implementing water patterns by parsing text files with ASCII characters representing the desired pattern are the next features we would like to implement.
Please log in to post comments.