基于Arduino的水位检测系统


前言

本系统是基于Arduino开发板的水位监测系统,通过DS18b20模块检测水温,通过水位监测模块监测水位的变化。当水温超过了某一阈值或水位超过了某一阈值时,蜂鸣器报警。同时,蓝牙能将数据传输至手机上同步进行显示。


一、用到的模块

1、DS18B20温度传感器(1m长的探头型,防水措施)

2、水位检测模块(市面上普通的几块钱一个的,通过电阻变化而影响电压)

3、0.96寸OLED显示屏(4PIN引脚,IIC接口)

4、5V蜂鸣器(低电平蜂鸣器响)

5、蓝牙3.0模块(市面常用,优信电子选购)

6、乐鑫ESP32开发板,搭载WROOM-32E模块

二、软硬件电路

1.硬件电路图

在这里插入图片描述
在这里插入图片描述

2.软件代码

#include <Wire.h>  
#include <Adafruit_SSD1306.h> 
#include <Adafruit_GFX.h>
#include <OneWire.h>
#include <DallasTemperature.h>

//定义引脚
#define ONE_WIRE_BUS 15       //定义DS18B20的data引脚
#define scl 22               //定义OLED的SCL引脚
#define sda 21               //定义OLED的SDA引脚
#define beep 4               //定义BEEP的驱动引脚
#define choice    27         //定义切换模式引脚
#define jia       32         //定义加信号引脚
#define jian      33         //定义减信号引脚

//新建DS18B20对象以及显示数据
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
 
//新建iic对象以及显示屏对象
TwoWire I2Cone = TwoWire(0);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &I2Cone); 

//定义中间变量
int choiceState = 0;         //定义选择信号状态
int jia_State    = 0;         //定义加信号状态
int jian_State   = 0;         //定义减信号状态
int work_mode   = 0;         //定义工作模式状态
float wendu_shangxian =31.00f;//定义水温报警上限
float wendu_xiaxian   =16.00f;//定义水温报警下限
double number,data2;
int data1=0;
//初始化主函数
void setup() {
    Serial.begin(9600);
    Serial.println("Hello Goouuu");
    sensors.begin();
    pinMode(beep  , OUTPUT);
    pinMode(choice, INPUT_PULLUP);
    pinMode(jia   , INPUT_PULLUP);
    pinMode(jian  , INPUT_PULLUP); 

      /*初始化显示屏参数*/
    I2Cone.begin(sda, scl, 400000);             //初始化显示屏的IIC接口
    display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //初始化显示屏参数 
    display.clearDisplay();                     //屏幕清屏
    display.setTextSize(2);                     //设置字体大小为2
    display.setTextColor(INVERSE);              //设定字体的颜色
}

void loop() {
    //数据获取
    number=(long)analogRead(34);
    sensors.requestTemperatures();     // 发送命令获取温度
    choiceState = digitalRead(choice);
    jia_State    = digitalRead(jia);
    jian_State   = digitalRead(jian);
    //数据处理
    data1 = (int)((float)number/2048*100);
    data2 = sensors.getTempCByIndex(0); //获取索引号0的传感器摄氏温度数据
    //工作模式切换
    if (choiceState == LOW){
      work_mode+=1;
      if(work_mode == 3){
        work_mode = 0;
      }
      delay(100);
    }
    else if (jia_State == LOW){
      if(work_mode == 1)
      wendu_shangxian+=0.1f;
      else if(work_mode ==2)
      wendu_xiaxian+=0.1f; 
      delay(100);   
    }
    else if (jian_State == LOW){
      if(work_mode == 1)
      wendu_shangxian-=0.1f;
      else if(work_mode ==2)
      wendu_xiaxian-=0.1f; 
      delay(100);   
    }

    
    //串口显示验证
    Serial.print("temp:");
    Serial.print(data2);
    Serial.print("*C");  
    //Serial.println(val);Serial.print("%\n"); //显示读取的数值    
    delay(1000);     
    Serial.print("hight:");
    Serial.print(data1);
    Serial.println("%"); 

    //OLED显示上下限
    if(work_mode==0){
    drawDHT11(data1,data2);     
    }
    else if(work_mode==1){
    drawshangxian(wendu_shangxian);   
    }
    else if(work_mode==2){
    drawxiaxian(wendu_xiaxian);   
    } 

    if(sensors.getTempCByIndex(0)>wendu_shangxian||data1>90)                           //若大于32°,则蜂鸣器鸣叫,电机开转
    {
    digitalWrite(beep,LOW);
    }
    else if(sensors.getTempCByIndex(0)<wendu_xiaxian||data1>90)                                     //否则不转
    {
    digitalWrite(beep,LOW);
    }
    else
    {
    digitalWrite(beep,HIGH);
    }
}

void drawDHT11(int H,float T){ 
  display.clearDisplay();
  display.setTextColor(INVERSE);
  display.setTextSize(1);
  //设置光标位置显示
  display.setCursor(0, 0);
  display.print("water_duty:");
  display.setCursor(30, 11);  
  display.print(H);  
  display.print("%");  
  display.setCursor(0, 22);
  display.print("water_status:");
  display.setCursor(30,33);
  if(data1<90){display.print("ok");}
  else {display.print("not ok");} 
  display.setCursor(0, 44);
  display.print("temp_value :");
  display.setCursor(30, 55);  
  display.print(T);  
  display.print("*C"); 
  display.display();
}

void drawshangxian(float A){
  display.clearDisplay();
  display.setTextColor(INVERSE);
  display.setTextSize(2);
  display.setCursor(0, 0);
  display.print("HIGH_Limit"); 
  display.setCursor(18, 34);
  display.print(A);  
  display.print("*C"); 
  display.display(); 
}

void drawxiaxian(float A){
  display.clearDisplay();
  display.setTextColor(INVERSE);
  display.setTextSize(2);
  display.setCursor(12,0);
  display.print("LOW_Limit"); 
  display.setCursor(18,34);
  display.print(A);  
  display.print("*C");  
  display.display();
}

代码引入了五个头文件,分别用来控制模块的驱动运行。

定义的引脚如图所示:
在这里插入图片描述
购买了ESP32开发板的可直接按照上述引脚的连线方式连接,其中27,32,33均是模拟输入引脚,外接一个轻触按键,按键的另一端接向地。当外部轻触按键按下的时候,由程序判断是否接收到了按键按下信号。

在这里插入图片描述
此处建立了DS18B20和IIC的面向对象,可通过此函数调用其内部相关的函数。IIC主要是为了驱动0.96寸的OLED屏幕,调用内部的显示函数即可在屏幕上显示特定的数据和图像

在这里插入图片描述
这里定义了在程序中需要使用的中间变量,其中前三个定义的变量关系到外部输入的引脚状态。work_mode的值关系到OLED屏幕的显示,在整体的设计中OLED屏幕将会有三种不同的显示界面。第一个界面显示各种参数的大小,第二个第三个界面分别通过按键可以改变温度上限和下限的大小。double数据用来存储获得的温度传感器数据。

在这里插入图片描述
初始化驱动的四个引脚,其中控制蜂鸣器为输出引脚,控制按键的为输入引脚。此处输入按键被设置为上拉是必要的,博主尝试过只将按键设置为输入的话,当按键按下就会一直执行按键的程序。当设置为上拉以后,按键没有按下时IO口的输出电平为高电平。

在这里插入图片描述
在数据获取那一块将获取到的数据全部赋值给我们定义的中间变量,以方便后续的数据处理。其中number数据是通过外部ADC的采集采集到的水位检测模块输出的模拟电压,从而判断水位到达了某一程度。工作模式切换函数原理即为检测按键按下的电平为低电平时,则将工作的模式+1,从而OLED显示屏上显示不同的界面。

在这里插入图片描述
此处在工作模式为1和2的时候对两个外部输入按键进行判断,若外部按键为低电平,则执行相对应的程序。下方还有串口显示的程序,由于在定义中蓝牙的输入端直接连接的主电路开发板的TX和RX,故串口发送的数据可同步在蓝牙上进行显示。

余下的就是一些显示界面和达到阈值进行一些判断,比如达到了温度上限阈值或低于温度下限阈值时,蜂鸣器进行报警。当水位检测模块检测到水位到了一定程度时,也同样进行报警。


总结

稍后AD文件会发到资源里,有需要的可以下载支持一下,5积分固定。

  • 9
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值