diff --git a/FeatureRequest.md b/FeatureRequest.md index 9a69ae69..5eddc5dc 100644 --- a/FeatureRequest.md +++ b/FeatureRequest.md @@ -11,6 +11,12 @@ ____ +#### #11 MQTT - configurable payload + +* https://github.com/jomjol/AI-on-the-edge-device/issues/344 + + + #### #10 Improve and bug fix logging of images * https://github.com/jomjol/AI-on-the-edge-device/issues/307 diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 10669682..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 jomjol - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index 3b4531ce..95b8123a 100644 --- a/README.md +++ b/README.md @@ -47,9 +47,32 @@ In other cases you can contact the developer via email: copyRmtHalfBlock(); + RMT.int_clr.val |= 1 << ( 24 + channel ); + } else if ( RMT.int_st.val & ( 1 << (3 * channel ) ) ) { // tx_end + if ( self ) + xSemaphoreGiveFromISR( self->_finishedFlag, nullptr ); + RMT.int_clr.val |= 1 << ( 3 * channel ); + } + } +} + +void IRAM_ATTR SmartLed::copyRmtHalfBlock() { + int offset = detail::MAX_PULSES * _halfIdx; + _halfIdx = !_halfIdx; + int len = 3 - _componentPosition + 3 * ( _count - 1 ); + len = std::min( len, detail::MAX_PULSES / 8 ); + + if ( !len ) { + for ( int i = 0; i < detail::MAX_PULSES; i++) { + RMTMEM.chan[ _channel].data32[i + offset ].val = 0; + } + } + + int i; + for ( i = 0; i != len && _pixelPosition != _count; i++ ) { + uint8_t val = _buffer[ _pixelPosition ].getGrb( _componentPosition ); + for ( int j = 0; j != 8; j++, val <<= 1 ) { + int bit = val >> 7; + int idx = i * 8 + offset + j; + RMTMEM.chan[ _channel ].data32[ idx ].val = _bitToRmt[ bit & 0x01 ].value; + } + if ( _pixelPosition == _count - 1 && _componentPosition == 2 ) { + RMTMEM.chan[ _channel ].data32[ i * 8 + offset + 7 ].duration1 = + _timing.TRS / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + } + + _componentPosition++; + if ( _componentPosition == 3 ) { + _componentPosition = 0; + _pixelPosition++; + } + } + + for ( i *= 8; i != detail::MAX_PULSES; i++ ) { + RMTMEM.chan[ _channel ].data32[ i + offset ].val = 0; + } +} diff --git a/code/SmartLeds.h b/code/SmartLeds.h new file mode 100644 index 00000000..824eb337 --- /dev/null +++ b/code/SmartLeds.h @@ -0,0 +1,530 @@ +#pragma once + +/* + * A C++ driver for the WS2812 LEDs using the RMT peripheral on the ESP32. + * + * Jan "yaqwsx" Mrázek + * + * Based on the work by Martin F. Falatic - https://github.com/FozzTexx/ws2812-demo + */ + +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#if defined ( ARDUINO ) + extern "C" { // ...someone forgot to put in the includes... + #include "esp32-hal.h" + #include "esp_intr_alloc.h" + #include "esp_ipc.h" + #include "driver/gpio.h" + #include "driver/periph_ctrl.h" + #include "freertos/semphr.h" + #include "soc/rmt_struct.h" + #include + #include "esp_idf_version.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 ) + #include "soc/dport_reg.h" +#endif + } +#elif defined ( ESP_PLATFORM ) + extern "C" { // ...someone forgot to put in the includes... + #include + #include + #include + #include + #include + #include + #include + #include + #include + } + #include +#endif + +#include "Color.h" + +namespace detail { + +struct TimingParams { + uint32_t T0H; + uint32_t T1H; + uint32_t T0L; + uint32_t T1L; + uint32_t TRS; +}; + +union RmtPulsePair { + struct { + int duration0:15; + int level0:1; + int duration1:15; + int level1:1; + }; + uint32_t value; +}; + +static const int DIVIDER = 4; // 8 still seems to work, but timings become marginal +static const int MAX_PULSES = 32; // A channel has a 64 "pulse" buffer - we use half per pass +static const double RMT_DURATION_NS = 12.5; // minimum time of a single RMT duration based on clock ns + +} // namespace detail + +using LedType = detail::TimingParams; + +static const LedType LED_WS2812 = { 350, 700, 800, 600, 50000 }; +static const LedType LED_WS2812B = { 400, 850, 850, 400, 50100 }; +static const LedType LED_SK6812 = { 300, 600, 900, 600, 80000 }; +static const LedType LED_WS2813 = { 350, 800, 350, 350, 300000 }; + +enum BufferType { SingleBuffer = 0, DoubleBuffer }; + +enum IsrCore { CoreFirst = 0, CoreSecond = 1, CoreCurrent = 2}; + +class SmartLed { +public: + // The RMT interrupt must not run on the same core as WiFi interrupts, otherwise SmartLeds + // can't fill the RMT buffer fast enough, resulting in rendering artifacts. + // Usually, that means you have to set isrCore == CoreSecond. + // + // If you use anything other than CoreCurrent, the FreeRTOS scheduler MUST be already running, + // so you can't use it if you define SmartLed as global variable. + SmartLed( const LedType& type, int count, int pin, int channel = 0, BufferType doubleBuffer = SingleBuffer, IsrCore isrCore = CoreCurrent) + : _timing( type ), + _channel( channel ), + _count( count ), + _firstBuffer( new Rgb[ count ] ), + _secondBuffer( doubleBuffer ? new Rgb[ count ] : nullptr ), + _finishedFlag( xSemaphoreCreateBinary() ) + { + assert( channel >= 0 && channel < 8 ); + assert( ledForChannel( channel ) == nullptr ); + + xSemaphoreGive( _finishedFlag ); + + DPORT_SET_PERI_REG_MASK( DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN ); + DPORT_CLEAR_PERI_REG_MASK( DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST ); + + PIN_FUNC_SELECT( GPIO_PIN_MUX_REG[ pin ], 2 ); + gpio_set_direction( static_cast< gpio_num_t >( pin ), GPIO_MODE_OUTPUT ); + gpio_matrix_out( static_cast< gpio_num_t >( pin ), RMT_SIG_OUT0_IDX + _channel, 0, 0 ); + initChannel( _channel ); + + RMT.tx_lim_ch[ _channel ].limit = detail::MAX_PULSES; + RMT.int_ena.val |= 1 << ( 24 + _channel ); + RMT.int_ena.val |= 1 << ( 3 * _channel ); + + _bitToRmt[ 0 ].level0 = 1; + _bitToRmt[ 0 ].level1 = 0; + _bitToRmt[ 0 ].duration0 = _timing.T0H / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + _bitToRmt[ 0 ].duration1 = _timing.T0L / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + + _bitToRmt[ 1 ].level0 = 1; + _bitToRmt[ 1 ].level1 = 0; + _bitToRmt[ 1 ].duration0 = _timing.T1H / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + _bitToRmt[ 1 ].duration1 = _timing.T1L / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + + if ( !anyAlive() ) { + _interruptCore = isrCore; + if(isrCore != CoreCurrent) { + ESP_ERROR_CHECK(esp_ipc_call_blocking(isrCore, registerInterrupt, NULL)); + } else { + registerInterrupt(NULL); + } + } + + ledForChannel( channel ) = this; + } + + ~SmartLed() { + ledForChannel( _channel ) = nullptr; + if ( !anyAlive() ) { + if(_interruptCore != CoreCurrent) { + ESP_ERROR_CHECK(esp_ipc_call_blocking(_interruptCore, unregisterInterrupt, NULL)); + } else { + unregisterInterrupt(NULL); + } + } + vSemaphoreDelete( _finishedFlag ); + } + + Rgb& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const Rgb& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + bool wait( TickType_t timeout = portMAX_DELAY ) { + if( xSemaphoreTake( _finishedFlag, timeout ) == pdTRUE ) { + xSemaphoreGive( _finishedFlag ); + return true; + } + return false; + } + + int size() const { + return _count; + } + + Rgb *begin() { return _firstBuffer.get(); } + const Rgb *begin() const { return _firstBuffer.get(); } + const Rgb *cbegin() const { return _firstBuffer.get(); } + + Rgb *end() { return _firstBuffer.get() + _count; } + const Rgb *end() const { return _firstBuffer.get() + _count; } + const Rgb *cend() const { return _firstBuffer.get() + _count; } + +private: + static intr_handle_t _interruptHandle; + static IsrCore _interruptCore; + + static void initChannel( int channel ) { + RMT.apb_conf.fifo_mask = 1; //enable memory access, instead of FIFO mode. + RMT.apb_conf.mem_tx_wrap_en = 1; //wrap around when hitting end of buffer + RMT.conf_ch[ channel ].conf0.div_cnt = detail::DIVIDER; + RMT.conf_ch[ channel ].conf0.mem_size = 1; + RMT.conf_ch[ channel ].conf0.carrier_en = 0; + RMT.conf_ch[ channel ].conf0.carrier_out_lv = 1; + RMT.conf_ch[ channel ].conf0.mem_pd = 0; + + RMT.conf_ch[ channel ].conf1.rx_en = 0; + RMT.conf_ch[ channel ].conf1.mem_owner = 0; + RMT.conf_ch[ channel ].conf1.tx_conti_mode = 0; //loop back mode. + RMT.conf_ch[ channel ].conf1.ref_always_on = 1; // use apb clock: 80M + RMT.conf_ch[ channel ].conf1.idle_out_en = 1; + RMT.conf_ch[ channel ].conf1.idle_out_lv = 0; + } + + static void registerInterrupt(void *) { + ESP_ERROR_CHECK(esp_intr_alloc( ETS_RMT_INTR_SOURCE, 0, interruptHandler, nullptr, &_interruptHandle)); + } + + static void unregisterInterrupt(void*) { + esp_intr_free( _interruptHandle ); + } + + static SmartLed*& IRAM_ATTR ledForChannel( int channel ); + static void IRAM_ATTR interruptHandler( void* ); + + void IRAM_ATTR copyRmtHalfBlock(); + + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + // Invalid use of the library + if( xSemaphoreTake( _finishedFlag, 0 ) != pdTRUE ) + abort(); + + _pixelPosition = _componentPosition = _halfIdx = 0; + copyRmtHalfBlock(); + if ( _pixelPosition < _count ) + copyRmtHalfBlock(); + + RMT.conf_ch[ _channel ].conf1.mem_rd_rst = 1; + RMT.conf_ch[ _channel ].conf1.tx_start = 1; + } + + static bool anyAlive() { + for ( int i = 0; i != 8; i++ ) + if ( ledForChannel( i ) != nullptr ) return true; + return false; + } + + const LedType& _timing; + int _channel; + detail::RmtPulsePair _bitToRmt[ 2 ]; + int _count; + std::unique_ptr< Rgb[] > _firstBuffer; + std::unique_ptr< Rgb[] > _secondBuffer; + Rgb *_buffer; + + xSemaphoreHandle _finishedFlag; + + int _pixelPosition; + int _componentPosition; + int _halfIdx; +}; + +class Apa102 { +public: + struct ApaRgb { + ApaRgb( uint8_t r = 0, uint8_t g = 0, uint32_t b = 0, uint32_t v = 0xFF ) + : v( 0xE0 | v ), b( b ), g( g ), r( r ) + {} + + ApaRgb& operator=( const Rgb& o ) { + r = o.r; + g = o.g; + b = o.b; + return *this; + } + + ApaRgb& operator=( const Hsv& o ) { + *this = Rgb{ o }; + return *this; + } + + uint8_t v, b, g, r; + }; + + static const int FINAL_FRAME_SIZE = 4; + static const int TRANS_COUNT = 2 + 8; + + Apa102( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer ) + : _count( count ), + _firstBuffer( new ApaRgb[ count ] ), + _secondBuffer( doubleBuffer ? new ApaRgb[ count ] : nullptr ), + _initFrame( 0 ) + { + spi_bus_config_t buscfg; + memset( &buscfg, 0, sizeof( buscfg ) ); + buscfg.mosi_io_num = datapin; + buscfg.miso_io_num = -1; + buscfg.sclk_io_num = clkpin; + buscfg.quadwp_io_num = -1; + buscfg.quadhd_io_num = -1; + buscfg.max_transfer_sz = 65535; + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( devcfg ) ); + devcfg.clock_speed_hz = 1000000; + devcfg.mode = 0; + devcfg.spics_io_num = -1; + devcfg.queue_size = TRANS_COUNT; + devcfg.pre_cb = nullptr; + + auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 ); + assert( ret == ESP_OK ); + + ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi ); + assert( ret == ESP_OK ); + + std::fill_n( _finalFrame, FINAL_FRAME_SIZE, 0xFFFFFFFF ); + } + + ~Apa102() { + // ToDo + } + + ApaRgb& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const ApaRgb& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + void wait() { + for ( int i = 0; i != _transCount; i++ ) { + spi_transaction_t *t; + spi_device_get_trans_result( _spi, &t, portMAX_DELAY ); + } + } +private: + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + for ( int i = 0; i != TRANS_COUNT; i++ ) { + _transactions[ i ].cmd = 0; + _transactions[ i ].addr = 0; + _transactions[ i ].flags = 0; + _transactions[ i ].rxlength = 0; + _transactions[ i ].rx_buffer = nullptr; + } + // Init frame + _transactions[ 0 ].length = 32; + _transactions[ 0 ].tx_buffer = &_initFrame; + spi_device_queue_trans( _spi, _transactions + 0, portMAX_DELAY ); + // Data + _transactions[ 1 ].length = 32 * _count; + _transactions[ 1 ].tx_buffer = _buffer; + spi_device_queue_trans( _spi, _transactions + 1, portMAX_DELAY ); + _transCount = 2; + // End frame + for ( int i = 0; i != 1 + _count / 32 / FINAL_FRAME_SIZE; i++ ) { + _transactions[ 2 + i ].length = 32 * FINAL_FRAME_SIZE; + _transactions[ 2 + i ].tx_buffer = _finalFrame; + spi_device_queue_trans( _spi, _transactions + 2 + i, portMAX_DELAY ); + _transCount++; + } + } + + spi_device_handle_t _spi; + int _count; + std::unique_ptr< ApaRgb[] > _firstBuffer, _secondBuffer; + ApaRgb *_buffer; + + spi_transaction_t _transactions[ TRANS_COUNT ]; + int _transCount; + + uint32_t _initFrame; + uint32_t _finalFrame[ FINAL_FRAME_SIZE ]; +}; + +class LDP8806 { +public: + struct LDP8806_GRB { + + LDP8806_GRB( uint8_t g_7bit = 0, uint8_t r_7bit = 0, uint32_t b_7bit = 0 ) + : g( g_7bit ), r( r_7bit ), b( b_7bit ) + { + } + + LDP8806_GRB& operator=( const Rgb& o ) { + //Convert 8->7bit colour + r = ( o.r * 127 / 256 ) | 0x80; + g = ( o.g * 127 / 256 ) | 0x80; + b = ( o.b * 127 / 256 ) | 0x80; + return *this; + } + + LDP8806_GRB& operator=( const Hsv& o ) { + *this = Rgb{ o }; + return *this; + } + + uint8_t g, r, b; + }; + + static const int LED_FRAME_SIZE_BYTES = sizeof( LDP8806_GRB ); + static const int LATCH_FRAME_SIZE_BYTES = 3; + static const int TRANS_COUNT_MAX = 20;//Arbitrary, supports up to 600 LED + + LDP8806( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer, uint32_t clock_speed_hz = 2000000 ) + : _count( count ), + _firstBuffer( new LDP8806_GRB[ count ] ), + _secondBuffer( doubleBuffer ? new LDP8806_GRB[ count ] : nullptr ), + // one 'latch'/start-of-data mark frame for every 32 leds + _latchFrames( ( count + 31 ) / 32 ) + { + spi_bus_config_t buscfg; + memset( &buscfg, 0, sizeof( buscfg ) ); + buscfg.mosi_io_num = datapin; + buscfg.miso_io_num = -1; + buscfg.sclk_io_num = clkpin; + buscfg.quadwp_io_num = -1; + buscfg.quadhd_io_num = -1; + buscfg.max_transfer_sz = 65535; + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( devcfg ) ); + devcfg.clock_speed_hz = clock_speed_hz; + devcfg.mode = 0; + devcfg.spics_io_num = -1; + devcfg.queue_size = TRANS_COUNT_MAX; + devcfg.pre_cb = nullptr; + + auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 ); + assert( ret == ESP_OK ); + + ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi ); + assert( ret == ESP_OK ); + + std::fill_n( _latchBuffer, LATCH_FRAME_SIZE_BYTES, 0x0 ); + } + + ~LDP8806() { + // noop + } + + LDP8806_GRB& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const LDP8806_GRB& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + void wait() { + while ( _transCount-- ) { + spi_transaction_t *t; + spi_device_get_trans_result( _spi, &t, portMAX_DELAY ); + } + } +private: + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + _transCount = 0; + for ( int i = 0; i != TRANS_COUNT_MAX; i++ ) { + _transactions[ i ].cmd = 0; + _transactions[ i ].addr = 0; + _transactions[ i ].flags = 0; + _transactions[ i ].rxlength = 0; + _transactions[ i ].rx_buffer = nullptr; + } + // LED Data + _transactions[ 0 ].length = ( LED_FRAME_SIZE_BYTES * 8 ) * _count; + _transactions[ 0 ].tx_buffer = _buffer; + spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY ); + _transCount++; + + // 'latch'/start-of-data marker frames + for ( int i = 0; i < _latchFrames; i++ ) { + _transactions[ _transCount ].length = ( LATCH_FRAME_SIZE_BYTES * 8 ); + _transactions[ _transCount ].tx_buffer = _latchBuffer; + spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY ); + _transCount++; + } + } + + spi_device_handle_t _spi; + int _count; + std::unique_ptr< LDP8806_GRB[] > _firstBuffer, _secondBuffer; + LDP8806_GRB *_buffer; + + spi_transaction_t _transactions[ TRANS_COUNT_MAX ]; + int _transCount; + + int _latchFrames; + uint8_t _latchBuffer[ LATCH_FRAME_SIZE_BYTES ]; +}; diff --git a/code/components/jomjol_controlGPIO/Color.cpp b/code/components/jomjol_controlGPIO/Color.cpp new file mode 100644 index 00000000..b2beb9ac --- /dev/null +++ b/code/components/jomjol_controlGPIO/Color.cpp @@ -0,0 +1,132 @@ +#include "Color.h" +#include +#include +#include + +namespace { + +// Int -> fixed point +int up( int x ) { return x * 255; } + +} // namespace + +int iRgbSqrt( int num ) { + // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 + assert( "sqrt input should be non-negative" && num >= 0 ); + assert( "sqrt input should no exceed 16 bits" && num <= 0xFFFF ); + int res = 0; + int bit = 1 << 16; + while ( bit > num ) + bit >>= 2; + while ( bit != 0 ) { + if ( num >= res + bit ) { + num -= res + bit; + res = ( res >> 1 ) + bit; + } else + res >>= 1; + bit >>= 2; + } + return res; +} + +Rgb::Rgb( Hsv y ) { + // https://stackoverflow.com/questions/24152553/hsv-to-rgb-and-back-without-floating-point-math-in-python + // greyscale + if( y.s == 0 ) { + r = g = b = y.v; + return; + } + + const int region = y.h / 43; + const int remainder = ( y.h - ( region * 43 ) ) * 6; + + const int p = ( y.v * ( 255 - y.s ) ) >> 8; + const int q = ( y.v * ( 255 - ( ( y.s * remainder ) >> 8 ) ) ) >> 8; + const int t = ( y.v * ( 255 - ( ( y.s * (255 -remainder ) ) >> 8 ) ) ) >> 8; + + switch( region ) { + case 0: r = y.v; g = t; b = p; break; + case 1: r = q; g = y.v; b = p; break; + case 2: r = p; g = y.v; b = t; break; + case 3: r = p; g = q; b = y.v; break; + case 4: r = t; g = p; b = y.v; break; + case 5: r = y.v; g = p; b = q; break; + default: __builtin_trap(); + } + + a = y.a; +} + +Rgb& Rgb::operator=( Hsv hsv ) { + Rgb r{ hsv }; + swap( r ); + return *this; +} + +Rgb Rgb::operator+( Rgb in ) const { + auto copy = *this; + copy += in; + return copy; +} + +Rgb& Rgb::operator+=( Rgb in ) { + unsigned int red = r + in.r; + r = ( red < 255 ) ? red : 255; + unsigned int green = g + in.g; + g = ( green < 255 ) ? green : 255; + unsigned int blue = b + in.b; + b = ( blue < 255 ) ? blue : 255; + return *this; +} + +Rgb& Rgb::blend( Rgb in ) { + unsigned int inAlpha = in.a * ( 255 - a ); + unsigned int alpha = a + inAlpha; + r = iRgbSqrt( ( ( r * r * a ) + ( in.r * in.r * inAlpha ) ) / alpha ); + g = iRgbSqrt( ( ( g * g * a ) + ( in.g * in.g * inAlpha ) ) / alpha ); + b = iRgbSqrt( ( ( b * b * a ) + ( in.b * in.b * inAlpha ) ) / alpha ); + a = alpha; + return *this; +} + +uint8_t IRAM_ATTR Rgb::getGrb( int idx ) { + switch ( idx ) { + case 0: return g; + case 1: return r; + case 2: return b; + } + __builtin_unreachable(); +} + +Hsv::Hsv( Rgb r ) { + int min = std::min( r.r, std::min( r.g, r.b ) ); + int max = std::max( r.r, std::max( r.g, r.b ) ); + int chroma = max - min; + + v = max; + if ( chroma == 0 ) { + h = s = 0; + return; + } + + s = up( chroma ) / max; + int hh; + if ( max == r.r ) + hh = ( up( int( r.g ) - int( r.b ) ) ) / chroma / 6; + else if ( max == r.g ) + hh = 255 / 3 + ( up( int( r.b ) - int( r.r ) ) ) / chroma / 6; + else + hh = 2 * 255 / 3 + ( up( int( r.r ) - int( r.g ) ) ) / chroma / 6; + + if ( hh < 0 ) + hh += 255; + h = hh; + + a = r.a; +} + +Hsv& Hsv::operator=( Rgb rgb ) { + Hsv h{ rgb }; + swap( h ); + return *this; +} diff --git a/code/components/jomjol_controlGPIO/Color.h b/code/components/jomjol_controlGPIO/Color.h new file mode 100644 index 00000000..1923cf0b --- /dev/null +++ b/code/components/jomjol_controlGPIO/Color.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include "esp_attr.h" +union Hsv; + +union Rgb { + struct __attribute__ ((packed)) { + uint8_t r, g, b, a; + }; + uint32_t value; + + Rgb( uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255 ) : r( r ), g( g ), b( b ), a( a ) {} + Rgb( Hsv c ); + Rgb& operator=( Rgb rgb ) { swap( rgb ); return *this; } + Rgb& operator=( Hsv hsv ); + Rgb operator+( Rgb in ) const; + Rgb& operator+=( Rgb in ); + bool operator==( Rgb in ) const { return in.value == value; } + Rgb& blend( Rgb in ); + void swap( Rgb& o ) { value = o.value; } + void linearize() { + r = channelGamma(r); + g = channelGamma(g); + b = channelGamma(b); + } + + uint8_t IRAM_ATTR getGrb( int idx ); + + void stretchChannels( uint8_t maxR, uint8_t maxG, uint8_t maxB ) { + r = stretch( r, maxR ); + g = stretch( g, maxG ); + b = stretch( b, maxB ); + } + + void stretchChannelsEvenly( uint8_t max ) { + stretchChannels( max, max, max ); + } + +private: + uint8_t stretch( int value, uint8_t max ) { + return ( value * max ) >> 8; + } + + uint8_t channelGamma( int channel ) { + /* The optimal gamma correction is x^2.8. However, this is expensive to + * compute. Therefore, we use x^3 for gamma correction. Also, we add a + * bias as the WS2812 LEDs do not turn on for values less than 4. */ + if (channel == 0) + return channel; + channel = channel * channel * channel * 251; + channel >>= 24; + return static_cast< uint8_t >( 4 + channel ); + } +}; + +union Hsv { + struct __attribute__ ((packed)) { + uint8_t h, s, v, a; + }; + uint32_t value; + + Hsv( uint8_t h, uint8_t s = 0, uint8_t v = 0, uint8_t a = 255 ) : h( h ), s( s ), v( v ), a( a ) {} + Hsv( Rgb r ); + Hsv& operator=( Hsv h ) { swap( h ); return *this; } + Hsv& operator=( Rgb rgb ); + bool operator==( Hsv in ) const { return in.value == value; } + void swap( Hsv& o ) { value = o.value; } +}; diff --git a/code/components/jomjol_controlGPIO/SmartLeds.cpp b/code/components/jomjol_controlGPIO/SmartLeds.cpp new file mode 100644 index 00000000..a2ba7b29 --- /dev/null +++ b/code/components/jomjol_controlGPIO/SmartLeds.cpp @@ -0,0 +1,63 @@ +#include "SmartLeds.h" + +IsrCore SmartLed::_interruptCore = CoreCurrent; +intr_handle_t SmartLed::_interruptHandle = NULL; + +SmartLed*& IRAM_ATTR SmartLed::ledForChannel( int channel ) { + static SmartLed* table[8] = { nullptr }; + assert( channel < 8 ); + return table[ channel ]; +} + +void IRAM_ATTR SmartLed::interruptHandler(void*) { + for (int channel = 0; channel != 8; channel++) { + auto self = ledForChannel( channel ); + + if ( RMT.int_st.val & (1 << (24 + channel ) ) ) { // tx_thr_event + if ( self ) + self->copyRmtHalfBlock(); + RMT.int_clr.val |= 1 << ( 24 + channel ); + } else if ( RMT.int_st.val & ( 1 << (3 * channel ) ) ) { // tx_end + if ( self ) + xSemaphoreGiveFromISR( self->_finishedFlag, nullptr ); + RMT.int_clr.val |= 1 << ( 3 * channel ); + } + } +} + +void IRAM_ATTR SmartLed::copyRmtHalfBlock() { + int offset = detail::MAX_PULSES * _halfIdx; + _halfIdx = !_halfIdx; + int len = 3 - _componentPosition + 3 * ( _count - 1 ); + len = std::min( len, detail::MAX_PULSES / 8 ); + + if ( !len ) { + for ( int i = 0; i < detail::MAX_PULSES; i++) { + RMTMEM.chan[ _channel].data32[i + offset ].val = 0; + } + } + + int i; + for ( i = 0; i != len && _pixelPosition != _count; i++ ) { + uint8_t val = _buffer[ _pixelPosition ].getGrb( _componentPosition ); + for ( int j = 0; j != 8; j++, val <<= 1 ) { + int bit = val >> 7; + int idx = i * 8 + offset + j; + RMTMEM.chan[ _channel ].data32[ idx ].val = _bitToRmt[ bit & 0x01 ].value; + } + if ( _pixelPosition == _count - 1 && _componentPosition == 2 ) { + RMTMEM.chan[ _channel ].data32[ i * 8 + offset + 7 ].duration1 = + _timing.TRS / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + } + + _componentPosition++; + if ( _componentPosition == 3 ) { + _componentPosition = 0; + _pixelPosition++; + } + } + + for ( i *= 8; i != detail::MAX_PULSES; i++ ) { + RMTMEM.chan[ _channel ].data32[ i + offset ].val = 0; + } +} diff --git a/code/components/jomjol_controlGPIO/SmartLeds.h b/code/components/jomjol_controlGPIO/SmartLeds.h new file mode 100644 index 00000000..824eb337 --- /dev/null +++ b/code/components/jomjol_controlGPIO/SmartLeds.h @@ -0,0 +1,530 @@ +#pragma once + +/* + * A C++ driver for the WS2812 LEDs using the RMT peripheral on the ESP32. + * + * Jan "yaqwsx" Mrázek + * + * Based on the work by Martin F. Falatic - https://github.com/FozzTexx/ws2812-demo + */ + +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#if defined ( ARDUINO ) + extern "C" { // ...someone forgot to put in the includes... + #include "esp32-hal.h" + #include "esp_intr_alloc.h" + #include "esp_ipc.h" + #include "driver/gpio.h" + #include "driver/periph_ctrl.h" + #include "freertos/semphr.h" + #include "soc/rmt_struct.h" + #include + #include "esp_idf_version.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 ) + #include "soc/dport_reg.h" +#endif + } +#elif defined ( ESP_PLATFORM ) + extern "C" { // ...someone forgot to put in the includes... + #include + #include + #include + #include + #include + #include + #include + #include + #include + } + #include +#endif + +#include "Color.h" + +namespace detail { + +struct TimingParams { + uint32_t T0H; + uint32_t T1H; + uint32_t T0L; + uint32_t T1L; + uint32_t TRS; +}; + +union RmtPulsePair { + struct { + int duration0:15; + int level0:1; + int duration1:15; + int level1:1; + }; + uint32_t value; +}; + +static const int DIVIDER = 4; // 8 still seems to work, but timings become marginal +static const int MAX_PULSES = 32; // A channel has a 64 "pulse" buffer - we use half per pass +static const double RMT_DURATION_NS = 12.5; // minimum time of a single RMT duration based on clock ns + +} // namespace detail + +using LedType = detail::TimingParams; + +static const LedType LED_WS2812 = { 350, 700, 800, 600, 50000 }; +static const LedType LED_WS2812B = { 400, 850, 850, 400, 50100 }; +static const LedType LED_SK6812 = { 300, 600, 900, 600, 80000 }; +static const LedType LED_WS2813 = { 350, 800, 350, 350, 300000 }; + +enum BufferType { SingleBuffer = 0, DoubleBuffer }; + +enum IsrCore { CoreFirst = 0, CoreSecond = 1, CoreCurrent = 2}; + +class SmartLed { +public: + // The RMT interrupt must not run on the same core as WiFi interrupts, otherwise SmartLeds + // can't fill the RMT buffer fast enough, resulting in rendering artifacts. + // Usually, that means you have to set isrCore == CoreSecond. + // + // If you use anything other than CoreCurrent, the FreeRTOS scheduler MUST be already running, + // so you can't use it if you define SmartLed as global variable. + SmartLed( const LedType& type, int count, int pin, int channel = 0, BufferType doubleBuffer = SingleBuffer, IsrCore isrCore = CoreCurrent) + : _timing( type ), + _channel( channel ), + _count( count ), + _firstBuffer( new Rgb[ count ] ), + _secondBuffer( doubleBuffer ? new Rgb[ count ] : nullptr ), + _finishedFlag( xSemaphoreCreateBinary() ) + { + assert( channel >= 0 && channel < 8 ); + assert( ledForChannel( channel ) == nullptr ); + + xSemaphoreGive( _finishedFlag ); + + DPORT_SET_PERI_REG_MASK( DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN ); + DPORT_CLEAR_PERI_REG_MASK( DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST ); + + PIN_FUNC_SELECT( GPIO_PIN_MUX_REG[ pin ], 2 ); + gpio_set_direction( static_cast< gpio_num_t >( pin ), GPIO_MODE_OUTPUT ); + gpio_matrix_out( static_cast< gpio_num_t >( pin ), RMT_SIG_OUT0_IDX + _channel, 0, 0 ); + initChannel( _channel ); + + RMT.tx_lim_ch[ _channel ].limit = detail::MAX_PULSES; + RMT.int_ena.val |= 1 << ( 24 + _channel ); + RMT.int_ena.val |= 1 << ( 3 * _channel ); + + _bitToRmt[ 0 ].level0 = 1; + _bitToRmt[ 0 ].level1 = 0; + _bitToRmt[ 0 ].duration0 = _timing.T0H / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + _bitToRmt[ 0 ].duration1 = _timing.T0L / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + + _bitToRmt[ 1 ].level0 = 1; + _bitToRmt[ 1 ].level1 = 0; + _bitToRmt[ 1 ].duration0 = _timing.T1H / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + _bitToRmt[ 1 ].duration1 = _timing.T1L / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + + if ( !anyAlive() ) { + _interruptCore = isrCore; + if(isrCore != CoreCurrent) { + ESP_ERROR_CHECK(esp_ipc_call_blocking(isrCore, registerInterrupt, NULL)); + } else { + registerInterrupt(NULL); + } + } + + ledForChannel( channel ) = this; + } + + ~SmartLed() { + ledForChannel( _channel ) = nullptr; + if ( !anyAlive() ) { + if(_interruptCore != CoreCurrent) { + ESP_ERROR_CHECK(esp_ipc_call_blocking(_interruptCore, unregisterInterrupt, NULL)); + } else { + unregisterInterrupt(NULL); + } + } + vSemaphoreDelete( _finishedFlag ); + } + + Rgb& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const Rgb& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + bool wait( TickType_t timeout = portMAX_DELAY ) { + if( xSemaphoreTake( _finishedFlag, timeout ) == pdTRUE ) { + xSemaphoreGive( _finishedFlag ); + return true; + } + return false; + } + + int size() const { + return _count; + } + + Rgb *begin() { return _firstBuffer.get(); } + const Rgb *begin() const { return _firstBuffer.get(); } + const Rgb *cbegin() const { return _firstBuffer.get(); } + + Rgb *end() { return _firstBuffer.get() + _count; } + const Rgb *end() const { return _firstBuffer.get() + _count; } + const Rgb *cend() const { return _firstBuffer.get() + _count; } + +private: + static intr_handle_t _interruptHandle; + static IsrCore _interruptCore; + + static void initChannel( int channel ) { + RMT.apb_conf.fifo_mask = 1; //enable memory access, instead of FIFO mode. + RMT.apb_conf.mem_tx_wrap_en = 1; //wrap around when hitting end of buffer + RMT.conf_ch[ channel ].conf0.div_cnt = detail::DIVIDER; + RMT.conf_ch[ channel ].conf0.mem_size = 1; + RMT.conf_ch[ channel ].conf0.carrier_en = 0; + RMT.conf_ch[ channel ].conf0.carrier_out_lv = 1; + RMT.conf_ch[ channel ].conf0.mem_pd = 0; + + RMT.conf_ch[ channel ].conf1.rx_en = 0; + RMT.conf_ch[ channel ].conf1.mem_owner = 0; + RMT.conf_ch[ channel ].conf1.tx_conti_mode = 0; //loop back mode. + RMT.conf_ch[ channel ].conf1.ref_always_on = 1; // use apb clock: 80M + RMT.conf_ch[ channel ].conf1.idle_out_en = 1; + RMT.conf_ch[ channel ].conf1.idle_out_lv = 0; + } + + static void registerInterrupt(void *) { + ESP_ERROR_CHECK(esp_intr_alloc( ETS_RMT_INTR_SOURCE, 0, interruptHandler, nullptr, &_interruptHandle)); + } + + static void unregisterInterrupt(void*) { + esp_intr_free( _interruptHandle ); + } + + static SmartLed*& IRAM_ATTR ledForChannel( int channel ); + static void IRAM_ATTR interruptHandler( void* ); + + void IRAM_ATTR copyRmtHalfBlock(); + + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + // Invalid use of the library + if( xSemaphoreTake( _finishedFlag, 0 ) != pdTRUE ) + abort(); + + _pixelPosition = _componentPosition = _halfIdx = 0; + copyRmtHalfBlock(); + if ( _pixelPosition < _count ) + copyRmtHalfBlock(); + + RMT.conf_ch[ _channel ].conf1.mem_rd_rst = 1; + RMT.conf_ch[ _channel ].conf1.tx_start = 1; + } + + static bool anyAlive() { + for ( int i = 0; i != 8; i++ ) + if ( ledForChannel( i ) != nullptr ) return true; + return false; + } + + const LedType& _timing; + int _channel; + detail::RmtPulsePair _bitToRmt[ 2 ]; + int _count; + std::unique_ptr< Rgb[] > _firstBuffer; + std::unique_ptr< Rgb[] > _secondBuffer; + Rgb *_buffer; + + xSemaphoreHandle _finishedFlag; + + int _pixelPosition; + int _componentPosition; + int _halfIdx; +}; + +class Apa102 { +public: + struct ApaRgb { + ApaRgb( uint8_t r = 0, uint8_t g = 0, uint32_t b = 0, uint32_t v = 0xFF ) + : v( 0xE0 | v ), b( b ), g( g ), r( r ) + {} + + ApaRgb& operator=( const Rgb& o ) { + r = o.r; + g = o.g; + b = o.b; + return *this; + } + + ApaRgb& operator=( const Hsv& o ) { + *this = Rgb{ o }; + return *this; + } + + uint8_t v, b, g, r; + }; + + static const int FINAL_FRAME_SIZE = 4; + static const int TRANS_COUNT = 2 + 8; + + Apa102( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer ) + : _count( count ), + _firstBuffer( new ApaRgb[ count ] ), + _secondBuffer( doubleBuffer ? new ApaRgb[ count ] : nullptr ), + _initFrame( 0 ) + { + spi_bus_config_t buscfg; + memset( &buscfg, 0, sizeof( buscfg ) ); + buscfg.mosi_io_num = datapin; + buscfg.miso_io_num = -1; + buscfg.sclk_io_num = clkpin; + buscfg.quadwp_io_num = -1; + buscfg.quadhd_io_num = -1; + buscfg.max_transfer_sz = 65535; + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( devcfg ) ); + devcfg.clock_speed_hz = 1000000; + devcfg.mode = 0; + devcfg.spics_io_num = -1; + devcfg.queue_size = TRANS_COUNT; + devcfg.pre_cb = nullptr; + + auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 ); + assert( ret == ESP_OK ); + + ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi ); + assert( ret == ESP_OK ); + + std::fill_n( _finalFrame, FINAL_FRAME_SIZE, 0xFFFFFFFF ); + } + + ~Apa102() { + // ToDo + } + + ApaRgb& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const ApaRgb& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + void wait() { + for ( int i = 0; i != _transCount; i++ ) { + spi_transaction_t *t; + spi_device_get_trans_result( _spi, &t, portMAX_DELAY ); + } + } +private: + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + for ( int i = 0; i != TRANS_COUNT; i++ ) { + _transactions[ i ].cmd = 0; + _transactions[ i ].addr = 0; + _transactions[ i ].flags = 0; + _transactions[ i ].rxlength = 0; + _transactions[ i ].rx_buffer = nullptr; + } + // Init frame + _transactions[ 0 ].length = 32; + _transactions[ 0 ].tx_buffer = &_initFrame; + spi_device_queue_trans( _spi, _transactions + 0, portMAX_DELAY ); + // Data + _transactions[ 1 ].length = 32 * _count; + _transactions[ 1 ].tx_buffer = _buffer; + spi_device_queue_trans( _spi, _transactions + 1, portMAX_DELAY ); + _transCount = 2; + // End frame + for ( int i = 0; i != 1 + _count / 32 / FINAL_FRAME_SIZE; i++ ) { + _transactions[ 2 + i ].length = 32 * FINAL_FRAME_SIZE; + _transactions[ 2 + i ].tx_buffer = _finalFrame; + spi_device_queue_trans( _spi, _transactions + 2 + i, portMAX_DELAY ); + _transCount++; + } + } + + spi_device_handle_t _spi; + int _count; + std::unique_ptr< ApaRgb[] > _firstBuffer, _secondBuffer; + ApaRgb *_buffer; + + spi_transaction_t _transactions[ TRANS_COUNT ]; + int _transCount; + + uint32_t _initFrame; + uint32_t _finalFrame[ FINAL_FRAME_SIZE ]; +}; + +class LDP8806 { +public: + struct LDP8806_GRB { + + LDP8806_GRB( uint8_t g_7bit = 0, uint8_t r_7bit = 0, uint32_t b_7bit = 0 ) + : g( g_7bit ), r( r_7bit ), b( b_7bit ) + { + } + + LDP8806_GRB& operator=( const Rgb& o ) { + //Convert 8->7bit colour + r = ( o.r * 127 / 256 ) | 0x80; + g = ( o.g * 127 / 256 ) | 0x80; + b = ( o.b * 127 / 256 ) | 0x80; + return *this; + } + + LDP8806_GRB& operator=( const Hsv& o ) { + *this = Rgb{ o }; + return *this; + } + + uint8_t g, r, b; + }; + + static const int LED_FRAME_SIZE_BYTES = sizeof( LDP8806_GRB ); + static const int LATCH_FRAME_SIZE_BYTES = 3; + static const int TRANS_COUNT_MAX = 20;//Arbitrary, supports up to 600 LED + + LDP8806( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer, uint32_t clock_speed_hz = 2000000 ) + : _count( count ), + _firstBuffer( new LDP8806_GRB[ count ] ), + _secondBuffer( doubleBuffer ? new LDP8806_GRB[ count ] : nullptr ), + // one 'latch'/start-of-data mark frame for every 32 leds + _latchFrames( ( count + 31 ) / 32 ) + { + spi_bus_config_t buscfg; + memset( &buscfg, 0, sizeof( buscfg ) ); + buscfg.mosi_io_num = datapin; + buscfg.miso_io_num = -1; + buscfg.sclk_io_num = clkpin; + buscfg.quadwp_io_num = -1; + buscfg.quadhd_io_num = -1; + buscfg.max_transfer_sz = 65535; + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( devcfg ) ); + devcfg.clock_speed_hz = clock_speed_hz; + devcfg.mode = 0; + devcfg.spics_io_num = -1; + devcfg.queue_size = TRANS_COUNT_MAX; + devcfg.pre_cb = nullptr; + + auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 ); + assert( ret == ESP_OK ); + + ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi ); + assert( ret == ESP_OK ); + + std::fill_n( _latchBuffer, LATCH_FRAME_SIZE_BYTES, 0x0 ); + } + + ~LDP8806() { + // noop + } + + LDP8806_GRB& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const LDP8806_GRB& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + void wait() { + while ( _transCount-- ) { + spi_transaction_t *t; + spi_device_get_trans_result( _spi, &t, portMAX_DELAY ); + } + } +private: + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + _transCount = 0; + for ( int i = 0; i != TRANS_COUNT_MAX; i++ ) { + _transactions[ i ].cmd = 0; + _transactions[ i ].addr = 0; + _transactions[ i ].flags = 0; + _transactions[ i ].rxlength = 0; + _transactions[ i ].rx_buffer = nullptr; + } + // LED Data + _transactions[ 0 ].length = ( LED_FRAME_SIZE_BYTES * 8 ) * _count; + _transactions[ 0 ].tx_buffer = _buffer; + spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY ); + _transCount++; + + // 'latch'/start-of-data marker frames + for ( int i = 0; i < _latchFrames; i++ ) { + _transactions[ _transCount ].length = ( LATCH_FRAME_SIZE_BYTES * 8 ); + _transactions[ _transCount ].tx_buffer = _latchBuffer; + spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY ); + _transCount++; + } + } + + spi_device_handle_t _spi; + int _count; + std::unique_ptr< LDP8806_GRB[] > _firstBuffer, _secondBuffer; + LDP8806_GRB *_buffer; + + spi_transaction_t _transactions[ TRANS_COUNT_MAX ]; + int _transCount; + + int _latchFrames; + uint8_t _latchBuffer[ LATCH_FRAME_SIZE_BYTES ]; +}; diff --git a/code/components/jomjol_controlGPIO/server_GPIO.cpp b/code/components/jomjol_controlGPIO/server_GPIO.cpp index c78207ec..13af9237 100644 --- a/code/components/jomjol_controlGPIO/server_GPIO.cpp +++ b/code/components/jomjol_controlGPIO/server_GPIO.cpp @@ -107,7 +107,8 @@ void GpioPin::init() //configure GPIO with the given settings gpio_config(&io_conf); - if (_interruptType != GPIO_INTR_DISABLE) { +// if (_interruptType != GPIO_INTR_DISABLE) { // ohne GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X, wenn das genutzt wird, dann soll auch der Handler hier nicht initialisiert werden, da das dann über SmartLED erfolgt. + if ((_interruptType != GPIO_INTR_DISABLE) && (_interruptType != GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X)) { //hook isr handler for specific gpio pin ESP_LOGD(TAG_SERVERGPIO, "GpioPin::init add isr handler for GPIO %d\r\n", _gpio); gpio_isr_handler_add(_gpio, gpio_isr_handler, (void*)&_gpio); @@ -212,6 +213,8 @@ void GpioHandler::init() // printf("wait before start %ldms\r\n", (long) xDelay); // vTaskDelay( xDelay ); + printf("*************** Start GPIOHandler_Init *****************\n"); + if (gpioMap == NULL) { gpioMap = new std::map(); } else { @@ -295,16 +298,24 @@ bool GpioHandler::readConfig() std::string line = ""; bool disabledLine = false; bool eof = false; + gpio_num_t gpioExtLED = (gpio_num_t) 0; + +// printf("readConfig - Start 1\n"); - while ((!configFile.GetNextParagraph(line, disabledLine, eof) || (line.compare("[GPIO]") != 0)) && !disabledLine && !eof) {} + while ((!configFile.GetNextParagraph(line, disabledLine, eof) || (line.compare("[GPIO]") != 0)) && !eof) {} if (eof) return false; - + +// printf("readConfig - Start 2 line: %s, disabbledLine: %d\n", line.c_str(), (int) disabledLine); + + _isEnabled = !disabledLine; if (!_isEnabled) return false; +// printf("readConfig - Start 3\n"); + // std::string mainTopicMQTT = ""; std::string mainTopicMQTT = GetMQTTMainTopic(); if (mainTopicMQTT.length() > 0) @@ -346,10 +357,40 @@ bool GpioHandler::readConfig() GpioPin* gpioPin = new GpioPin(gpioNr, gpioName, pinMode, intType,dutyResolution, mqttTopic, httpEnabled); (*gpioMap)[gpioNr] = gpioPin; + if (pinMode == GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X) + { + printf("Set WS2812 to GPIO %d\n", gpioNr); + gpioExtLED = gpioNr; + } + if (intType != GPIO_INTR_DISABLE) { registerISR = true; } } + if (toUpper(zerlegt[0]) == "LEDNUMBERS") + { + LEDNumbers = stoi(zerlegt[1]); + } + if (toUpper(zerlegt[0]) == "LEDCOLOR") + { + uint8_t _r, _g, _b; + _r = stoi(zerlegt[1]); + _g = stoi(zerlegt[2]); + _b = stoi(zerlegt[3]); + + LEDColor = Rgb{_r, _g, _b}; + } + if (toUpper(zerlegt[0]) == "LEDTYPE") + { + if (zerlegt[1] == "WS2812") + LEDType = LED_WS2812; + if (zerlegt[1] == "WS2812B") + LEDType = LED_WS2812B; + if (zerlegt[1] == "SK6812") + LEDType = LED_SK6812; + if (zerlegt[1] == "WS2813") + LEDType = LED_WS2813; + } } if (registerISR) { @@ -357,6 +398,28 @@ bool GpioHandler::readConfig() gpio_install_isr_service(ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_IRAM); } + if (gpioExtLED > 0) + { + // LogFile.WriteToFile("Startsequence 06"); +// vTaskDelay( xDelay ); +// xDelay = 5000 / portTICK_PERIOD_MS; +// printf("main: sleep for : %ldms\n", (long) xDelay); + + SmartLed leds( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer ); + + + leds[ 0 ] = Rgb{ 255, 0, 0 }; + leds[ 1 ] = Rgb{ 255, 255, 255 }; + leds.show(); +/* +// _SmartLED = new SmartLed(LEDType, LEDNumbers, gpioExtLED, 0, DoubleBuffer); + _SmartLED = new SmartLed( LED_WS2812, 2, GPIO_NUM_12, 0, DoubleBuffer ); + (*_SmartLED)[ 0 ] = Rgb{ 255, 0, 0 }; + (*_SmartLED)[ 1 ] = LEDColor; + _SmartLED->show(); +*/ + } + return true; } @@ -498,7 +561,24 @@ void GpioHandler::flashLightEnable(bool value) } else { ESP_LOGE(TAG_SERVERGPIO, "Can't set flash light pin GPIO %d. Error: %s\r\n", (int)it->first, resp_str.c_str()); } - } + } else + { + if (it->second->getMode() == GPIO_PIN_MODE_EXTERNAL_FLASH_WS281X) + { + SmartLed leds( LEDType, LEDNumbers, it->second->getGPIO(), 0, DoubleBuffer ); + if (value) + { + for (int i = 0; i < LEDNumbers; ++i) + leds[i] = LEDColor; + } + else + { + for (int i = 0; i < LEDNumbers; ++i) + leds[i] = Rgb{0, 0, 0}; + } + leds.show(); + } + } } } } diff --git a/code/components/jomjol_controlGPIO/server_GPIO.h b/code/components/jomjol_controlGPIO/server_GPIO.h index 14d88412..7e708222 100644 --- a/code/components/jomjol_controlGPIO/server_GPIO.h +++ b/code/components/jomjol_controlGPIO/server_GPIO.h @@ -7,6 +7,8 @@ #include #include "driver/gpio.h" +#include "SmartLeds.h" + //#include "ClassControllCamera.h" typedef enum { @@ -45,6 +47,7 @@ public: void gpioInterrupt(int value); gpio_int_type_t getInterruptType() { return _interruptType; } gpio_pin_mode_t getMode() { return _mode; } + gpio_num_t getGPIO(){return _gpio;}; private: gpio_num_t _gpio; @@ -80,6 +83,11 @@ private: TaskHandle_t xHandleTaskGpio = NULL; bool _isEnabled = false; + int LEDNumbers = 2; + Rgb LEDColor = Rgb{ 255, 255, 255 }; + LedType LEDType = LED_WS2812; + + bool readConfig(); void clear(); diff --git a/code/components/jomjol_controlcamera/ClassControllCamera.cpp b/code/components/jomjol_controlcamera/ClassControllCamera.cpp index defa7777..01c60f37 100644 --- a/code/components/jomjol_controlcamera/ClassControllCamera.cpp +++ b/code/components/jomjol_controlcamera/ClassControllCamera.cpp @@ -499,6 +499,7 @@ void CCamera::LightOnOff(bool status) { GpioHandler* gpioHandler = gpio_handler_get(); if ((gpioHandler != NULL) && (gpioHandler->isEnabled())) { + printf("Use gpioHandler flashLigh\n"); gpioHandler->flashLightEnable(status); } else { // Init the GPIO diff --git a/code/components/jomjol_fileserver_ota/server_help.cpp b/code/components/jomjol_fileserver_ota/server_help.cpp index 21648aa4..25ffbcc4 100644 --- a/code/components/jomjol_fileserver_ota/server_help.cpp +++ b/code/components/jomjol_fileserver_ota/server_help.cpp @@ -111,6 +111,8 @@ esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filename) return httpd_resp_set_type(req, "image/jpeg"); } else if (IS_FILE_EXT(filename, ".ico")) { return httpd_resp_set_type(req, "image/x-icon"); + } else if (IS_FILE_EXT(filename, ".js")) { + return httpd_resp_set_type(req, "text/javascript"); } /* This is a limited set only */ /* For any other type always set as plain text */ diff --git a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp index f9909b7c..e6afbbc0 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.cpp @@ -21,23 +21,23 @@ ClassFlowCNNGeneral::ClassFlowCNNGeneral(ClassFlowAlignment *_flowalign, t_CNNTy previousElement = NULL; SaveAllFiles = false; disabled = false; - extendedResolution = false; +// extendedResolution = false; isLogImageSelect = false; CNNType = AutoDetect; CNNType = _cnntype; flowpostalignment = _flowalign; } - +/* int ClassFlowCNNGeneral::AnzahlROIs(int _analog = 0) { int zw = GENERAL[_analog]->ROI.size(); if (extendedResolution && (CNNType != Digital)) zw++; // da letzte Ziffer inkl Nachhkomma, es sei denn, das Nachkomma gibt es nicht (Digital) return zw; } +*/ - -string ClassFlowCNNGeneral::getReadout(int _analog = 0) +string ClassFlowCNNGeneral::getReadout(int _analog = 0, bool _extendedResolution = false) { string result = ""; if (GENERAL[_analog]->ROI.size() == 0) @@ -45,20 +45,20 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0) if (CNNType == Analogue) { - float zahl = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result; - int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10; + float zahl = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float; + int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10; int prev = -1; - prev = ZeigerEval(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result, prev); + prev = ZeigerEval(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, prev); result = std::to_string(prev); - if (extendedResolution && (CNNType != Digital)) + if (_extendedResolution && (CNNType != Digital)) result = result + std::to_string(ergebnis_nachkomma); for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i) { - prev = ZeigerEval(GENERAL[_analog]->ROI[i]->result, prev); + prev = ZeigerEval(GENERAL[_analog]->ROI[i]->result_float, prev); result = std::to_string(prev) + result; } } @@ -67,10 +67,10 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0) { for (int i = 0; i < GENERAL[_analog]->ROI.size(); ++i) { - if (GENERAL[_analog]->ROI[i]->resultklasse == 10) + if (GENERAL[_analog]->ROI[i]->result_klasse >= 10) result = result + "N"; else - result = result + std::to_string(GENERAL[_analog]->ROI[i]->resultklasse); + result = result + std::to_string(GENERAL[_analog]->ROI[i]->result_klasse); } } @@ -79,34 +79,35 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0) // int ergebnis_nachkomma = -1; int zif_akt = -1; - float zahl = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result; + float zahl = GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float; if (zahl >= 0) // NaN? { - if (extendedResolution) + if (_extendedResolution) { int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10; int ergebnis_vorkomma = ((int) floor(zahl)) % 10; result = std::to_string(ergebnis_vorkomma) + std::to_string(ergebnis_nachkomma); + zif_akt = ergebnis_vorkomma; } else { - zif_akt = ZeigerEvalHybrid(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result, -1, -1); + zif_akt = ZeigerEvalHybrid(GENERAL[_analog]->ROI[GENERAL[_analog]->ROI.size() - 1]->result_float, -1, -1); result = std::to_string(zif_akt); } } else { result = "N"; - if (extendedResolution && (CNNType != Digital)) + if (_extendedResolution && (CNNType != Digital)) result = "NN"; } for (int i = GENERAL[_analog]->ROI.size() - 2; i >= 0; --i) { - if (GENERAL[_analog]->ROI[i]->result >= 0) + if (GENERAL[_analog]->ROI[i]->result_float >= 0) { - zif_akt = ZeigerEvalHybrid(GENERAL[_analog]->ROI[i]->result, GENERAL[_analog]->ROI[i+1]->result, zif_akt); + zif_akt = ZeigerEvalHybrid(GENERAL[_analog]->ROI[i]->result_float, GENERAL[_analog]->ROI[i+1]->result_float, zif_akt); result = std::to_string(zif_akt) + result; } else @@ -117,7 +118,6 @@ string ClassFlowCNNGeneral::getReadout(int _analog = 0) } } - return result; } @@ -129,43 +129,43 @@ int ClassFlowCNNGeneral::ZeigerEvalHybrid(float zahl, float zahl_vorgaenger, int if (zahl_vorgaenger < 0) // keine Vorzahl vorhanden !!! --> Runde die Zahl { if ((ergebnis_nachkomma <= 2) || (ergebnis_nachkomma >= 8)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht - return (int) round(zahl); + return ((int) round(zahl) + 10) % 10; else - return (int) trunc(zahl); + return ((int) trunc(zahl) + 10) % 10; } if (zahl_vorgaenger > 9.2) // Ziffernwechsel beginnt { if (eval_vorgaenger == 0) // Wechsel hat schon stattgefunden { - return (int) round(zahl); // Annahme, dass die neue Zahl schon in der Nähe des Ziels ist + return ((int) round(zahl) + 10) % 10; // Annahme, dass die neue Zahl schon in der Nähe des Ziels ist } else { if (zahl_vorgaenger <= 9.5) // Wechsel startet gerade, aber beginnt erst { if ((ergebnis_nachkomma <= 2) || (ergebnis_nachkomma >= 8)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht - return (int) round(zahl); + return ((int) round(zahl) + 10) % 10; else - return (int) trunc(zahl); + return ((int) trunc(zahl) + 10) % 10; } else { - return (int) trunc(zahl); // Wechsel schon weiter fortgeschritten, d.h. über 2 als Nachkomma + return ((int) trunc(zahl) + 10) % 10; // Wechsel schon weiter fortgeschritten, d.h. über 2 als Nachkomma } } } if ((ergebnis_nachkomma <= 2) || (ergebnis_nachkomma >= 8)) // Band um die Ziffer --> Runden, da Ziffer im Rahmen Ungenauigkeit erreicht - return (int) round(zahl); + return ((int) round(zahl) + 10) % 10; - return (int) trunc(zahl); + return ((int) trunc(zahl) + 10) % 10; } int ClassFlowCNNGeneral::ZeigerEval(float zahl, int ziffer_vorgaenger) { - int ergebnis_nachkomma = ((int) floor(zahl * 10)) % 10; - int ergebnis_vorkomma = ((int) floor(zahl)) % 10; + int ergebnis_nachkomma = ((int) floor(zahl * 10) + 10) % 10; + int ergebnis_vorkomma = ((int) floor(zahl) + 10) % 10; int ergebnis, ergebnis_rating; if (ziffer_vorgaenger == -1) @@ -182,7 +182,7 @@ int ClassFlowCNNGeneral::ZeigerEval(float zahl, int ziffer_vorgaenger) if (ergebnis == -1) ergebnis+=10; - ergebnis = ergebnis % 10; + ergebnis = (ergebnis + 10) % 10; return ergebnis; } @@ -260,7 +260,7 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) neuroi->posy = std::stoi(zerlegt[2]); neuroi->deltax = std::stoi(zerlegt[3]); neuroi->deltay = std::stoi(zerlegt[4]); - neuroi->result = -1; + neuroi->result_float = -1; neuroi->image = NULL; neuroi->image_org = NULL; } @@ -271,13 +271,16 @@ bool ClassFlowCNNGeneral::ReadParameter(FILE* pfile, string& aktparamgraph) SaveAllFiles = true; } +/* if ((toUpper(zerlegt[0]) == "EXTENDEDRESOLUTION") && (zerlegt.size() > 1)) { if (toUpper(zerlegt[1]) == "TRUE") extendedResolution = true; } +*/ } + for (int _ana = 0; _ana < GENERAL.size(); ++_ana) for (int i = 0; i < GENERAL[_ana]->ROI.size(); ++i) { @@ -482,6 +485,7 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) default: printf("ERROR ERROR ERROR - tflite passt nicht zur Firmware - ERROR ERROR ERROR\n"); } +// flowpostprocessing->UpdateNachkommaDecimalShift(); } for (int _ana = 0; _ana < GENERAL.size(); ++_ana) @@ -503,27 +507,27 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) f1 = tflite->GetOutputValue(0); f2 = tflite->GetOutputValue(1); float result = fmod(atan2(f1, f2) / (M_PI * 2) + 2, 1); - GENERAL[_ana]->ROI[i]->result = result * 10; - printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result); + GENERAL[_ana]->ROI[i]->result_float = result * 10; + printf("Result General(Analog)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); if (isLogImage) - LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result, NULL, time, GENERAL[_ana]->ROI[i]->image_org); + LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org); } break; case Digital: { - GENERAL[_ana]->ROI[i]->resultklasse = 0; - GENERAL[_ana]->ROI[i]->resultklasse = tflite->GetClassFromImageBasis(GENERAL[_ana]->ROI[i]->image); - printf("Result General(Digit)%i: %d\n", i, GENERAL[_ana]->ROI[i]->resultklasse); + GENERAL[_ana]->ROI[i]->result_klasse = 0; + GENERAL[_ana]->ROI[i]->result_klasse = tflite->GetClassFromImageBasis(GENERAL[_ana]->ROI[i]->image); + printf("Result General(Digit)%i: %d\n", i, GENERAL[_ana]->ROI[i]->result_klasse); if (isLogImage) { if (isLogImageSelect) { if (LogImageSelect.find(GENERAL[_ana]->ROI[i]->name) != std::string::npos) - LogImage(logPath, GENERAL[_ana]->ROI[i]->name, NULL, &GENERAL[_ana]->ROI[i]->resultklasse, time, GENERAL[_ana]->ROI[i]->image_org); + LogImage(logPath, GENERAL[_ana]->ROI[i]->name, NULL, &GENERAL[_ana]->ROI[i]->result_klasse, time, GENERAL[_ana]->ROI[i]->image_org); } else { - LogImage(logPath, GENERAL[_ana]->ROI[i]->name, NULL, &GENERAL[_ana]->ROI[i]->resultklasse, time, GENERAL[_ana]->ROI[i]->image_org); + LogImage(logPath, GENERAL[_ana]->ROI[i]->name, NULL, &GENERAL[_ana]->ROI[i]->result_klasse, time, GENERAL[_ana]->ROI[i]->image_org); } } } break; @@ -543,16 +547,16 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) if (debugdetailgeneral) LogFile.WriteToFile(_zwres); if ((_num == 10) || (_nachkomma == 10)) // NaN detektiert - GENERAL[_ana]->ROI[i]->result = -1; + GENERAL[_ana]->ROI[i]->result_float = -1; else - GENERAL[_ana]->ROI[i]->result = fmod((double) _num + (((double)_nachkomma)-5)/10 + (double) 10, 10); + GENERAL[_ana]->ROI[i]->result_float = fmod((double) _num + (((double)_nachkomma)-5)/10 + (double) 10, 10); - printf("Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result); - _zwres = "Result General(DigitalHyprid)" + to_string(i) + ": " + to_string(GENERAL[_ana]->ROI[i]->result); + printf("Result General(DigitalHyprid)%i: %f\n", i, GENERAL[_ana]->ROI[i]->result_float); + _zwres = "Result General(DigitalHyprid)" + to_string(i) + ": " + to_string(GENERAL[_ana]->ROI[i]->result_float); if (debugdetailgeneral) LogFile.WriteToFile(_zwres); if (isLogImage) - LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result, NULL, time, GENERAL[_ana]->ROI[i]->image_org); + LogImage(logPath, GENERAL[_ana]->ROI[i]->name, &GENERAL[_ana]->ROI[i]->result_float, NULL, time, GENERAL[_ana]->ROI[i]->image_org); } break; default: break; @@ -567,7 +571,8 @@ bool ClassFlowCNNGeneral::doNeuralNetwork(string time) bool ClassFlowCNNGeneral::isExtendedResolution(int _number) { - if (extendedResolution && !(CNNType == Digital)) +// if (extendedResolution && !(CNNType == Digital)) + if (!(CNNType == Digital)) return true; return false; @@ -600,13 +605,20 @@ std::vector ClassFlowCNNGeneral::GetHTMLInfo() zw->filename_org = GENERAL[_ana]->name + "_" + GENERAL[_ana]->ROI[i]->name + ".jpg"; } - zw->val = GENERAL[_ana]->ROI[i]->result; + if (CNNType == Digital) + zw->val = GENERAL[_ana]->ROI[i]->result_klasse; + else + zw->val = GENERAL[_ana]->ROI[i]->result_float; zw->image = GENERAL[_ana]->ROI[i]->image; zw->image_org = GENERAL[_ana]->ROI[i]->image_org; +// printf("Push %s\n", zw->filename.c_str()); + result.push_back(zw); } +// printf("größe: %d\n", result.size()); + return result; } diff --git a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h index 2b2c7ac7..f06d7b72 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h +++ b/code/components/jomjol_flowcontroll/ClassFlowCNNGeneral.h @@ -1,6 +1,10 @@ -#pragma once -#include "ClassFlowImage.h" +#ifndef __CLASSCNNGENERAL__ +#define __CLASSCNNGENERAL__ + +#include"ClassFlowDefineTypes.h" #include "ClassFlowAlignment.h" +// #include "ClassFlowPostProcessing.h" + enum t_CNNType { AutoDetect, @@ -10,20 +14,6 @@ enum t_CNNType { None }; -struct roi { - int posx, posy, deltax, deltay; - float result; - int resultklasse; - string name; - CImageBasis *image, *image_org; -}; - -struct general { - string name; - std::vector ROI; -}; - - class ClassFlowCNNGeneral : public ClassFlowImage { @@ -36,8 +26,9 @@ protected: bool isLogImageSelect; string LogImageSelect; ClassFlowAlignment* flowpostalignment; +// ClassFlowPostProcessing *flowpostprocessing = NULL; bool SaveAllFiles; - bool extendedResolution; +// bool extendedResolution; int ZeigerEval(float zahl, int ziffer_vorgaenger); int ZeigerEvalHybrid(float zahl, float zahl_vorgaenger, int eval_vorgaenger); @@ -53,20 +44,22 @@ public: bool doFlow(string time); string getHTMLSingleStep(string host); - string getReadout(int _analog); + string getReadout(int _analog, bool _extendedResolution); void DrawROI(CImageBasis *_zw); std::vector GetHTMLInfo(); - int AnzahlROIs(int _analog); +// int AnzahlROIs(int _analog); int getAnzahlGENERAL(); general* GetGENERAL(int _analog); general* GetGENERAL(string _name, bool _create); general* FindGENERAL(string _name_number); string getNameGENERAL(int _analog); - bool isExtendedResolution(int _number = 0); + bool isExtendedResolution(int _number = 0); + +// void setPostprocessing(ClassFlowPostProcessing *_fpp){flowpostprocessing = _fpp;}; void UpdateNameNumbers(std::vector *_name_numbers); @@ -75,3 +68,5 @@ public: string name(){return "ClassFlowCNNGeneral";}; }; +#endif + diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index 0d17e7be..aac8c8e3 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -74,16 +74,13 @@ std::string ClassFlowControll::TranslateAktstatus(std::string _input) } -std::vector ClassFlowControll::GetAllDigital() +std::vector ClassFlowControll::GetAllDigital() { -/* - for (int i = 0; i < FlowControll.size(); ++i) - if (FlowControll[i]->name().compare("ClassFlowCNNGeneral") == 0) - return ((ClassFlowCNNGeneral*) (FlowControll[i]))->GetHTMLInfo(); -*/ - if (flowdigit) - flowdigit->GetHTMLInfo(); + { + printf("ClassFlowControll::GetAllDigital - flowdigit != NULL\n"); + return flowdigit->GetHTMLInfo(); + } std::vector empty; return empty; @@ -91,17 +88,8 @@ std::vector ClassFlowControll::GetAllDigital() std::vector ClassFlowControll::GetAllAnalog() { -/* - for (int i = 0; i < FlowControll.size(); ++i) - if (FlowControll[i]->name().compare("ClassFlowAnalog") == 0) - return ((ClassFlowAnalog*) (FlowControll[i]))->GetHTMLInfo(); - - std::vector empty; - return empty; -*/ - if (flowanalog) - flowanalog->GetHTMLInfo(); + return flowanalog->GetHTMLInfo(); std::vector empty; return empty; @@ -252,8 +240,8 @@ void ClassFlowControll::InitFlow(std::string config) } -std::string ClassFlowControll::getActStatus(){ - return aktstatus; +std::string* ClassFlowControll::getActStatus(){ + return &aktstatus; } void ClassFlowControll::doFlowMakeImageOnly(string time){ @@ -297,7 +285,7 @@ bool ClassFlowControll::doFlow(string time) if (!FlowControll[i]->doFlow(time)){ repeat++; LogFile.WriteToFile("Fehler im vorheriger Schritt - wird zum " + to_string(repeat) + ". Mal wiederholt"); - i = -1; // vorheriger Schritt muss wiederholt werden (vermutlich Bilder aufnehmen) + if (i) i -= 1; // vorheriger Schritt muss wiederholt werden (vermutlich Bilder aufnehmen) result = false; if (repeat > 5) { LogFile.WriteToFile("Wiederholung 5x nicht erfolgreich --> reboot"); @@ -323,39 +311,41 @@ bool ClassFlowControll::doFlow(string time) string ClassFlowControll::getReadoutAll(int _type) { - std::vector numbers = flowpostprocessing->GetNumbers(); std::string out = ""; - - for (int i = 0; i < numbers.size(); ++i) + if (flowpostprocessing) { - out = out + numbers[i]->name + "\t"; - switch (_type) { - case READOUT_TYPE_VALUE: - out = out + numbers[i]->ReturnValueNoError; - break; - case READOUT_TYPE_PREVALUE: - if (flowpostprocessing->PreValueUse) - { - if (numbers[i]->PreValueOkay) - out = out + numbers[i]->ReturnPreValue; - else - out = out + "PreValue too old"; - } - else - out = out + "PreValue deactivated"; - break; - case READOUT_TYPE_RAWVALUE: - out = out + numbers[i]->ReturnRawValue; - break; - case READOUT_TYPE_ERROR: - out = out + numbers[i]->ErrorMessageText; - break; - } - if (i < numbers.size()-1) - out = out + "\r\n"; - } + std::vector *numbers = flowpostprocessing->GetNumbers(); -// printf("OUT: %s", out.c_str()); + for (int i = 0; i < (*numbers).size(); ++i) + { + out = out + (*numbers)[i]->name + "\t"; + switch (_type) { + case READOUT_TYPE_VALUE: + out = out + (*numbers)[i]->ReturnValueNoError; + break; + case READOUT_TYPE_PREVALUE: + if (flowpostprocessing->PreValueUse) + { + if ((*numbers)[i]->PreValueOkay) + out = out + (*numbers)[i]->ReturnPreValue; + else + out = out + "PreValue too old"; + } + else + out = out + "PreValue deactivated"; + break; + case READOUT_TYPE_RAWVALUE: + out = out + (*numbers)[i]->ReturnRawValue; + break; + case READOUT_TYPE_ERROR: + out = out + (*numbers)[i]->ErrorMessageText; + break; + } + if (i < (*numbers).size()-1) + out = out + "\r\n"; + } + // printf("OUT: %s", out.c_str()); + } return out; } @@ -564,66 +554,60 @@ esp_err_t ClassFlowControll::GetJPGStream(std::string _fn, httpd_req_t *req) { _send = flowalignment->ImageBasis; } - - - - if (_fn == "alg_roi.jpg") + else { - CImageBasis* _imgzw = new CImageBasis(flowalignment->ImageBasis); - flowalignment->DrawRef(_imgzw); - if (flowdigit) flowdigit->DrawROI(_imgzw); - if (flowanalog) flowanalog->DrawROI(_imgzw); + if (_fn == "alg_roi.jpg") + { + CImageBasis* _imgzw = new CImageBasis(flowalignment->ImageBasis); + flowalignment->DrawRef(_imgzw); + if (flowdigit) flowdigit->DrawROI(_imgzw); + if (flowanalog) flowanalog->DrawROI(_imgzw); + _send = _imgzw; + Dodelete = true; + } + else + { + std::vector htmlinfo; + htmlinfo = GetAllDigital(); + for (int i = 0; i < htmlinfo.size(); ++i) + { + if (_fn == htmlinfo[i]->filename) + { + if (htmlinfo[i]->image) + _send = htmlinfo[i]->image; + } + if (_fn == htmlinfo[i]->filename_org) + { + if (htmlinfo[i]->image_org) + _send = htmlinfo[i]->image_org; + } + delete htmlinfo[i]; + } + htmlinfo.clear(); -/*///////////////////////////////////// - cimg_library::CImg cimg(_imgzw->rgb_image, _imgzw->bpp, _imgzw->width, _imgzw->height, 1); - - //Convert cimg type -// cimg.permute_axes("yzcx"); - cimg.draw_text(300, 300, "Dies ist ein Test", "black"); + if (!_send) + { + htmlinfo = GetAllAnalog(); + for (int i = 0; i < htmlinfo.size(); ++i) + { + if (_fn == htmlinfo[i]->filename) + { + if (htmlinfo[i]->image) + _send = htmlinfo[i]->image; + } + if (_fn == htmlinfo[i]->filename_org) + { + if (htmlinfo[i]->image_org) + _send = htmlinfo[i]->image_org; + } + delete htmlinfo[i]; + } + htmlinfo.clear(); - - //Convert back to stb type to save -// cimg.permute_axes("cxyz"); -*//////////////////////////////////// - _send = _imgzw; - Dodelete = true; + } + } } - std::vector htmlinfo; - htmlinfo = GetAllDigital(); - for (int i = 0; i < htmlinfo.size(); ++i) - { - if (_fn == htmlinfo[i]->filename) - { - if (htmlinfo[i]->image) - _send = htmlinfo[i]->image; - } - if (_fn == htmlinfo[i]->filename_org) - { - if (htmlinfo[i]->image_org) - _send = htmlinfo[i]->image_org; - } - delete htmlinfo[i]; - } - htmlinfo.clear(); - - htmlinfo = GetAllAnalog(); - for (int i = 0; i < htmlinfo.size(); ++i) - { - if (_fn == htmlinfo[i]->filename) - { - if (htmlinfo[i]->image) - _send = htmlinfo[i]->image; - } - if (_fn == htmlinfo[i]->filename_org) - { - if (htmlinfo[i]->image_org) - _send = htmlinfo[i]->image_org; - } - delete htmlinfo[i]; - } - htmlinfo.clear(); - if (_send) { ESP_LOGI(TAG, "Sending file : %s ...", _fn.c_str()); diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.h b/code/components/jomjol_flowcontroll/ClassFlowControll.h index 339b496f..904259ef 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.h +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.h @@ -1,11 +1,11 @@ -#pragma once +#ifndef __FLOWCONTROLL__ +#define __FLOWCONTROLL__ #include #include "ClassFlow.h" #include "ClassFlowMakeImage.h" #include "ClassFlowAlignment.h" -//#include "ClassFlowDigit.h" #include "ClassFlowCNNGeneral.h" #include "ClassFlowPostProcessing.h" #include "ClassFlowMQTT.h" @@ -60,7 +60,7 @@ public: bool isAutoStart(long &_intervall); - std::string getActStatus(); + std::string* getActStatus(); std::vector GetAllDigital(); std::vector GetAllAnalog(); @@ -73,4 +73,6 @@ public: string name(){return "ClassFlowControll";}; }; +#endif + diff --git a/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h new file mode 100644 index 00000000..6295502b --- /dev/null +++ b/code/components/jomjol_flowcontroll/ClassFlowDefineTypes.h @@ -0,0 +1,52 @@ +#ifndef __CLASSFLOWIMAGE_CLASS__ +#define __CLASSFLOWIMAGE_CLASS__ + +#include "ClassFlowImage.h" + +struct roi { + int posx, posy, deltax, deltay; + float result_float; + int result_klasse; + string name; + CImageBasis *image, *image_org; +}; + +struct general { + string name; + std::vector ROI; +}; + + +struct NumberPost { + float MaxRateValue; + bool useMaxRateValue; + bool ErrorMessage; + bool PreValueOkay; + bool AllowNegativeRates; + bool checkDigitIncreaseConsistency; + time_t lastvalue; + string timeStamp; + float FlowRateAct; // m3 / min + float PreValue; // letzter Wert, der gut ausgelesen wurde + float Value; // letzer ausgelesener Wert, inkl. Korrekturen + string ReturnRawValue; // Rohwert (mit N & führenden 0) + string ReturnValue; // korrigierter Rückgabewert, ggf. mit Fehlermeldung + string ReturnPreValue; // korrigierter Rückgabewert ohne Fehlermeldung + string ReturnValueNoError; + string ErrorMessageText; // Fehlermeldung bei Consistency Check + int AnzahlAnalog; + int AnzahlDigital; + int DecimalShift; + int DecimalShiftInitial; + int Nachkomma; + + bool isExtendedResolution; + + general *digit_roi; + general *analog_roi; + + string name; +}; + +#endif + diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index 1d752f3e..9a918435 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -154,16 +154,16 @@ bool ClassFlowMQTT::doFlow(string zwtime) if (flowpostprocessing) { - std::vector NUMBERS = flowpostprocessing->GetNumbers(); + std::vector* NUMBERS = flowpostprocessing->GetNumbers(); - for (int i = 0; i < NUMBERS.size(); ++i) + for (int i = 0; i < (*NUMBERS).size(); ++i) { - result = NUMBERS[i]->ReturnValueNoError; - resulterror = NUMBERS[i]->ErrorMessageText; - resultrate = std::to_string(NUMBERS[i]->FlowRateAct); - resulttimestamp = NUMBERS[i]->timeStamp; + result = (*NUMBERS)[i]->ReturnValueNoError; + resulterror = (*NUMBERS)[i]->ErrorMessageText; + resultrate = std::to_string((*NUMBERS)[i]->FlowRateAct); + resulttimestamp = (*NUMBERS)[i]->timeStamp; - namenumber = NUMBERS[i]->name; + namenumber = (*NUMBERS)[i]->name; if (namenumber == "default") namenumber = maintopic + "/"; else diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp index b20ef9fc..2ff8a381 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.cpp @@ -1,5 +1,4 @@ #include "ClassFlowPostProcessing.h" - #include "Helper.h" #include "ClassFlowMakeImage.h" #include "ClassLogFile.h" @@ -124,7 +123,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void) if (NUMBERS[j]->digit_roi || NUMBERS[j]->analog_roi) { - NUMBERS[j]->ReturnValue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift); + NUMBERS[j]->ReturnValue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma); NUMBERS[j]->ReturnValueNoError = NUMBERS[j]->ReturnValue; } } @@ -186,7 +185,7 @@ bool ClassFlowPostProcessing::LoadPreValue(void) if (NUMBERS[0]->digit_roi || NUMBERS[0]->analog_roi) { - NUMBERS[0]->ReturnValue = RundeOutput(NUMBERS[0]->Value, NUMBERS[0]->AnzahlAnalog - NUMBERS[0]->DecimalShift); + NUMBERS[0]->ReturnValue = RundeOutput(NUMBERS[0]->Value, NUMBERS[0]->Nachkomma); NUMBERS[0]->ReturnValueNoError = NUMBERS[0]->ReturnValue; } @@ -241,7 +240,6 @@ ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector* lfc, C flowAnalog = _analog; flowDigit = _digit; - for (int i = 0; i < ListFlowControll->size(); ++i) { if (((*ListFlowControll)[i])->name().compare("ClassFlowMakeImage") == 0) @@ -251,6 +249,36 @@ ClassFlowPostProcessing::ClassFlowPostProcessing(std::vector* lfc, C } } +void ClassFlowPostProcessing::handleDecimalExtendedResolution(string _decsep, string _value) +{ + string _digit, _decpos; + int _pospunkt = _decsep.find_first_of("."); +// printf("Name: %s, Pospunkt: %d\n", _decsep.c_str(), _pospunkt); + if (_pospunkt > -1) + _digit = _decsep.substr(0, _pospunkt); + else + _digit = "default"; + + for (int j = 0; j < NUMBERS.size(); ++j) + { + bool _zwdc = false; + + if (toUpper(_value) == "TRUE") + _zwdc = true; + + if (_digit == "default") // erstmal auf default setzen (falls sonst nichts gesetzt) + { + NUMBERS[j]->isExtendedResolution = _zwdc; + } + + if (NUMBERS[j]->name == _digit) + { + NUMBERS[j]->isExtendedResolution = _zwdc; + } + } +} + + void ClassFlowPostProcessing::handleDecimalSeparator(string _decsep, string _value) { string _digit, _decpos; @@ -265,15 +293,15 @@ void ClassFlowPostProcessing::handleDecimalSeparator(string _decsep, string _val { int _zwdc = 0; - try +// try { _zwdc = stoi(_value); } - catch(const std::exception& e) +/* catch(const std::exception& e) { printf("ERROR - Decimalshift is not a number: %s\n", _value.c_str()); } - +*/ if (_digit == "default") // erstmal auf default setzen (falls sonst nichts gesetzt) { NUMBERS[j]->DecimalShift = _zwdc; @@ -304,15 +332,15 @@ void ClassFlowPostProcessing::handleMaxRateValue(string _decsep, string _value) { float _zwdc = 1; - try +// try { _zwdc = stof(_value); } - catch(const std::exception& e) +/* catch(const std::exception& e) { printf("ERROR - MaxRateValue is not a number: %s\n", _value.c_str()); } - +*/ if (_digit == "default") // erstmal auf default setzen (falls sonst nichts gesetzt) { @@ -352,6 +380,11 @@ bool ClassFlowPostProcessing::ReadParameter(FILE* pfile, string& aktparamgraph) zerlegt = this->ZerlegeZeile(aktparamgraph); std::string _param = GetParameterName(zerlegt[0]); + if ((toUpper(_param) == "EXTENDEDRESOLUTION") && (zerlegt.size() > 1)) + { + handleDecimalExtendedResolution(zerlegt[0], zerlegt[1]); + } + if ((toUpper(_param) == "DECIMALSHIFT") && (zerlegt.size() > 1)) { handleDecimalSeparator(zerlegt[0], zerlegt[1]); @@ -463,6 +496,7 @@ void ClassFlowPostProcessing::InitNUMBERS() _number->useMaxRateValue = false; _number->DecimalShift = 0; _number->DecimalShiftInitial = 0; + _number->isExtendedResolution = false; _number->FlowRateAct = 0; // m3 / min @@ -557,26 +591,23 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) NUMBERS[j]->ReturnRawValue = ""; NUMBERS[j]->ErrorMessageText = ""; - if (flowAnalog) NUMBERS[j]->AnzahlAnalog = flowAnalog->AnzahlROIs(j); - if (flowDigit) NUMBERS[j]->AnzahlDigital = flowDigit->AnzahlROIs(j); - - if (flowDigit->isExtendedResolution()) - NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial - 1; - - NUMBERS[j]->Nachkomma = NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift; - + UpdateNachkommaDecimalShift(); if (NUMBERS[j]->digit_roi) - NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j); + { + if (NUMBERS[j]->analog_roi) + NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, false); + else + NUMBERS[j]->ReturnRawValue = flowDigit->getReadout(j, NUMBERS[j]->isExtendedResolution); // Extended Resolution nur falls es keine analogen Ziffern gibt + } if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi) NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + "."; if (NUMBERS[j]->analog_roi) - NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + flowAnalog->getReadout(j); + NUMBERS[j]->ReturnRawValue = NUMBERS[j]->ReturnRawValue + flowAnalog->getReadout(j, NUMBERS[j]->isExtendedResolution); NUMBERS[j]->ReturnRawValue = ShiftDecimal(NUMBERS[j]->ReturnRawValue, NUMBERS[j]->DecimalShift); -///////////////// SPEZIALFALL für User Gustl /////////////////////////////////////////////////////// if (IgnoreLeadingNaN) { while ((NUMBERS[j]->ReturnRawValue.length() > 1) && (NUMBERS[j]->ReturnRawValue[0] == 'N')) @@ -584,7 +615,6 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) NUMBERS[j]->ReturnRawValue.erase(0, 1); } } -//////////////////////////////////////////////////////////////////////////////////////////////////// rohwert = NUMBERS[j]->ReturnRawValue; @@ -622,13 +652,13 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) NUMBERS[j]->Value = checkDigitConsistency(NUMBERS[j]->Value, NUMBERS[j]->DecimalShift, NUMBERS[j]->analog_roi != NULL, NUMBERS[j]->PreValue); } - zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift); + zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma); if ((!NUMBERS[j]->AllowNegativeRates) && (NUMBERS[j]->Value < NUMBERS[j]->PreValue)) { NUMBERS[j]->ErrorMessageText = NUMBERS[j]->ErrorMessageText + "Neg. Rate - Read: " + zwvalue + " - Raw: " + NUMBERS[j]->ReturnRawValue + " - Pre: " + RundeOutput(NUMBERS[j]->PreValue, NUMBERS[j]->Nachkomma) + " "; NUMBERS[j]->Value = NUMBERS[j]->PreValue; - zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->AnzahlAnalog - NUMBERS[j]->DecimalShift); + zwvalue = RundeOutput(NUMBERS[j]->Value, NUMBERS[j]->Nachkomma); } if (NUMBERS[j]->useMaxRateValue && (abs(NUMBERS[j]->Value - NUMBERS[j]->PreValue) > NUMBERS[j]->MaxRateValue)) @@ -663,6 +693,49 @@ bool ClassFlowPostProcessing::doFlow(string zwtime) return true; } + +void ClassFlowPostProcessing::UpdateNachkommaDecimalShift() +{ + for (int j = 0; j < NUMBERS.size(); ++j) + { + if (NUMBERS[j]->digit_roi && !NUMBERS[j]->analog_roi) // es gibt nur digitale ziffern + { +// printf("Nurdigital\n"); + NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial; + + if (NUMBERS[j]->isExtendedResolution && flowDigit->isExtendedResolution()) // extended resolution ist an und soll auch bei dieser Ziffer verwendet werden + NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShift-1; + + NUMBERS[j]->Nachkomma = -NUMBERS[j]->DecimalShift; + } + + if (!NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi) // es gibt nur analoge ziffern + { +// printf("Nur analog\n"); + NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial; + if (NUMBERS[j]->isExtendedResolution && flowAnalog->isExtendedResolution()) // extended resolution ist an und soll auch bei dieser Ziffer verwendet werden + NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShift-1; + + NUMBERS[j]->Nachkomma = -NUMBERS[j]->DecimalShift; + } + + if (NUMBERS[j]->digit_roi && NUMBERS[j]->analog_roi) // digital + analog + { +// printf("Nur digital + analog\n"); + + NUMBERS[j]->Nachkomma = NUMBERS[j]->analog_roi->ROI.size(); + NUMBERS[j]->DecimalShift = NUMBERS[j]->DecimalShiftInitial; + + if (NUMBERS[j]->isExtendedResolution && flowAnalog->isExtendedResolution()) // extended resolution ist an und soll auch bei dieser Ziffer verwendet werden + NUMBERS[j]->Nachkomma = NUMBERS[j]->Nachkomma+1; + + } + + printf("UpdateNachkommaDecShift NUMBER%i: Nachkomma %i, DecShift %i\n", j, NUMBERS[j]->Nachkomma,NUMBERS[j]->DecimalShift); + } +} + + string ClassFlowPostProcessing::getReadout(int _number) { return NUMBERS[_number]->ReturnValue; diff --git a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h index 7079fcc9..23a87124 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h +++ b/code/components/jomjol_flowcontroll/ClassFlowPostProcessing.h @@ -1,45 +1,13 @@ -#pragma once +#ifndef __FLOWPOSTPROCESSING__ +#define __FLOWPOSTPROCESSING__ + #include "ClassFlow.h" #include "ClassFlowMakeImage.h" #include "ClassFlowCNNGeneral.h" -#include "ClassFlowCNNGeneral.h" - +#include "ClassFlowDefineTypes.h" #include - -struct NumberPost { - float MaxRateValue; - bool useMaxRateValue; - bool ErrorMessage; - bool PreValueOkay; - bool AllowNegativeRates; - bool checkDigitIncreaseConsistency; - time_t lastvalue; - string timeStamp; - float FlowRateAct; // m3 / min - float PreValue; // letzter Wert, der gut ausgelesen wurde - float Value; // letzer ausgelesener Wert, inkl. Korrekturen - string ReturnRawValue; // Rohwert (mit N & führenden 0) - string ReturnValue; // korrigierter Rückgabewert, ggf. mit Fehlermeldung - string ReturnPreValue; // korrigierter Rückgabewert ohne Fehlermeldung - string ReturnValueNoError; - string ErrorMessageText; // Fehlermeldung bei Consistency Check - int AnzahlAnalog; - int AnzahlDigital; - int DecimalShift; - int DecimalShiftInitial; - int Nachkomma; - - general *digit_roi; - general *analog_roi; - - string name; -}; - - - - class ClassFlowPostProcessing : public ClassFlow { @@ -70,6 +38,8 @@ protected: void InitNUMBERS(); void handleDecimalSeparator(string _decsep, string _value); void handleMaxRateValue(string _decsep, string _value); + void handleDecimalExtendedResolution(string _decsep, string _value); + public: @@ -86,8 +56,13 @@ public: void SavePreValue(); string GetPreValue(std::string _number = ""); void SetPreValue(float zw, string _numbers, bool _extern = false); - std::vector GetNumbers(){return NUMBERS;}; + + void UpdateNachkommaDecimalShift(); + + std::vector* GetNumbers(){return &NUMBERS;}; string name(){return "ClassFlowPostProcessing";}; }; + +#endif diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index 07f7e7e0..d5479c31 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -83,17 +83,20 @@ FILE* OpenFileAndWait(const char* nm, const char* _mode, int _waitsec) printf("open config file %s in mode %s\n", nm, _mode); FILE *pfile = fopen(nm, _mode); +/* if (pfile == NULL) { TickType_t xDelay; xDelay = _waitsec * 1000 / portTICK_PERIOD_MS; - std::string zw = "File is locked: " + std::string(nm) + " - wait for " + std::to_string(_waitsec); + std::string zw = "File is locked: " + std::string(nm) + " - wait for " + std::to_string(_waitsec) + " seconds"; printf(zw.c_str()); printf("\n"); LogFile.WriteToFile(zw); vTaskDelay( xDelay ); pfile = fopen(nm, _mode); } +*/ + return pfile; } diff --git a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp index f6957e06..b97a122f 100644 --- a/code/components/jomjol_tfliteclass/CTfLiteClass.cpp +++ b/code/components/jomjol_tfliteclass/CTfLiteClass.cpp @@ -69,32 +69,6 @@ int CTfLiteClass::GetOutClassification(int _von, int _bis) return (zw_class - _von); } -/* -int CTfLiteClass::GetOutClassification() -{ - TfLiteTensor* output2 = interpreter->output(0); - - float zw_max = 0; - float zw; - int zw_class = -1; - - if (output2 == NULL) - return -1; - - int numeroutput = output2->dims->data[1]; - for (int i = 0; i < numeroutput; ++i) - { - zw = output2->data.f[i]; - if (zw > zw_max) - { - zw_max = zw; - zw_class = i; - } - } - return zw_class; -} -*/ - void CTfLiteClass::GetInputDimension(bool silent = false) { TfLiteTensor* input2 = this->interpreter->input(0); @@ -283,7 +257,7 @@ CTfLiteClass::CTfLiteClass() this->interpreter = nullptr; this->input = nullptr; this->output = nullptr; - this->kTensorArenaSize = 200 * 1024; /// laut testfile: 108000 - bisher 600 + this->kTensorArenaSize = 800 * 1024; /// laut testfile: 108000 - bisher 600;; 2021-09-11: 200 * 1024 this->tensor_arena = new uint8_t[kTensorArenaSize]; } diff --git a/code/components/jomjol_tfliteclass/server_tflite.cpp b/code/components/jomjol_tfliteclass/server_tflite.cpp index dbfa1ce1..354f9250 100644 --- a/code/components/jomjol_tfliteclass/server_tflite.cpp +++ b/code/components/jomjol_tfliteclass/server_tflite.cpp @@ -28,9 +28,6 @@ ClassFlowControll tfliteflow; TaskHandle_t xHandleblink_task_doFlow = NULL; TaskHandle_t xHandletask_autodoFlow = NULL; - - - bool flowisrunning = false; long auto_intervall = 0; @@ -283,48 +280,48 @@ esp_err_t handler_wasserzaehler(httpd_req_t *req) txt = txt + "Digital Counter:

"; httpd_resp_sendstr_chunk(req, txt.c_str()); - std::vector htmlinfo; - htmlinfo = tfliteflow.GetAllDigital(); - printf("Size of htmlinfo: %i\n", htmlinfo.size()); - for (int i = 0; i < htmlinfo.size(); ++i) + std::vector htmlinfodig; + htmlinfodig = tfliteflow.GetAllDigital(); + for (int i = 0; i < htmlinfodig.size(); ++i) { if (tfliteflow.GetTypeDigital() == Digital) { - if (htmlinfo[i]->val == 10) + if (htmlinfodig[i]->val == 10) zw = "NaN"; else - zw = to_string((int) htmlinfo[i]->val); + zw = to_string((int) htmlinfodig[i]->val); - txt = "filename + "\"> " + zw; + txt = "filename + "\"> " + zw; } else { std::stringstream stream; - stream << std::fixed << std::setprecision(1) << htmlinfo[i]->val; + stream << std::fixed << std::setprecision(1) << htmlinfodig[i]->val; zw = stream.str(); - txt = "filename + "\"> " + zw; + txt = "filename + "\"> " + zw; } httpd_resp_sendstr_chunk(req, txt.c_str()); - delete htmlinfo[i]; + delete htmlinfodig[i]; } - htmlinfo.clear(); + htmlinfodig.clear(); txt = "

Analog Meter:

"; httpd_resp_sendstr_chunk(req, txt.c_str()); - htmlinfo = tfliteflow.GetAllAnalog(); - for (int i = 0; i < htmlinfo.size(); ++i) + std::vector htmlinfoana; + htmlinfoana = tfliteflow.GetAllAnalog(); + for (int i = 0; i < htmlinfoana.size(); ++i) { std::stringstream stream; - stream << std::fixed << std::setprecision(1) << htmlinfo[i]->val; + stream << std::fixed << std::setprecision(1) << htmlinfoana[i]->val; zw = stream.str(); - txt = "filename + "\"> " + zw; + txt = "filename + "\"> " + zw; httpd_resp_sendstr_chunk(req, txt.c_str()); - delete htmlinfo[i]; + delete htmlinfoana[i]; } - htmlinfo.clear(); + htmlinfoana.clear(); } @@ -506,35 +503,6 @@ esp_err_t handler_editflow(httpd_req_t *req) httpd_resp_sendstr_chunk(req, zw.c_str()); } -/* - if (_task.compare("test_analog") == 0) - { - std::string _host = ""; - if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) { - _host = std::string(_valuechar); - } -// printf("Parameter host: "); printf(_host.c_str()); printf("\n"); -// string zwzw = "Do " + _task + " start\n"; printf(zwzw.c_str()); - std::string zw = tfliteflow.doSingleStep("[Analog]", _host); - httpd_resp_sendstr_chunk(req, zw.c_str()); - } -*/ -/* - if (_task.compare("test_digits") == 0) - { - std::string _host = ""; - if (httpd_query_key_value(_query, "host", _valuechar, 30) == ESP_OK) { - _host = std::string(_valuechar); - } -// printf("Parameter host: "); printf(_host.c_str()); printf("\n"); - -// string zwzw = "Do " + _task + " start\n"; printf(zwzw.c_str()); - std::string zw = tfliteflow.doSingleStep("[Digits]", _host); - httpd_resp_sendstr_chunk(req, zw.c_str()); - } -*/ - - /* Respond with an empty chunk to signal HTTP response completion */ httpd_resp_sendstr_chunk(req, NULL); @@ -553,15 +521,13 @@ esp_err_t handler_statusflow(httpd_req_t *req) #endif const char* resp_str; - string zw; #ifdef DEBUG_DETAIL_ON printf("handler_prevalue:\n"); printf(req->uri); printf("\n"); #endif - zw = tfliteflow.getActStatus(); - - resp_str = zw.c_str(); + string* zw = tfliteflow.getActStatus(); + resp_str = zw->c_str(); httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); httpd_resp_send(req, resp_str, strlen(resp_str)); diff --git a/code/components/jomjol_wlan/connect_wlan.cpp b/code/components/jomjol_wlan/connect_wlan.cpp index 38cf3a3c..13d6f227 100644 --- a/code/components/jomjol_wlan/connect_wlan.cpp +++ b/code/components/jomjol_wlan/connect_wlan.cpp @@ -50,14 +50,14 @@ std::string std_hostname = "watermeter"; std::string ipadress = ""; std::string ssid = ""; -std::string getIPAddress() +std::string* getIPAddress() { - return ipadress; + return &ipadress; } -std::string getSSID() +std::string* getSSID() { - return ssid; + return &ssid; } diff --git a/code/components/jomjol_wlan/connect_wlan.h b/code/components/jomjol_wlan/connect_wlan.h index 29f9889a..7dc1b609 100644 --- a/code/components/jomjol_wlan/connect_wlan.h +++ b/code/components/jomjol_wlan/connect_wlan.h @@ -7,8 +7,8 @@ void wifi_init_sta(const char *_ssid, const char *_password, const char *_hostna void wifi_init_sta(const char *_ssid, const char *_password, const char *_hostname); void wifi_init_sta(const char *_ssid, const char *_password); -std::string getIPAddress(); -std::string getSSID(); +std::string* getIPAddress(); +std::string* getSSID(); extern std::string hostname; extern std::string std_hostname; diff --git a/code/components/tfmicro.zip b/code/components/tfmicro.zip index 8da73d50..b8ea5596 100644 Binary files a/code/components/tfmicro.zip and b/code/components/tfmicro.zip differ diff --git a/code/components/tfmicro_new_version.zip b/code/components/tfmicro_new_version.zip new file mode 100644 index 00000000..98f57a42 Binary files /dev/null and b/code/components/tfmicro_new_version.zip differ diff --git a/code/main/Color.cpp b/code/main/Color.cpp new file mode 100644 index 00000000..b2beb9ac --- /dev/null +++ b/code/main/Color.cpp @@ -0,0 +1,132 @@ +#include "Color.h" +#include +#include +#include + +namespace { + +// Int -> fixed point +int up( int x ) { return x * 255; } + +} // namespace + +int iRgbSqrt( int num ) { + // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 + assert( "sqrt input should be non-negative" && num >= 0 ); + assert( "sqrt input should no exceed 16 bits" && num <= 0xFFFF ); + int res = 0; + int bit = 1 << 16; + while ( bit > num ) + bit >>= 2; + while ( bit != 0 ) { + if ( num >= res + bit ) { + num -= res + bit; + res = ( res >> 1 ) + bit; + } else + res >>= 1; + bit >>= 2; + } + return res; +} + +Rgb::Rgb( Hsv y ) { + // https://stackoverflow.com/questions/24152553/hsv-to-rgb-and-back-without-floating-point-math-in-python + // greyscale + if( y.s == 0 ) { + r = g = b = y.v; + return; + } + + const int region = y.h / 43; + const int remainder = ( y.h - ( region * 43 ) ) * 6; + + const int p = ( y.v * ( 255 - y.s ) ) >> 8; + const int q = ( y.v * ( 255 - ( ( y.s * remainder ) >> 8 ) ) ) >> 8; + const int t = ( y.v * ( 255 - ( ( y.s * (255 -remainder ) ) >> 8 ) ) ) >> 8; + + switch( region ) { + case 0: r = y.v; g = t; b = p; break; + case 1: r = q; g = y.v; b = p; break; + case 2: r = p; g = y.v; b = t; break; + case 3: r = p; g = q; b = y.v; break; + case 4: r = t; g = p; b = y.v; break; + case 5: r = y.v; g = p; b = q; break; + default: __builtin_trap(); + } + + a = y.a; +} + +Rgb& Rgb::operator=( Hsv hsv ) { + Rgb r{ hsv }; + swap( r ); + return *this; +} + +Rgb Rgb::operator+( Rgb in ) const { + auto copy = *this; + copy += in; + return copy; +} + +Rgb& Rgb::operator+=( Rgb in ) { + unsigned int red = r + in.r; + r = ( red < 255 ) ? red : 255; + unsigned int green = g + in.g; + g = ( green < 255 ) ? green : 255; + unsigned int blue = b + in.b; + b = ( blue < 255 ) ? blue : 255; + return *this; +} + +Rgb& Rgb::blend( Rgb in ) { + unsigned int inAlpha = in.a * ( 255 - a ); + unsigned int alpha = a + inAlpha; + r = iRgbSqrt( ( ( r * r * a ) + ( in.r * in.r * inAlpha ) ) / alpha ); + g = iRgbSqrt( ( ( g * g * a ) + ( in.g * in.g * inAlpha ) ) / alpha ); + b = iRgbSqrt( ( ( b * b * a ) + ( in.b * in.b * inAlpha ) ) / alpha ); + a = alpha; + return *this; +} + +uint8_t IRAM_ATTR Rgb::getGrb( int idx ) { + switch ( idx ) { + case 0: return g; + case 1: return r; + case 2: return b; + } + __builtin_unreachable(); +} + +Hsv::Hsv( Rgb r ) { + int min = std::min( r.r, std::min( r.g, r.b ) ); + int max = std::max( r.r, std::max( r.g, r.b ) ); + int chroma = max - min; + + v = max; + if ( chroma == 0 ) { + h = s = 0; + return; + } + + s = up( chroma ) / max; + int hh; + if ( max == r.r ) + hh = ( up( int( r.g ) - int( r.b ) ) ) / chroma / 6; + else if ( max == r.g ) + hh = 255 / 3 + ( up( int( r.b ) - int( r.r ) ) ) / chroma / 6; + else + hh = 2 * 255 / 3 + ( up( int( r.r ) - int( r.g ) ) ) / chroma / 6; + + if ( hh < 0 ) + hh += 255; + h = hh; + + a = r.a; +} + +Hsv& Hsv::operator=( Rgb rgb ) { + Hsv h{ rgb }; + swap( h ); + return *this; +} diff --git a/code/main/Color.h b/code/main/Color.h new file mode 100644 index 00000000..1923cf0b --- /dev/null +++ b/code/main/Color.h @@ -0,0 +1,69 @@ +#pragma once + +#include +#include "esp_attr.h" +union Hsv; + +union Rgb { + struct __attribute__ ((packed)) { + uint8_t r, g, b, a; + }; + uint32_t value; + + Rgb( uint8_t r = 0, uint8_t g = 0, uint8_t b = 0, uint8_t a = 255 ) : r( r ), g( g ), b( b ), a( a ) {} + Rgb( Hsv c ); + Rgb& operator=( Rgb rgb ) { swap( rgb ); return *this; } + Rgb& operator=( Hsv hsv ); + Rgb operator+( Rgb in ) const; + Rgb& operator+=( Rgb in ); + bool operator==( Rgb in ) const { return in.value == value; } + Rgb& blend( Rgb in ); + void swap( Rgb& o ) { value = o.value; } + void linearize() { + r = channelGamma(r); + g = channelGamma(g); + b = channelGamma(b); + } + + uint8_t IRAM_ATTR getGrb( int idx ); + + void stretchChannels( uint8_t maxR, uint8_t maxG, uint8_t maxB ) { + r = stretch( r, maxR ); + g = stretch( g, maxG ); + b = stretch( b, maxB ); + } + + void stretchChannelsEvenly( uint8_t max ) { + stretchChannels( max, max, max ); + } + +private: + uint8_t stretch( int value, uint8_t max ) { + return ( value * max ) >> 8; + } + + uint8_t channelGamma( int channel ) { + /* The optimal gamma correction is x^2.8. However, this is expensive to + * compute. Therefore, we use x^3 for gamma correction. Also, we add a + * bias as the WS2812 LEDs do not turn on for values less than 4. */ + if (channel == 0) + return channel; + channel = channel * channel * channel * 251; + channel >>= 24; + return static_cast< uint8_t >( 4 + channel ); + } +}; + +union Hsv { + struct __attribute__ ((packed)) { + uint8_t h, s, v, a; + }; + uint32_t value; + + Hsv( uint8_t h, uint8_t s = 0, uint8_t v = 0, uint8_t a = 255 ) : h( h ), s( s ), v( v ), a( a ) {} + Hsv( Rgb r ); + Hsv& operator=( Hsv h ) { swap( h ); return *this; } + Hsv& operator=( Rgb rgb ); + bool operator==( Hsv in ) const { return in.value == value; } + void swap( Hsv& o ) { value = o.value; } +}; diff --git a/code/main/SmartLeds.cpp b/code/main/SmartLeds.cpp new file mode 100644 index 00000000..a2ba7b29 --- /dev/null +++ b/code/main/SmartLeds.cpp @@ -0,0 +1,63 @@ +#include "SmartLeds.h" + +IsrCore SmartLed::_interruptCore = CoreCurrent; +intr_handle_t SmartLed::_interruptHandle = NULL; + +SmartLed*& IRAM_ATTR SmartLed::ledForChannel( int channel ) { + static SmartLed* table[8] = { nullptr }; + assert( channel < 8 ); + return table[ channel ]; +} + +void IRAM_ATTR SmartLed::interruptHandler(void*) { + for (int channel = 0; channel != 8; channel++) { + auto self = ledForChannel( channel ); + + if ( RMT.int_st.val & (1 << (24 + channel ) ) ) { // tx_thr_event + if ( self ) + self->copyRmtHalfBlock(); + RMT.int_clr.val |= 1 << ( 24 + channel ); + } else if ( RMT.int_st.val & ( 1 << (3 * channel ) ) ) { // tx_end + if ( self ) + xSemaphoreGiveFromISR( self->_finishedFlag, nullptr ); + RMT.int_clr.val |= 1 << ( 3 * channel ); + } + } +} + +void IRAM_ATTR SmartLed::copyRmtHalfBlock() { + int offset = detail::MAX_PULSES * _halfIdx; + _halfIdx = !_halfIdx; + int len = 3 - _componentPosition + 3 * ( _count - 1 ); + len = std::min( len, detail::MAX_PULSES / 8 ); + + if ( !len ) { + for ( int i = 0; i < detail::MAX_PULSES; i++) { + RMTMEM.chan[ _channel].data32[i + offset ].val = 0; + } + } + + int i; + for ( i = 0; i != len && _pixelPosition != _count; i++ ) { + uint8_t val = _buffer[ _pixelPosition ].getGrb( _componentPosition ); + for ( int j = 0; j != 8; j++, val <<= 1 ) { + int bit = val >> 7; + int idx = i * 8 + offset + j; + RMTMEM.chan[ _channel ].data32[ idx ].val = _bitToRmt[ bit & 0x01 ].value; + } + if ( _pixelPosition == _count - 1 && _componentPosition == 2 ) { + RMTMEM.chan[ _channel ].data32[ i * 8 + offset + 7 ].duration1 = + _timing.TRS / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + } + + _componentPosition++; + if ( _componentPosition == 3 ) { + _componentPosition = 0; + _pixelPosition++; + } + } + + for ( i *= 8; i != detail::MAX_PULSES; i++ ) { + RMTMEM.chan[ _channel ].data32[ i + offset ].val = 0; + } +} diff --git a/code/main/SmartLeds.h b/code/main/SmartLeds.h new file mode 100644 index 00000000..824eb337 --- /dev/null +++ b/code/main/SmartLeds.h @@ -0,0 +1,530 @@ +#pragma once + +/* + * A C++ driver for the WS2812 LEDs using the RMT peripheral on the ESP32. + * + * Jan "yaqwsx" Mrázek + * + * Based on the work by Martin F. Falatic - https://github.com/FozzTexx/ws2812-demo + */ + +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#if defined ( ARDUINO ) + extern "C" { // ...someone forgot to put in the includes... + #include "esp32-hal.h" + #include "esp_intr_alloc.h" + #include "esp_ipc.h" + #include "driver/gpio.h" + #include "driver/periph_ctrl.h" + #include "freertos/semphr.h" + #include "soc/rmt_struct.h" + #include + #include "esp_idf_version.h" +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL( 4, 0, 0 ) + #include "soc/dport_reg.h" +#endif + } +#elif defined ( ESP_PLATFORM ) + extern "C" { // ...someone forgot to put in the includes... + #include + #include + #include + #include + #include + #include + #include + #include + #include + } + #include +#endif + +#include "Color.h" + +namespace detail { + +struct TimingParams { + uint32_t T0H; + uint32_t T1H; + uint32_t T0L; + uint32_t T1L; + uint32_t TRS; +}; + +union RmtPulsePair { + struct { + int duration0:15; + int level0:1; + int duration1:15; + int level1:1; + }; + uint32_t value; +}; + +static const int DIVIDER = 4; // 8 still seems to work, but timings become marginal +static const int MAX_PULSES = 32; // A channel has a 64 "pulse" buffer - we use half per pass +static const double RMT_DURATION_NS = 12.5; // minimum time of a single RMT duration based on clock ns + +} // namespace detail + +using LedType = detail::TimingParams; + +static const LedType LED_WS2812 = { 350, 700, 800, 600, 50000 }; +static const LedType LED_WS2812B = { 400, 850, 850, 400, 50100 }; +static const LedType LED_SK6812 = { 300, 600, 900, 600, 80000 }; +static const LedType LED_WS2813 = { 350, 800, 350, 350, 300000 }; + +enum BufferType { SingleBuffer = 0, DoubleBuffer }; + +enum IsrCore { CoreFirst = 0, CoreSecond = 1, CoreCurrent = 2}; + +class SmartLed { +public: + // The RMT interrupt must not run on the same core as WiFi interrupts, otherwise SmartLeds + // can't fill the RMT buffer fast enough, resulting in rendering artifacts. + // Usually, that means you have to set isrCore == CoreSecond. + // + // If you use anything other than CoreCurrent, the FreeRTOS scheduler MUST be already running, + // so you can't use it if you define SmartLed as global variable. + SmartLed( const LedType& type, int count, int pin, int channel = 0, BufferType doubleBuffer = SingleBuffer, IsrCore isrCore = CoreCurrent) + : _timing( type ), + _channel( channel ), + _count( count ), + _firstBuffer( new Rgb[ count ] ), + _secondBuffer( doubleBuffer ? new Rgb[ count ] : nullptr ), + _finishedFlag( xSemaphoreCreateBinary() ) + { + assert( channel >= 0 && channel < 8 ); + assert( ledForChannel( channel ) == nullptr ); + + xSemaphoreGive( _finishedFlag ); + + DPORT_SET_PERI_REG_MASK( DPORT_PERIP_CLK_EN_REG, DPORT_RMT_CLK_EN ); + DPORT_CLEAR_PERI_REG_MASK( DPORT_PERIP_RST_EN_REG, DPORT_RMT_RST ); + + PIN_FUNC_SELECT( GPIO_PIN_MUX_REG[ pin ], 2 ); + gpio_set_direction( static_cast< gpio_num_t >( pin ), GPIO_MODE_OUTPUT ); + gpio_matrix_out( static_cast< gpio_num_t >( pin ), RMT_SIG_OUT0_IDX + _channel, 0, 0 ); + initChannel( _channel ); + + RMT.tx_lim_ch[ _channel ].limit = detail::MAX_PULSES; + RMT.int_ena.val |= 1 << ( 24 + _channel ); + RMT.int_ena.val |= 1 << ( 3 * _channel ); + + _bitToRmt[ 0 ].level0 = 1; + _bitToRmt[ 0 ].level1 = 0; + _bitToRmt[ 0 ].duration0 = _timing.T0H / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + _bitToRmt[ 0 ].duration1 = _timing.T0L / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + + _bitToRmt[ 1 ].level0 = 1; + _bitToRmt[ 1 ].level1 = 0; + _bitToRmt[ 1 ].duration0 = _timing.T1H / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + _bitToRmt[ 1 ].duration1 = _timing.T1L / ( detail::RMT_DURATION_NS * detail::DIVIDER ); + + if ( !anyAlive() ) { + _interruptCore = isrCore; + if(isrCore != CoreCurrent) { + ESP_ERROR_CHECK(esp_ipc_call_blocking(isrCore, registerInterrupt, NULL)); + } else { + registerInterrupt(NULL); + } + } + + ledForChannel( channel ) = this; + } + + ~SmartLed() { + ledForChannel( _channel ) = nullptr; + if ( !anyAlive() ) { + if(_interruptCore != CoreCurrent) { + ESP_ERROR_CHECK(esp_ipc_call_blocking(_interruptCore, unregisterInterrupt, NULL)); + } else { + unregisterInterrupt(NULL); + } + } + vSemaphoreDelete( _finishedFlag ); + } + + Rgb& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const Rgb& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + bool wait( TickType_t timeout = portMAX_DELAY ) { + if( xSemaphoreTake( _finishedFlag, timeout ) == pdTRUE ) { + xSemaphoreGive( _finishedFlag ); + return true; + } + return false; + } + + int size() const { + return _count; + } + + Rgb *begin() { return _firstBuffer.get(); } + const Rgb *begin() const { return _firstBuffer.get(); } + const Rgb *cbegin() const { return _firstBuffer.get(); } + + Rgb *end() { return _firstBuffer.get() + _count; } + const Rgb *end() const { return _firstBuffer.get() + _count; } + const Rgb *cend() const { return _firstBuffer.get() + _count; } + +private: + static intr_handle_t _interruptHandle; + static IsrCore _interruptCore; + + static void initChannel( int channel ) { + RMT.apb_conf.fifo_mask = 1; //enable memory access, instead of FIFO mode. + RMT.apb_conf.mem_tx_wrap_en = 1; //wrap around when hitting end of buffer + RMT.conf_ch[ channel ].conf0.div_cnt = detail::DIVIDER; + RMT.conf_ch[ channel ].conf0.mem_size = 1; + RMT.conf_ch[ channel ].conf0.carrier_en = 0; + RMT.conf_ch[ channel ].conf0.carrier_out_lv = 1; + RMT.conf_ch[ channel ].conf0.mem_pd = 0; + + RMT.conf_ch[ channel ].conf1.rx_en = 0; + RMT.conf_ch[ channel ].conf1.mem_owner = 0; + RMT.conf_ch[ channel ].conf1.tx_conti_mode = 0; //loop back mode. + RMT.conf_ch[ channel ].conf1.ref_always_on = 1; // use apb clock: 80M + RMT.conf_ch[ channel ].conf1.idle_out_en = 1; + RMT.conf_ch[ channel ].conf1.idle_out_lv = 0; + } + + static void registerInterrupt(void *) { + ESP_ERROR_CHECK(esp_intr_alloc( ETS_RMT_INTR_SOURCE, 0, interruptHandler, nullptr, &_interruptHandle)); + } + + static void unregisterInterrupt(void*) { + esp_intr_free( _interruptHandle ); + } + + static SmartLed*& IRAM_ATTR ledForChannel( int channel ); + static void IRAM_ATTR interruptHandler( void* ); + + void IRAM_ATTR copyRmtHalfBlock(); + + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + // Invalid use of the library + if( xSemaphoreTake( _finishedFlag, 0 ) != pdTRUE ) + abort(); + + _pixelPosition = _componentPosition = _halfIdx = 0; + copyRmtHalfBlock(); + if ( _pixelPosition < _count ) + copyRmtHalfBlock(); + + RMT.conf_ch[ _channel ].conf1.mem_rd_rst = 1; + RMT.conf_ch[ _channel ].conf1.tx_start = 1; + } + + static bool anyAlive() { + for ( int i = 0; i != 8; i++ ) + if ( ledForChannel( i ) != nullptr ) return true; + return false; + } + + const LedType& _timing; + int _channel; + detail::RmtPulsePair _bitToRmt[ 2 ]; + int _count; + std::unique_ptr< Rgb[] > _firstBuffer; + std::unique_ptr< Rgb[] > _secondBuffer; + Rgb *_buffer; + + xSemaphoreHandle _finishedFlag; + + int _pixelPosition; + int _componentPosition; + int _halfIdx; +}; + +class Apa102 { +public: + struct ApaRgb { + ApaRgb( uint8_t r = 0, uint8_t g = 0, uint32_t b = 0, uint32_t v = 0xFF ) + : v( 0xE0 | v ), b( b ), g( g ), r( r ) + {} + + ApaRgb& operator=( const Rgb& o ) { + r = o.r; + g = o.g; + b = o.b; + return *this; + } + + ApaRgb& operator=( const Hsv& o ) { + *this = Rgb{ o }; + return *this; + } + + uint8_t v, b, g, r; + }; + + static const int FINAL_FRAME_SIZE = 4; + static const int TRANS_COUNT = 2 + 8; + + Apa102( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer ) + : _count( count ), + _firstBuffer( new ApaRgb[ count ] ), + _secondBuffer( doubleBuffer ? new ApaRgb[ count ] : nullptr ), + _initFrame( 0 ) + { + spi_bus_config_t buscfg; + memset( &buscfg, 0, sizeof( buscfg ) ); + buscfg.mosi_io_num = datapin; + buscfg.miso_io_num = -1; + buscfg.sclk_io_num = clkpin; + buscfg.quadwp_io_num = -1; + buscfg.quadhd_io_num = -1; + buscfg.max_transfer_sz = 65535; + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( devcfg ) ); + devcfg.clock_speed_hz = 1000000; + devcfg.mode = 0; + devcfg.spics_io_num = -1; + devcfg.queue_size = TRANS_COUNT; + devcfg.pre_cb = nullptr; + + auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 ); + assert( ret == ESP_OK ); + + ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi ); + assert( ret == ESP_OK ); + + std::fill_n( _finalFrame, FINAL_FRAME_SIZE, 0xFFFFFFFF ); + } + + ~Apa102() { + // ToDo + } + + ApaRgb& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const ApaRgb& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + void wait() { + for ( int i = 0; i != _transCount; i++ ) { + spi_transaction_t *t; + spi_device_get_trans_result( _spi, &t, portMAX_DELAY ); + } + } +private: + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + for ( int i = 0; i != TRANS_COUNT; i++ ) { + _transactions[ i ].cmd = 0; + _transactions[ i ].addr = 0; + _transactions[ i ].flags = 0; + _transactions[ i ].rxlength = 0; + _transactions[ i ].rx_buffer = nullptr; + } + // Init frame + _transactions[ 0 ].length = 32; + _transactions[ 0 ].tx_buffer = &_initFrame; + spi_device_queue_trans( _spi, _transactions + 0, portMAX_DELAY ); + // Data + _transactions[ 1 ].length = 32 * _count; + _transactions[ 1 ].tx_buffer = _buffer; + spi_device_queue_trans( _spi, _transactions + 1, portMAX_DELAY ); + _transCount = 2; + // End frame + for ( int i = 0; i != 1 + _count / 32 / FINAL_FRAME_SIZE; i++ ) { + _transactions[ 2 + i ].length = 32 * FINAL_FRAME_SIZE; + _transactions[ 2 + i ].tx_buffer = _finalFrame; + spi_device_queue_trans( _spi, _transactions + 2 + i, portMAX_DELAY ); + _transCount++; + } + } + + spi_device_handle_t _spi; + int _count; + std::unique_ptr< ApaRgb[] > _firstBuffer, _secondBuffer; + ApaRgb *_buffer; + + spi_transaction_t _transactions[ TRANS_COUNT ]; + int _transCount; + + uint32_t _initFrame; + uint32_t _finalFrame[ FINAL_FRAME_SIZE ]; +}; + +class LDP8806 { +public: + struct LDP8806_GRB { + + LDP8806_GRB( uint8_t g_7bit = 0, uint8_t r_7bit = 0, uint32_t b_7bit = 0 ) + : g( g_7bit ), r( r_7bit ), b( b_7bit ) + { + } + + LDP8806_GRB& operator=( const Rgb& o ) { + //Convert 8->7bit colour + r = ( o.r * 127 / 256 ) | 0x80; + g = ( o.g * 127 / 256 ) | 0x80; + b = ( o.b * 127 / 256 ) | 0x80; + return *this; + } + + LDP8806_GRB& operator=( const Hsv& o ) { + *this = Rgb{ o }; + return *this; + } + + uint8_t g, r, b; + }; + + static const int LED_FRAME_SIZE_BYTES = sizeof( LDP8806_GRB ); + static const int LATCH_FRAME_SIZE_BYTES = 3; + static const int TRANS_COUNT_MAX = 20;//Arbitrary, supports up to 600 LED + + LDP8806( int count, int clkpin, int datapin, BufferType doubleBuffer = SingleBuffer, uint32_t clock_speed_hz = 2000000 ) + : _count( count ), + _firstBuffer( new LDP8806_GRB[ count ] ), + _secondBuffer( doubleBuffer ? new LDP8806_GRB[ count ] : nullptr ), + // one 'latch'/start-of-data mark frame for every 32 leds + _latchFrames( ( count + 31 ) / 32 ) + { + spi_bus_config_t buscfg; + memset( &buscfg, 0, sizeof( buscfg ) ); + buscfg.mosi_io_num = datapin; + buscfg.miso_io_num = -1; + buscfg.sclk_io_num = clkpin; + buscfg.quadwp_io_num = -1; + buscfg.quadhd_io_num = -1; + buscfg.max_transfer_sz = 65535; + + spi_device_interface_config_t devcfg; + memset( &devcfg, 0, sizeof( devcfg ) ); + devcfg.clock_speed_hz = clock_speed_hz; + devcfg.mode = 0; + devcfg.spics_io_num = -1; + devcfg.queue_size = TRANS_COUNT_MAX; + devcfg.pre_cb = nullptr; + + auto ret = spi_bus_initialize( HSPI_HOST, &buscfg, 1 ); + assert( ret == ESP_OK ); + + ret = spi_bus_add_device( HSPI_HOST, &devcfg, &_spi ); + assert( ret == ESP_OK ); + + std::fill_n( _latchBuffer, LATCH_FRAME_SIZE_BYTES, 0x0 ); + } + + ~LDP8806() { + // noop + } + + LDP8806_GRB& operator[]( int idx ) { + return _firstBuffer[ idx ]; + } + + const LDP8806_GRB& operator[]( int idx ) const { + return _firstBuffer[ idx ]; + } + + void show() { + _buffer = _firstBuffer.get(); + startTransmission(); + swapBuffers(); + } + + void wait() { + while ( _transCount-- ) { + spi_transaction_t *t; + spi_device_get_trans_result( _spi, &t, portMAX_DELAY ); + } + } +private: + void swapBuffers() { + if ( _secondBuffer ) + _firstBuffer.swap( _secondBuffer ); + } + + void startTransmission() { + _transCount = 0; + for ( int i = 0; i != TRANS_COUNT_MAX; i++ ) { + _transactions[ i ].cmd = 0; + _transactions[ i ].addr = 0; + _transactions[ i ].flags = 0; + _transactions[ i ].rxlength = 0; + _transactions[ i ].rx_buffer = nullptr; + } + // LED Data + _transactions[ 0 ].length = ( LED_FRAME_SIZE_BYTES * 8 ) * _count; + _transactions[ 0 ].tx_buffer = _buffer; + spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY ); + _transCount++; + + // 'latch'/start-of-data marker frames + for ( int i = 0; i < _latchFrames; i++ ) { + _transactions[ _transCount ].length = ( LATCH_FRAME_SIZE_BYTES * 8 ); + _transactions[ _transCount ].tx_buffer = _latchBuffer; + spi_device_queue_trans( _spi, _transactions + _transCount, portMAX_DELAY ); + _transCount++; + } + } + + spi_device_handle_t _spi; + int _count; + std::unique_ptr< LDP8806_GRB[] > _firstBuffer, _secondBuffer; + LDP8806_GRB *_buffer; + + spi_transaction_t _transactions[ TRANS_COUNT_MAX ]; + int _transCount; + + int _latchFrames; + uint8_t _latchBuffer[ LATCH_FRAME_SIZE_BYTES ]; +}; diff --git a/code/main/main.cpp b/code/main/main.cpp index 145f862f..9b2947fa 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -28,6 +28,9 @@ #include "server_main.h" #include "server_camera.h" +// #include "jomjol_WS2812Slow.h" +#include "SmartLeds.h" + #define __SD_USE_ONE_LINE_MODE__ @@ -135,8 +138,12 @@ void task_NoSDBlink(void *pvParameter) vTaskDelete(NULL); //Delete this task if it exits from the loop above } + extern "C" void app_main(void) { + TickType_t xDelay; + + printf("Do Reset Camera\n"); PowerResetCamera(); Camera.InitCam(); @@ -171,7 +178,7 @@ extern "C" void app_main(void) wifi_init_sta(ssid, passwd, hostname, ip, gateway, netmask, dns); - TickType_t xDelay; + xDelay = 2000 / portTICK_PERIOD_MS; printf("main: sleep for : %ldms\n", (long) xDelay); // LogFile.WriteToFile("Startsequence 06"); @@ -184,6 +191,9 @@ extern "C" void app_main(void) LogFile.WriteToFile("============================================================================================="); LogFile.SwitchOnOff(false); + + + std::string zw = gettimestring("%Y%m%d-%H%M%S"); printf("time %s\n", zw.c_str()); diff --git a/code/main/server_main.cpp b/code/main/server_main.cpp index b06eca6a..a180aa03 100644 --- a/code/main/server_main.cpp +++ b/code/main/server_main.cpp @@ -47,11 +47,11 @@ esp_err_t info_get_handler(httpd_req_t *req) } }; + httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*"); + if (_task.compare("GitBranch") == 0) { - std::string zw; - zw = std::string(libfive_git_branch()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, libfive_git_branch()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } @@ -59,9 +59,7 @@ esp_err_t info_get_handler(httpd_req_t *req) if (_task.compare("GitTag") == 0) { - std::string zw; - zw = std::string(libfive_git_version()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, libfive_git_version()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } @@ -70,36 +68,30 @@ esp_err_t info_get_handler(httpd_req_t *req) if (_task.compare("GitRevision") == 0) { - std::string zw; - zw = std::string(libfive_git_revision()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, libfive_git_revision()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } if (_task.compare("BuildTime") == 0) { - std::string zw; - zw = std::string(build_time()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, build_time()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } if (_task.compare("GitBaseBranch") == 0) { - std::string zw; - zw = std::string(git_base_branch()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + httpd_resp_sendstr_chunk(req, git_base_branch()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } if (_task.compare("HTMLVersion") == 0) { - std::string zw; - zw = std::string(getHTMLversion()); - httpd_resp_sendstr_chunk(req, zw.c_str()); +// std::string zw; +// zw = std::string(getHTMLversion()); + httpd_resp_sendstr_chunk(req, getHTMLversion()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } @@ -115,18 +107,18 @@ esp_err_t info_get_handler(httpd_req_t *req) if (_task.compare("IP") == 0) { - std::string zw; - zw = std::string(getIPAddress()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + std::string *zw; + zw = getIPAddress(); + httpd_resp_sendstr_chunk(req, zw->c_str()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } if (_task.compare("SSID") == 0) { - std::string zw; - zw = std::string(getSSID()); - httpd_resp_sendstr_chunk(req, zw.c_str()); + std::string *zw; + zw = getSSID(); + httpd_resp_sendstr_chunk(req, zw->c_str()); httpd_resp_sendstr_chunk(req, NULL); return ESP_OK; } @@ -140,28 +132,15 @@ esp_err_t info_get_handler(httpd_req_t *req) return ESP_OK; } - -#ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("info_get_handler - Done"); -#endif - return ESP_OK; } esp_err_t starttime_get_handler(httpd_req_t *req) { -#ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("starttime_get_handler - Start"); -#endif - httpd_resp_send(req, starttime.c_str(), strlen(starttime.c_str())); /* Respond with an empty chunk to signal HTTP response completion */ httpd_resp_send_chunk(req, NULL, 0); -#ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("starttime_get_handler - Done"); -#endif - return ESP_OK; } @@ -215,12 +194,15 @@ esp_err_t hello_main_handler(httpd_req_t *req) } res = send_file(req, filetosend); + /* Respond with an empty chunk to signal HTTP response completion */ + httpd_resp_send_chunk(req, NULL, 0); + if (res != ESP_OK) return res; /* Respond with an empty chunk to signal HTTP response completion */ // httpd_resp_sendstr(req, ""); - httpd_resp_send_chunk(req, NULL, 0); +// httpd_resp_send_chunk(req, NULL, 0); #ifdef DEBUG_DETAIL_ON LogFile.WriteHeapInfo("hello_main_handler - Stop"); @@ -297,10 +279,6 @@ esp_err_t img_tmp_virtual_handler(httpd_req_t *req) esp_err_t sysinfo_handler(httpd_req_t *req) { -#ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("sysinfo_handler - Start"); -#endif - const char* resp_str; std::string zw; std::string cputemp = std::to_string(temperatureRead()); @@ -331,7 +309,6 @@ esp_err_t sysinfo_handler(httpd_req_t *req) }\ ]"; - resp_str = zw.c_str(); httpd_resp_set_type(req, "application/json"); @@ -339,10 +316,6 @@ esp_err_t sysinfo_handler(httpd_req_t *req) /* Respond with an empty chunk to signal HTTP response completion */ httpd_resp_send_chunk(req, NULL, 0); -#ifdef DEBUG_DETAIL_ON - LogFile.WriteHeapInfo("sysinfo_handler - Done"); -#endif - return ESP_OK; } @@ -399,25 +372,24 @@ httpd_handle_t start_webserver(void) httpd_handle_t server = NULL; httpd_config_t config = { }; - config.task_priority = tskIDLE_PRIORITY+5; - config.stack_size = 32768; // bei 32k stürzt das Programm beim Bilderaufnehmen ab + config.task_priority = tskIDLE_PRIORITY+1; // 20210924 --> vorher +5 + config.stack_size = 32768; //20210921 --> vorher 32768 // bei 32k stürzt das Programm beim Bilderaufnehmen ab config.core_id = tskNO_AFFINITY; config.server_port = 80; config.ctrl_port = 32768; - config.max_open_sockets = 7; + config.max_open_sockets = 5; //20210921 --> vorher 7 config.max_uri_handlers = 24; config.max_resp_headers = 8; config.backlog_conn = 5; - config.lru_purge_enable = true; // dadurch werden alter Verbindungen gekappt, falls neue benögt werden. - config.recv_wait_timeout = 30; // default: 5 - config.send_wait_timeout = 30; // default: 5 + config.lru_purge_enable = true; // dadurch werden alte Verbindungen gekappt, falls neue benögt werden. + config.recv_wait_timeout = 5; // default: 5 20210924 --> vorher 30 + config.send_wait_timeout = 5; // default: 5 20210924 --> vorher 30 config.global_user_ctx = NULL; config.global_user_ctx_free_fn = NULL; config.global_transport_ctx = NULL; config.global_transport_ctx_free_fn = NULL; config.open_fn = NULL; config.close_fn = NULL; - config.lru_purge_enable = true; // neu, um schlechte Serverbindung zu verhindern // config.uri_match_fn = NULL; config.uri_match_fn = httpd_uri_match_wildcard; diff --git a/code/main/version.cpp b/code/main/version.cpp index 893450de..55c22f5e 100644 --- a/code/main/version.cpp +++ b/code/main/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="7fcb5d1"; +const char* GIT_REV="f15e5f0"; const char* GIT_TAG=""; -const char* GIT_BRANCH="master"; -const char* BUILD_TIME="2021-09-12 07:30"; \ No newline at end of file +const char* GIT_BRANCH="rolling"; +const char* BUILD_TIME="2021-09-24 19:25"; \ No newline at end of file diff --git a/code/main/version.h b/code/main/version.h index eb5e597a..498acfd6 100644 --- a/code/main/version.h +++ b/code/main/version.h @@ -13,7 +13,7 @@ extern "C" #include "Helper.h" #include -const char* GIT_BASE_BRANCH = "master - v8.3.0 - 2021-09-12"; +const char* GIT_BASE_BRANCH = "master - v8.4.0 - 2021-09-24"; const char* git_base_branch(void) @@ -42,21 +42,19 @@ const char* libfive_git_branch(void) return GIT_BRANCH; } -std::string getHTMLversion(void){ - - string line = ""; - + +char _char_getHTMLversion[20]="NaN\0"; + +const char* getHTMLversion(void){ FILE* pFile; string fn = FormatFileName("/sdcard/html/version.txt"); pFile = fopen(fn.c_str(), "r"); if (pFile == NULL) - return std::string("NAN"); + return _char_getHTMLversion; - char zw[1024]; - fgets(zw, 1024, pFile); - line = std::string(trim(zw)); + fgets(_char_getHTMLversion, 20, pFile); fclose(pFile); - return line; + return _char_getHTMLversion; } \ No newline at end of file diff --git a/code/sdkconfig b/code/sdkconfig index bf0da769..71eeba50 100644 --- a/code/sdkconfig +++ b/code/sdkconfig @@ -389,7 +389,7 @@ CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 CONFIG_ESP_INT_WDT_CHECK_CPU1=y CONFIG_ESP_TASK_WDT=y # CONFIG_ESP_TASK_WDT_PANIC is not set -CONFIG_ESP_TASK_WDT_TIMEOUT_S=3 +CONFIG_ESP_TASK_WDT_TIMEOUT_S=6 CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_ESP_PANIC_HANDLER_IRAM is not set @@ -1107,7 +1107,7 @@ CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y # CONFIG_TASK_WDT_PANIC is not set -CONFIG_TASK_WDT_TIMEOUT_S=3 +CONFIG_TASK_WDT_TIMEOUT_S=6 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y # CONFIG_EVENT_LOOP_PROFILING is not set diff --git a/code/sdkconfig.esp32cam b/code/sdkconfig.esp32cam new file mode 100644 index 00000000..08dc98a1 --- /dev/null +++ b/code/sdkconfig.esp32cam @@ -0,0 +1,1300 @@ +# +# Automatically generated file. DO NOT EDIT. +# Espressif IoT Development Framework (ESP-IDF) Project Configuration +# +CONFIG_IDF_CMAKE=y +CONFIG_IDF_TARGET_ARCH_XTENSA=y +CONFIG_IDF_TARGET="esp32" +CONFIG_IDF_TARGET_ESP32=y +CONFIG_IDF_FIRMWARE_CHIP_ID=0x0000 + +# +# SDK tool configuration +# +CONFIG_SDK_TOOLPREFIX="xtensa-esp32-elf-" +# CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS is not set +# end of SDK tool configuration + +# +# Build type +# +CONFIG_APP_BUILD_TYPE_APP_2NDBOOT=y +# CONFIG_APP_BUILD_TYPE_ELF_RAM is not set +CONFIG_APP_BUILD_GENERATE_BINARIES=y +CONFIG_APP_BUILD_BOOTLOADER=y +CONFIG_APP_BUILD_USE_FLASH_SECTIONS=y +# end of Build type + +# +# Application manager +# +CONFIG_APP_COMPILE_TIME_DATE=y +# CONFIG_APP_EXCLUDE_PROJECT_VER_VAR is not set +# CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR is not set +# CONFIG_APP_PROJECT_VER_FROM_CONFIG is not set +CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 +# end of Application manager + +# +# Bootloader config +# +CONFIG_BOOTLOADER_OFFSET_IN_FLASH=0x1000 +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_NONE is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_ERROR is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_WARN is not set +CONFIG_BOOTLOADER_LOG_LEVEL_INFO=y +# CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG is not set +# CONFIG_BOOTLOADER_LOG_LEVEL_VERBOSE is not set +CONFIG_BOOTLOADER_LOG_LEVEL=3 +# CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_8V is not set +CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y +# CONFIG_BOOTLOADER_FACTORY_RESET is not set +# CONFIG_BOOTLOADER_APP_TEST is not set +CONFIG_BOOTLOADER_WDT_ENABLE=y +# CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE is not set +CONFIG_BOOTLOADER_WDT_TIME_MS=9000 +# CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON is not set +# CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS is not set +CONFIG_BOOTLOADER_RESERVE_RTC_SIZE=0 +# CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC is not set +# end of Bootloader config + +# +# Security features +# +# CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT is not set +# CONFIG_SECURE_BOOT is not set +# CONFIG_SECURE_FLASH_ENC_ENABLED is not set +# end of Security features + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 +# CONFIG_ESPTOOLPY_NO_STUB is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QIO is not set +# CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE_DIO=y +# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set +CONFIG_ESPTOOLPY_FLASHMODE="dio" +# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set +CONFIG_ESPTOOLPY_FLASHFREQ_40M=y +# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set +# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set +CONFIG_ESPTOOLPY_FLASHFREQ="40m" +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="2MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y +CONFIG_ESPTOOLPY_BEFORE_RESET=y +# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set +CONFIG_ESPTOOLPY_BEFORE="default_reset" +CONFIG_ESPTOOLPY_AFTER_RESET=y +# CONFIG_ESPTOOLPY_AFTER_NORESET is not set +CONFIG_ESPTOOLPY_AFTER="hard_reset" +# CONFIG_ESPTOOLPY_MONITOR_BAUD_CONSOLE is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_9600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_57600B is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y +# CONFIG_ESPTOOLPY_MONITOR_BAUD_230400B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_921600B is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_2MB is not set +# CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER is not set +CONFIG_ESPTOOLPY_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_ESPTOOLPY_MONITOR_BAUD=115200 +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_SINGLE_APP=y +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +# CONFIG_PARTITION_TABLE_CUSTOM is not set +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# Example Connection Configuration +# +CONFIG_EXAMPLE_CONNECT_WIFI=y +CONFIG_EXAMPLE_WIFI_SSID="myssid" +CONFIG_EXAMPLE_WIFI_PASSWORD="mypassword" +# CONFIG_EXAMPLE_CONNECT_ETHERNET is not set +CONFIG_EXAMPLE_CONNECT_IPV6=y +CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK=y +# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL is not set +# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL is not set +# CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL is not set +# end of Example Connection Configuration + +# +# Compiler options +# +CONFIG_COMPILER_OPTIMIZATION_DEFAULT=y +# CONFIG_COMPILER_OPTIMIZATION_SIZE is not set +# CONFIG_COMPILER_OPTIMIZATION_PERF is not set +# CONFIG_COMPILER_OPTIMIZATION_NONE is not set +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set +# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +# CONFIG_COMPILER_CXX_RTTI is not set +CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y +# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_STRONG is not set +# CONFIG_COMPILER_STACK_CHECK_MODE_ALL is not set +# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set +# CONFIG_COMPILER_DISABLE_GCC8_WARNINGS is not set +# CONFIG_COMPILER_DUMP_RTL_FILES is not set +# end of Compiler options + +# +# Component config +# + +# +# Application Level Tracing +# +# CONFIG_APPTRACE_DEST_TRAX is not set +CONFIG_APPTRACE_DEST_NONE=y +CONFIG_APPTRACE_LOCK_ENABLE=y +# end of Application Level Tracing + +# +# ESP-ASIO +# +# CONFIG_ASIO_SSL_SUPPORT is not set +# end of ESP-ASIO + +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 +CONFIG_BTDM_CTRL_PCM_ROLE_EFF=0 +CONFIG_BTDM_CTRL_PCM_POLAR_EFF=0 +CONFIG_BTDM_CTRL_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CTRL_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CTRL_PINNED_TO_CORE=0 +CONFIG_BTDM_BLE_SLEEP_CLOCK_ACCURACY_INDEX_EFF=1 +CONFIG_BT_CTRL_MODE_EFF=1 +CONFIG_BT_CTRL_BLE_MAX_ACT=10 +CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=10 +CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0 +CONFIG_BT_CTRL_PINNED_TO_CORE=0 +CONFIG_BT_CTRL_HCI_TL=1 +CONFIG_BT_CTRL_ADV_DUP_FILT_MAX=30 +CONFIG_BT_CTRL_HW_CCA_EFF=0 +CONFIG_BT_CTRL_DFT_TX_POWER_LEVEL_EFF=0 +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_SUPP=y +CONFIG_BT_CTRL_BLE_ADV_REPORT_FLOW_CTRL_NUM=100 +CONFIG_BT_CTRL_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 +CONFIG_BT_CTRL_BLE_SCAN_DUPL=y +CONFIG_BT_CTRL_SCAN_DUPL_TYPE=0 +CONFIG_BT_CTRL_SCAN_DUPL_CACHE_SIZE=100 +CONFIG_BT_CTRL_COEX_PHY_CODED_TX_RX_TLIM_EFF=0 +CONFIG_BT_CTRL_SLEEP_MODE_EFF=0 +CONFIG_BT_CTRL_SLEEP_CLOCK_EFF=0 +CONFIG_BT_CTRL_HCI_TL_EFF=1 +CONFIG_BT_RESERVE_DRAM=0 +# end of Bluetooth + +# +# CoAP Configuration +# +CONFIG_COAP_MBEDTLS_PSK=y +# CONFIG_COAP_MBEDTLS_PKI is not set +# CONFIG_COAP_MBEDTLS_DEBUG is not set +CONFIG_COAP_LOG_DEFAULT_LEVEL=0 +# end of CoAP Configuration + +# +# Driver configurations +# + +# +# ADC configuration +# +# CONFIG_ADC_FORCE_XPD_FSM is not set +CONFIG_ADC_DISABLE_DAC=y +# end of ADC configuration + +# +# SPI configuration +# +# CONFIG_SPI_MASTER_IN_IRAM is not set +CONFIG_SPI_MASTER_ISR_IN_IRAM=y +# CONFIG_SPI_SLAVE_IN_IRAM is not set +CONFIG_SPI_SLAVE_ISR_IN_IRAM=y +# end of SPI configuration + +# +# TWAI configuration +# +# CONFIG_TWAI_ISR_IN_IRAM is not set +# CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC is not set +# CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST is not set +# CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID is not set +# CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT is not set +# end of TWAI configuration + +# +# UART configuration +# +# CONFIG_UART_ISR_IN_IRAM is not set +# end of UART configuration + +# +# RTCIO configuration +# +# CONFIG_RTCIO_SUPPORT_RTC_GPIO_DESC is not set +# end of RTCIO configuration + +# +# GPIO Configuration +# +# CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL is not set +# end of GPIO Configuration +# end of Driver configurations + +# +# eFuse Bit Manager +# +# CONFIG_EFUSE_CUSTOM_TABLE is not set +# CONFIG_EFUSE_VIRTUAL is not set +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE is not set +CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y +# CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT is not set +CONFIG_EFUSE_MAX_BLK_LEN=192 +# end of eFuse Bit Manager + +# +# ESP-TLS +# +CONFIG_ESP_TLS_USING_MBEDTLS=y +# CONFIG_ESP_TLS_USE_SECURE_ELEMENT is not set +# CONFIG_ESP_TLS_SERVER is not set +# CONFIG_ESP_TLS_PSK_VERIFICATION is not set +# CONFIG_ESP_TLS_INSECURE is not set +# end of ESP-TLS + +# +# ESP32-specific +# +CONFIG_ESP32_REV_MIN_0=y +# CONFIG_ESP32_REV_MIN_1 is not set +# CONFIG_ESP32_REV_MIN_2 is not set +# CONFIG_ESP32_REV_MIN_3 is not set +CONFIG_ESP32_REV_MIN=0 +CONFIG_ESP32_DPORT_WORKAROUND=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_80 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_160=y +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=160 +# CONFIG_ESP32_SPIRAM_SUPPORT is not set +# CONFIG_ESP32_TRAX is not set +CONFIG_ESP32_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_TWO is not set +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES_FOUR=y +CONFIG_ESP32_UNIVERSAL_MAC_ADDRESSES=4 +# CONFIG_ESP32_ULP_COPROC_ENABLED is not set +CONFIG_ESP32_ULP_COPROC_RESERVE_MEM=0 +CONFIG_ESP32_DEBUG_OCDAWARE=y +CONFIG_ESP32_BROWNOUT_DET=y +CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_ESP32_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_ESP32_BROWNOUT_DET_LVL=0 +CONFIG_ESP32_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y +# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set +# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set +CONFIG_ESP32_RTC_CLK_SRC_INT_RC=y +# CONFIG_ESP32_RTC_CLK_SRC_EXT_CRYS is not set +# CONFIG_ESP32_RTC_CLK_SRC_EXT_OSC is not set +# CONFIG_ESP32_RTC_CLK_SRC_INT_8MD256 is not set +CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 +CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 +CONFIG_ESP32_XTAL_FREQ_40=y +# CONFIG_ESP32_XTAL_FREQ_26 is not set +# CONFIG_ESP32_XTAL_FREQ_AUTO is not set +CONFIG_ESP32_XTAL_FREQ=40 +# CONFIG_ESP32_DISABLE_BASIC_ROM_CONSOLE is not set +# CONFIG_ESP32_NO_BLOBS is not set +# CONFIG_ESP32_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +# CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE is not set +CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 +# end of ESP32-specific + +# +# ADC-Calibration +# +CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y +CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y +CONFIG_ADC_CAL_LUT_ENABLE=y +# end of ADC-Calibration + +# +# Common ESP-related +# +CONFIG_ESP_ERR_TO_NAME_LOOKUP=y +CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584 +CONFIG_ESP_IPC_TASK_STACK_SIZE=1024 +CONFIG_ESP_IPC_USES_CALLERS_PRIORITY=y +CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048 +CONFIG_ESP_CONSOLE_UART_DEFAULT=y +# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_NONE is not set +CONFIG_ESP_CONSOLE_UART=y +CONFIG_ESP_CONSOLE_MULTIPLE_UART=y +CONFIG_ESP_CONSOLE_UART_NUM=0 +CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 +CONFIG_ESP_INT_WDT=y +CONFIG_ESP_INT_WDT_TIMEOUT_MS=300 +CONFIG_ESP_INT_WDT_CHECK_CPU1=y +CONFIG_ESP_TASK_WDT=y +# CONFIG_ESP_TASK_WDT_PANIC is not set +CONFIG_ESP_TASK_WDT_TIMEOUT_S=5 +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_ESP_PANIC_HANDLER_IRAM is not set +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_STA=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_WIFI_AP=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_BT=y +CONFIG_ESP_MAC_ADDR_UNIVERSE_ETH=y +# end of Common ESP-related + +# +# Ethernet +# +CONFIG_ETH_ENABLED=y +CONFIG_ETH_USE_ESP32_EMAC=y +CONFIG_ETH_PHY_INTERFACE_RMII=y +# CONFIG_ETH_PHY_INTERFACE_MII is not set +CONFIG_ETH_RMII_CLK_INPUT=y +# CONFIG_ETH_RMII_CLK_OUTPUT is not set +CONFIG_ETH_RMII_CLK_IN_GPIO=0 +CONFIG_ETH_DMA_BUFFER_SIZE=512 +CONFIG_ETH_DMA_RX_BUFFER_NUM=10 +CONFIG_ETH_DMA_TX_BUFFER_NUM=10 +CONFIG_ETH_USE_SPI_ETHERNET=y +# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set +# CONFIG_ETH_SPI_ETHERNET_W5500 is not set +# CONFIG_ETH_USE_OPENETH is not set +# end of Ethernet + +# +# Event Loop Library +# +# CONFIG_ESP_EVENT_LOOP_PROFILING is not set +CONFIG_ESP_EVENT_POST_FROM_ISR=y +CONFIG_ESP_EVENT_POST_FROM_IRAM_ISR=y +# end of Event Loop Library + +# +# GDB Stub +# +# end of GDB Stub + +# +# ESP HTTP client +# +CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y +# CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH is not set +# end of ESP HTTP client + +# +# HTTP Server +# +CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 +CONFIG_HTTPD_MAX_URI_LEN=512 +CONFIG_HTTPD_ERR_RESP_NO_DELAY=y +CONFIG_HTTPD_PURGE_BUF_LEN=32 +# CONFIG_HTTPD_LOG_PURGE_DATA is not set +# CONFIG_HTTPD_WS_SUPPORT is not set +# end of HTTP Server + +# +# ESP HTTPS OTA +# +# CONFIG_OTA_ALLOW_HTTP is not set +# end of ESP HTTPS OTA + +# +# ESP HTTPS server +# +# CONFIG_ESP_HTTPS_SERVER_ENABLE is not set +# end of ESP HTTPS server + +# +# ESP NETIF Adapter +# +CONFIG_ESP_NETIF_IP_LOST_TIMER_INTERVAL=120 +CONFIG_ESP_NETIF_TCPIP_LWIP=y +# CONFIG_ESP_NETIF_LOOPBACK is not set +CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=y +# end of ESP NETIF Adapter + +# +# Power Management +# +# CONFIG_PM_ENABLE is not set +# end of Power Management + +# +# ESP System Settings +# +# CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT is not set +CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y +# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set +CONFIG_ESP_SYSTEM_PD_FLASH=y + +# +# Memory protection +# +# end of Memory protection +# end of ESP System Settings + +# +# High resolution timer (esp_timer) +# +# CONFIG_ESP_TIMER_PROFILING is not set +CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER=y +CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER=y +CONFIG_ESP_TIMER_TASK_STACK_SIZE=3584 +# CONFIG_ESP_TIMER_IMPL_FRC2 is not set +CONFIG_ESP_TIMER_IMPL_TG0_LAC=y +# end of High resolution timer (esp_timer) + +# +# Wi-Fi +# +CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10 +CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y +CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 +CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32 +# CONFIG_ESP32_WIFI_CSI_ENABLED is not set +CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y +CONFIG_ESP32_WIFI_TX_BA_WIN=6 +CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y +CONFIG_ESP32_WIFI_RX_BA_WIN=6 +CONFIG_ESP32_WIFI_NVS_ENABLED=y +CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y +# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set +CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 +CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 +# CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE is not set +CONFIG_ESP32_WIFI_IRAM_OPT=y +CONFIG_ESP32_WIFI_RX_IRAM_OPT=y +CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y +# CONFIG_ESP_WIFI_SLP_IRAM_OPT is not set +# CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE is not set +# end of Wi-Fi + +# +# PHY +# +CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y +# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set +CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 +CONFIG_ESP32_PHY_MAX_TX_POWER=20 +# end of PHY + +# +# Core dump +# +# CONFIG_ESP_COREDUMP_ENABLE_TO_FLASH is not set +# CONFIG_ESP_COREDUMP_ENABLE_TO_UART is not set +CONFIG_ESP_COREDUMP_ENABLE_TO_NONE=y +# end of Core dump + +# +# FAT Filesystem support +# +# CONFIG_FATFS_CODEPAGE_DYNAMIC is not set +CONFIG_FATFS_CODEPAGE_437=y +# CONFIG_FATFS_CODEPAGE_720 is not set +# CONFIG_FATFS_CODEPAGE_737 is not set +# CONFIG_FATFS_CODEPAGE_771 is not set +# CONFIG_FATFS_CODEPAGE_775 is not set +# CONFIG_FATFS_CODEPAGE_850 is not set +# CONFIG_FATFS_CODEPAGE_852 is not set +# CONFIG_FATFS_CODEPAGE_855 is not set +# CONFIG_FATFS_CODEPAGE_857 is not set +# CONFIG_FATFS_CODEPAGE_860 is not set +# CONFIG_FATFS_CODEPAGE_861 is not set +# CONFIG_FATFS_CODEPAGE_862 is not set +# CONFIG_FATFS_CODEPAGE_863 is not set +# CONFIG_FATFS_CODEPAGE_864 is not set +# CONFIG_FATFS_CODEPAGE_865 is not set +# CONFIG_FATFS_CODEPAGE_866 is not set +# CONFIG_FATFS_CODEPAGE_869 is not set +# CONFIG_FATFS_CODEPAGE_932 is not set +# CONFIG_FATFS_CODEPAGE_936 is not set +# CONFIG_FATFS_CODEPAGE_949 is not set +# CONFIG_FATFS_CODEPAGE_950 is not set +CONFIG_FATFS_CODEPAGE=437 +CONFIG_FATFS_LFN_NONE=y +# CONFIG_FATFS_LFN_HEAP is not set +# CONFIG_FATFS_LFN_STACK is not set +CONFIG_FATFS_FS_LOCK=0 +CONFIG_FATFS_TIMEOUT_MS=10000 +CONFIG_FATFS_PER_FILE_CACHE=y +# CONFIG_FATFS_USE_FASTSEEK is not set +# end of FAT Filesystem support + +# +# Modbus configuration +# +CONFIG_FMB_COMM_MODE_TCP_EN=y +CONFIG_FMB_TCP_PORT_DEFAULT=502 +CONFIG_FMB_TCP_PORT_MAX_CONN=5 +CONFIG_FMB_TCP_CONNECTION_TOUT_SEC=20 +CONFIG_FMB_COMM_MODE_RTU_EN=y +CONFIG_FMB_COMM_MODE_ASCII_EN=y +CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_FMB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_FMB_QUEUE_LENGTH=20 +CONFIG_FMB_PORT_TASK_STACK_SIZE=4096 +CONFIG_FMB_SERIAL_BUF_SIZE=256 +CONFIG_FMB_SERIAL_ASCII_BITS_PER_SYMB=8 +CONFIG_FMB_SERIAL_ASCII_TIMEOUT_RESPOND_MS=1000 +CONFIG_FMB_PORT_TASK_PRIO=10 +CONFIG_FMB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_FMB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_FMB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_FMB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_FMB_CONTROLLER_STACK_SIZE=4096 +CONFIG_FMB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_FMB_TIMER_PORT_ENABLED=y +CONFIG_FMB_TIMER_GROUP=0 +CONFIG_FMB_TIMER_INDEX=0 +# CONFIG_FMB_TIMER_ISR_IN_IRAM is not set +# end of Modbus configuration + +# +# FreeRTOS +# +# CONFIG_FREERTOS_UNICORE is not set +CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF +CONFIG_FREERTOS_CORETIMER_0=y +# CONFIG_FREERTOS_CORETIMER_1 is not set +CONFIG_FREERTOS_HZ=100 +CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set +# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set +CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y +# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set +CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y +CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 +CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y +# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set +# CONFIG_FREERTOS_ASSERT_DISABLE is not set +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304 +CONFIG_FREERTOS_ISR_STACKSIZE=1536 +# CONFIG_FREERTOS_LEGACY_HOOKS is not set +CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 +CONFIG_FREERTOS_SUPPORT_STATIC_ALLOCATION=y +# CONFIG_FREERTOS_ENABLE_STATIC_TASK_CLEAN_UP is not set +CONFIG_FREERTOS_TIMER_TASK_PRIORITY=1 +CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_FREERTOS_TIMER_QUEUE_LENGTH=10 +CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 +# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set +# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set +CONFIG_FREERTOS_TASK_FUNCTION_WRAPPER=y +CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y +# CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE is not set +# CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH is not set +CONFIG_FREERTOS_DEBUG_OCDAWARE=y +# CONFIG_FREERTOS_FPU_IN_ISR is not set +# end of FreeRTOS + +# +# Heap memory debugging +# +CONFIG_HEAP_POISONING_DISABLED=y +# CONFIG_HEAP_POISONING_LIGHT is not set +# CONFIG_HEAP_POISONING_COMPREHENSIVE is not set +CONFIG_HEAP_TRACING_OFF=y +# CONFIG_HEAP_TRACING_STANDALONE is not set +# CONFIG_HEAP_TRACING_TOHOST is not set +# CONFIG_HEAP_ABORT_WHEN_ALLOCATION_FAILS is not set +# end of Heap memory debugging + +# +# jsmn +# +# CONFIG_JSMN_PARENT_LINKS is not set +# CONFIG_JSMN_STRICT is not set +# end of jsmn + +# +# libsodium +# +# end of libsodium + +# +# Log output +# +# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set +# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set +# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set +# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_LOG_COLORS=y +CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y +# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set +# end of Log output + +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif" +CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=y +# CONFIG_LWIP_L2_TO_L3_COPY is not set +# CONFIG_LWIP_IRAM_OPTIMIZATION is not set +CONFIG_LWIP_TIMERS_ONDEMAND=y +CONFIG_LWIP_MAX_SOCKETS=10 +# CONFIG_LWIP_USE_ONLY_LWIP_SELECT is not set +# CONFIG_LWIP_SO_LINGER is not set +CONFIG_LWIP_SO_REUSE=y +CONFIG_LWIP_SO_REUSE_RXTOALL=y +# CONFIG_LWIP_SO_RCVBUF is not set +# CONFIG_LWIP_NETBUF_RECVINFO is not set +CONFIG_LWIP_IP4_FRAG=y +CONFIG_LWIP_IP6_FRAG=y +# CONFIG_LWIP_IP4_REASSEMBLY is not set +# CONFIG_LWIP_IP6_REASSEMBLY is not set +# CONFIG_LWIP_IP_FORWARD is not set +# CONFIG_LWIP_STATS is not set +# CONFIG_LWIP_ETHARP_TRUST_IP_MAC is not set +CONFIG_LWIP_ESP_GRATUITOUS_ARP=y +CONFIG_LWIP_GARP_TMR_INTERVAL=60 +CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32 +CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y +# CONFIG_LWIP_DHCP_RESTORE_LAST_IP is not set + +# +# DHCP server +# +CONFIG_LWIP_DHCPS_LEASE_UNIT=60 +CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 +# end of DHCP server + +# CONFIG_LWIP_AUTOIP is not set +CONFIG_LWIP_IPV6=y +# CONFIG_LWIP_IPV6_AUTOCONFIG is not set +CONFIG_LWIP_NETIF_LOOPBACK=y +CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 + +# +# TCP +# +CONFIG_LWIP_MAX_ACTIVE_TCP=16 +CONFIG_LWIP_MAX_LISTENING_TCP=16 +CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y +CONFIG_LWIP_TCP_MAXRTX=12 +CONFIG_LWIP_TCP_SYNMAXRTX=12 +CONFIG_LWIP_TCP_MSS=1440 +CONFIG_LWIP_TCP_TMR_INTERVAL=250 +CONFIG_LWIP_TCP_MSL=60000 +CONFIG_LWIP_TCP_SND_BUF_DEFAULT=5744 +CONFIG_LWIP_TCP_WND_DEFAULT=5744 +CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 +CONFIG_LWIP_TCP_QUEUE_OOSEQ=y +# CONFIG_LWIP_TCP_SACK_OUT is not set +# CONFIG_LWIP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_LWIP_TCP_OVERSIZE_MSS=y +# CONFIG_LWIP_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_LWIP_TCP_OVERSIZE_DISABLE is not set +CONFIG_LWIP_TCP_RTO_TIME=1500 +# end of TCP + +# +# UDP +# +CONFIG_LWIP_MAX_UDP_PCBS=16 +CONFIG_LWIP_UDP_RECVMBOX_SIZE=6 +# end of UDP + +# +# Checksums +# +# CONFIG_LWIP_CHECKSUM_CHECK_IP is not set +# CONFIG_LWIP_CHECKSUM_CHECK_UDP is not set +CONFIG_LWIP_CHECKSUM_CHECK_ICMP=y +# end of Checksums + +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_LWIP_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_LWIP_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_LWIP_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_LWIP_PPP_SUPPORT is not set +CONFIG_LWIP_IPV6_MEMP_NUM_ND6_QUEUE=3 +CONFIG_LWIP_IPV6_ND6_NUM_NEIGHBORS=5 +# CONFIG_LWIP_SLIP_SUPPORT is not set + +# +# ICMP +# +# CONFIG_LWIP_MULTICAST_PING is not set +# CONFIG_LWIP_BROADCAST_PING is not set +# end of ICMP + +# +# LWIP RAW API +# +CONFIG_LWIP_MAX_RAW_PCBS=16 +# end of LWIP RAW API + +# +# SNTP +# +CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 +CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 +# end of SNTP + +CONFIG_LWIP_ESP_LWIP_ASSERT=y + +# +# Hooks +# +# CONFIG_LWIP_HOOK_TCP_ISN_NONE is not set +CONFIG_LWIP_HOOK_TCP_ISN_DEFAULT=y +# CONFIG_LWIP_HOOK_TCP_ISN_CUSTOM is not set +CONFIG_LWIP_HOOK_IP6_ROUTE_NONE=y +# CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT is not set +# CONFIG_LWIP_HOOK_IP6_ROUTE_CUSTOM is not set +CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_NONE=y +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_DEFAULT is not set +# CONFIG_LWIP_HOOK_NETCONN_EXT_RESOLVE_CUSTOM is not set +# end of Hooks + +# CONFIG_LWIP_DEBUG is not set +# end of LWIP + +# +# mbedTLS +# +CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y +# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set +# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set +CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y +CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384 +CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=4096 +# CONFIG_MBEDTLS_DYNAMIC_BUFFER is not set +# CONFIG_MBEDTLS_DEBUG is not set + +# +# Certificate Bundle +# +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE=y +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN is not set +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE is not set +# CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE is not set +# end of Certificate Bundle + +# CONFIG_MBEDTLS_ECP_RESTARTABLE is not set +# CONFIG_MBEDTLS_CMAC_C is not set +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_HARDWARE_SHA=y +CONFIG_MBEDTLS_ROM_MD5=y +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN is not set +# CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY is not set +CONFIG_MBEDTLS_HAVE_TIME=y +# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set +CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=y +CONFIG_MBEDTLS_SHA512_C=y +CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y +# CONFIG_MBEDTLS_TLS_SERVER_ONLY is not set +# CONFIG_MBEDTLS_TLS_CLIENT_ONLY is not set +# CONFIG_MBEDTLS_TLS_DISABLED is not set +CONFIG_MBEDTLS_TLS_SERVER=y +CONFIG_MBEDTLS_TLS_CLIENT=y +CONFIG_MBEDTLS_TLS_ENABLED=y + +# +# TLS Key Exchange Methods +# +# CONFIG_MBEDTLS_PSK_MODES is not set +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y +# end of TLS Key Exchange Methods + +CONFIG_MBEDTLS_SSL_RENEGOTIATION=y +# CONFIG_MBEDTLS_SSL_PROTO_SSL3 is not set +CONFIG_MBEDTLS_SSL_PROTO_TLS1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +# CONFIG_MBEDTLS_SSL_PROTO_DTLS is not set +CONFIG_MBEDTLS_SSL_ALPN=y +CONFIG_MBEDTLS_CLIENT_SSL_SESSION_TICKETS=y +CONFIG_MBEDTLS_SERVER_SSL_SESSION_TICKETS=y + +# +# Symmetric Ciphers +# +CONFIG_MBEDTLS_AES_C=y +# CONFIG_MBEDTLS_CAMELLIA_C is not set +# CONFIG_MBEDTLS_DES_C is not set +CONFIG_MBEDTLS_RC4_DISABLED=y +# CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT is not set +# CONFIG_MBEDTLS_RC4_ENABLED is not set +# CONFIG_MBEDTLS_BLOWFISH_C is not set +# CONFIG_MBEDTLS_XTEA_C is not set +CONFIG_MBEDTLS_CCM_C=y +CONFIG_MBEDTLS_GCM_C=y +# end of Symmetric Ciphers + +# CONFIG_MBEDTLS_RIPEMD160_C is not set + +# +# Certificates +# +CONFIG_MBEDTLS_PEM_PARSE_C=y +CONFIG_MBEDTLS_PEM_WRITE_C=y +CONFIG_MBEDTLS_X509_CRL_PARSE_C=y +CONFIG_MBEDTLS_X509_CSR_PARSE_C=y +# end of Certificates + +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +# CONFIG_MBEDTLS_ECJPAKE_C is not set +CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_SECP256K1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED=y +CONFIG_MBEDTLS_ECP_DP_CURVE25519_ENABLED=y +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y +# CONFIG_MBEDTLS_POLY1305_C is not set +# CONFIG_MBEDTLS_CHACHA20_C is not set +# CONFIG_MBEDTLS_HKDF_C is not set +# CONFIG_MBEDTLS_THREADING_C is not set +# CONFIG_MBEDTLS_LARGE_KEY_SOFTWARE_MPI is not set +# CONFIG_MBEDTLS_SECURITY_RISKS is not set +# end of mbedTLS + +# +# mDNS +# +CONFIG_MDNS_MAX_SERVICES=10 +CONFIG_MDNS_TASK_PRIORITY=1 +CONFIG_MDNS_TASK_STACK_SIZE=4096 +# CONFIG_MDNS_TASK_AFFINITY_NO_AFFINITY is not set +CONFIG_MDNS_TASK_AFFINITY_CPU0=y +# CONFIG_MDNS_TASK_AFFINITY_CPU1 is not set +CONFIG_MDNS_TASK_AFFINITY=0x0 +CONFIG_MDNS_SERVICE_ADD_TIMEOUT_MS=2000 +# CONFIG_MDNS_STRICT_MODE is not set +CONFIG_MDNS_TIMER_PERIOD_MS=100 +# end of mDNS + +# +# ESP-MQTT Configurations +# +CONFIG_MQTT_PROTOCOL_311=y +CONFIG_MQTT_TRANSPORT_SSL=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET=y +CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y +# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set +# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set +# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set +# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set +# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set +# CONFIG_MQTT_CUSTOM_OUTBOX is not set +# end of ESP-MQTT Configurations + +# +# Newlib +# +CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF is not set +# CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF is not set +# CONFIG_NEWLIB_STDIN_LINE_ENDING_LF is not set +CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y +# CONFIG_NEWLIB_NANO_FORMAT is not set +# end of Newlib + +# +# NVS +# +# end of NVS + +# +# OpenSSL +# +# CONFIG_OPENSSL_DEBUG is not set +CONFIG_OPENSSL_ERROR_STACK=y +# CONFIG_OPENSSL_ASSERT_DO_NOTHING is not set +CONFIG_OPENSSL_ASSERT_EXIT=y +# end of OpenSSL + +# +# PThreads +# +CONFIG_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_PTHREAD_STACK_MIN=768 +CONFIG_PTHREAD_DEFAULT_CORE_NO_AFFINITY=y +# CONFIG_PTHREAD_DEFAULT_CORE_0 is not set +# CONFIG_PTHREAD_DEFAULT_CORE_1 is not set +CONFIG_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_PTHREAD_TASK_NAME_DEFAULT="pthread" +# end of PThreads + +# +# SPI Flash driver +# +# CONFIG_SPI_FLASH_VERIFY_WRITE is not set +# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set +CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS=y +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS is not set +# CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED is not set +# CONFIG_SPI_FLASH_USE_LEGACY_IMPL is not set +# CONFIG_SPI_FLASH_SHARE_SPI1_BUS is not set +# CONFIG_SPI_FLASH_BYPASS_BLOCK_ERASE is not set +CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y +CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 +CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 +CONFIG_SPI_FLASH_WRITE_CHUNK_SIZE=8192 +# CONFIG_SPI_FLASH_SIZE_OVERRIDE is not set +# CONFIG_SPI_FLASH_CHECK_ERASE_TIMEOUT_DISABLED is not set + +# +# Auto-detect flash chips +# +CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_GD_CHIP=y +CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP=y +# end of Auto-detect flash chips + +CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=y +# end of SPI Flash driver + +# +# SPIFFS Configuration +# +CONFIG_SPIFFS_MAX_PARTITIONS=3 + +# +# SPIFFS Cache Configuration +# +CONFIG_SPIFFS_CACHE=y +CONFIG_SPIFFS_CACHE_WR=y +# CONFIG_SPIFFS_CACHE_STATS is not set +# end of SPIFFS Cache Configuration + +CONFIG_SPIFFS_PAGE_CHECK=y +CONFIG_SPIFFS_GC_MAX_RUNS=10 +# CONFIG_SPIFFS_GC_STATS is not set +CONFIG_SPIFFS_PAGE_SIZE=256 +CONFIG_SPIFFS_OBJ_NAME_LEN=32 +# CONFIG_SPIFFS_FOLLOW_SYMLINKS is not set +CONFIG_SPIFFS_USE_MAGIC=y +CONFIG_SPIFFS_USE_MAGIC_LENGTH=y +CONFIG_SPIFFS_META_LENGTH=4 +CONFIG_SPIFFS_USE_MTIME=y + +# +# Debug Configuration +# +# CONFIG_SPIFFS_DBG is not set +# CONFIG_SPIFFS_API_DBG is not set +# CONFIG_SPIFFS_GC_DBG is not set +# CONFIG_SPIFFS_CACHE_DBG is not set +# CONFIG_SPIFFS_CHECK_DBG is not set +# CONFIG_SPIFFS_TEST_VISUALISATION is not set +# end of Debug Configuration +# end of SPIFFS Configuration + +# +# TCP Transport +# +CONFIG_WS_BUFFER_SIZE=1024 +# end of TCP Transport + +# +# TinyUSB +# +# end of TinyUSB + +# +# Unity unit testing library +# +CONFIG_UNITY_ENABLE_FLOAT=y +CONFIG_UNITY_ENABLE_DOUBLE=y +# CONFIG_UNITY_ENABLE_COLOR is not set +CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y +# CONFIG_UNITY_ENABLE_FIXTURE is not set +# CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL is not set +# end of Unity unit testing library + +# +# Virtual file system +# +CONFIG_VFS_SUPPORT_IO=y +CONFIG_VFS_SUPPORT_DIR=y +CONFIG_VFS_SUPPORT_SELECT=y +CONFIG_VFS_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_VFS_SUPPORT_TERMIOS=y + +# +# Host File System I/O (Semihosting) +# +CONFIG_VFS_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_VFS_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# end of Host File System I/O (Semihosting) +# end of Virtual file system + +# +# Wear Levelling +# +# CONFIG_WL_SECTOR_SIZE_512 is not set +CONFIG_WL_SECTOR_SIZE_4096=y +CONFIG_WL_SECTOR_SIZE=4096 +# end of Wear Levelling + +# +# Wi-Fi Provisioning Manager +# +CONFIG_WIFI_PROV_SCAN_MAX_ENTRIES=16 +CONFIG_WIFI_PROV_AUTOSTOP_TIMEOUT=30 +# end of Wi-Fi Provisioning Manager + +# +# Supplicant +# +CONFIG_WPA_MBEDTLS_CRYPTO=y +# CONFIG_WPA_WAPI_PSK is not set +# CONFIG_WPA_DEBUG_PRINT is not set +# CONFIG_WPA_TESTING_OPTIONS is not set +# CONFIG_WPA_WPS_WARS is not set +# CONFIG_WPA_11KV_SUPPORT is not set +# end of Supplicant + +# +# Camera configuration +# +CONFIG_OV7670_SUPPORT=y +# CONFIG_OV7725_SUPPORT is not set +CONFIG_NT99141_SUPPORT=y +CONFIG_OV2640_SUPPORT=y +CONFIG_OV3660_SUPPORT=y +CONFIG_OV5640_SUPPORT=y +# CONFIG_SCCB_HARDWARE_I2C_PORT0 is not set +CONFIG_SCCB_HARDWARE_I2C_PORT1=y +CONFIG_CAMERA_CORE0=y +# CONFIG_CAMERA_CORE1 is not set +# CONFIG_CAMERA_NO_AFFINITY is not set +# end of Camera configuration +# end of Component config + +# +# Compatibility options +# +# CONFIG_LEGACY_INCLUDE_COMMON_HEADERS is not set +# end of Compatibility options + +# Deprecated options for backward compatibility +CONFIG_TOOLPREFIX="xtensa-esp32-elf-" +# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set +CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y +# CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG is not set +# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set +CONFIG_LOG_BOOTLOADER_LEVEL=3 +# CONFIG_APP_ROLLBACK_ENABLE is not set +# CONFIG_FLASH_ENCRYPTION_ENABLED is not set +# CONFIG_FLASHMODE_QIO is not set +# CONFIG_FLASHMODE_QOUT is not set +CONFIG_FLASHMODE_DIO=y +# CONFIG_FLASHMODE_DOUT is not set +# CONFIG_MONITOR_BAUD_9600B is not set +# CONFIG_MONITOR_BAUD_57600B is not set +CONFIG_MONITOR_BAUD_115200B=y +# CONFIG_MONITOR_BAUD_230400B is not set +# CONFIG_MONITOR_BAUD_921600B is not set +# CONFIG_MONITOR_BAUD_2MB is not set +# CONFIG_MONITOR_BAUD_OTHER is not set +CONFIG_MONITOR_BAUD_OTHER_VAL=115200 +CONFIG_MONITOR_BAUD=115200 +CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG=y +# CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE is not set +CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y +# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set +# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set +# CONFIG_CXX_EXCEPTIONS is not set +CONFIG_STACK_CHECK_NONE=y +# CONFIG_STACK_CHECK_NORM is not set +# CONFIG_STACK_CHECK_STRONG is not set +# CONFIG_STACK_CHECK_ALL is not set +# CONFIG_WARN_WRITE_STRINGS is not set +# CONFIG_DISABLE_GCC8_WARNINGS is not set +# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set +CONFIG_ESP32_APPTRACE_DEST_NONE=y +CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 +CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=0 +CONFIG_ADC2_DISABLE_DAC=y +# CONFIG_SPIRAM_SUPPORT is not set +CONFIG_TRACEMEM_RESERVE_DRAM=0x0 +# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set +CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y +CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 +# CONFIG_ULP_COPROC_ENABLED is not set +CONFIG_ULP_COPROC_RESERVE_MEM=0 +CONFIG_BROWNOUT_DET=y +CONFIG_BROWNOUT_DET_LVL_SEL_0=y +# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set +# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set +CONFIG_BROWNOUT_DET_LVL=0 +CONFIG_REDUCE_PHY_TX_POWER=y +CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC is not set +# CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256 is not set +# CONFIG_DISABLE_BASIC_ROM_CONSOLE is not set +# CONFIG_NO_BLOBS is not set +# CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS is not set +CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 +CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304 +CONFIG_MAIN_TASK_STACK_SIZE=3584 +CONFIG_IPC_TASK_STACK_SIZE=1024 +CONFIG_CONSOLE_UART_DEFAULT=y +# CONFIG_CONSOLE_UART_CUSTOM is not set +# CONFIG_ESP_CONSOLE_UART_NONE is not set +CONFIG_CONSOLE_UART=y +CONFIG_CONSOLE_UART_NUM=0 +CONFIG_CONSOLE_UART_BAUDRATE=115200 +CONFIG_INT_WDT=y +CONFIG_INT_WDT_TIMEOUT_MS=300 +CONFIG_INT_WDT_CHECK_CPU1=y +CONFIG_TASK_WDT=y +# CONFIG_TASK_WDT_PANIC is not set +CONFIG_TASK_WDT_TIMEOUT_S=5 +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y +CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y +# CONFIG_EVENT_LOOP_PROFILING is not set +CONFIG_POST_EVENTS_FROM_ISR=y +CONFIG_POST_EVENTS_FROM_IRAM_ISR=y +# CONFIG_ESP32S2_PANIC_PRINT_HALT is not set +CONFIG_ESP32S2_PANIC_PRINT_REBOOT=y +# CONFIG_ESP32S2_PANIC_SILENT_REBOOT is not set +# CONFIG_ESP32S2_PANIC_GDBSTUB is not set +CONFIG_TIMER_TASK_STACK_SIZE=3584 +# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set +# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set +CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y +CONFIG_MB_MASTER_TIMEOUT_MS_RESPOND=150 +CONFIG_MB_MASTER_DELAY_MS_CONVERT=200 +CONFIG_MB_QUEUE_LENGTH=20 +CONFIG_MB_SERIAL_TASK_STACK_SIZE=4096 +CONFIG_MB_SERIAL_BUF_SIZE=256 +CONFIG_MB_SERIAL_TASK_PRIO=10 +CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT=y +CONFIG_MB_CONTROLLER_SLAVE_ID=0x00112233 +CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 +CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 +CONFIG_MB_CONTROLLER_STACK_SIZE=4096 +CONFIG_MB_EVENT_QUEUE_TIMEOUT=20 +CONFIG_MB_TIMER_PORT_ENABLED=y +CONFIG_MB_TIMER_GROUP=0 +CONFIG_MB_TIMER_INDEX=0 +# CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK is not set +CONFIG_TIMER_TASK_PRIORITY=1 +CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_QUEUE_LENGTH=10 +# CONFIG_L2_TO_L3_COPY is not set +# CONFIG_USE_ONLY_LWIP_SELECT is not set +CONFIG_ESP_GRATUITOUS_ARP=y +CONFIG_GARP_TMR_INTERVAL=60 +CONFIG_TCPIP_RECVMBOX_SIZE=32 +CONFIG_TCP_MAXRTX=12 +CONFIG_TCP_SYNMAXRTX=12 +CONFIG_TCP_MSS=1440 +CONFIG_TCP_MSL=60000 +CONFIG_TCP_SND_BUF_DEFAULT=5744 +CONFIG_TCP_WND_DEFAULT=5744 +CONFIG_TCP_RECVMBOX_SIZE=6 +CONFIG_TCP_QUEUE_OOSEQ=y +# CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES is not set +CONFIG_TCP_OVERSIZE_MSS=y +# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set +# CONFIG_TCP_OVERSIZE_DISABLE is not set +CONFIG_UDP_RECVMBOX_SIZE=6 +CONFIG_TCPIP_TASK_STACK_SIZE=3072 +CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y +# CONFIG_TCPIP_TASK_AFFINITY_CPU0 is not set +# CONFIG_TCPIP_TASK_AFFINITY_CPU1 is not set +CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF +# CONFIG_PPP_SUPPORT is not set +CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 +CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 +CONFIG_ESP32_PTHREAD_STACK_MIN=768 +CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0 is not set +# CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1 is not set +CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 +CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" +CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS is not set +# CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is not set +CONFIG_SUPPRESS_SELECT_DEBUG_OUTPUT=y +CONFIG_SUPPORT_TERMIOS=y +CONFIG_SEMIHOSTFS_MAX_MOUNT_POINTS=1 +CONFIG_SEMIHOSTFS_HOST_PATH_MAX_LEN=128 +# End of deprecated options diff --git a/code/sdkconfig.old b/code/sdkconfig.old index fff6566a..6e728c9a 100644 --- a/code/sdkconfig.old +++ b/code/sdkconfig.old @@ -138,7 +138,8 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set # CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set -# CONFIG_COMPILER_CXX_EXCEPTIONS is not set +CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_COMPILER_CXX_EXCEPTIONS_EMG_POOL_SIZE=0 # CONFIG_COMPILER_CXX_RTTI is not set CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y # CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set diff --git a/code/version.cpp b/code/version.cpp index 893450de..55c22f5e 100644 --- a/code/version.cpp +++ b/code/version.cpp @@ -1,4 +1,4 @@ -const char* GIT_REV="7fcb5d1"; +const char* GIT_REV="f15e5f0"; const char* GIT_TAG=""; -const char* GIT_BRANCH="master"; -const char* BUILD_TIME="2021-09-12 07:30"; \ No newline at end of file +const char* GIT_BRANCH="rolling"; +const char* BUILD_TIME="2021-09-24 19:25"; \ No newline at end of file diff --git a/firmware/bootloader.bin b/firmware/bootloader.bin index 0ed1520d..cd54c830 100644 Binary files a/firmware/bootloader.bin and b/firmware/bootloader.bin differ diff --git a/firmware/firmware.bin b/firmware/firmware.bin index 976c7cc8..32f791a8 100644 Binary files a/firmware/firmware.bin and b/firmware/firmware.bin differ diff --git a/firmware/html.zip b/firmware/html.zip index ae06f6dc..52dfc3f5 100644 Binary files a/firmware/html.zip and b/firmware/html.zip differ diff --git a/sd-card/config/dig1200s1q.tflite b/sd-card/config/dig1200s1q.tflite deleted file mode 100644 index fbca07d6..00000000 Binary files a/sd-card/config/dig1200s1q.tflite and /dev/null differ diff --git a/sd-card/config/dig1300s1q.tflite b/sd-card/config/dig1300s1q.tflite new file mode 100644 index 00000000..305335b7 Binary files /dev/null and b/sd-card/config/dig1300s1q.tflite differ diff --git a/sd-card/html/edit_alignment.html b/sd-card/html/edit_alignment.html index ccee3ccd..0c286929 100644 --- a/sd-card/html/edit_alignment.html +++ b/sd-card/html/edit_alignment.html @@ -1,6 +1,7 @@ + Make Alignment diff --git a/sd-card/html/edit_analog.html b/sd-card/html/edit_analog.html index c2d63897..563f4c62 100644 --- a/sd-card/html/edit_analog.html +++ b/sd-card/html/edit_analog.html @@ -1,6 +1,7 @@ + Make Analog Alignment diff --git a/sd-card/html/edit_check.html b/sd-card/html/edit_check.html index 499ce6c5..46e52e71 100644 --- a/sd-card/html/edit_check.html +++ b/sd-card/html/edit_check.html @@ -1,6 +1,7 @@ + Check diff --git a/sd-card/html/edit_config.html b/sd-card/html/edit_config.html index b3cf9ec2..64330985 100644 --- a/sd-card/html/edit_config.html +++ b/sd-card/html/edit_config.html @@ -1,6 +1,7 @@ + Edit Config diff --git a/sd-card/html/edit_config_param.html b/sd-card/html/edit_config_param.html index 169f1a97..6af9aeb2 100644 --- a/sd-card/html/edit_config_param.html +++ b/sd-card/html/edit_config_param.html @@ -1,6 +1,7 @@ + Edit Config @@ -349,24 +350,6 @@ textarea { Time to keep the separated digit images (in days -"0" = forever) - - - - - - ExtendedResolution - - - - - - Enable to use the after point resolution for the last analog counter - - - ModelInputSize @@ -502,6 +485,41 @@ textarea { Maximum change of reading from one to the next readout + + + + + + ExtendedResolution + + + + + + Enable to use the after point resolution for the last analog counter + + + + + + + + + IgnoreLeadingNaN + + + + + + Leading "N"'s will be deleted before further processing + + @@ -1028,7 +1046,7 @@ textarea { - + @@ -1452,7 +1470,7 @@ function WriteParameter(_param, _category, _cat, _name, _optional, _number = -1) setEnabled(_cat+"_"+_name, false); } - EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional); + EnDisableItem(_category[_cat]["enabled"], _param, _category, _cat, _name, _optional, _number); } function InvertEnableItem(_cat, _param) @@ -1619,12 +1637,16 @@ function UpdateInputIndividual() { ReadParameter(param, "PostProcessing", "DecimalShift", true, NUNBERSAkt) ReadParameter(param, "PostProcessing", "MaxRateValue", true, NUNBERSAkt) + ReadParameter(param, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt) + ReadParameter(param, "PostProcessing", "IgnoreLeadingNaN", true, NUNBERSAkt) } var sel = document.getElementById("Numbers_value1"); NUNBERSAkt = sel.selectedIndex; WriteParameter(param, category, "PostProcessing", "DecimalShift", true, NUNBERSAkt); WriteParameter(param, category, "PostProcessing", "MaxRateValue", true, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "ExtendedResolution", true, NUNBERSAkt); + WriteParameter(param, category, "PostProcessing", "IgnoreLeadingNaN", true, NUNBERSAkt); } function UpdateInput() { @@ -1656,7 +1678,7 @@ function UpdateInput() { WriteParameter(param, category, "Analog", "Model", false); WriteParameter(param, category, "Analog", "LogImageLocation", true); WriteParameter(param, category, "Analog", "LogfileRetentionInDays", true); - WriteParameter(param, category, "Analog", "ExtendedResolution", true); +// WriteParameter(param, category, "Analog", "ExtendedResolution", true); WriteParameter(param, category, "Analog", "ModelInputSize", false); WriteParameter(param, category, "PostProcessing", "PreValueUse", true); @@ -1719,13 +1741,13 @@ function ReadParameterAll() ReadParameter(param, "Analog", "Model", false); ReadParameter(param, "Analog", "LogImageLocation", true); ReadParameter(param, "Analog", "LogfileRetentionInDays", true); - ReadParameter(param, "Analog", "ExtendedResolution", true); +// ReadParameter(param, "Analog", "ExtendedResolution", true); ReadParameter(param, "Analog", "ModelInputSize", false); ReadParameter(param, "PostProcessing", "PreValueUse", true); ReadParameter(param, "PostProcessing", "PreValueAgeStartup", true); ReadParameter(param, "PostProcessing", "AllowNegativeRates", true); - ReadParameter(param, "PostProcessing", "MaxRateValue", true); +// ReadParameter(param, "PostProcessing", "MaxRateValue", true); ReadParameter(param, "PostProcessing", "ErrorMessage", true); ReadParameter(param, "PostProcessing", "CheckDigitIncreaseConsistency", true); diff --git a/sd-card/html/edit_digits.html b/sd-card/html/edit_digits.html index e01b4a9e..01123482 100644 --- a/sd-card/html/edit_digits.html +++ b/sd-card/html/edit_digits.html @@ -1,6 +1,7 @@ + Make Digital Alignment diff --git a/sd-card/html/edit_explain_0.html b/sd-card/html/edit_explain_0.html index e1023a55..c1ee7248 100644 --- a/sd-card/html/edit_explain_0.html +++ b/sd-card/html/edit_explain_0.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/edit_explain_6.html b/sd-card/html/edit_explain_6.html index 7e67df4f..2a465bad 100644 --- a/sd-card/html/edit_explain_6.html +++ b/sd-card/html/edit_explain_6.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/edit_reference.html b/sd-card/html/edit_reference.html index 91a53dda..4cbbddc4 100644 --- a/sd-card/html/edit_reference.html +++ b/sd-card/html/edit_reference.html @@ -1,6 +1,7 @@ + Make Reference diff --git a/sd-card/html/explain_0.html b/sd-card/html/explain_0.html index 75f66304..d8bcdd81 100644 --- a/sd-card/html/explain_0.html +++ b/sd-card/html/explain_0.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/explain_1.html b/sd-card/html/explain_1.html index 6653c2aa..cebebd8d 100644 --- a/sd-card/html/explain_1.html +++ b/sd-card/html/explain_1.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/explain_2.html b/sd-card/html/explain_2.html index 976738ed..43f2f1a9 100644 --- a/sd-card/html/explain_2.html +++ b/sd-card/html/explain_2.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/explain_3.html b/sd-card/html/explain_3.html index ff1ae887..09a18c2d 100644 --- a/sd-card/html/explain_3.html +++ b/sd-card/html/explain_3.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/explain_4.html b/sd-card/html/explain_4.html index 862bfaf9..7a2a288e 100644 --- a/sd-card/html/explain_4.html +++ b/sd-card/html/explain_4.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/explain_5.html b/sd-card/html/explain_5.html index 8ae3bae0..e4e0782e 100644 --- a/sd-card/html/explain_5.html +++ b/sd-card/html/explain_5.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/explain_6.html b/sd-card/html/explain_6.html index a617db25..29e6e6bc 100644 --- a/sd-card/html/explain_6.html +++ b/sd-card/html/explain_6.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/index.html b/sd-card/html/index.html index 3212111e..9416e5c1 100644 --- a/sd-card/html/index.html +++ b/sd-card/html/index.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge @@ -73,28 +74,28 @@ li.dropdown { -

Digitizer - AI on the edge

+

Digitizer - AI on the edge

An ESP32 all inclusive neural network recognition system for meter digitalization

@@ -102,5 +103,46 @@ li.dropdown { + + + + + + + \ No newline at end of file diff --git a/sd-card/html/index_configure.html b/sd-card/html/index_configure.html index 70187bef..090cae08 100644 --- a/sd-card/html/index_configure.html +++ b/sd-card/html/index_configure.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/ota_page.html b/sd-card/html/ota_page.html index c166d4ba..0a8abeab 100644 --- a/sd-card/html/ota_page.html +++ b/sd-card/html/ota_page.html @@ -1,6 +1,7 @@ + OTA Update diff --git a/sd-card/html/ota_page_v2.html b/sd-card/html/ota_page_v2.html index ce83a030..df65e95d 100644 --- a/sd-card/html/ota_page_v2.html +++ b/sd-card/html/ota_page_v2.html @@ -1,4 +1,6 @@ - + + + jomjol - AI on the edge diff --git a/sd-card/html/prevalue_set.html b/sd-card/html/prevalue_set.html index fa599f3b..ed83dc26 100644 --- a/sd-card/html/prevalue_set.html +++ b/sd-card/html/prevalue_set.html @@ -1,6 +1,7 @@ + Set PreValue diff --git a/sd-card/html/readconfigparam.js b/sd-card/html/readconfigparam.js index 47717a20..14c17fa9 100644 --- a/sd-card/html/readconfigparam.js +++ b/sd-card/html/readconfigparam.js @@ -31,6 +31,7 @@ function ParseConfig() { ParamAddValue(param, catname, "ImageQuality"); ParamAddValue(param, catname, "ImageSize"); ParamAddValue(param, catname, "FixedExposure"); + ParamAddValue(param, catname, "UseGPIOControlledIllumination"); var catname = "Alignment"; category[catname] = new Object(); @@ -53,7 +54,7 @@ function ParseConfig() { ParamAddValue(param, catname, "LogImageLocation"); ParamAddValue(param, catname, "LogfileRetentionInDays"); ParamAddValue(param, catname, "ModelInputSize", 2); - ParamAddValue(param, catname, "ExtendedResolution"); +// ParamAddValue(param, catname, "ExtendedResolution"); var catname = "Analog"; category[catname] = new Object(); @@ -64,7 +65,7 @@ function ParseConfig() { ParamAddValue(param, catname, "LogImageLocation"); ParamAddValue(param, catname, "LogfileRetentionInDays"); ParamAddValue(param, catname, "ModelInputSize", 2); - ParamAddValue(param, catname, "ExtendedResolution"); +// ParamAddValue(param, catname, "ExtendedResolution"); var catname = "PostProcessing"; category[catname] = new Object(); @@ -76,9 +77,11 @@ function ParseConfig() { ParamAddValue(param, catname, "PreValueAgeStartup"); ParamAddValue(param, catname, "AllowNegativeRates"); ParamAddValue(param, catname, "MaxRateValue", 1, true); + ParamAddValue(param, catname, "ExtendedResolution", 1, true); + ParamAddValue(param, catname, "IgnoreLeadingNaN", 1, true); ParamAddValue(param, catname, "ErrorMessage"); ParamAddValue(param, catname, "CheckDigitIncreaseConsistency"); - ParamAddValue(param, catname, "IgnoreLeadingNaN"); +// ParamAddValue(param, catname, "IgnoreLeadingNaN"); var catname = "MQTT"; category[catname] = new Object(); @@ -102,6 +105,10 @@ function ParseConfig() { ParamAddValue(param, catname, "IO4", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); ParamAddValue(param, catname, "IO12", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); ParamAddValue(param, catname, "IO13", 6, false, [null, null, /^[0-9]*$/, null, null, /^[a-zA-Z0-9_-]*$/]); + ParamAddValue(param, catname, "LEDType"); + ParamAddValue(param, catname, "LEDNumbers"); + ParamAddValue(param, catname, "LEDColor", 3); + var catname = "AutoTimer"; category[catname] = new Object(); @@ -673,4 +680,4 @@ function CreateROI(_number, _type, _pos, _roinew, _x, _y, _dx, _dy){ NUMBERS[_indexnumber][_type].splice(_pos+1, 0, _ret); return ""; -} \ No newline at end of file +} diff --git a/sd-card/html/reboot_page.html b/sd-card/html/reboot_page.html index 3b924f2c..bc503c66 100644 --- a/sd-card/html/reboot_page.html +++ b/sd-card/html/reboot_page.html @@ -1,6 +1,7 @@ + Reboot diff --git a/sd-card/html/setup.html b/sd-card/html/setup.html index 0b9f67bf..5d207d07 100644 --- a/sd-card/html/setup.html +++ b/sd-card/html/setup.html @@ -1,6 +1,7 @@ + jomjol - AI on the edge diff --git a/sd-card/html/test.html b/sd-card/html/test.html index 5cd12021..560ed1cf 100644 --- a/sd-card/html/test.html +++ b/sd-card/html/test.html @@ -1,6 +1,7 @@ + diff --git a/sd-card/html/version.txt b/sd-card/html/version.txt index c83418e8..3b9bddfc 100644 --- a/sd-card/html/version.txt +++ b/sd-card/html/version.txt @@ -1 +1 @@ -9.7.1 \ No newline at end of file +10.1.0 \ No newline at end of file diff --git a/sd-card/html/wasserzaehler_roi.html b/sd-card/html/wasserzaehler_roi.html index 61e6cd80..5a82b21f 100644 --- a/sd-card/html/wasserzaehler_roi.html +++ b/sd-card/html/wasserzaehler_roi.html @@ -1,6 +1,7 @@ + Overview