From b168f004169689146b03675b7a562b244a9420a5 Mon Sep 17 00:00:00 2001 From: RoSchmi Date: Sun, 7 Nov 2021 18:02:40 +0100 Subject: [PATCH] Added support for INMP441 --- lib/RoSchmi/SensorData/AnalogSensorMgr.cpp | 6 +- lib/RoSchmi/SensorData/SoundSwitcher.cpp | 137 +++++----- lib/RoSchmi/SensorData/SoundSwitcher.cpp_ | 283 +++++++++++++++++++++ lib/RoSchmi/SensorData/SoundSwitcher.h | 74 ++++-- lib/RoSchmi/SensorData/SoundSwitcher.h_ | 113 ++++++++ src/main.cpp | 18 +- 6 files changed, 530 insertions(+), 101 deletions(-) create mode 100644 lib/RoSchmi/SensorData/SoundSwitcher.cpp_ create mode 100644 lib/RoSchmi/SensorData/SoundSwitcher.h_ diff --git a/lib/RoSchmi/SensorData/AnalogSensorMgr.cpp b/lib/RoSchmi/SensorData/AnalogSensorMgr.cpp index 22e8ec3..35c71bc 100644 --- a/lib/RoSchmi/SensorData/AnalogSensorMgr.cpp +++ b/lib/RoSchmi/SensorData/AnalogSensorMgr.cpp @@ -48,9 +48,7 @@ void AnalogSensorMgr::SetReadTimeAndValues(int pSensorIndex, DateTime now, float AnalogSensor AnalogSensorMgr::GetSensorDates(int pSensorIndex) -{ - - return readValues[pSensorIndex]; - +{ + return readValues[pSensorIndex]; } diff --git a/lib/RoSchmi/SensorData/SoundSwitcher.cpp b/lib/RoSchmi/SensorData/SoundSwitcher.cpp index 4d1f73a..4f0bbb9 100644 --- a/lib/RoSchmi/SensorData/SoundSwitcher.cpp +++ b/lib/RoSchmi/SensorData/SoundSwitcher.cpp @@ -1,14 +1,11 @@ -#include "SoundSwitcher.h" - - - -//DateTime lastSwitchTime = DateTime(); -//TimeSpan switchInterval = TimeSpan(60); - +// SoundSwitcher +// How it works: See file SoundSwitcher.h +#include "SoundSwitcher.h" static const i2s_port_t i2s_num = I2S_NUM_0; // i2s port number -static const i2s_config_t i2s_config = { + +static const i2s_config_t i2s_config_SPH0645LM4H = { .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), .sample_rate = 22050, .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, @@ -19,6 +16,20 @@ static const i2s_config_t i2s_config = { .dma_buf_len = 64, .use_apll = false }; +// https://esp32.com/viewtopic.php?t=15185 +i2s_config_t i2s_config_INMP441 = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = 11025, // or 44100 if you like + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, // Ground the L/R pin on the INMP441. + .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, + .dma_buf_count = 8, //changed from .dma_buf_count = 4, + .dma_buf_len = 64, // changed from .dma_buf_len = ESP_NOW_MAX_DATA_LEN * 4, + .use_apll = false, + .tx_desc_auto_clear = false, + .fixed_mclk = 0, +}; // For Adafruit Huzzah Esp32 /* @@ -40,52 +51,51 @@ static const i2s_pin_config_t pin_config = { }; */ -SoundSwitcher::SoundSwitcher(i2s_pin_config_t config) +SoundSwitcher::SoundSwitcher(i2s_pin_config_t config, MicType micType) { - pin_config = config; -} - -void SoundSwitcher::begin(uint16_t switchThreshold, Hysteresis pHysteresis, uint32_t updateIntervalMs, uint32_t delayTimeMs) -{ - i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver - REG_SET_BIT( I2S_TIMING_REG(i2s_num),BIT(9)); /* #include "soc/i2s_reg.h" I2S_NUM -> 0 or 1*/ - REG_SET_BIT( I2S_CONF_REG(i2s_num), I2S_RX_MSB_SHIFT); - i2s_set_pin(i2s_num, &pin_config); - - lastFeedTimeMillis = millis(); - lastBorderNarrowTimeMillis = millis(); - feedIntervalMs = updateIntervalMs; - threshold = (float)switchThreshold; - hysteresis = pHysteresis; - readDelayTimeMs = delayTimeMs; - /* - if (pHysteresis == Hysteresis::Percent_20) + pin_config = config; + if (micType == MicType::SPH0645LM4H) { - hysteresis = 20; + // https://www.esp32.com/viewtopic.php?t=4997 + //install and start i2s driver + if (ESP_OK != i2s_driver_install(i2s_num, &i2s_config_SPH0645LM4H, 0, NULL)) + { + Serial.println("SPH0645LM4H_i2s_driver_install: error"); + } + REG_SET_BIT( I2S_TIMING_REG(i2s_num),BIT(9)); /* #include "soc/i2s_reg.h" I2S_NUM -> 0 or 1*/ + REG_SET_BIT( I2S_CONF_REG(i2s_num), I2S_RX_MSB_SHIFT); } else { - if (pHysteresis == Hysteresis::Percent_10) + if (micType == MicType::INMP441) { - hysteresis = 10; + //https://esp32.com/viewtopic.php?t=15185 + //install and start i2s driver + if (ESP_OK != i2s_driver_install(i2s_num, &i2s_config_SPH0645LM4H, 0, NULL)) + { + Serial.println("INMP441_i2s_driver_install: error"); + } } else { - if (pHysteresis == Hysteresis::Percent_5) - { - hysteresis = 5; - } - else - { - if (pHysteresis == Hysteresis::Percent_2) - { - hysteresis = 2; - } - } + Serial.println("Not allowed microphone"); } } - */ - + if (ESP_OK != i2s_set_pin(I2S_NUM_0, &pin_config)) + { + Serial.println("i2s_set_pin: error"); + } + +} + +void SoundSwitcher::begin(uint16_t switchThreshold, Hysteresis pHysteresis, uint32_t updateIntervalMs, uint32_t delayTimeMs) +{ + lastFeedTimeMillis = millis(); + lastBorderNarrowTimeMillis = millis(); + feedIntervalMs = updateIntervalMs; + threshold = (float)switchThreshold; + hysteresis = pHysteresis; + readDelayTimeMs = delayTimeMs; } bool SoundSwitcher::hasToggled() @@ -183,14 +193,13 @@ FeedResponse SoundSwitcher::feed() feedResponse.avValue = average; feedResponse.lowAvValue = lowAvBorder; feedResponse.highAvValue = highAvBorder; - } } } hasSwitched = false; return feedResponse; - } + AverageValue SoundSwitcher::getAverage() { AverageValue averageValue; @@ -199,34 +208,17 @@ AverageValue SoundSwitcher::getAverage() return averageValue; } -/* -bool SoundSwitcher::hasToggled(DateTime actUtcTime) -{ - if (isActive) - { - if (actUtcTime.operator>=(lastSwitchTime.operator+(switchInterval))) - { - lastSwitchTime = actUtcTime; - state = !state; - return true; - } - else - { - return false; - } - } - else - { - return false; - } -} -*/ - bool SoundSwitcher::GetState() { return state; } +void SoundSwitcher::SetCalibrationParams(float pCalibOffset, float pCalibFactor) +{ + calibOffset = pCalibOffset; + calibFactor = pCalibFactor; +} + void SoundSwitcher::SetInactive() { isActive = false; @@ -277,7 +269,10 @@ float SoundSwitcher::getSoundFromMicro() minsample = _min(minsample, cleanBuf[i]); maxsample = _max(maxsample, cleanBuf[i]); } - Serial.print("Volume: "); - Serial.println(maxsample - minsample); - return maxsample - minsample; + + float retValue = (maxsample - minsample) * calibFactor + calibOffset; + retValue = retValue <= 0.0 ? 0.0 : retValue; + //Serial.print("Volume: "); + //Serial.println(retValue); + return retValue; } \ No newline at end of file diff --git a/lib/RoSchmi/SensorData/SoundSwitcher.cpp_ b/lib/RoSchmi/SensorData/SoundSwitcher.cpp_ new file mode 100644 index 0000000..4d1f73a --- /dev/null +++ b/lib/RoSchmi/SensorData/SoundSwitcher.cpp_ @@ -0,0 +1,283 @@ +#include "SoundSwitcher.h" + + + +//DateTime lastSwitchTime = DateTime(); +//TimeSpan switchInterval = TimeSpan(60); + + + +static const i2s_port_t i2s_num = I2S_NUM_0; // i2s port number +static const i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = 22050, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), + .intr_alloc_flags = 0, // default interrupt priority + .dma_buf_count = 8, + .dma_buf_len = 64, + .use_apll = false +}; + +// For Adafruit Huzzah Esp32 +/* +static const i2s_pin_config_t pin_config = { + .bck_io_num = 14, // BCKL + .ws_io_num = 15, // LRCL + .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) + .data_in_num = 32 // DOUT +}; +*/ + +// For some other Esp32 board +/* +static const i2s_pin_config_t pin_config = { + .bck_io_num = 26, // BCKL + .ws_io_num = 25, // LRCL + .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) + .data_in_num = 22 // DOUT +}; +*/ + +SoundSwitcher::SoundSwitcher(i2s_pin_config_t config) +{ + pin_config = config; +} + +void SoundSwitcher::begin(uint16_t switchThreshold, Hysteresis pHysteresis, uint32_t updateIntervalMs, uint32_t delayTimeMs) +{ + i2s_driver_install(i2s_num, &i2s_config, 0, NULL); //install and start i2s driver + REG_SET_BIT( I2S_TIMING_REG(i2s_num),BIT(9)); /* #include "soc/i2s_reg.h" I2S_NUM -> 0 or 1*/ + REG_SET_BIT( I2S_CONF_REG(i2s_num), I2S_RX_MSB_SHIFT); + i2s_set_pin(i2s_num, &pin_config); + + lastFeedTimeMillis = millis(); + lastBorderNarrowTimeMillis = millis(); + feedIntervalMs = updateIntervalMs; + threshold = (float)switchThreshold; + hysteresis = pHysteresis; + readDelayTimeMs = delayTimeMs; + /* + if (pHysteresis == Hysteresis::Percent_20) + { + hysteresis = 20; + } + else + { + if (pHysteresis == Hysteresis::Percent_10) + { + hysteresis = 10; + } + else + { + if (pHysteresis == Hysteresis::Percent_5) + { + hysteresis = 5; + } + else + { + if (pHysteresis == Hysteresis::Percent_2) + { + hysteresis = 2; + } + } + } + } + */ + +} + +bool SoundSwitcher::hasToggled() +{ + return hasSwitched; +} + +FeedResponse SoundSwitcher::feed() +{ + FeedResponse feedResponse; + feedResponse.isValid = false; + feedResponse.hasToggled = false; + feedResponse.analogToSend = false; + feedResponse.state = false; + feedResponse.avValue = 0.0; + feedResponse.lowAvValue = 0.0; + feedResponse.highAvValue = 0.0; + + if (isActive) + { + if (millis() - lastFeedTimeMillis > feedIntervalMs) + { + lastFeedTimeMillis = millis(); + soundVolume = getSoundFromMicro(); + if (bufferIsFilled) + { + // limit the effect of short very high sound levels + volBuffer[bufIdx] = soundVolume < (average * 4) ? soundVolume : average * 4; + } + else + { + volBuffer[bufIdx] = soundVolume; + } + + bufIdx++; + if (bufIdx >= buflen) + { + bufIdx = 0; + bufferIsFilled = true; + } + if (bufferIsFilled) + { + float mean = 0.0; + for (int i = 0; i < buflen; i++) + { + mean += volBuffer[i]; + } + average = mean / buflen; + if (state == false) + { + if (average > threshold) + { + hasSwitched = true; + lastSwitchTimeMillis = millis(); + analogSendIsPending = true; + state = true; + } + + } + else // state == true + { + if (average < threshold - threshold / 100 * hysteresis) + { + hasSwitched = true; + lastSwitchTimeMillis = millis(); + analogSendIsPending = true; + state = false; + } + + } + lowAvBorder = average < lowAvBorder ? average : lowAvBorder; + highAvBorder = average > highAvBorder ? average : highAvBorder; + + // every 30 minutes narrow range between low and high boarder + if (millis()- lastBorderNarrowTimeMillis > (30 * 60 * 1000)) + { + lastBorderNarrowTimeMillis = millis(); + float spanPercent = (highAvBorder - lowAvBorder) / 100; + lowAvBorder += spanPercent; + highAvBorder -= spanPercent; + } + feedResponse.isValid = true; + feedResponse.hasToggled = hasSwitched; + // RoSchmi to do + if (analogSendIsPending) + { + if (millis() - lastSwitchTimeMillis >= readDelayTimeMs) + { + feedResponse.analogToSend = true; + analogSendIsPending = false; + } + } + + feedResponse.state = state; + feedResponse.avValue = average; + feedResponse.lowAvValue = lowAvBorder; + feedResponse.highAvValue = highAvBorder; + + } + } + } + hasSwitched = false; + return feedResponse; + +} +AverageValue SoundSwitcher::getAverage() +{ + AverageValue averageValue; + averageValue.isValid = bufferIsFilled ? true : false; + averageValue.value = bufferIsFilled ? average : 0.0; + return averageValue; +} + +/* +bool SoundSwitcher::hasToggled(DateTime actUtcTime) +{ + if (isActive) + { + if (actUtcTime.operator>=(lastSwitchTime.operator+(switchInterval))) + { + lastSwitchTime = actUtcTime; + state = !state; + return true; + } + else + { + return false; + } + } + else + { + return false; + } +} +*/ + +bool SoundSwitcher::GetState() +{ + return state; +} + +void SoundSwitcher::SetInactive() +{ + isActive = false; +} + +void SoundSwitcher::SetActive() +{ + isActive = true; +} + +float SoundSwitcher::getSoundFromMicro() +{ + int32_t audio_buf[BUFLEN]; + int bytes_read = i2s_read_bytes(i2s_num, audio_buf, sizeof(audio_buf), portMAX_DELAY); + int32_t cleanBuf[BUFLEN / 2] {0}; + int cleanBufIdx = 0; + for (int i = 0; i < BUFLEN; i++) + { + if (audio_buf[i] != 0) // Exclude values from other channel + { + cleanBuf[cleanBufIdx] = audio_buf[i] >> 14; + cleanBufIdx++; + } + } + float meanval = 0; + int volCount = 0; + for (int i=0; i < BUFLEN / 2; i++) + { + if (cleanBuf[i] != 0) + { + meanval += cleanBuf[i]; + volCount++; + } + } + meanval /= volCount; + + // subtract it from all sapmles to get a 'normalized' output + for (int i=0; i< volCount; i++) + { + cleanBuf[i] -= meanval; + } + + // find the 'peak to peak' max + float maxsample, minsample; + minsample = 100000; + maxsample = -100000; + for (int i=0; i -#include #include #include "soc/i2s_reg.h" #ifndef _SOUND_SWITCHER_H_ #define _SOUND_SWITCHER_H_ - - typedef struct { bool isValid = false; @@ -37,18 +68,25 @@ typedef enum } Hysteresis; +typedef enum +{ + INMP441 = 0, + SPH0645LM4H = 1 +} +MicType; class SoundSwitcher { public: - SoundSwitcher(i2s_pin_config_t config); + SoundSwitcher(i2s_pin_config_t config, MicType pMicType); void begin(uint16_t switchThreshold, Hysteresis hysteresis, uint32_t updateIntervalMs, uint32_t delayTimeMs); FeedResponse feed(); AverageValue getAverage(); void SetInactive(); void SetActive(); + void SetCalibrationParams(float pCalibOffset = 0.0, float pCalibFactor = 1.0); bool hasToggled(); bool GetState(); @@ -81,33 +119,29 @@ class SoundSwitcher float average = 0; float lowAvBorder = 10000; float highAvBorder = 0; + float calibOffset = 0.0; + float calibFactor = 1.0; #define BUFLEN 256 -//static const i2s_port_t i2s_num; = I2S_NUM_0; // i2s port number -/* -static const i2s_config_t i2s_config = { - .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), - .sample_rate = 22050, - .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, - .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, - .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), - .intr_alloc_flags = 0, // default interrupt priority - .dma_buf_count = 8, - .dma_buf_len = 64, - .use_apll = false -}; -*/ - +// Examples for possible configurations // For Adafruit Huzzah Esp32 /* -static const i2s_pin_config_t pin_config = { +static const i2s_pin_config_t pin_config_Adafruit_Huzzah_Esp32 = { .bck_io_num = 14, // BCKL .ws_io_num = 15, // LRCL .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) .data_in_num = 32 // DOUT }; +// For some other Esp32 board +static const i2s_pin_config_t pin_config_Esp32_dev = { + .bck_io_num = 26, // BCKL + .ws_io_num = 25, // LRCL + .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) + .data_in_num = 22 // DOUT +}; */ + }; #endif // _SOUND_SWITCHER_H_ \ No newline at end of file diff --git a/lib/RoSchmi/SensorData/SoundSwitcher.h_ b/lib/RoSchmi/SensorData/SoundSwitcher.h_ new file mode 100644 index 0000000..ead884e --- /dev/null +++ b/lib/RoSchmi/SensorData/SoundSwitcher.h_ @@ -0,0 +1,113 @@ +#include +#include +#include +#include "soc/i2s_reg.h" + +#ifndef _SOUND_SWITCHER_H_ +#define _SOUND_SWITCHER_H_ + + + +typedef struct + { + bool isValid = false; + float value = 0.0; + } + AverageValue; + + typedef struct + { + bool isValid = false; + bool hasToggled = false; + bool analogToSend = false; + bool state = false; + float avValue = 0.0; + float lowAvValue = 100000; + float highAvValue = -100000; + } + FeedResponse; + +typedef enum +{ + Percent_0 = 0, + Percent_2 = 2, + Percent_5 = 5, + Percent_10 = 10, + Percent_20 = 20 +} +Hysteresis; + + +class SoundSwitcher +{ + +public: + SoundSwitcher(i2s_pin_config_t config); + + void begin(uint16_t switchThreshold, Hysteresis hysteresis, uint32_t updateIntervalMs, uint32_t delayTimeMs); + FeedResponse feed(); + AverageValue getAverage(); + void SetInactive(); + void SetActive(); + bool hasToggled(); + bool GetState(); + +private: + + i2s_pin_config_t pin_config = { + .bck_io_num = 2, // BCKL + .ws_io_num = 2, // LRCL + .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) + .data_in_num = 2 // DOUT +}; + + uint32_t lastFeedTimeMillis = millis(); + uint32_t lastSwitchTimeMillis = millis(); + uint32_t readDelayTimeMs = 0; + uint32_t lastBorderNarrowTimeMillis = millis(); + size_t feedIntervalMs = 100; + bool hasSwitched = false; + bool analogSendIsPending = false; + float getSoundFromMicro(); + float soundVolume; + float threshold; + int hysteresis; + bool state = false; + bool isActive = false; + bool bufferIsFilled = false; + uint32_t bufIdx = 0; + const static int buflen = 10; + float volBuffer[buflen] {0.0}; + float average = 0; + float lowAvBorder = 10000; + float highAvBorder = 0; + + #define BUFLEN 256 + +//static const i2s_port_t i2s_num; = I2S_NUM_0; // i2s port number +/* +static const i2s_config_t i2s_config = { + .mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX), + .sample_rate = 22050, + .bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT, + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, + .communication_format = (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB), + .intr_alloc_flags = 0, // default interrupt priority + .dma_buf_count = 8, + .dma_buf_len = 64, + .use_apll = false +}; +*/ + +// For Adafruit Huzzah Esp32 +/* +static const i2s_pin_config_t pin_config = { + .bck_io_num = 14, // BCKL + .ws_io_num = 15, // LRCL + .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) + .data_in_num = 32 // DOUT +}; +*/ +}; + +#endif // _SOUND_SWITCHER_H_ \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 1548fa9..1a91060 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,9 @@ -// Program 'Esp32_WiFiManager_HeatingSurvey' Version 1.0.2 +// Program 'Esp32_WiFiManager_HeatingSurvey' Version 1.0.3 // Copyright: RoSchmi 2021, License: Apache 2.0 // This App for Esp32 monitors the activity of the burner of an oil-heating // (or any other noisy thing) by measuring the sound of e.g. the heating burner -// using an Adafruit I2S microphone +// using an I2S microphone (Adafruit SPH0645 or INMP441) // The on/off states are transferred to the Cloud (Azure Storage Tables) // via WLAN and internet and can be visulized graphically through the iPhone- or Android-App // Charts4Azure. @@ -164,14 +164,14 @@ OnOffDataContainerWio onOffDataContainer; OnOffSwitcherWio onOffSwitcherWio; -// For Adafruit Huzzah Esp32 +// Possible configuration for Adafruit Huzzah Esp32 static const i2s_pin_config_t pin_config_Adafruit_Huzzah_Esp32 = { .bck_io_num = 14, // BCKL .ws_io_num = 15, // LRCL .data_out_num = I2S_PIN_NO_CHANGE, // not used (only for speakers) .data_in_num = 32 // DOUT }; -// For some other Esp32 board +// Possible configuration for some Esp32 DevKitC V4 static const i2s_pin_config_t pin_config_Esp32_dev = { .bck_io_num = 26, // BCKL .ws_io_num = 25, // LRCL @@ -179,8 +179,12 @@ static const i2s_pin_config_t pin_config_Esp32_dev = { .data_in_num = 22 // DOUT }; -SoundSwitcher soundSwitcher(pin_config_Esp32_dev); -//SoundSwitcher soundSwitcher(pin_config_Adafruit_Huzzah_Esp32); +MicType usedMicType = MicType::SPH0645LM4H; +//MicType usedMicType = MicType::INMP441; + +SoundSwitcher soundSwitcher(pin_config_Esp32_dev, usedMicType); +//SoundSwitcher soundSwitcher(pin_config_Adafruit_Huzzah_Esp32, usedMicType); + FeedResponse feedResult; @@ -1383,6 +1387,7 @@ void setup() } soundSwitcher.begin(atoi((char *)sSwiThresholdStr), Hysteresis::Percent_10, soundSwitcherUpdateInterval, soundSwitcherReadDelayTime); + soundSwitcher.SetCalibrationParams(-20.0); // optional soundSwitcher.SetActive(); //************************************************************** onOffDataContainer.begin(DateTime(), OnOffTableName_1, OnOffTableName_2, OnOffTableName_3, OnOffTableName_4); @@ -1949,6 +1954,7 @@ float ReadAnalogSensor(int pSensorIndex) analogSensorMgr.SetReadTimeAndValues(pSensorIndex, dateTimeUTCNow, soundValues[1], soundValues[0], MAGIC_NUMBER_INVALID); //theRead = feedResult.highAvValue / 10; + // Function not used in this App, can be used to display another sensor theRead = MAGIC_NUMBER_INVALID;