diff --git a/data_svelte/items.json b/data_svelte/items.json index 46e6b216..74a8c083 100644 --- a/data_svelte/items.json +++ b/data_svelte/items.json @@ -276,7 +276,58 @@ "num": 20 }, { - "name": "21. GY21 Температура", + "name": "21. Частотомер на ADC, Частота", + "type": "Reading", + "subtype": "FreqMeterF", + "id": "freq", + "widget": "anydataHtz", + "page": "Частотомер", + "descr": "Частота", + "plus": 0, + "multiply": 1, + "round": 1, + "pin-Esp32": 33, + "samples": 512, + "samplingFrequency": 5000, + "int": 5, + "num": 21 + }, + { + "name": "22. Частотомер на ADC, Процент Пульсации", + "type": "Reading", + "subtype": "FreqMeterPcFl", + "id": "pctFlicker", + "widget": "anydataPct", + "page": "Частотомер", + "descr": "Процент Пульсации", + "plus": 0, + "multiply": 1, + "round": 1, + "pin-Esp32": 33, + "samples": 512, + "samplingFrequency": 5000, + "int": 5, + "num": 22 + }, + { + "name": "23. Частотомер на ADC, Индекс Пульсации", + "type": "Reading", + "subtype": "FreqMeterFlIn", + "id": "flickerIndex", + "widget": "anydataDef", + "page": "Частотомер", + "descr": "Индекс Пульсации", + "plus": 0, + "multiply": 1, + "round": 10, + "pin-Esp32": 33, + "samples": 512, + "samplingFrequency": 5000, + "int": 5, + "num": 23 + }, + { + "name": "24. GY21 Температура", "type": "Reading", "subtype": "GY21t", "id": "tmp4", @@ -285,10 +336,10 @@ "descr": "Температура", "round": 1, "int": 15, - "num": 21 + "num": 24 }, { - "name": "22. GY21 Влажность", + "name": "25. GY21 Влажность", "type": "Reading", "subtype": "GY21h", "id": "Hum4", @@ -297,10 +348,10 @@ "descr": "Влажность", "round": 1, "int": 15, - "num": 22 + "num": 25 }, { - "name": "23. HDC1080 Температура", + "name": "26. HDC1080 Температура", "type": "Reading", "subtype": "Hdc1080t", "id": "Temp1080", @@ -310,10 +361,10 @@ "int": 15, "addr": "0x40", "round": 1, - "num": 23 + "num": 26 }, { - "name": "24. HDC1080 Влажность", + "name": "27. HDC1080 Влажность", "type": "Reading", "subtype": "Hdc1080h", "id": "Hum1080", @@ -323,10 +374,10 @@ "int": 15, "addr": "0x40", "round": 1, - "num": 24 + "num": 27 }, { - "name": "25. MAX6675 Температура", + "name": "28. MAX6675 Температура", "type": "Reading", "subtype": "Max6675t", "id": "maxtmp", @@ -337,71 +388,89 @@ "DO": 12, "CS": 13, "CLK": 14, - "num": 25 + "num": 28 }, { - "name": "26. PZEM 004t Напряжение", + "name": "29. PZEM 004t Напряжение", "type": "Reading", "subtype": "Pzem004v", "id": "v", "widget": "anydataVlt", - "page": "Сенсоры", + "page": "PZEM", "descr": "Напряжение", "int": 15, "addr": "0xF8", - "num": 26 + "round": 1, + "num": 29 }, { - "name": "27. PZEM 004t Сила тока", + "name": "30. PZEM 004t Сила тока", "type": "Reading", "subtype": "Pzem004a", "id": "a", "widget": "anydataAmp", - "page": "Сенсоры", + "page": "PZEM", "descr": "Сила тока", "int": 15, "addr": "0xF8", - "num": 27 + "round": 1, + "num": 30 }, { - "name": "28. PZEM 004t Мощность", + "name": "31. PZEM 004t Мощность", "type": "Reading", "subtype": "Pzem004w", "id": "w", "widget": "anydataWt", - "page": "Сенсоры", + "page": "PZEM", "descr": "Мощность", "int": 15, "addr": "0xF8", - "num": 28 + "round": 1, + "num": 31 }, { - "name": "29. PZEM 004t Энергия", + "name": "32. PZEM 004t Энергия", "type": "Reading", "subtype": "Pzem004wh", "id": "wh", "widget": "anydataWth", - "page": "Сенсоры", + "page": "PZEM", "descr": "Энергия", "int": 15, "addr": "0xF8", - "num": 29 + "round": 1, + "num": 32 }, { - "name": "30. PZEM 004t Частота", + "name": "33. PZEM 004t Частота", "type": "Reading", "subtype": "Pzem004hz", "id": "hz", "widget": "anydataHtz", - "page": "Сенсоры", + "page": "PZEM", "descr": "Частота", "int": 15, "addr": "0xF8", - "num": 30 + "round": 1, + "num": 33 }, { - "name": "31. Сканер кнопок 433 MHz", - "num": 31, + "name": "34. PZEM 004t Косинус", + "type": "Reading", + "subtype": "Pzem004pf", + "id": "pf", + "widget": "anydata", + "page": "PZEM", + "descr": "Косинус F", + "int": 15, + "addr": "0xF8", + "round": 1, + "num": 34 + }, + { + "name": "35. Сканер кнопок 433 MHz", + "num": 35, "type": "Reading", "subtype": "RCswitch", "id": "rsw", @@ -410,7 +479,7 @@ "pinTx": 12 }, { - "name": "32. Sht20 Температура", + "name": "36. Sht20 Температура", "type": "Reading", "subtype": "Sht20t", "id": "tmp2", @@ -419,10 +488,10 @@ "descr": "Температура", "int": 15, "round": 1, - "num": 32 + "num": 36 }, { - "name": "33. Sht20 Влажность", + "name": "37. Sht20 Влажность", "type": "Reading", "subtype": "Sht20h", "id": "Hum2", @@ -431,10 +500,10 @@ "descr": "Влажность", "int": 15, "round": 1, - "num": 33 + "num": 37 }, { - "name": "34. Sht30 Температура", + "name": "38. Sht30 Температура", "type": "Reading", "subtype": "Sht30t", "id": "tmp30", @@ -443,10 +512,10 @@ "descr": "SHT30 Температура", "int": 15, "round": 1, - "num": 34 + "num": 38 }, { - "name": "35. Sht30 Влажность", + "name": "39. Sht30 Влажность", "type": "Reading", "subtype": "Sht30h", "id": "Hum30", @@ -455,11 +524,11 @@ "descr": "SHT30 Влажность", "int": 15, "round": 1, - "num": 35 + "num": 39 }, { - "name": "36. HC-SR04 Ультразвуковой дальномер", - "num": 36, + "name": "40. HC-SR04 Ультразвуковой дальномер", + "num": 40, "type": "Reading", "subtype": "Sonar", "id": "sonar", @@ -471,7 +540,7 @@ "int": 5 }, { - "name": "37. UART", + "name": "41. UART", "type": "Reading", "subtype": "UART", "page": "", @@ -481,13 +550,13 @@ "tx": 12, "rx": 13, "speed": 9600, - "num": 37 + "num": 41 }, { "header": "Исполнительные устройства" }, { - "name": "38. Кнопка подключенная к пину", + "name": "42. Кнопка подключенная к пину", "type": "Writing", "subtype": "ButtonIn", "id": "btn", @@ -500,10 +569,10 @@ "pinMode": "INPUT", "debounceDelay": 50, "fixState": 0, - "num": 38 + "num": 42 }, { - "name": "39. Управление пином", + "name": "43. Управление пином", "type": "Writing", "subtype": "ButtonOut", "id": "btn", @@ -513,10 +582,10 @@ "int": 0, "inv": 0, "pin": 2, - "num": 39 + "num": 43 }, { - "name": "40. Сервопривод", + "name": "44. Сервопривод", "type": "Writing", "subtype": "IoTServo", "id": "servo", @@ -527,10 +596,10 @@ "pin": 12, "apin": -1, "amap": "0, 4096, 0, 180", - "num": 40 + "num": 44 }, { - "name": "41. Расширитель портов Mcp23017", + "name": "45. Расширитель портов Mcp23017", "type": "Reading", "subtype": "Mcp23017", "id": "Mcp", @@ -540,10 +609,10 @@ "int": "0", "addr": "0x20", "index": 1, - "num": 41 + "num": 45 }, { - "name": "42. MP3 плеер", + "name": "46. MP3 плеер", "type": "Reading", "subtype": "Mp3", "id": "mp3", @@ -553,10 +622,10 @@ "int": 1, "pins": "14,12", "volume": 20, - "num": 42 + "num": 46 }, { - "name": "43. Расширитель портов Pcf8574", + "name": "47. Расширитель портов Pcf8574", "type": "Reading", "subtype": "Pcf8574", "id": "Pcf", @@ -566,10 +635,10 @@ "int": "0", "addr": "0x20", "index": 1, - "num": 43 + "num": 47 }, { - "name": "44. PWM ESP8266", + "name": "48. PWM ESP8266", "type": "Writing", "subtype": "Pwm8266", "id": "pwm", @@ -581,10 +650,10 @@ "freq": 5000, "val": 0, "apin": -1, - "num": 44 + "num": 48 }, { - "name": "45. Телеграм-Лайт", + "name": "49. Телеграм-Лайт", "type": "Writing", "subtype": "TelegramLT", "id": "tg", @@ -593,13 +662,13 @@ "descr": "", "token": "", "chatID": "", - "num": 45 + "num": 49 }, { "header": "Экраны" }, { - "name": "46. LCD экран 2004", + "name": "50. LCD экран 2004", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -611,10 +680,10 @@ "size": "20,4", "coord": "0,0", "id2show": "id датчика", - "num": 46 + "num": 50 }, { - "name": "47. LCD экран 1602", + "name": "51. LCD экран 1602", "type": "Reading", "subtype": "Lcd2004", "id": "Lcd", @@ -626,6 +695,6 @@ "size": "16,2", "coord": "0,0", "id2show": "id датчика", - "num": 47 + "num": 51 } ] \ No newline at end of file diff --git a/myProfile.json b/myProfile.json index 1fa1ae2f..4e2a5610 100644 --- a/myProfile.json +++ b/myProfile.json @@ -88,6 +88,10 @@ "path": "src/modules/sensors/Emon", "active": false }, + { + "path": "src/modules/sensors/FreqMeter", + "active": true + }, { "path": "src/modules/sensors/GY21", "active": true diff --git a/platformio.ini b/platformio.ini index 920bc4f8..b38209a2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -58,10 +58,11 @@ lib_deps = adafruit/Adafruit BMP280 Library beegee-tokyo/DHT sensor library for ESPx milesburton/DallasTemperature@^3.9.1 + kosme/arduinoFFT@^1.5.6 https://github.com/JonasGMorsch/GY-21.git ClosedCube HDC1080 adafruit/MAX6675 library - mandulaj/PZEM-004T-v30 + https://github.com/mandulaj/PZEM-004T-v30 rc-switch @ ^2.6.4 robtillaart/SHT2x@^0.1.1 WEMOS SHT3x@1.0.0 @@ -84,6 +85,7 @@ build_src_filter = + + + + + + + + diff --git a/src/modules/API.cpp b/src/modules/API.cpp index ab864765..38b509e8 100644 --- a/src/modules/API.cpp +++ b/src/modules/API.cpp @@ -12,6 +12,7 @@ void* getAPI_Bme280(String subtype, String params); void* getAPI_Bmp280(String subtype, String params); void* getAPI_Dht1122(String subtype, String params); void* getAPI_Ds18b20(String subtype, String params); +void* getAPI_FreqMeter(String subtype, String params); void* getAPI_GY21(String subtype, String params); void* getAPI_Hdc1080(String subtype, String params); void* getAPI_Max6675(String subtype, String params); @@ -45,6 +46,7 @@ if ((tmpAPI = getAPI_Bme280(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Bmp280(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Dht1122(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Ds18b20(subtype, params)) != nullptr) return tmpAPI; +if ((tmpAPI = getAPI_FreqMeter(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_GY21(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Hdc1080(subtype, params)) != nullptr) return tmpAPI; if ((tmpAPI = getAPI_Max6675(subtype, params)) != nullptr) return tmpAPI; diff --git a/src/modules/sensors/FreqMeter/FreqMeter.cpp b/src/modules/sensors/FreqMeter/FreqMeter.cpp new file mode 100644 index 00000000..b4bc297f --- /dev/null +++ b/src/modules/sensors/FreqMeter/FreqMeter.cpp @@ -0,0 +1,398 @@ +#include "Global.h" +#include "classes/IoTItem.h" +// +#include "arduinoFFT.h" + +arduinoFFT FFT = arduinoFFT(); /* Create FFT object */ + +uint16_t samples = 512; // This value MUST ALWAYS be a power of 2 +const uint16_t maxSamples = 1024; // This value MUST ALWAYS be a power of 2 + +double samplingFrequency = 10000; // Hz, must be less than 10000 due to ADC + +unsigned int sampling_period_us; + +double vReal[maxSamples]; +double vImag[maxSamples]; + +#define SCL_INDEX 0x00 +#define SCL_TIME 0x01 +#define SCL_FREQUENCY 0x02 +#define SCL_PLOT 0x03 + +double Sampling(); +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType); + +unsigned int freqMeterPin; // Esp32 Analog pins: 32, 33, 34, 35, 36, 39 + +int FreqMeterFirstSensor = 0; + +IoTItem *item_FreqMeterF = nullptr; // pointer +IoTItem *item_FreqMeterPcFl = nullptr; +IoTItem *item_FreqMeterFlIn = nullptr; + +void FreqMeterRequest(int sensorID); + +double PercentFlickerMax; +double FlickerIndex; + +extern IoTGpio IoTgpio; + +//Это файл сенсора, в нем осуществляется чтение сенсора. +class FreqMeterF : public IoTItem +{ +private: + //======================================================================================================= + // Секция переменных. + //Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы + //впоследствии использовать их в loop и setup + +public: + //======================================================================================================= + //это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора. + + FreqMeterF(String parameters) : IoTItem(parameters) + { + item_FreqMeterF = this; + +#ifdef ESP8266 + freqMeterPin = 0; +#endif +#ifdef ESP32 + freqMeterPin = jsonReadInt(parameters, "pin-Esp32"); +#endif + + pinMode(freqMeterPin, INPUT); + + samples = jsonReadInt(parameters, "samples"); + if (samples != 64 && samples != 128 && samples != 256 && samples != 512 && samples != 1024) + { + samples = 512; + } + SerialPrint("i", "Sensor FreqMeterF", "samples = " + String(samples)); + + samplingFrequency = jsonReadInt(parameters, "samplingFrequency"); + SerialPrint("i", "Sensor FreqMeterF", "samplingFrequency = " + String(samplingFrequency)); + + sampling_period_us = round(1000000 * (1.0 / samplingFrequency)); + // FreqMeterF_On = 1; + FreqMeterFirstSensor = 0; + } + + //======================================================================================================= + // doByInterval() + //это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора + //а затем выполнить regEvent - это регистрация произошедшего события чтения + //здесь так же доступны все переменные из секции переменных, и полученные в setup + //если у сенсора несколько величин то делайте несколько regEvent + void doByInterval() + { + FreqMeterRequest(1); + // double frequency = Sampling(); + // value.valD = frequency; + + // regEvent(value.valD, "FreqMeterF"); //обязательный вызов хотяб один + } + //======================================================================================================= + + ~FreqMeterF(){}; +}; + +//Это файл сенсора, в нем осуществляется чтение сенсора. Percent Flicker +class FreqMeterPcFl : public IoTItem +{ +private: + //======================================================================================================= + // Секция переменных. + //Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы + //впоследствии использовать их в loop и setup + +public: + //======================================================================================================= + //это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора. + + FreqMeterPcFl(String parameters) : IoTItem(parameters) + { + item_FreqMeterPcFl = this; + +#ifdef ESP8266 + freqMeterPin = 0; +#endif +#ifdef ESP32 + freqMeterPin = jsonReadInt(parameters, "pin-Esp32"); +#endif + + pinMode(freqMeterPin, INPUT); + + samples = jsonReadInt(parameters, "samples"); + if (samples != 64 && samples != 128 && samples != 256 && samples != 512 && samples != 1024 && samples != 2048) + { + samples = 512; + } + SerialPrint("i", "Sensor FreqMeterF", "samples = " + String(samples)); + + samplingFrequency = jsonReadInt(parameters, "samplingFrequency"); + SerialPrint("i", "Sensor FreqMeterF", "samplingFrequency = " + String(samplingFrequency)); + + sampling_period_us = round(1000000 * (1.0 / samplingFrequency)); + FreqMeterFirstSensor = 0; + } + + //======================================================================================================= + // doByInterval() + //это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора + //а затем выполнить regEvent - это регистрация произошедшего события чтения + //здесь так же доступны все переменные из секции переменных, и полученные в setup + //если у сенсора несколько величин то делайте несколько regEvent + void doByInterval() + { + FreqMeterRequest(2); + // double frequency = Sampling(); + // value.valD = frequency; + + // regEvent(value.valD, "FreqMeterPFl"); //обязательный вызов хотяб один + } + //======================================================================================================= + + ~FreqMeterPcFl(){}; +}; + +//Это файл сенсора, в нем осуществляется чтение сенсора. Flicker Index +class FreqMeterFlIn : public IoTItem +{ +private: + //======================================================================================================= + // Секция переменных. + //Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы + //впоследствии использовать их в loop и setup + +public: + //======================================================================================================= + //это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора. + + FreqMeterFlIn(String parameters) : IoTItem(parameters) + { + item_FreqMeterFlIn = this; + +#ifdef ESP8266 + freqMeterPin = 0; +#endif +#ifdef ESP32 + freqMeterPin = jsonReadInt(parameters, "pin-Esp32"); +#endif + + pinMode(freqMeterPin, INPUT); + + samples = jsonReadInt(parameters, "samples"); + if (samples != 64 && samples != 128 && samples != 256 && samples != 512 && samples != 1024 && samples != 2048) + { + samples = 512; + } + SerialPrint("i", "Sensor FreqMeterF", "samples = " + String(samples)); + + samplingFrequency = jsonReadInt(parameters, "samplingFrequency"); + SerialPrint("i", "Sensor FreqMeterF", "samplingFrequency = " + String(samplingFrequency)); + + sampling_period_us = round(1000000 * (1.0 / samplingFrequency)); + FreqMeterFirstSensor = 0; + } + + //======================================================================================================= + // doByInterval() + //это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора + //а затем выполнить regEvent - это регистрация произошедшего события чтения + //здесь так же доступны все переменные из секции переменных, и полученные в setup + //если у сенсора несколько величин то делайте несколько regEvent + void doByInterval() + { + FreqMeterRequest(3); + // double frequency = Sampling(); + // value.valD = frequency; + // regEvent(value.valD, "FreqMeterFlIn"); //обязательный вызов хотяб один + } + //======================================================================================================= + + ~FreqMeterFlIn(){}; +}; + +//после замены названия сенсора, на функцию можно не обращать внимания +//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть +//создание и контроль соответствующих глобальных переменных +void *getAPI_FreqMeter(String subtype, String param) +{ + if (subtype == F("FreqMeterF")) + { + return new FreqMeterF(param); + } + else if (subtype == F("FreqMeterPcFl")) + { + return new FreqMeterPcFl(param); + } + else if (subtype == F("FreqMeterFlIn")) + { + return new FreqMeterFlIn(param); + } + else + { + return nullptr; + } +} + +void FreqMeterRequest(int sensorID) +{ + + if (FreqMeterFirstSensor == 0) + FreqMeterFirstSensor = sensorID; + + if (FreqMeterFirstSensor == sensorID) + { + double frequency = Sampling(); + if (item_FreqMeterF) + { + item_FreqMeterF->value.valD = frequency; + item_FreqMeterF->regEvent(item_FreqMeterF->value.valD, "FreqMeterF"); + } + + if (item_FreqMeterPcFl) + { + item_FreqMeterPcFl->value.valD = PercentFlickerMax; + item_FreqMeterPcFl->regEvent(item_FreqMeterPcFl->value.valD, "FreqMeterPcFl"); + } + + if (item_FreqMeterFlIn) + { + item_FreqMeterFlIn->value.valD = FlickerIndex; + item_FreqMeterFlIn->regEvent(item_FreqMeterFlIn->value.valD, "FreqMeterFlIn"); + } + } + else + { + //пропускаем вызов от остальных сенсоров + } +} + +double Sampling() +{ + // double ADCRange = 0; + double MaxADCValue = 0; + +#ifdef ESP8266 + double MinADCValue = 1023; +#endif + +#ifdef ESP32 + double MinADCValue = 4095; +#endif + + double analogReadSum = 0; + //double PercentFlickerSum = 0; + + unsigned long microseconds = micros(); + + for (int i = 0; i < samples; i++) + { + + vReal[i] = analogRead(freqMeterPin); + analogReadSum += vReal[i]; + vImag[i] = 0; + while (micros() - microseconds < sampling_period_us) + { + // empty loop + } + microseconds += sampling_period_us; + double A1Value = vReal[i]; + + if (A1Value > MaxADCValue) + { + MaxADCValue = A1Value; + } + + if (A1Value < MinADCValue) + { + MinADCValue = A1Value; + } + // заготовка под другие сенсоры + /* + if (i > 3) + { + double PercentFlicker = 100 * (MaxADCValue - MinADCValue) / (MaxADCValue + MinADCValue); + PercentFlickerSum += PercentFlicker; + } + */ + } + double analogReadAv = (MaxADCValue + MinADCValue) / 2; + // double analogReadAv = analogReadSum / samples; + + double area1 = 0; + double area2 = 0; + + for (int i = 0; i < samples; i++) + { + if (vReal[i] > analogReadAv) + { + area1 += (vReal[i] - analogReadAv)* sampling_period_us; + area2 += analogReadAv * sampling_period_us; + } + else + { + area2 += vReal[i] * sampling_period_us; + } + } + + FlickerIndex = area1 / (area1 + area2); + + // double PercentFlickerAv = PercentFlickerSum / (samples - 4); + + PercentFlickerMax = 100 * (MaxADCValue - MinADCValue) / (MaxADCValue + MinADCValue); + + // ADCRange = MaxADCValue - MinADCValue; + + /* Print the results of the sampling according to time */ + // Serial.println("Data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */ + // Serial.println("Weighed data:"); + PrintVector(vReal, samples, SCL_TIME); + FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */ + // Serial.println("Computed Real values:"); + PrintVector(vReal, samples, SCL_INDEX); + // Serial.println("Computed Imaginary values:"); + PrintVector(vImag, samples, SCL_INDEX); + FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */ + // Serial.println("Computed magnitudes:"); + PrintVector(vReal, (samples >> 1), SCL_FREQUENCY); + double x = FFT.MajorPeak(vReal, samples, samplingFrequency); + // Serial.print("dominant frequency = "); + // Serial.println(x, 6); // Print out what frequency is the most dominant. + // while(1); /* Run Once */ + double frequency = x; + return frequency; +} + +void PrintVector(double *vData, uint16_t bufferSize, uint8_t scaleType) +{ + for (uint16_t i = 0; i < bufferSize; i++) + { + double abscissa; + /* Print abscissa value */ + switch (scaleType) + { + case SCL_INDEX: + abscissa = (i * 1.0); + break; + case SCL_TIME: + abscissa = ((i * 1.0) / samplingFrequency); + break; + case SCL_FREQUENCY: + abscissa = ((i * 1.0 * samplingFrequency) / samples); + break; + } + // Serial.print(abscissa, 6); + if (scaleType == SCL_FREQUENCY) + ; + // Serial.print("Hz"); + // Serial.print(" "); + // Serial.println(vData[i], 4); + } + // Serial.println(); +} \ No newline at end of file diff --git a/src/modules/sensors/FreqMeter/modinfo.json b/src/modules/sensors/FreqMeter/modinfo.json new file mode 100644 index 00000000..c581802c --- /dev/null +++ b/src/modules/sensors/FreqMeter/modinfo.json @@ -0,0 +1,91 @@ +{ + "menuSection": "Сенсоры", + "configItem": [ + { + "name": "Частотомер на ADC, Частота", + "type": "Reading", + "subtype": "FreqMeterF", + "id": "freq", + "widget": "anydataHtz", + "page": "Частотомер", + "descr": "Частота", + "plus": 0, + "multiply": 1, + "round": 1, + "pin-Esp32": 33, + "samples": 512, + "samplingFrequency": 5000, + "int": 5 + }, + { + "name": "Частотомер на ADC, Процент Пульсации", + "type": "Reading", + "subtype": "FreqMeterPcFl", + "id": "pctFlicker", + "widget": "anydataPct", + "page": "Частотомер", + "descr": "Процент Пульсации", + "plus": 0, + "multiply": 1, + "round": 1, + "pin-Esp32": 33, + "samples": 512, + "samplingFrequency": 5000, + "int": 5 + }, + { + "name": "Частотомер на ADC, Индекс Пульсации", + "type": "Reading", + "subtype": "FreqMeterFlIn", + "id": "flickerIndex", + "widget": "anydataDef", + "page": "Частотомер", + "descr": "Индекс Пульсации", + "plus": 0, + "multiply": 1, + "round": 10, + "pin-Esp32": 33, + "samples": 512, + "samplingFrequency": 5000, + "int": 5 + } + ], + "about": { + "authorName": "Alex K", + "authorContact": "https://t.me/cmche", + "authorGit": "https://github.com/CHE77/FrequencyMeter_IotManager", + "exampleURL": "https://iotmanager.org/wiki", + "specialThanks": "", + "moduleName": "FreqMeter", + "moduleVersion": "1.0 - Процент Пульсации и Индекс Пульсации определяется без перевода в Люксы, то есть через попугаев ADC", + "usedRam": { + "esp32_4mb": 15, + "esp8266_4mb": 15 + }, + "subTypes": [ + "FreqMeterF", + "FreqMeterPcFl", + "FreqMeterFlIn" + ], + "title": "Измерение пульсаций света", + "moduleDesc": "Позволяет получить частоту на аналогового GPIO, а также Процент Пульсации и Индекс Пульсации для источников света", + "propInfo": { + "plus": "поправочный коэффиент +c", + "multiply": "поправочный коэффиент k*", + "round": "округление", + "samples": "Количество замеров за опрос: 64, 128, 256, 512, 1024", + "samplingFrequency": "Частота замеров. Должна быть в несколько раз больше частоты измеряемого сигнала.", + "pin-Esp32": "Esp32: Аналоговый GPIO номер, к которому подключен датчик:32, 33, 34, 35, 36, 39. Для Esp8266 указывать не надо.", + "int": "Количество секунд между опросами датчика." + } + }, + "defActive": true, + "usedLibs": { + "esp32_4mb": [ + "kosme/arduinoFFT@^1.5.6" + ], + "esp8266_4mb": [ + "kosme/arduinoFFT@^1.5.6" + ] + } +} \ No newline at end of file