Skip to content

Instantly share code, notes, and snippets.

@PsyChip
Last active October 9, 2022 12:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PsyChip/6e8b745c865c6dbf658b9e6632655053 to your computer and use it in GitHub Desktop.
Save PsyChip/6e8b745c865c6dbf658b9e6632655053 to your computer and use it in GitHub Desktop.
Smart soap dispenser
/* Smart soap dispenser
Uses
+ digispark pro (https://digistump.com)
+ Sharp 0a41skf85 distance sensor
+ IRF540 mosfet module
+ dual water pump
Coded by PsyChip
root@psychip.net
Sep 2022
More Details available at: https://psychip.net/video/home-improvement--attiny85-powered-soap-dispenser
*/
const unsigned int dispenseTime = 250; // stop after x ms
const unsigned int dispenseInterval = 1500; // wait x ms after dispense
const unsigned int distanceTreshold = 8; // pump if its closer than x cm
const unsigned int treshold_time = 250; // pump if hand is waiting since x ms
const unsigned long idle_delay = 21600000L; // pump extra x ms if idle since 6 hours
const unsigned int idle_extra = 100; // extra pump time
unsigned long dispense_start = 0;
unsigned long dispense_finish = 0;
unsigned int extra = 0;
boolean treshold = false;
boolean treshold_buf = false;
unsigned long tresholdStart = 0;
boolean dispensing = false;
void setup() {
delay(500);
pinMode(1, OUTPUT);
pinMode(3, OUTPUT);
dispenseStop();
}
void dispenseStart() {
if (dispensing == true) {
return;
}
dispense_start = millis();
dispensing = true;
digitalWrite(1, HIGH);
digitalWrite(3, HIGH);
}
void dispenseStop() {
if (dispensing == false) {
return;
}
extra = 0;
dispense_finish = millis();
dispensing = false;
digitalWrite(1, LOW);
digitalWrite(3, LOW);
}
void loop() {
if (dispensing == true && ((millis() - dispense_start) >= (dispenseTime + extra))) {
dispenseStop();
return;
}
if (dispense_finish > 0 && ((millis() - dispense_finish) <= dispenseInterval)) {
return;
}
float volts = analogRead(1) * 0.0048828125;
int distance = 13 * pow(volts, -1);
if (distance < distanceTreshold) {
treshold = true;
} else {
treshold = false;
}
if (treshold != treshold_buf) {
treshold_buf = treshold;
tresholdStart = millis();
}
if (dispense_finish > 0 && ((millis() - dispense_finish) >= idle_delay)) {
extra = idle_extra;
}
if (dispense_finish == 0) {
extra = idle_extra;
}
if (treshold == true && ((millis() - tresholdStart) >= treshold_time)) {
dispenseStart();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment