技能梳理6@NODEMCU+BH1750+DS18B20+DHT11+PWM电机+ONENET

该博客介绍了一个基于ESP32的智能鱼缸系统,集成了土壤湿度、室内温湿度、光照、鱼缸水位和温度的监测,具备蜂鸣器报警和舵机、水泵控制功能。系统能通过OneNet上传数据并在OLED屏幕上显示,确保鱼缸环境的稳定。核心代码涉及WiFi连接、传感器读取、数据处理及电机控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

智慧鱼缸,检测土壤湿度,检测室内温湿度和光照,检测鱼缸水位,检测鱼缸温度,各种蜂鸣器报警(水温超20-24)和控制舵机(步进电机),控制两个水泵,一个需要是从植物里面抽水到鱼缸,另外一个是供养氧作用,数据上传onenet,显示在oled,ESP32做主MCU,下行控制氧气水泵

1、项目简介

在这里插入图片描述

2、实现逻辑

在这里插入图片描述

3、应用场景

#智慧鱼缸

4、核心代码梳理


const char *ssid = "ziroom602";//WIFI
const char *password = "4001111";//WIFI密码
const char* serverIP = "183.230.40.33"; //欲访问的地址
uint16_t serverPort = 80;         //服务器端口号
String url = "http://api.heclouds.com/devices/7xxxxxxxxx7/datapoints?type=3";//网址 设备ID
String api="h8txxxxxxxxxxxxxxxxxxxYFNsgW4=";//api-key
String post;//http请求
int Content_Length;
WiFiClient client; //声明一个客户端对象,用于与服务器进行连接

OneWire  ds(0);  // on pin 10 (a 4.7K resistor is necessary)
BH1750FVI myBH1750(BH1750_DEFAULT_I2CADDR, BH1750_CONTINUOUS_HIGH_RES_MODE_2, BH1750_SENSITIVITY_DEFAULT, BH1750_ACCURACY_DEFAULT);
U8G2_SSD1306_128X64_NONAME_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=*/ 18, /* data=*/ 19, /* cs=*/ 5, /* dc=*/ 16, /* reset=*/ 17);
Servo myservo;  // create servo object to control a servo
#define DHTTYPE       DHT11 //选择的类型


int     servoPin    = 14;      // GPIO pin used to connect the servo control (digital out)
#define LED_BUILTIN   02
#define WATER         15
#define GROUND_H      4
#define WATER_MOTOR   12 //
#define O2_MOTOR      13
#define BEEP          33
#define DHTPIN        27 //DHT11 DATA 数据引脚
DHT dht(DHTPIN, DHTTYPE);
long  ground_h = 0, water = 0, pwm_value = 0;
float tank_temp = 0, house_h = 0, house_t = 0, light_value = 0;
int8_t rx_data = 0, beep_flag = 0, water_ok_flag = 0, water_in_flag = 0, O2_in_flag = 0;
static unsigned long time_=0;//定义初始发送时间为0
static unsigned long time_out=0;//定义超时发送时间为0

void setup(void)
{
    //DHT11
    dht.begin();  

    //OLED
    u8g2.begin();
    u8g2.enableUTF8Print();        // enable UTF8 support for the Arduino print() function

    //USART
    Serial.begin(9600);

    //PIN CFG
    pinMode(LED_BUILTIN, OUTPUT);
    pinMode(WATER_MOTOR, OUTPUT);
    pinMode(O2_MOTOR, OUTPUT); 
    pinMode(BEEP, OUTPUT);
    digitalWrite(BEEP, 1); //low - beep

    pinMode(GROUND_H, INPUT);
    pinMode(GROUND_H, INPUT_PULLUP);
    pinMode(WATER, INPUT);
    pinMode(WATER, INPUT_PULLUP);

    //WIFI
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.begin(ssid, password);//连接到网络

   while (WiFi.status() != WL_CONNECTED) {//等待网络连接成功
        delay(500);
        Serial.print(".");
    }

    Serial.println("");
    Serial.println("WiFi connected");
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());//打印模块IP

    //BH1750
    while (myBH1750.begin() != true)               
    {
        Serial.println(F("ROHM BH1750FVI is not present")); //(F()) saves string to flash & keeps dynamic memory free
        delay(5000);
    }
    Serial.println(F("ROHM BH1750FVI is present"));

    
    //PWM & MOTOR
    ESP32PWM::allocateTimer(0);
	ESP32PWM::allocateTimer(1);
	ESP32PWM::allocateTimer(2);
	ESP32PWM::allocateTimer(3);
    myservo.setPeriodHertz(50);// Standard 50hz servo
    myservo.attach(servoPin, 500, 2400); 
}

void loop(void)
{
    byte i;
    byte present = 0;
    byte type_s;
    byte data[12];
    byte addr[8];
    float celsius, fahrenheit;

    //DS18B20
    if ( !ds.search(addr)) {
    ds.reset_search();
    delay(250);
    return;
    }

    if (OneWire::crc8(addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return;
    }

    switch (addr[0]) {
        case 0x10:
        //Serial.println("  Chip = DS18S20");  // or old DS1820
        type_s = 1;
        break;
        case 0x28:
        //Serial.println("  Chip = DS18B20");
        type_s = 0;
        break;
        case 0x22:
       // Serial.println("  Chip = DS1822");
        type_s = 0;
        break;
        default:
        Serial.println("Device is not a DS18x20 family device.");
        return;
    } 

    ds.reset();
    ds.select(addr);
    ds.write(0x44, 1);        // start conversion, with parasite power on at the end  
    delay(1000);     // maybe 750ms is enough, maybe not
    present = ds.reset();
    ds.select(addr);    
    ds.write(0xBE);         // Read Scratchpad

    for ( i = 0; i < 9; i++) {           // we need 9 bytes
        data[i] = ds.read();
    }

    int16_t raw = (data[1] << 8) | data[0];
    if (type_s) {
        raw = raw << 3; // 9 bit resolution default
        if (data[7] == 0x10) {
        // "count remain" gives full 12 bit resolution
        raw = (raw & 0xFFF0) + 12 - data[6];
        }
    } else {
        byte cfg = (data[4] & 0x60);
        // at lower res, the low bits are undefined, so let's zero them
        if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
        else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
        else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
        //// default is 12 bit resolution, 750 ms conversion time
    }
    celsius = (float)raw / 16.0;
    fahrenheit = celsius * 1.8 + 32.0;
    tank_temp = celsius;
    
    //DHT11
    house_h = dht.readHumidity();
    house_t = dht.readTemperature();
    
    
     if (isnan(house_h) || isnan(house_t))
     {
         Serial.println("Failed to read from DHT sensor!");
         return;
     }

     //BH1750
    light_value = myBH1750.readLightLevel();


    //logic
    ground_h = 1-digitalRead(GROUND_H);
    water = 1-digitalRead(WATER);
    Serial.printf("GROUND-WATER: %d,%d",ground_h,water);
    Serial.println("//");
    digitalWrite(WATER_MOTOR, 1-ground_h); //HIGH-OPEN ground h low  open water motor
    digitalWrite(O2_MOTOR, water);//no use

    if(light_value >= 50)
        pwm_value = 180;
    else if(light_value <= 20)
        pwm_value = 0;
    
    if((tank_temp>30) || (tank_temp<20))
    {
        digitalWrite(BEEP, 0); //low - beep
    }
    else digitalWrite(BEEP, 1);

    //MOTOR 
    myservo.write(pwm_value);                  // set the servo position according to the scaled value  (value between 0 and 180)

    //LED
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);

    //OLED
    u8g2.setFont(u8g2_font_unifont_t_chinese2);
    u8g2.clearBuffer(); //清除模组的缓存
    u8g2.setFont(u8g2_font_ncenB08_tr); // 设置字体
    u8g2.setCursor(0, 15);
    u8g2.printf("TEMP-WATER: %.2fC", tank_temp);
    u8g2.setCursor(0, 30);
    u8g2.printf("GOUND:%d WATER:%d",ground_h, water);
    u8g2.setCursor(0, 45);
    u8g2.printf("HOUSE-TH: %.1fC,%.1f%",house_t,house_h); 
    u8g2.setCursor(0, 60);
    u8g2.printf("LIGHT-LUX: %.2fLux",light_value);
    u8g2.sendBuffer(); // 将缓存输出到屏幕
}


5、部分参考资料

#硬件原理图资料见资料包(下)

6、注意事项

#代码暂不包含nodemcu代码

完整可运行项目地址

或 点击下方”大饼匠人“卡片,关注并回复"6"免费下载开发资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大饼酱人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值