野路子学习esp32(十九)ESP32-Arduino 第二篇 智能孵化器 @a.宏万

先上代码。

完整的代码,可以直接运行哦。

代码中包括了 自动连接WiFi  连接MQTT  继电器控制 LED灯的控制  OLED的显示

 

#include <DHTesp.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <String.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


#define OLED_MOSI   13
#define OLED_CLK   14
#define OLED_DC    17
#define OLED_CS    16
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

const char* ssid = "xz220";
const char* password = "00000000";
const char* mqtt_server = "0.0.0.0";

const char* TOPIC = "home/devices/onoff/";                     // 订阅信息主题
const char* client_id = "clientId-ApjJZcy9Dh";                   // 标识当前设备的客户端编号

WiFiClient espClient;                                                         // 定义wifiClient实例
PubSubClient client(espClient);                                         // 定义PubSubClient的实例
long lastMsg = 0;

DHTesp dht;
int dhtPin = 19;
int heatPin = 18;

//WiFi自动连接
void setup_wifi() {
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  //randomSeed(micros());

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

//MQTT收到消息的回调
void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);   // 打印主题信息
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]); // 打印主题内容
  }
  Serial.println();

  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, HIGH);   // 亮灯
  } else {
    digitalWrite(BUILTIN_LED, LOW);   // 熄灯
  }
}

//MQTT连接
void reconnect() {
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect(client_id)) {
      Serial.println("connected");
      // 连接成功时订阅主题
      client.subscribe(TOPIC);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


void setup() {
  Serial.begin(115200);
  pinMode(heatPin, OUTPUT);     // 定义加热继电器
  pinMode(BUILTIN_LED, OUTPUT);     // 定义板载LED灯为输出方式
  setup_wifi();                                          //执行Wifi初始化,下文有具体描述
  client.setServer(mqtt_server, 1883);    //设定MQTT服务器与使用的端口,1883是默认的MQTT端口
  client.setCallback(callback);                 //设定回调方式,当ESP8266收到订阅消息时会调用此方法
  dht.setup(dhtPin, DHTesp::DHT11);
  display.begin(SSD1306_SWITCHCAPVCC);//开始启动的语句
  display.setTextColor(WHITE);//开像素点发光
}


static const unsigned char PROGMEM str1[] =
{
  0x00, 0x00, 0x33, 0xFC, 0x1B, 0x0C, 0x1B, 0x0C, 0xC3, 0xFC, 0x63, 0x0C, 0x63, 0x0C, 0x1B, 0xFC,
  0x18, 0x00, 0x37, 0xFE, 0xF6, 0xF6, 0x36, 0xF6, 0x36, 0xF6, 0x36, 0xF6, 0x3F, 0xFF, 0x00, 0x00 /*"温",0*/

};

static const unsigned char PROGMEM str2[] =
{
  0x01, 0x80, 0x00, 0xC0, 0x3F, 0xFF, 0x33, 0x30, 0x33, 0x30, 0x3F, 0xFE, 0x33, 0x30, 0x33, 0x30,
  0x33, 0xF0, 0x30, 0x00, 0x3F, 0xF8, 0x36, 0x18, 0x63, 0x30, 0x61, 0xE0, 0xC7, 0x38, 0x3C, 0x0F /*"度",2*/
};

static const unsigned char PROGMEM str3[] =
{
  0x00, 0x00, 0x37, 0xFC, 0x1E, 0x0C, 0x1E, 0x0C, 0xC7, 0xFC, 0x66, 0x0C, 0x66, 0x0C, 0x1F, 0xFC,
  0x19, 0xB0, 0x31, 0xB0, 0xFD, 0xB6, 0x37, 0xBC, 0x33, 0xB8, 0x31, 0xB0, 0x3F, 0xFF, 0x00, 0x00 /*"湿",1*/
};

static const unsigned char PROGMEM str4[] =
{
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 /*":",0*/
};

//火图标
static const unsigned char PROGMEM pic1[] =
{
  0x00, 0x01, 0x80, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x01, 0xF0, 0x00,
  0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x01, 0xFC, 0x00, 0x00, 0x01, 0xFC, 0x00,
  0x00, 0x33, 0xFC, 0x00, 0x00, 0x33, 0xFC, 0x00, 0x00, 0x7F, 0xFC, 0x00, 0x00, 0xFF, 0xFC, 0x00,
  0x00, 0xFF, 0xFD, 0x00, 0x01, 0xFF, 0xFF, 0x00, 0x01, 0xFF, 0xFF, 0x80, 0x03, 0xFF, 0xFF, 0x80,
  0x03, 0xFF, 0x7F, 0x80, 0x01, 0xFF, 0x3F, 0xC0, 0x01, 0xFE, 0x3F, 0xC0, 0x0D, 0xFE, 0x1F, 0xC0,
  0x0E, 0xFC, 0x1F, 0xC0, 0x0F, 0xF8, 0x1F, 0xC0, 0x0F, 0xF0, 0x1F, 0xC0, 0x0F, 0xF1, 0xB7, 0xC0,
  0x0F, 0xF3, 0xC7, 0xC0, 0x0F, 0xB3, 0xC7, 0xC0, 0x07, 0x87, 0xE7, 0xC0, 0x07, 0xDF, 0xE7, 0x80,
  0x03, 0xDF, 0xE7, 0x00, 0x01, 0xCF, 0xEF, 0x00, 0x00, 0xEF, 0xEC, 0x00, 0x00, 0x77, 0xCC, 0x00,
};

//保温图标
static const unsigned char PROGMEM pic2[] =
{
  0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x07, 0x83, 0x81, 0xC0, 0x03, 0x83, 0xC1, 0xE0,
  0x03, 0xC1, 0xC1, 0xE0, 0x01, 0xC1, 0xE0, 0xE0, 0x01, 0xC1, 0xE0, 0xE0, 0x01, 0xC1, 0xE0, 0xE0,
  0x03, 0xC1, 0xC0, 0xE0, 0x03, 0xC3, 0xC1, 0xE0, 0x07, 0x83, 0x83, 0xC0, 0x07, 0x07, 0x83, 0x80,
  0x0F, 0x07, 0x07, 0x80, 0x0E, 0x0F, 0x07, 0x00, 0x0E, 0x0E, 0x07, 0x00, 0x0E, 0x0F, 0x07, 0x00,
  0x0F, 0x07, 0x07, 0x80, 0x07, 0x07, 0x83, 0x80, 0x07, 0x07, 0x83, 0xC0, 0x07, 0x03, 0x83, 0xC0,
  0x07, 0x03, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x7F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFC,
  0x7F, 0xFF, 0xFF, 0xFC, 0x7F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};


void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  //两秒刷新温湿度数据并显示
  if (now - lastMsg > 2000) {
    lastMsg = now;
    //读取温湿度传感器数据
    TempAndHumidity lastValues = dht.getTempAndHumidity();
    //将数据通过MQTT实时发送到服务器
    String str = client_id;     //const char*类型转string类型
    String Mestr = "{\"client_id\":\"" + str + "\",\"Temperature\":" + String(lastValues.temperature, 0) + ",\"Humidity\":" + String(lastValues.humidity, 0) + "}";
    //通过串口输出测试
    Serial.println(Mestr);
    char buf[Mestr.length()];
    Mestr.toCharArray(buf, Mestr.length()+1);
    client.publish("home/status/", buf);

    //通过串口输出
    //Serial.println("Temperature: " + String(lastValues.temperature, 0));
    //Serial.println("Humidity: " + String(lastValues.humidity, 0));

    //清除显示内容
    display.clearDisplay();
    //定义显示内容 文字
    display.setTextSize(2);
    display.setCursor(60, 1);
    display.println(String(lastValues.temperature, 0));
    display.setCursor(60, 18);
    display.println(String(lastValues.humidity, 0));
    //定义显示内容 字符
    display.drawBitmap(10, 0, str1, 16, 16, 1);
    display.drawBitmap(26, 0, str2, 16, 16, 1);
    display.drawBitmap(46, 0, str4, 16, 16, 1);

    display.drawBitmap(10, 16, str3, 16, 16, 1);
    display.drawBitmap(26, 16, str2, 16, 16, 1);
    display.drawBitmap(46, 16, str4, 16, 16, 1);


    //判断温度控制继电器
    if (lastValues.temperature < 38 ) {
      display.drawBitmap(90, 0, pic1, 30, 32, 1);
      digitalWrite(heatPin, HIGH);   // 继电器开
    } else    {
      display.drawBitmap(90, 0, pic2, 30, 32, 1);
      digitalWrite(heatPin, LOW);   // 继电器关
    }

    //显示以上定义内容
    display.display();
  }
}

 

串口输出

 

 

 

MQTT订阅主题打印

 

 

模块实拍

 

 

 

显示实拍

 

 

 

 

 

posted @ 2020-07-07 11:15  创客宏万  阅读(1229)  评论(0编辑  收藏  举报