Метеостанция анемометр + BME280 ESP8266 MQTT



Модуль состоит из микроконтроллера ESP8266 NodeMCU, датчика ветра (геркона), BME280 (датчика температуры, влажности и атмосферного давления) и  и датчика освещенности (фоторезистор).



Принцип работы анемометра очень прост, во время движения лопастей магнит проходит над герконом, включая / выключая его. С помошью прерываний подсчитываем число включений геркона за определённый промежуток времени.

ESP8266 Прерывания (Interrupt)

О подключении фоторезистора

Подключение BME280  по SPI





Геркон подсоединён одной ногой к GND, другой к GPIO2 - D4

Замените ssid, password и mqtt_server на свои.

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

//--------------WIFI---------------------//
const char* ssid = "...........";       // имя Wifi
const char* password = "...........";   // пароль от Wifi
const char* mqtt_server = ".........."; // К примеру 192.168.8.1

#define NAME  "Wetter" // Имя ESPшки

//const char* mqtt_user = "majordomo";
//const char* mqtt_password = "123456";

//--------------MQTT и топики----------------//
const char *comand = NAME "/comand";
const char *topicIP = NAME "/IP";           // отправляет IP
const char *topicInfo = NAME "/info";        // отправляет инфу о подкл. датчиках

const char *topicPressure = NAME "/pressure"; // топик давления
const char *topicVisota = NAME "/visota";     // топик высота над у.м.
const char *topicLicht = NAME "/licht";       // фоторезистор
const char *topicWind = NAME "/wind";         // скорость ветра
const char *topicTemp = NAME "/temp";         // температура
const char *topicHum = NAME "/hum";           // влажность


//--------------Переменные-----------------//
#define BME_SCK 14    // SCL D5
#define BME_MISO 12   // SDO D6
#define BME_MOSI 13   // SDA D7
#define BME_CS 5      // CSB D1

#define SEALEVELPRESSURE_HPA (1013.25)
int wind, val;
int timerSensor, timeold;     // Таймеры
bool infoCom = false;         // Если false то отсылает свой IP
const byte interruptPin = 2;  // Геркон датчик ветра GPIO2 - D4

//--------------Инициализация----------------//
WiFiClient espClient;
PubSubClient client(espClient);

Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

//-------------- Подключение к сети WiFi----------//
void setup_wifi() {
  delay(10);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
  }
}

//--------------- Петля, пока мы не подключимся к WiFi-------------//
void reconnect() {
  while (!client.connected()) {     // Попытка подключения
    if (client.connect(NAME)) {
      client.subscribe(comand); // Подписываемся на топик comand

    } else {            // Подождите 5 секунд до повторной попытки
      delay(5000);
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  // Преобразование входящего массива байтов в строку
  payload[length] = '\0'; // Null terminator используется для завершения массива char
  String message = (char*)payload;
  String top = topic;

  /*-------------Info ESP-----------------*/
  if (top == comand) {
    if (message == NAME) {
      String esp = "ESP-12F Датчики: lichtS A0, BME280 software SPI, WindS (GPIO2 D4)";
      client.publish(topicInfo, String(esp).c_str(), true);
    } else if (message == "ID") {
      infoCom = false;
    }
  }
}

void setup() {
  Serial.begin(9600);
  pinMode (interruptPin, INPUT_PULLUP);
  // Задаем  функцию blink , которая будет вызвана по внешнему прерыванию.
  attachInterrupt ( digitalPinToInterrupt(interruptPin), blink, CHANGE);

  //------------ WIFI-OTA-MQTT---------------//
  setup_wifi();
  ArduinoOTA.setHostname(NAME);               // Задаем имя сетевого порта
  //ArduinoOTA.setPassword((const char *)"0000"); // Задаем пароль доступа для удаленной прошивки
  ArduinoOTA.begin();                             // Инициализируем OTA
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  if (! bme.begin(&Wire)) {// Датчик BME280 не найден
    client.publish(topicInfo, String("valid BME280 sensor").c_str(), true);
    while (1);
  }
}


void loop() {
  ArduinoOTA.handle();      // Всегда готовы к прошивке

  /*------------ Подключение к MQTT ----------------*/
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  delay(100);

  /*---- Отправляем IP при старте МК и по запросу ----*/
  if (!infoCom && WiFi.status() == WL_CONNECTED) {
    String ipInfo = WiFi.localIP().toString();
    client.publish(topicIP, ipInfo.c_str(), true);
    infoCom = true;
  }
/*---- Отправляем скорость ветра на сервер ----*/
if (timeold >= 100) { client.publish(topicWind, String(wind).c_str(), true); wind = 0; timeold = 0; delay(100); } timeold++; /*---- Считываем показания датчиков ----*/ if (timerSensor >= 500) { val = analogRead(A0); client.publish(topicLicht, String(val).c_str(), true); delay(1000); val = bme.readTemperature(); client.publish(topicTemp, String(val).c_str(), true); delay(100); val = bme.readHumidity(); client.publish(topicHum, String(val).c_str(), true); delay(100); val = bme.readPressure() / 100.0F; delay(100); val = val * 0.75; client.publish(topicPressure, String(val).c_str(), true); delay(100); val = bme.readAltitude(SEALEVELPRESSURE_HPA); client.publish(topicVisota, String(val).c_str(), true); delay(100); timerSensor = 0; } timerSensor++; } void blink () { wind++; }

Комментарии

Отправить комментарий

Популярные сообщения из этого блога

Motor Shield L293D + Arduino

Перенос Armbian на SSD

Радиореле 220В 433МГц c кодировкой сигнала eV1527