背景说明:办公室的饮水机坏了,刚好最近在玩Arduino,就想用Arduino来改造一下,废物利用,于是就有了这个项目。直接上图看成果:
实现功能
1.在按键1为on的状态下,杯子放在压力传感器上即可出水;
2.按下按键2即可出水,再按一下便关闭;
3.侧面的lcd显示屏可以记录喝水次数,按下按键3可将次数清零。
物料清单
- 饮水机 *1(坏的。。没坏你想改造我也没话说)
- Arduino Uno *1
- 按钮 *3
- LED灯 *3
-
FSR402力敏电阻器(压力传感器) *1
-
LCD 1602显示屏(带转接板) *1
- 小型水泵 *1
-
继电器 *1
- 导线、跳线若干
- 热缩管若干
- 电烙铁、热风枪、十字螺丝刀、钻孔器等
附上部分元件图:
元件接线
FSR402 |
|
Arduino |
+ |
-> |
5v |
- |
10kOhm |
GND |
同上 |
-> |
A0 |
继电器 |
|
Arduino |
IN |
-> |
8 |
VCC |
-> |
5V |
GND |
-> |
GND |
按钮1 |
|
Arduino |
一端 |
-> |
5v |
另一端 |
10kOhm电阻 |
GND |
同上 |
-> |
2 |
按钮2 |
|
Arduino |
一端 |
-> |
5v |
另一端 |
10kOhm电阻 |
GND |
同上 |
-> |
3 |
按钮3 |
|
Arduino |
一端 |
-> |
5v |
另一端 |
10kOhm电阻 |
GND |
同上 |
-> |
4 |
LED1 |
|
Arduino |
正极 |
-> |
5 |
负极 |
-> |
GND |
LED2 |
|
Arduino |
正极 |
-> |
6 |
负极 |
-> |
GND |
LED3 |
|
Arduino |
正极 |
-> |
7 |
负极 |
-> |
GND |
LCD |
|
Arduino |
GND |
-> |
GND |
VCC |
-> |
5V |
SDA |
-> |
A4 |
SCL |
-> |
A5 |
源程序
#include <SCoop.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,2,1,0,4,5,6,7);
int Button1 = 2;
int Button2 = 3;
int Button3 = 4;
int Led1 = 5;
int Led2 = 6;
int Led3 = 7;
int sensorPin = A0;
int value;
void button1Function();
void button2Function();
void button3Function();
boolean switchFlag = LOW;
boolean waterFlag = LOW;
int times = 0;
defineTask(Task1)
void Task1::setup() {
}
void Task1::loop() {
button1Function();
}
defineTask(Task2)
void Task2::setup() {
}
void Task2::loop() {
button2Function();
}
defineTaskLoop(Task3) {
button3Function();
}
void setup() {
mySCoop.start();
lcd.begin (16,2); // for 16 x 2 LCD module
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
pinMode(Button1,INPUT);
pinMode(Button2,INPUT);
pinMode(Button3,INPUT);
pinMode(Led1,OUTPUT);
pinMode(Led2,OUTPUT);
pinMode(Led3,OUTPUT);
pinMode(sensorPin,INPUT);
pinMode(8,OUTPUT);
Serial.begin(9600);
}
void loop() {
int a1,a2,a3;
yield(); //本函数必须放在主线的loop循环体中
a1 = analogRead(sensorPin);
a2 = analogRead(sensorPin);
a3 = analogRead(sensorPin);
value = (a1+a2+a3)/3;
Serial.println(value);
if(value > 15 && switchFlag == HIGH){
digitalWrite(8,LOW);
times++;
delay(2000);
digitalWrite(8,HIGH);
}else
digitalWrite(8,HIGH);
if(waterFlag == HIGH){
digitalWrite(8,LOW);
}else
digitalWrite(8,HIGH);
lcd.home (); // set cursor to 0,0
lcd.print("Drink Water Times");
lcd.setCursor (6,1); // go to start of 2nd line
lcd.print(times);
lcd.setCursor (12,1); // go to start of 2nd line
lcd.print("CUPS");
}
void button1Function(){
if(digitalRead(Button1)==LOW) //由于本例检测上升沿触发,所以先检测输入是否低电平,
{
delay(10); //然后延时一段时间,
if(digitalRead(Button1)==HIGH) //然后检测是不是电平变为高了。是的话,就是刚好按钮按下了。
{
switchFlag = !switchFlag;
Serial.println(switchFlag);
digitalWrite(Led1,switchFlag);
delay(10); //延时一段时间,防止按钮突然断开再按下。
while(digitalRead(Button1)==HIGH) //判断按钮状态,如果仍然按下的话,等待松开。防止一直按住导致LED输出端连续反转
{
delay(1);
}
}
}
}
void button2Function(){
if(digitalRead(Button2)==LOW) //由于本例检测上升沿触发,所以先检测输入是否低电平,
{
delay(10); //然后延时一段时间,
if(digitalRead(Button2)==HIGH) //然后检测是不是电平变为高了。是的话,就是刚好按钮按下了。
{
waterFlag = !waterFlag;
Serial.println(waterFlag);
digitalWrite(Led2,waterFlag);
if(waterFlag == HIGH)
times++;
delay(10); //延时一段时间,防止按钮突然断开再按下。
while(digitalRead(Button2)==HIGH) //判断按钮状态,如果仍然按下的话,等待松开。防止一直按住导致LED输出端连续反转
{
delay(1);
}
}
}
}
void button3Function(){
if(digitalRead(Button3)==LOW) //由于本例检测上升沿触发,所以先检测输入是否低电平,
{
delay(10); //然后延时一段时间,
if(digitalRead(Button3)==HIGH) //然后检测是不是电平变为高了。是的话,就是刚好按钮按下了。
{
times = 0;
delay(10); //延时一段时间,防止按钮突然断开再按下。
while(digitalRead(Button3)==HIGH) //判断按钮状态,如果仍然按下的话,等待松开。防止一直按住导致LED输出端连续反转
{
delay(1);
}
}
}
}
写在最后
1.压力感应模块在加入小型水泵后,读出的值就会不稳定,建议采取各种滤波。
2.项目完整实现下来,存在一个问题,就是会漏水,就是水泵停止泵水后水龙头还会滴水,目前还在想解决方案。
3.过程写得有点粗略,如果你在实现的过程遇到任何问题,或者有更好的建议,随时欢迎沟通交流,共同进步哈~