ESP32でMQTTの送受信

#include <WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_AHTX0.h>
#include <Adafruit_BMP280.h>
#include <ArduinoJson.h>

#define PIN_SWITCH 4
#define PIN_STATUS 2

// WiFi設定
const char* ssid = "Buffalo-DE20";
const char* password = "delightfulbreeze1508";

// MQTT設定
const char* mqtt_server = "192.168.**.**"; 
const int mqtt_port = 1883;
const char* topic = "sensor/workroom";
const char* topic_cfg = "sensor/workroom/config";
const int BmpAddr = 0x77;

// 設定変数
int publishInterval = 1000; // デフォルト送信間隔(ms)
unsigned long lastPublish = 0; // 最後の送信時刻

WiFiClient espClient;
PubSubClient client(espClient);

Adafruit_AHTX0 aht;
Adafruit_BMP280 bmp;

bool aht_ok = false;
bool bmp_ok = false;

void setup_wifi() {
  Serial.println("WiFi setup...");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(200);
    Serial.print(".");
  }
  Serial.println("\nWiFi OK");
  Serial.print("IP: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  while (!client.connected()) {
    Serial.print("MQTT connecting...");
    if (client.connect("ESP32Client")) {
      Serial.println("OK");
      client.subscribe(topic_cfg); // 再接続時に再購読
    } else {
      Serial.print("failed, rc=");
      Serial.println(client.state());
      delay(1000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  StaticJsonDocument<256> doc;
  DeserializationError error = deserializeJson(doc, payload, length);

  if (error) {
    Serial.print("JSON parse failed: ");
    Serial.println(error.c_str());
    return;
  }

  if (doc.containsKey("interval")) {
    publishInterval = doc["interval"];
    Serial.print("Updated interval: ");
    Serial.println(publishInterval);
  }

  if (doc.containsKey("led")) {
    String ledState = doc["led"];
    Serial.print("led = ");
    Serial.println(ledState);
    digitalWrite(PIN_SWITCH, ledState == "on" ? HIGH : LOW);
  }
}

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println("ESP32 Start");

  pinMode(PIN_STATUS, OUTPUT); 
  digitalWrite(PIN_STATUS, LOW); 

  pinMode(PIN_SWITCH,OUTPUT);
  digitalWrite(PIN_SWITCH,LOW);

  // I2C初期化
  Wire.begin(21, 22);
  Wire.setClock(100000); // 100kHzで安定化

  // センサー初期化(一度だけ)
  aht_ok = aht.begin();
  if (!aht_ok) {
    Serial.println("❌ AHT sensor init failed");
  } else {
    Serial.println("✅ AHT sensor OK");
  }

  bmp_ok = bmp.begin(BmpAddr);
  if (!bmp_ok) {
    Serial.println("❌ BMP sensor init failed");
  } else {
    Serial.println("✅ BMP sensor OK");
    bmp.setSampling(
      Adafruit_BMP280::MODE_NORMAL,
      Adafruit_BMP280::SAMPLING_X2,
      Adafruit_BMP280::SAMPLING_X16,
      Adafruit_BMP280::FILTER_X16,
      Adafruit_BMP280::STANDBY_MS_500
    );
  }

  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);

  digitalWrite(PIN_STATUS, HIGH); 
  Serial.println("Setup complete.");
}

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

  // publishInterval間隔で送信
  unsigned long now = millis();
  if (now - lastPublish >= publishInterval) {
    lastPublish = now;

    if (!aht_ok || !bmp_ok) {
      Serial.println("⚠️ Sensor not ready");
      return;
    }

    sensors_event_t humidity, temp;
    aht.getEvent(&humidity, &temp);
    float pressure = bmp.readPressure() / 100.0F;

    StaticJsonDocument<128> doc;
    doc["temp"] = temp.temperature;
    doc["hum"] = humidity.relative_humidity;
    doc["pres"] = pressure;

    char buffer[128];
    serializeJson(doc, buffer);
    
    if (client.publish(topic, buffer)) {
      Serial.println(buffer);
    } else {
      Serial.println("❌ Publish failed");
    }
  }
}

タイトルとURLをコピーしました