Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Hackster is hosting Impact Spotlights: Industrial Automation. Watch the stream live on Thursday!Hackster is hosting Impact Spotlights: Industrial Automation. Stream on Thursday!
arvindrk
Published © GPL3+

Smart Faucet #CloudGames2022

Motion-sensing faucets:- Pro: Saves Water. Yay! Con: No Taps means No Temp Control. Boo! Introducing, "Smart Faucet"

AdvancedShowcase (no instructions)583
Smart Faucet #CloudGames2022

Things used in this project

Story

Read more

Schematics

Temp sensor DS18B20

Stepper A4988

Code

Smart Faucet

Arduino
#include "thingProperties.h"
#include<AccelStepper.h>
#include <DS18B20.h>
#include <Arduino_MKRIoTCarrier.h>
#include <ezButton.h>

float tempCold = 25;
float prevTempDesired;
float tempHot = 48;

//~~~~~~~~~~Status Messages~~~~~~~~~~//
String stringOne = "Desired: ";
String stringTwo = " Curr: ";
String stringThree = "Desired Temperaure is out of Scope.";
String stringFour = "Desired Temp Reached.";
String stringFive = "No Motion Detected.";
String stringSix = "°";
String stringSeven = " Sensor(s) Missing";
String stringEight = " Current Temp: ";
//~~~~~~<END>Status Messages~~~~~~//

//~~~~Define MKR Carrier Sensors and Hardware~~~~//
#define PIR A5
MKRIoTCarrier carrier;
extern bool CARRIER_CASE;
int Val = 0;
//~~<END>Setup MKR Carrier Sensors and Hardware~~//

//~~~~~~~~Create the Motor Instances~~~~~~~~//
long positions[2];
long zeroPos[2]; 
long mid[2] = {0,80};
AccelStepper stepperCold(1,1,0);
AccelStepper stepperHot(1,4,3);
float Vd;
bool dirCold = 0;
bool dirHot = 0;
float positionCold, positionHot;
//~~~~~<END>Create the Motor Instances~~~~~//

//~~Create Instances for Temperature Sensors~~//
DS18B20 Temps(21);
uint8_t Sensor2Add[8] = {40, 59, 22, 70, 146, 9, 2, 107};
uint8_t Sensor3Add[8] = {40, 47, 17, 210, 11, 0, 0, 250};
float Uqr = 0;
float pqr = 0;
//~~<END>create instances for temperature sensors~~//

//~~~~~~~~~~Define Limit Switches~~~~~~~~~~//
ezButton ls_hot(7);
ezButton ls_cold(8);
int stateHot, stateCold;
bool fin = false;
float Th_1 = 0;
//~~~~~~~<END>Define Limit Switches~~~~~~~~//

//~~~~~~~~~~~~~~~~Display features~~~~~~~~~~~~~~~//
int ht = 0;
//~~~~~~~~~~~~~<END> Display Features~~~~~~~~~~~~//

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~SETUP~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void setup() {
//~~~~~~~Initialize serial~~~~~~//
  Serial.begin(9600); 
  delay(6000);
//~~~~<END>Initialize serial~~~~//

// Setup and Initialize Arduino Cloud  
// Defined in thingProperties.h
  initProperties();

// Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  ArduinoCloud.addCallback(ArduinoIoTCloudEvent::CONNECT, doThisOnConnect);
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
  tempDesired = 36;
// <END>Setup and Initialize Arduino Cloud
  
//~~~~~Setup MKR Carrier and Sensors~~~~//
  CARRIER_CASE = true;
  carrier.begin();
  pinMode (PIR, INPUT);
//~~<END>Setup MKR Carrier and Sensors~~//
  
//~~~~~~~~Initialize Motor Settings~~~~~~~~//
  stepperCold.setAcceleration(80);
  stepperCold.setMaxSpeed(1000);
  stepperHot.setAcceleration(80);  
  stepperHot.setMaxSpeed(1000);
//~~~~~<END>Initialize Motor Settings~~~~~~//

//~~~~~~~~~~Limit Switch Settings~~~~~~~~~~//
  ls_hot.setDebounceTime(50);
  ls_cold.setDebounceTime(50);
//~~~~~~~<END>Limit Switch Settings~~~~~~~~//
  
//~~~~~~~~Setup Temperature Sensors~~~~~~~~//
  float Th_1 = 0;
  int p = 1;
  int n = Temps.getNumberOfDevices();
  Serial.println(n);
  if(n < 2){//Verify if all snesors are pressent
    int see = 2 - n;
    String errr = see+stringSeven;
    Serial.println(errr);
  }
//~~~~~~~<END>Setup Temperature Sensors~~~~~~~//
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~LOOP~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int check = 1;
int imp = 0;
int prevTemp = 0;
void loop() {
  ArduinoCloud.update();
// carrier.display.setRotation(0);  
//~~~~~~~~~Check Touch Buttons~~~~~~~~~~//
  TouchButtonsCheck();
//~~~~~~~~~<END>Check Touch Buttons~~~~~//

//~~~~~~~~~~~~~~Run Flow Checks~~~~~~~~~~~~~//
  Val = digitalRead(PIR);
//~~~~~~~~~~~~No Motion Detected?~~~~~~~~~~~//
  while(Val == LOW){
    ArduinoCloud.update();
    for(int r = 0; r < 5; r++){
      carrier.leds.setPixelColor(r, 0, 0, 0);
      carrier.leds.show();
    }
    Status = stringFive;
    
//~~~~~~~~~~~Check Touch Buttons~~~~~~~~~~~~~//
    TouchButtonsCheck();
//~~~~~~~~~<END>Check Touch Buttons~~~~~~~~~~//
  motorHot = stepperHot.currentPosition();
  motorCold = stepperCold.currentPosition();
    Val = digitalRead(PIR);
  }
  
//~~~~~~~~~~~~~~~Motion Detected~~~~~~~~~~~~~//
  
//~~~~~~~~~~~~Check Touch Buttons~~~~~~~~~~~//
  TouchButtonsCheck();
//~~~~~~~~~<END>Check Touch Buttons~~~~~~~~~//
   
//~~~~~~~~~~<END>Run Flow Checks~~~~~~~~~~~~//

//~~~~~~~~~~Wash Em' Hands Folks~~~~~~~~~~~~// 
  float flT = millis();
  while((millis() - flT) <= 10000){ 
    tempOut = getT(2); 
    Status = stringEight + tempOut+stringSix;
    ArduinoCloud.update();
    for(int r = 0; r < 5; r++){
      if (r % 2 == 0){carrier.leds.setPixelColor(r, 50, 0, 0);}
      else{carrier.leds.setPixelColor(r, 0, 50, 0);}
      carrier.leds.show();
    }
//~~~~~~~~~~~Check Touch Buttons~~~~~~~~~~~~//
    TouchButtonsCheck();
//~~~~~~~~<END>Check Touch Buttons~~~~~~~~~~//

//~~~~~~~~~~~~Run Motor Control~~~~~~~~~~~~~//
    if(tempDesired != prevTempDesired){
      TempDesiredChange();
      motors(positions);
      prevTempDesired = tempDesired;
    }
    else{
      motors(positions);
    }
    motorHot = stepperHot.currentPosition();
    motorCold = stepperCold.currentPosition();
  }
//~~~~~~~~<END> Run Motor Control~~~~~~~~~~~// 
  motorsZero();
}

float Kalman(float x){    
  float rq = 0.00001; float qq = 0.000005; float hq = 1;
  float kq = pqr*hq/(hq*pqr*hq+rq);
  Uqr = Uqr+kq*(x-hq*Uqr);
  pqr = (hq-kq*hq)*pqr+qq;
  return Uqr;
}

float getT(int num){
  float tTheo;
  switch(num){
    case 1:
//      Temps.select(Sensor1Add);
//      return Temps.getTempC();
      break;
    case 2:
      Temps.select(Sensor2Add);
      if(stepperCold.currentPosition() != 0 || stepperHot.currentPosition() != 0){
        if(stepperCold.currentPosition() != 0 && stepperHot.currentPosition() == 0){
          tTheo = tempCold;
        }
        if(stepperCold.currentPosition() == 0 && stepperCold.currentPosition() != 0){
          tTheo = tempHot;
        }
        if(stepperCold.currentPosition() != 0 && stepperHot.currentPosition() != 0){
          tTheo = tempCold + (tempHot-tempCold)*(stepperHot.currentPosition()/198)/(stepperCold.currentPosition()/204+positions[1]/198);
        }
        return 0.7 * tTheo + 0.3 * Kalman(Temps.getTempC());
        break;
      }
    case 3:
      Temps.select(Sensor3Add);
      return Temps.getTempC();
      break;
  }
}
void TempDesiredChange(){
  Vd = tempDesired / 100;
  positions[1] = (long)(Vd * 198); 
  if (Vd <= 0.25){
    positions[0] = 200;
  }
  if (Vd <= 0.5 && Vd > 0.25){
    positions[0] = 140;
  }
  if (Vd <= 0.75 && Vd > 0.5){
    positions[0] = 90;
  }
  if (Vd <= 1 && Vd > 0.75){
    positions[0] = 30;
  }
  
}
void TouchButtonsCheck(){
  carrier.Buttons.update();
  if (carrier.Buttons.onTouchDown(TOUCH0)) {
    tempDesired = 0;
    carrier.leds.setPixelColor(0, 0, 50, 0);
    carrier.leds.show();
  } 
  if(carrier.Buttons.onTouchUp(TOUCH0)){
    carrier.leds.setPixelColor(0, 0);
    carrier.leds.show();
  }
  if (carrier.Buttons.onTouchDown(TOUCH1)) {
    tempDesired = 50; 
    carrier.leds.setPixelColor(1, 0, 50, 0);
    carrier.leds.show();    
  } 
  if(carrier.Buttons.onTouchUp(TOUCH1)){
    carrier.leds.setPixelColor(1, 0);
    carrier.leds.show();
  }
  if (carrier.Buttons.onTouchDown(TOUCH2)) {
    tempDesired = 76;
    carrier.leds.setPixelColor(2, 0, 50, 0); 
    carrier.leds.show();
  } 
  if(carrier.Buttons.onTouchUp(TOUCH2)){
    carrier.leds.setPixelColor(2, 0);
    carrier.leds.show();
  }
  if (carrier.Buttons.onTouchDown(TOUCH3)) {
    if(tempDesired < 102){
      tempDesired += 2;
    }
    carrier.leds.setPixelColor(3, 50, 0, 0);   
    carrier.leds.show();
  }
  if (carrier.Buttons.onTouchUp(TOUCH3)) {
    carrier.leds.setPixelColor(3, 0);
    carrier.leds.show();
  }
  if (carrier.Buttons.onTouchDown(TOUCH4)) {
    if(tempDesired > -2){
      tempDesired -= 2;
    }
    carrier.leds.setPixelColor(4, 0, 0, 50);   
    carrier.leds.show();
  }
  if (carrier.Buttons.onTouchUp(TOUCH4)) {
    carrier.leds.setPixelColor(4, 0);
    carrier.leds.show();
  }
}
void motors(long psn[2]){
  int j = 1; int k = 1; 
  stepperCold.moveTo(psn[0]);
  stepperHot.moveTo(psn[1]);
  while(j == 1 || k == 1){
    ls_cold.loop();
    ls_hot.loop();
    stateCold = ls_cold.getState();
    stateHot = ls_hot.getState();
    if(j == 1){
      stepperCold.run();
    }
    if(k == 1){
      stepperHot.run();
    }      
    if(ls_cold.isPressed() || stepperCold.distanceToGo() == 0){
      if(j == 1){
        stepperCold.stop();
        j++;
      }
    }
    if(ls_hot.isPressed() || stepperHot.distanceToGo() == 0){
      if(k == 1){
        stepperHot.stop();
        k++;
      }
    }
  }
  positionHot = stepperHot.currentPosition();
  positionCold = stepperCold.currentPosition();
}
void motorsZero(){
  int j = 1; int k = 1;
  while(j == 1 || k == 1){
    ls_cold.loop();
    ls_hot.loop();
    stateCold = ls_cold.getState();
    stateHot = ls_hot.getState();
    if(j == 1){
      stepperCold.moveTo(stepperCold.currentPosition() - 20);
      stepperCold.run();
    }
    if(k == 1){
      stepperHot.moveTo(stepperHot.currentPosition() - 20);
      stepperHot.run();
    }
    if(ls_cold.isPressed()){
      if(j == 1){
        stepperCold.stop();
        Serial.println("1 pressed");
        stepperCold.setCurrentPosition(0);
        j++;
      }
    }
    if(ls_hot.isPressed()){
      if(k == 1){
        stepperHot.stop();
        Serial.println("2 pressed");
        stepperHot.setCurrentPosition(0);
        k++;
      }
    }
  }
  positionHot = stepperHot.currentPosition();
  positionCold = stepperCold.currentPosition();
}

Credits

arvindrk
0 projects • 1 follower
Contact

Comments

Please log in or sign up to comment.