Water System
Table of Contents
Week 18









- Completion of soldering (pumps)
- All power supplies plugged in.
- Handling water ripple and splashing. Tested metal mesh which sunk. Tested foam board which still caused splashing. Decided to have tubes push against interior container wall to spill down instead of drip to negate splashing.
- Further tweaking of program speeds and ranges.
Week 17












- Adjusted planter brace from Week 5 to hook onto water container.
- Adjusting pump speeds and sensor ranges.
- Reprinted all pump mount lids with vent holes. Reprinted main lid with white filament to reduce heat retained from sensors/pcb (compared to black filament).
- Splashing from the water surface causes error with water level sensor readings due to rippling. Also poses risk of getting the sensor wet when the water level is high. Considering using mesh to dull ripples or act as a cover directly in front of the sensor.
Week 16









- Recalibrating (new) sensors after resoldering
- Adjusting mounts and covers for pumps (vent holes and lenghtened cover)
- Confirming water level sensor still behaves properly (video)
Week 15
- Altered pump mount from https://www.thingiverse.com/thing:3356513
- Mock set-up of overall project
- Color-coded pump mounts
- Adding ventilation to water container lids to balance humidity
- Damaged sensors due to incorrect voltage provided. Reordered sensors.
Week 14









Extreme Case Main Loop if-else statement snippet. Reordered which extreme cases are checked first as only one can be fulfilled at once (Prioritizing Hydrate/Water Level to avoid overflow). Replaced generalizing function for checking water level condition with direct code due to logic errors in generalization.:
if(hydLowActive){ // case for LOW water level
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = false;
// checkExtremeCaseWaterDist(midWaterDistance);
if(lastWaterDistReading <= midWaterDistance){ // checking for water rising, so it needs to meet at or above it (since water lvl starts already farther dist)
setNormalState(); // reset extreme active cases and sensor timers
bufferedOut.println("Finished extreme case.");
}
}
else if(hydHighActive){ // case for HIGH water level
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = true;
// checkExtremeCaseWaterDist(midWaterDistance);
if(lastWaterDistReading >= midWaterDistance){ // checking for water lowering, so it needs to meet at or below it (since water lvl starts already shorter dist)
setNormalState(); // reset extreme active cases and sensor timers
bufferedOut.println("Finished extreme case.");
}
}
else if(socMaxActive){
// set socialize at max behaviors
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = true;
// checkExtremeCaseWaterDist(waterDistToReach);
if(lastWaterDistReading >= waterDistToReach){ // checking for water to reach down to so at or below it
setNormalState(); // reset extreme active cases and sensor timers
bufferedOut.println("Finished extreme case.");
}
}
else if(socMinActive){
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = true;
// checkExtremeCaseWaterDist(waterDistToReach);
if(lastWaterDistReading >= waterDistToReach){ // checking for water to reach down to so at or below it
setNormalState(); // reset extreme active cases and sensor timers
bufferedOut.println("Finished extreme case.");
}
}
else if(creMaxActive){ // yellow runs alone at max
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 255;
waterSpeed = 0;
removeWater = true;
}
else if(creMinActive){
magentaSpeed = 255;
cyanSpeed = 255;
yellowSpeed = 0;
waterSpeed = 0;
removeWater = true;
}
else{
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 0;
removeWater = true;
}
}
RGB LED indicator is set when extreme case is set. However, if more than one extreme were to be triggered in the same loop iteration, the last to be called would be set (Socialize-->Hydrate-->Create) even if the extreme case that runs does not match the color coding (Hydrate>Socialize>Create):
void setExtremeState(int delayTime){
extremeCaseActive = true;
pirSonarDelay.stop();
// waterSonarDelay.stop(); // dont use, never stop sonar bc itll be used to determine length of extreme state
floatDelay.stop();
printOutTimer.stop(); // stopped in an extreme case to reflect the cut off of communication in an overwhelmed or underwhelmed system
extremeBlockDelay.start(delayTime);
}
if (socialize > SOCIALIZERANGE) {
// upper bound
socialize = (BASESOCIALIZE * 9) / 10; // reduce to slightly below base 90%
socMaxActive = true;
setExtremeState(0);
// water is going to be removed
if(lastWaterDistReading >= (farthestDistanceToWater - 6)){ // 6mm error; bc water is to be removed, have to check if the water is too low or not
setNormalState(); // water is too low to remove any further, skip extreme case (should trigger water case instead)
}
else{
waterDistToReach = (lastWaterDistReading * 3) / 2;
if(waterDistToReach >= farthestDistanceToWater){
waterDistToReach = farthestDistanceToWater;
}
bufferedOut.println("Max Socialize Set");
digitalWrite(REDPIN, HIGH); //red led
digitalWrite(GREENPIN, LOW);
digitalWrite(BLUEPIN, LOW);
}
}
else if (socialize < 0) {
// hit the lower bound
socialize = BASESOCIALIZE / 10; // it learned some self love or smth
socMinActive = true;
setExtremeState(0);
// water to be removed
if(lastWaterDistReading >= (farthestDistanceToWater - 6)){ // 6mm error; bc water is to be removed, have to check if the water is too low or not
setNormalState(); // water is too low to remove any further, skip extreme case (should trigger water case instead)
}
else{
waterDistToReach = (lastWaterDistReading * 5) / 4;
if(waterDistToReach >= farthestDistanceToWater){
waterDistToReach = farthestDistanceToWater;
}
bufferedOut.println("Min Socialize Set");
digitalWrite(REDPIN, HIGH); //magenta led
digitalWrite(GREENPIN, LOW);
digitalWrite(BLUEPIN, HIGH);
}
}
Week 13















Week 12











- Temporary lids printed for testing purposes. Filed-down to fit sensors and pumps due to mis-sizing.
- Makerspace helped resize the original mason jar pump lid by horizontally scaling it, though the holes in the lid have to be sized back to the original lid size.
- Issues with the MB sonar sensor mount due to placement of the sensor and screws. Altered the PIR mount file for the sonar file. Opened back of sensor mount to allow wires to go through.
- Redesigned main tank lid and fixed mason jar lid holes.
Week 11







Adjustments:
- Use a tank larger than the total liquid volume possible for each dye container and main tank as a backup tank holding water that gets added to and removed from the main tank (a 5 gallon water container as opposed to a jar that would have been the same size as the dye containers), in order to avoid an additional sensor for checking for overflow in the backup container.
- Decision to use 64oz mason jars to hold dyes and a tall, narrow vase as the main tank (to allow for the water level to change more given an amount of volume added).
- Alterations to pump mounting lids and sensor mounts for 3D print due to size mismatches and missing features.
Sensor 3D Models:
- PIR Sensor: https://www.thingiverse.com/thing:3251488
- MaxBotix Sonar Sensor: https://www.thingiverse.com/thing:38531
Week 10
Testing MB1644 sensor.Code also corrected for manual button on/off and overflow detection due to misplaced function calls.
Water level measuring code:
int readWaterSonar(){
// hrlv shortrange mb1644
if(waterSonarDelay.justFinished()){ // mb1644
waterSonarDelay.repeat();
int distancemm = (analogRead(WATERSONARPIN) * 6) - 300; // directly from maxbotix doc; mm reading
lastWaterDistReading = distancemm; // always record last reading in global var
return distancemm;
}
else{
return -1;
}
}
Code for extreme cases with escape conditions based on water level or time elapsed (Extreme case main loop if-else statement snippet). Unsuccessful implementation until later testing (See Week 14):
if(socMaxActive){
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = true;
checkExtremeCaseWaterDist();
}
else if(socMinActive){
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = true;
checkExtremeCaseWaterDist();
}
else if(hydLowActive){ // case for LOW water level
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = false;
checkExtremeCaseWaterDist();
}
else if(hydHighActive){ // case for HIGH water level
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 255;
removeWater = true;
checkExtremeCaseWaterDist();
}
else if(creMaxActive){
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 255;
waterSpeed = 90;
removeWater = true;
}
else if(creMinActive){
magentaSpeed = 255;
cyanSpeed = 255;
yellowSpeed = 0;
waterSpeed = 90;
removeWater = true;
}
else{
magentaSpeed = 0;
cyanSpeed = 0;
yellowSpeed = 0;
waterSpeed = 0;
removeWater = true;
}
Week 9
Ultrasonic Sensor Incorporation into PIR sensor reading function for sensing proximity of visitors (snippet):
void readPIRSonar(){
// read PIR and sonar at the same time
if(pirSonarDelay.justFinished()){
pirSonarDelay.repeat();
int pirState = digitalRead(PIRPIN);
// distance accord to https://maxbotix.com/blogs/blog/arduino-guide
int distance = analogRead(PPLSONARPIN) / 2; // inches, distance
pirSonarInfo[0] = pirState; // 0/1
pirSonarInfo[1] = distance; // inches
}
else{
pirSonarInfo[0] = -1;
pirSonarInfo[1] = -1;
}
}
3D Print Mason Jar Pump Mount: https://www.thingiverse.com/thing:4823002
Week 8











Week 7










Major changes:
- Planning to use short-range ultrasonic sensor for measuring water level instead of calculating in program due to challenging variables in calculating water volume vs. water level mathematically (different shapes of tanks, unideal variations in pumps running).
- Planning to use long-range ultrasonic sensor for detecting proximity of people in the gallery space (for affecting socialization factor/variable) instead of capacitive sensor because it would be more straightforward and precise.
Week 6
Major Change: Shifting code from custom libraries to all written in Arduino IDE with non-blocking delays and continuously running pumps.