Hi everyone, so I'm trying to build an automatic toilet flusher and I need a little help on the coding.
I got my code to flush every time it comes in contact with your hand (which is a good start),
but it's not so functional when you sit down and use the toilet and it flushes every time it comes into
contact. I'm looking to try to have the sensor trigger when it gets to a certain distance(which I have already)
then wait until the sensor is not (i.e the person leaves the toilet) triggered anymore and then flush.
So my question is how do I get it to store the reading and wait until the reading is gone then flush
and not have it flush when no one is around?
Any help will be greatly appreciated
here's my code so far
#include <Servo.h>
Servo myservo1; //first servo
int SHARP_IR_PIN = 1; //analog pin used to connect the sensor
int ledPin = 9; //select pin for the servo
int val = 0; //variable to read the value from the analog pin
int adc_to_cm(int adc) {
return 14251 * pow(adc,-1.17);
}
void setup()
{
myservo1.attach(9); //set up the servo as usual first servo
pinMode(ledPin, OUTPUT); //variable to store the value coming from the sensor
Serial.begin(9600);
}
void loop() {
int reading = analogRead(SHARP_IR_PIN); // replace this pin with the analog pin your sensor is connected to
int distance = adc_to_cm(reading);
char buf[50];
sprintf(buf, "Distance: %d, voltage: %.02f, adc: %d\r\n", distance, reading * 5.00 / 1024 , reading);
Serial.print(buf);
if (distance < 40) {
myservo1.write(0);
delay(2000);
}
else {
myservo1.write(180);
}
}
I remember written on the wall in a public loo "If you want a cold surprise, pull the trigger before you rise" and you want to automate that
So my question is how do I get it to store the reading and wait until the reading is gone then flush
and not have it flush when no one is around?
You must define a state machine : take paper and pencil
draw two circles
write in one - nearby - and in the other faraway.
There are two events possible,
no person detected
person detected.
a. Draw an arrow from faraway to nearby and write (2) along the arrow
b. Draw a second arrow from faraway to faraway and write (1) along the arrow
c. Draw a 3rd arrow from nearby to faraway and write (1) along it
d. Draw a 4th arrow from nearby to nearby and write (2) along it.
You should have one variable in your code representing the state and you change the state according to the events.
Now the flush should only occur in case (c) if the state is "nearby" and you get a reading "no person detected"
(maybe add a small delay...)
give it a try.
You can extend this state machine by keeping tim how long a person is detected, might be an indication how much to flush
Very short person detections are possible failures (or a fly in front of the detector) so they dont need a flush.
I found some code that someone used for thee exact project I want to do and updated it a little
#include <Servo.h>
Servo servo1;
int sensor=0;
int sensorPin=5; //distance sensor on analog pin 5
int PreparingToFlush=0;
void setup() {
Serial.begin(9600);
servo1.attach(10); //servo data line on pin 10
servo1.write(3);
}
void loop() {
sensor=analogRead(sensorPin);
if (sensor > 100){ //if distance sensor detects someone
delay(2000); // wait
sensor=analogRead(sensorPin);
if (sensor > 100){ // check again to make sure someone is actually there
PreparingToFlush=1;
}
}
if (PreparingToFlush==1){ //if a person has been detected
if (sensor < 100){ // if the person has now left
servo1.write(175); //FLUSH
delay(5000);
servo1.write(3);
delay(1000);
PreparingToFlush=0; //reset the trigger
}
}
delay(10);
}
This does exactly what I want but is this the right way to do it?
I actually updated that code on the second page of the tutorial. I had a problem with random flushes because of noise in the data (I wasn't using a capacitor to smooth the signal) so I added a part where it takes 4 values then averages them. I also came up with a good flushing mechanism that's just a servo in the tank.
Other options: You could point the ir sensor off to the side so that you can just set it off with your hand when you want.
Here's the new code :
#include <ServoTimer1.h>
ServoTimer1 servo1;
int sensor=0;
int sensorPin=5; //distance sensor on analog pin 5
int PreparingToFlush=0;
int sample1;
int sample2;
int sample3;
int sample4;
void setup() {
Serial.begin(9600);
servo1.attach(10); //servo data line on pin 10
servo1.write(3);
// digitalWrite(3,HIGH); //(an LED)
}
void loop() {
sensor=analogRead(sensorPin);
Serial.println(sensor);
if (PreparingToFlush==0){
if (sensor > 90){ //if distance sensor detects someone
delay(1000); // wait
sample1=analogRead(sensorPin); //take a sample of the data
Serial.println("Sensing");
delay(300);
sample2=analogRead(sensorPin);
delay(300);
sample3=analogRead(sensorPin);
delay(400);
sample4=analogRead(sensorPin);
sensor= (sample1 + sample2 + sample3 + sample4)/4;
if (sensor > 90){ // check again to make sure someone is actually there
PreparingToFlush=1;
digitalWrite(13, HIGH);
Serial.println(sensor);
}
}
}
if (PreparingToFlush==1){ //if a person has been detected
if (sensor < 60){ // if the person has now left
delay(1000);
sensor=analogRead(sensorPin);
if (sensor < 60){
Serial.println("Flushing");
servo1.write(175); //FLUSH
digitalWrite(13, LOW);
delay(9000);
servo1.write(3);
delay(1000);
PreparingToFlush=0; //reset the trigger
}
}
}
delay(10);
}