Это тема поддержки статьи: Самодельная метеостанция на esp8266. Оставляйте здесь свои комментарии и вопросы.
Повідомлення відредагував RUS_D: 04 грудень 2016 - 22:36
Тема | Форум | Написано | Дата |
---|---|---|---|
|
|
Это тема поддержки статьи: Самодельная метеостанция на esp8266. Оставляйте здесь свои комментарии и вопросы.
Повідомлення відредагував RUS_D: 04 грудень 2016 - 22:36
Вывод датчиков прямо тут на сайте
Повідомлення відредагував RUS_D: 06 жовтень 2020 - 22:41
Выложу программу для ARDUINO если кто надумает повторить
В ней отсуствует только код ля дозиметра (можно встроить тот что выше выложен)
//--- One-wire // #include <OneWire.h> #define ONE_WIRE_BUS 8 OneWire oneWire(ONE_WIRE_BUS); #include <DallasTemperature.h> DallasTemperature sensors(&oneWire); //DS18B20 DeviceAddress Thermometer1 = { //второй термометр 0x28, 0x00, 0x54, 0xB6, 0x04, 0x00, 0x00, 0x92 }; DeviceAddress Thermometer3 = { // улица 0x28, 0xFF, 0x56, 0xCB, 0x6A, 0x14, 0x03, 0x16 }; //--- One-wire // #define chclient 1 // номер клиента 1... #define timeoutper 400 // таймаут запросов от сервера. #define timesend 300 // интервал отправки данных,для обычных датчиков можно установить время выше. #include <SPI.h> #include "DHT.h" DHT dht; #include "nRF24L01.h" #include "RF24.h" unsigned long time1=0; unsigned long time2=0; #define RELE_1 6 // #define RELE_2 7 // Set up nRF24L01 radio on SPI bus plus pins 9 & 10 RF24 radio(9,10); // // 0 -прием , 1 -передача const uint64_t pipes[2] = { 0xF0F0F0F0E1LL,0xF0F0F0F0D2LL}; // // структура принятых данных.МЕНЯТЬ НЕЛЬЗЯ typedef struct{ byte identifier; byte val1; byte val2; byte val3; byte val4; } nf0; nf0 servernf; // структура отправляемых данных.Изменяемые данные.Размер структуры должен быть не больше 32 байт ! typedef struct{ byte identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ int temperature_Sensor;// передаём температуру. int Humidity_Sensor;// передаём влажность int temperature1_Sensor;// передаём температуру. int Analog; //int Analog; unsigned int Error_Message; // счетчик ошибок unsigned long count;// счетчик передач для контроля качества канала // boolean test_data; } nf1; nf1 clientnf; /* ************************************** */ void setup() { Serial.begin(9600); dht.setup(3); // DHT датчик на пине 3 pinMode(RELE_1, OUTPUT); pinMode(RELE_2, OUTPUT); radio.begin(); delay(2); // выбор скорости // radio.setDataRate(RF24_250KBPS); radio.setDataRate(RF24_1MBPS); // radio.setDataRate(RF24_2MBPS); radio.setPALevel(RF24_PA_MAX); radio.setChannel(100); //тут установка канала radio.setCRCLength(RF24_CRC_16); radio.setAutoAck(false); // выключить аппаратное потверждение radio.setRetries(15,15); radio.openReadingPipe(1,pipes[0]); // Открываем канал приема radio.openWritingPipe(pipes[1]); // Открываем канал передачи clientnf.identifier = chclient; sensors.begin(); //sensors.setResolution(Thermometer1, 10); //второй термометр sensors.setResolution(Thermometer3, 10); } byte errorstate; void loop() { sensors.requestTemperatures(); // опрос датчика температуры улица // для чтения сенсоров if ((millis()-time1) >= 1000) { // обновляем сенсоры раз в секунду (1000млс) // тут будут опросы сенсоров clientnf.temperature_Sensor = dht.getTemperature()*10; clientnf.Humidity_Sensor = dht.getHumidity()*10; clientnf.temperature1_Sensor = sensors.getTempC(Thermometer3)*10; // опрос датчика температуры улица clientnf.Analog=analogRead(0); //пример передачи int данных //clientnf.Analog1=analogRead(1); //пример передачи int данных //clientnf.Analog2=analogRead(2); //пример передачи int данных //clientnf.Analog3=analogRead(3); //пример передачи int данных //Serial.print(" C "); Serial.println(clientnf.temperature1_Sensor/10); time1 = millis(); } //**************************************************************/ if ((millis() - time2) >= timesend || errorstate !=0) { if (clientnf.count <= 2147483646) clientnf.count++; // счетчик передач для контроля качества канала else clientnf.count = 0; radio.stopListening(); bool ok = radio.write( &clientnf, sizeof(clientnf) ); radio.startListening(); unsigned long started_waiting_at = millis(); bool timeout = false; while ( ! radio.available() && ! timeout ) if (millis() - started_waiting_at > timeoutper ) timeout = true; if ( timeout ) { // счетчик ошибок clientnf.Error_Message++; errorstate++; // счетчик ошибок для повтора } else { radio.read( &servernf, sizeof(servernf) ); errorstate=0; } if (errorstate>=50) errorstate=0; // не более 3 попыток для повтора //************************************************************************************************/ if (servernf.identifier == chclient) { // выполнение команд с сервера,если данные предназначены для этого клиента: // val1= 10 -значит дергаем пинами, val2 - номер пина, val3 - состояние пина // не забудте установить режим OUTPUT для нужных пинов. // nRF-USB write 1 10 7 1 1 - что значит установить на 7 выводе логический уровень 1 if (servernf.val1==10) digitalWrite(servernf.val2,servernf.val3); // val1= 11 -значит управляем ШИМ пинами, val2 - номер пина, val3 - уровень 0..255. // не забудте установить режим OUTPUT для нужных пинов. // ШИМ возможен только на некоторых пинах !! if (servernf.val1==11) analogWrite(servernf.val2,servernf.val3); } time2 = millis(); } } // конец loop
В настройке сервера у казать Data structure: THTAL
Счетчик можно закоментить в скетче, тогда данные будут так - THTA
Обновленный вид на метеостанцию в смартфоне (спецпрограмма) - могу поглядеть что делается дома с любой точки мира.
Обновлю тему по случаю приезда печатной платы
Все было разобрано, запаяно на новую плату и запущено в работу...
Временно собранный модуль все никак не вызреет у меня корпус для метеостанции
Обновлю тему.
Проект пересобран на печатной плате. Присутствует дистанционное (интернет) управление реле.
Также есть управление по планировщику заданий, термостат и много другого.
Ну после марта 2016г.
Скетч не правился - вот последний
/* Код мониторинга электропотребления и трансляции данных на сервер */ //------------ Измерение напряжения / тока -------------- // int numberOfSamples = 500; //Установка датчиков тока и напряжения int inPinV = A0; int inPinI = 1; // Коэффициенты для калибровки выводимых значений // Подбираются опытным путем сверяясь с эталонным прибором double VCAL = 13.0; // для напряжения double ICAL = 0.21; // для тока double PHASECAL = 2.3; // для мощности //************************************************************************* double V_RATIO = 50.5 / 1024 * VCAL; double I_RATIO = (long double) 15.15 * 5 / 1024 * ICAL; //Образцы переменных int lastSampleV,lastSampleI,sampleV,sampleI; //Переменные для фильтров double lastFilteredV, lastFilteredI, filteredV, filteredI; double filterTemp; //Сюда сохраняем калибровочное значение фазы мгновенного напряжения double shiftedV; //Расчет переменной для мощности double sqI,sqV,instP,sumI,sumV,sumP; //Полезные значения переменных double realPower, apparentPower, apparentPower1, powerFactor, Vrms, Irms; //------------ Измерение радиации -------------- // #include <SPI.h> #define LOG_PERIOD 300000//34280 //Logging period in milliseconds, recommended value 15000-60000. //#define MAX_PERIOD 60000 //Maximum logging period without modifying this sketch unsigned long counts; //variable for GM Tube events unsigned long cpm; //variable for CPM //unsigned int multiplier; //variable for calculation CPM in this sketch unsigned long previousMillis; //variable for time measurement //------------ Измерение радиации -------------- // //--- One-wire ----------------------------------------------------------- // #include <OneWire.h> #define ONE_WIRE_BUS 8 OneWire oneWire(ONE_WIRE_BUS); #include <DallasTemperature.h> DallasTemperature sensors(&oneWire); //DS18B20 DeviceAddress Thermometer1 = { 0x28, 0x00, 0x54, 0xB6, 0x04, 0x00, 0x00, 0x92 }; DeviceAddress Thermometer3 = { 0x28, 0xFF, 0x56, 0xCB, 0x6A, 0x14, 0x03, 0x16 }; // улица //--- One-wire ----------------------------------------------------------- // #define chclient 1 // номер клиента 1... #define timeoutper 400 // таймаут запросов от сервера. #define timesend 1000 // интервал отправки данных,для обычных датчиков можно установить время выше. #include <SPI.h> #include "DHT.h" DHT dht; #include "nRF24L01.h" #include "RF24.h" unsigned long time1=0; unsigned long time2=0; #define RELE_1 6 // #define RELE_2 7 // Set up nRF24L01 radio on SPI bus plus pins 9 & 10 RF24 radio(9,10); // // 0 -прием , 1 -передача const uint64_t pipes[2] = { 0xF0F0F0F0E1LL,0xF0F0F0F0D2LL}; // // структура принятых данных.МЕНЯТЬ НЕЛЬЗЯ typedef struct{ byte identifier; byte val1; byte val2; byte val3; byte val4; } nf0; nf0 servernf; // структура отправляемых данных.Изменяемые данные.Размер структуры должен быть не больше 32 байт ! typedef struct{ byte identifier;// номер передатчика.МЕНЯТЬ НЕЛЬЗЯ int temperature_Sensor;// передаём температуру. int Humidity_Sensor;// передаём влажность // float Humidity_Sensor;// передаём влажность int temperature1_Sensor;// передаём температуру. int Analog; int Analog1; int Analog2; //int Analog2; //int Analog3; unsigned int Error_Message; // счетчик ошибок unsigned long count;// счетчик передач для контроля качества канала boolean test_data; } nf1; nf1 clientnf; void setup() { //Serial.begin(9600); dht.setup(3); // DHT датчик на пине 3 pinMode(4, OUTPUT); pinMode(RELE_1, OUTPUT); pinMode(RELE_2, OUTPUT); radio.begin(); delay(2); // выбор скорости // radio.setDataRate(RF24_250KBPS); radio.setDataRate(RF24_1MBPS); // radio.setDataRate(RF24_2MBPS); radio.setPALevel(RF24_PA_MAX); radio.setChannel(100); //тут установка канала radio.setCRCLength(RF24_CRC_16); radio.setAutoAck(false); // выключить аппаратное потверждение // radio.enableDynamicPayloads(); // разрешить Dynamic Payloads // radio.enableAckPayload(); // разрешить AckPayload radio.setRetries(15,15); radio.openReadingPipe(1,pipes[0]); // Открываем канал приема radio.openWritingPipe(pipes[1]); // Открываем канал передачи clientnf.identifier = chclient; sensors.begin(); sensors.setResolution(Thermometer1, 10); sensors.setResolution(Thermometer3, 10); //датчик радиации counts = 0; cpm = 0; // multiplier = MAX_PERIOD / LOG_PERIOD; //calculating multiplier, depend on your log period attachInterrupt(0, tube_impulse, FALLING); //define external interrupts //датчик радиации } byte errorstate; void loop() { // измерение радиации unsigned long currentMillis = millis(); if(currentMillis - previousMillis > LOG_PERIOD){ previousMillis = currentMillis; //cpm = counts * multiplier; cpm = (counts*35)/300; // Serial.print(cpm); Serial.println(" - mlr/h"); //Serial.print(currentMillis); Serial.println(" currentMillis"); counts = 0; } // измерение радиации // // для чтения сенсоров if ((millis()-time1) >= 1000) { // обновляем сенсоры раз в секунду (1000млс) sensors.requestTemperatures(); // опрос датчика температуры улица // тут будут опросы сенсоров //float tempC = sensors.getTempC(Thermometer3); // опрос датчика температуры улица clientnf.temperature_Sensor = dht.getTemperature()*10; clientnf.Humidity_Sensor = dht.getHumidity()*10-10; clientnf.temperature1_Sensor = sensors.getTempC(Thermometer3)*10; clientnf.Analog=Vrms; //передача напряжения clientnf.Analog1=Irms; //пример передачи int данных clientnf.Analog2=cpm; //радиация //clientnf.Analog3=analogRead(3); //пример передачи int данных //Serial.println (clientnf.Analog); //Serial.println (clientnf.Analog1); //Serial.print(clientnf.Analog2);Serial.println("_mlr"); //Serial.println(clientnf.temperature1_Sensor/10); //------------ Измерение напряжения / тока -------------- // //Serial.println(temp); for (int n=0; n<numberOfSamples; n++) // цикл крутится 3000 раз { //Используется для удаления смещения 2,5в lastSampleV=sampleV; lastSampleI=sampleI; //Читаем с пинов текущее значение U и I sampleV = analogRead(inPinV); sampleI = analogRead(inPinI); // Используется для удаления смещения 2,5в lastFilteredV = filteredV; lastFilteredI = filteredI; //Цифровой фильтр для удаления постоянного смещения 2,5 в filteredV = 0.996*(lastFilteredV+sampleV-lastSampleV); filteredI = 0.996*(lastFilteredI+sampleI-lastSampleI); //Тут калибруем фазу shiftedV = lastFilteredV + PHASECAL * (filteredV - lastFilteredV); //Среднеквадратический метод расчета напряжения //1) square voltage values sqV= filteredV * filteredV; //2) Суммируем sumV += sqV; // Среднеквадратический метод расчета тока //1) square current values sqI = filteredI * filteredI; //2) Суммируем sumI += sqI; //Мгновенная мощность instP = shiftedV * filteredI; //Суммируем sumP +=instP; } //Расчет корня из среднего напряжения и тока (rms) Vrms = V_RATIO*sqrt(sumV / numberOfSamples); Irms = I_RATIO*sqrt(sumI / numberOfSamples); //Расчет величины мощности //realPower = V_RATIO*I_RATIO*sumP / numberOfSamples; apparentPower = (Vrms * Irms)/1000; // значение в Киловатах apparentPower1 = (Vrms * Irms); // значение в Ваттах powerFactor = realPower / apparentPower; //Сброс накопленных значений sumV = 0; sumI = 0; sumP = 0; // устанавливаем курсор в 0-ом столбце, 1 строка (начинается с 0): //Serial.println(Vrms); //lcd.setCursor (0, 0); //lcd.print ("U="); //lcd.setCursor (2, 0); //lcd.print (Vrms); //lcd.setCursor (0, 2); //lcd.print ("I="); //lcd.setCursor (2, 2); //lcd.print (Irms); //lcd.print(sampleI); //lcd.setCursor (0, 2); //lcd.print ("P="); //lcd.setCursor (2, 2); //lcd.print(apparentPower); //lcd.setCursor (6, 2); //lcd.print ("kW"); //------------ Измерение напряжения / тока -------------- // time1 = millis(); } //************************************************************************************************/ if ((millis() - time2) >= timesend || errorstate !=0) { if (clientnf.count <= 2147483646) clientnf.count++; // счетчик передач для контроля качества канала else clientnf.count = 0; radio.stopListening(); bool ok = radio.write( &clientnf, sizeof(clientnf) ); radio.startListening(); unsigned long started_waiting_at = millis(); bool timeout = false; while ( ! radio.available() && ! timeout ) if (millis() - started_waiting_at > timeoutper ) timeout = true; if ( timeout ) { // счетчик ошибок clientnf.Error_Message++; errorstate++; // счетчик ошибок для повтора } else { radio.read( &servernf, sizeof(servernf) ); errorstate=0; } if (errorstate>=50) errorstate=0; // не более 3 попыток для повтора //************************************************************************************************/ if (servernf.identifier == chclient) { // выполнение команд с сервера,если данные предназначены для этого клиента: // val1= 10 -значит дергаем пинами, val2 - номер пина, val3 - состояние пина // не забудте установить режим OUTPUT для нужных пинов. // nRF-USB write 1 10 7 1 1 - что значит установить на 7 выводе логический уровень 1 if (servernf.val1==10) digitalWrite(servernf.val2,servernf.val3); // val1= 11 -значит управляем ШИМ пинами, val2 - номер пина, val3 - уровень 0..255. // не забудте установить режим OUTPUT для нужных пинов. // ШИМ возможен только на некоторых пинах !! if (servernf.val1==11) analogWrite(servernf.val2,servernf.val3); } time2 = millis(); } } // конец loop ////////////////////////////////////////////////// void tube_impulse(){ //subprocedure for capturing events from Geiger Kit digitalWrite(4, HIGH); // turn the LED on (HIGH is the voltage level) delay(1); // wait for a second digitalWrite(4, LOW); counts++; }
Соединения блока датчиков и основного
конструктор прошивок тут http://wifi-iot.com/
Мега проект! Хочу повторить! Буду изучать мат часть да и теоретическую тоже. Спасибо!
Я смог повторить, простой, чей-то проект на народе (BME280/ESP8266), но такой проект это для меня уже фантастика, очень и очень впечатляет и естественно хочу аналогично улучшить на Вашем примере и свою метеостанцию.
Метеостанция пересобрана на новом модуле ESP32
Будут добавляться другие датчики - тут ножек для входа выхода хватит..
Если кому интересно буду по мере расширения функционала публиковать тут схемы и код