diff --git a/.cproject b/.cproject
deleted file mode 100644
index 07ce0be..0000000
--- a/.cproject
+++ /dev/null
@@ -1,82 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.gitignore b/.gitignore
index f0dfac8..f96e839 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-/Release/
-/sloeber.ino.cpp
-/spec.d
-/credentials.cpp
+.pioenvs
+.piolibdeps
+.vscode
+credentials.cpp
diff --git a/.project b/.project
deleted file mode 100644
index 330704e..0000000
--- a/.project
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
- esp32-geiger-counter
-
-
-
-
-
- io.sloeber.core.inoToCpp
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.genmakebuilder
- clean,full,incremental,
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
- full,incremental,
-
-
-
-
-
- org.eclipse.cdt.core.cnature
- org.eclipse.cdt.core.ccnature
- org.eclipse.cdt.managedbuilder.core.managedBuildNature
- org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
- io.sloeber.arduinonature
-
-
-
- core/core
- 2
- C:/dev/git/arduino-esp32/cores/esp32
-
-
- core/variant
- 2
- C:/dev/git/arduino-esp32/variants/lolin32
-
-
- libraries/ESP32
- 2
- C:/dev/git/arduino-esp32/libraries/ESP32
-
-
- libraries/SPI
- 2
- C:/dev/git/arduino-esp32/libraries/SPI
-
-
- libraries/Time
- 2
- ECLIPSE_HOME/arduinoPlugin/libraries/Time/1.5.0
-
-
- libraries/U8g2
- 2
- ECLIPSE_HOME/arduinoPlugin/libraries/U8g2/2.25.10
-
-
- libraries/WiFi
- 2
- C:/dev/git/arduino-esp32/libraries/WiFi
-
-
- libraries/Wire
- 2
- C:/dev/git/arduino-esp32/libraries/Wire
-
-
-
diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
deleted file mode 100644
index f0278cc..0000000
--- a/.settings/language.settings.xml
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
deleted file mode 100644
index 10b0469..0000000
--- a/.settings/org.eclipse.cdt.core.prefs
+++ /dev/null
@@ -1,465 +0,0 @@
-eclipse.preferences.version=1
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ALT_SIZE_COMMAND/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ALT_SIZE_COMMAND/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ALT_SIZE_COMMAND/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" --format\=avr --mcu\=${A.BUILD.MCU} "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ARCHIVE_FILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ARCHIVE_FILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ARCHIVE_FILE/value=arduino.ar
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ARCHIVE_FILE_PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ARCHIVE_FILE_PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ARCHIVE_FILE_PATH/value=${A.BUILD.PATH}/${A.ARCHIVE_FILE}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.ARCH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.ARCH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.ARCH/value=ARDUINO-ESP32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.BOARD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.BOARD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.BOARD/value=LOLIN32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.BOOT/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.BOOT/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.BOOT/value=dio
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CODE_DEBUG/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CODE_DEBUG/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CODE_DEBUG/value=0
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CORE.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CORE.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CORE.PATH/value=C\:\\dev\\git\\arduino-esp32\\cores\\esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CORE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CORE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.CORE/value=esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.DEFINES/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.DEFINES/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.DEFINES/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.EXTRA_FLAGS/value=-DESP32 -DCORE_DEBUG_LEVEL\=${A.BUILD.CODE_DEBUG} ${A.BUILD.DEFINES}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_FREQ/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_FREQ/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_FREQ/value=40m
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_MODE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_MODE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_MODE/value=dio
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_SIZE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_SIZE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.FLASH_SIZE/value=4MB
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.F_CPU/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.F_CPU/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.F_CPU/value=240000000L
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.MCU/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.MCU/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.MCU/value=esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PARTITIONS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PARTITIONS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PARTITIONS/value=default
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PATH/value=${ProjDirPath}/${ConfigName}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PROJECT_NAME/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PROJECT_NAME/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.PROJECT_NAME/value=${ProjName}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.SYSTEM.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.SYSTEM.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.SYSTEM.PATH/value=${A.RUNTIME.PLATFORM.PATH}/system
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.VARIANT.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.VARIANT.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.VARIANT.PATH/value=C\:\\dev\\git\\arduino-esp32\\variants\\lolin32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.VARIANT/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.VARIANT/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.BUILD.VARIANT/value=lolin32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.CMD/value=xtensa-esp32-elf-ar
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AR.FLAGS/value=cru
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AS.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AS.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.AS.CMD/value=xtensa-esp32-elf-as
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.CMD/value=xtensa-esp32-elf-gcc
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.CMD/value=xtensa-esp32-elf-gcc
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.FLAGS/value=-nostdlib "-L${A.COMPILER.SDK.PATH}/lib" "-L${A.COMPILER.SDK.PATH}/ld" -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.spiram_incompatible_fns.ld -u ld_include_panic_highint_hdl -u call_user_start_cpu0 -Wl,--gc-sections -Wl,-static -Wl,--undefined\=uxTopUsedPriority -u __cxa_guard_dummy -u __cxx_fatal_exception
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.LIBS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.LIBS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.ELF.LIBS/value=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lesp_http_client -lprotobuf-c -lhal -lnewlib -ldriver -lbootloader_support -lpp -lfreemodbus -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lfrmn -lapp_trace -lfr_coefficients -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lesp32-camera -lcxx -lxtensa-debug-module -ltcp_transport -lmdns -lvfs -lmtmn -lespcoredump -lesp_ringbuf -lsoc -lcore -lfb_gfx -lsdmmc -llibsodium -lcoap -ltcpip_adapter -lprotocomm -lesp_event -limage_util -lc_nano -lesp-tls -lasio -lrtc -lspi_flash -lwpa2 -lwifi_provisioning -lesp32 -lface_recognition -lapp_update -lnghttp -lspiffs -lface_detection -lefuse -lunity -lesp_https_server -lespnow -lnvs_flash -lesp_adc_cal -llog -ldl_lib -lsmartconfig_ack -lexpat -lfd_coefficients -lm -lmqtt -lc -lheap -lmbedtls -llwip -lnet80211 -lesp_http_server -lpthread -ljson -lesp_https_ota -lstdc++
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.C.FLAGS/value=-std\=gnu99 -Os -g3 -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -Wpointer-arith ${A.COMPILER.WARNING_FLAGS} -Wno-error\=unused-function -Wno-error\=unused-but-set-variable -Wno-error\=unused-variable -Wno-error\=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -Wno-old-style-declaration -MMD -c
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.CMD/value=xtensa-esp32-elf-g++
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPP.FLAGS/value=-std\=gnu++11 -fno-exceptions -Os -g3 -Wpointer-arith -fexceptions -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib ${A.COMPILER.WARNING_FLAGS} -Wno-error\=unused-function -Wno-error\=unused-but-set-variable -Wno-error\=unused-variable -Wno-error\=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -fno-rtti -MMD -c
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPREPROCESSOR.FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPREPROCESSOR.FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.CPREPROCESSOR.FLAGS/value=-DESP_PLATFORM -DMBEDTLS_CONFIG_FILE\="mbedtls/esp_config.h" -DHAVE_CONFIG_H "-I${A.COMPILER.SDK.PATH}/include/config" "-I${A.COMPILER.SDK.PATH}/include/app_trace" "-I${A.COMPILER.SDK.PATH}/include/app_update" "-I${A.COMPILER.SDK.PATH}/include/asio" "-I${A.COMPILER.SDK.PATH}/include/bootloader_support" "-I${A.COMPILER.SDK.PATH}/include/bt" "-I${A.COMPILER.SDK.PATH}/include/coap" "-I${A.COMPILER.SDK.PATH}/include/console" "-I${A.COMPILER.SDK.PATH}/include/driver" "-I${A.COMPILER.SDK.PATH}/include/efuse" "-I${A.COMPILER.SDK.PATH}/include/esp-tls" "-I${A.COMPILER.SDK.PATH}/include/esp32" "-I${A.COMPILER.SDK.PATH}/include/esp_adc_cal" "-I${A.COMPILER.SDK.PATH}/include/esp_event" "-I${A.COMPILER.SDK.PATH}/include/esp_http_client" "-I${A.COMPILER.SDK.PATH}/include/esp_http_server" "-I${A.COMPILER.SDK.PATH}/include/esp_https_ota" "-I${A.COMPILER.SDK.PATH}/include/esp_https_server" "-I${A.COMPILER.SDK.PATH}/include/esp_ringbuf" "-I${A.COMPILER.SDK.PATH}/include/espcoredump" "-I${A.COMPILER.SDK.PATH}/include/ethernet" "-I${A.COMPILER.SDK.PATH}/include/expat" "-I${A.COMPILER.SDK.PATH}/include/fatfs" "-I${A.COMPILER.SDK.PATH}/include/freemodbus" "-I${A.COMPILER.SDK.PATH}/include/freertos" "-I${A.COMPILER.SDK.PATH}/include/heap" "-I${A.COMPILER.SDK.PATH}/include/idf_test" "-I${A.COMPILER.SDK.PATH}/include/jsmn" "-I${A.COMPILER.SDK.PATH}/include/json" "-I${A.COMPILER.SDK.PATH}/include/libsodium" "-I${A.COMPILER.SDK.PATH}/include/log" "-I${A.COMPILER.SDK.PATH}/include/lwip" "-I${A.COMPILER.SDK.PATH}/include/mbedtls" "-I${A.COMPILER.SDK.PATH}/include/mdns" "-I${A.COMPILER.SDK.PATH}/include/micro-ecc" "-I${A.COMPILER.SDK.PATH}/include/mqtt" "-I${A.COMPILER.SDK.PATH}/include/newlib" "-I${A.COMPILER.SDK.PATH}/include/nghttp" "-I${A.COMPILER.SDK.PATH}/include/nvs_flash" "-I${A.COMPILER.SDK.PATH}/include/openssl" "-I${A.COMPILER.SDK.PATH}/include/protobuf-c" "-I${A.COMPILER.SDK.PATH}/include/protocomm" "-I${A.COMPILER.SDK.PATH}/include/pthread" "-I${A.COMPILER.SDK.PATH}/include/sdmmc" "-I${A.COMPILER.SDK.PATH}/include/smartconfig_ack" "-I${A.COMPILER.SDK.PATH}/include/soc" "-I${A.COMPILER.SDK.PATH}/include/spi_flash" "-I${A.COMPILER.SDK.PATH}/include/spiffs" "-I${A.COMPILER.SDK.PATH}/include/tcp_transport" "-I${A.COMPILER.SDK.PATH}/include/tcpip_adapter" "-I${A.COMPILER.SDK.PATH}/include/ulp" "-I${A.COMPILER.SDK.PATH}/include/unity" "-I${A.COMPILER.SDK.PATH}/include/vfs" "-I${A.COMPILER.SDK.PATH}/include/wear_levelling" "-I${A.COMPILER.SDK.PATH}/include/wifi_provisioning" "-I${A.COMPILER.SDK.PATH}/include/wpa_supplicant" "-I${A.COMPILER.SDK.PATH}/include/xtensa-debug-module" "-I${A.COMPILER.SDK.PATH}/include/esp32-camera" "-I${A.COMPILER.SDK.PATH}/include/esp-face" "-I${A.COMPILER.SDK.PATH}/include/fb_gfx"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.ELF2HEX.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.ELF2HEX.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.ELF2HEX.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.OBJCOPY.EEP.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.PATH/value=${A.RUNTIME.TOOLS.XTENSA-ESP32-ELF-GCC.PATH}/bin/
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.CMD/value=xtensa-esp32-elf-gcc
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.EXTRA_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.EXTRA_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.EXTRA_FLAGS/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.S.FLAGS/value=-c -g3 -x assembler-with-cpp -MMD -mlongcalls
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.SDK.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.SDK.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.SDK.PATH/value=${A.RUNTIME.PLATFORM.PATH}/tools/sdk
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.SIZE.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.SIZE.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.SIZE.CMD/value=xtensa-esp32-elf-size
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.ALL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.ALL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.ALL/value=-Wall -Werror\=all -Wextra
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.DEFAULT/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.DEFAULT/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.DEFAULT/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.MORE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.MORE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.MORE/value=-Wall -Werror\=all
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.NONE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.NONE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS.NONE/value=-w
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.COMPILER.WARNING_FLAGS/value=${A.COMPILER.WARNING_FLAGS.ALL}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ESP8266.NETWORK.UPLOAD.TOOL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ESP8266.NETWORK.UPLOAD.TOOL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.ESP8266.NETWORK.UPLOAD.TOOL/value=esp8266OTA
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.NAME/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.NAME/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.NAME/value=WEMOS LOLIN32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.PACKAGES/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.PACKAGES/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.PACKAGES/value=${eclipse_home}/arduinoPlugin/packages
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.AR.CMD}" ${A.COMPILER.AR.FLAGS} ${A.COMPILER.AR.EXTRA_FLAGS}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.2/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.2/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.2/value=\
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.3/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.3/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN.3/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.AR.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.AR.CMD}" ${A.COMPILER.AR.FLAGS} ${A.COMPILER.AR.EXTRA_FLAGS} "${A.ARCHIVE_FILE_PATH}" "${A.OBJECT_FILE}"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.C.ELF.CMD}" ${A.COMPILER.C.ELF.FLAGS} ${A.COMPILER.C.ELF.EXTRA_FLAGS} -Wl,--start-group
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.2/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.2/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.2/value=\
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.3/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.3/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN.3/value=\ ${A.COMPILER.C.ELF.LIBS} -Wl,--end-group -Wl,-EL -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.COMBINE.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.C.ELF.CMD}" ${A.COMPILER.C.ELF.FLAGS} ${A.COMPILER.C.ELF.EXTRA_FLAGS} -Wl,--start-group ${A.OBJECT_FILES} "${A.ARCHIVE_FILE_PATH}" ${A.COMPILER.C.ELF.LIBS} -Wl,--end-group -Wl,-EL -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.CPREPROCESSOR.FLAGS} ${A.COMPILER.C.FLAGS} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} -DARDUINO_BOARD\="${A.BUILD.BOARD}" -DARDUINO_VARIANT\="${A.BUILD.VARIANT}" ${A.COMPILER.C.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.2/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.2/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.2/value=\ -o
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.3/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.3/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN.3/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.C.O.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.CPREPROCESSOR.FLAGS} ${A.COMPILER.C.FLAGS} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} -DARDUINO_BOARD\="${A.BUILD.BOARD}" -DARDUINO_VARIANT\="${A.BUILD.VARIANT}" ${A.COMPILER.C.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.CPP.CMD}" ${A.COMPILER.CPREPROCESSOR.FLAGS} ${A.COMPILER.CPP.FLAGS} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} -DARDUINO_BOARD\="${A.BUILD.BOARD}" -DARDUINO_VARIANT\="${A.BUILD.VARIANT}" ${A.COMPILER.CPP.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.2/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.2/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.2/value=\ -o
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.3/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.3/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN.3/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.CPP.O.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.CPP.CMD}" ${A.COMPILER.CPREPROCESSOR.FLAGS} ${A.COMPILER.CPP.FLAGS} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} -DARDUINO_BOARD\="${A.BUILD.BOARD}" -DARDUINO_VARIANT\="${A.BUILD.VARIANT}" ${A.COMPILER.CPP.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.EEP.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.EEP.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.EEP.PATTERN.1/value=${A.TOOLS.GEN_ESP32PART.CMD} -q "${A.RUNTIME.PLATFORM.PATH}/tools/partitions/${A.BUILD.PARTITIONS}.csv" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.partitions.bin"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.EEP.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.EEP.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.EEP.PATTERN/value=${A.TOOLS.GEN_ESP32PART.CMD} -q "${A.RUNTIME.PLATFORM.PATH}/tools/partitions/${A.BUILD.PARTITIONS}.csv" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.partitions.bin"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN.1/value="${A.TOOLS.ESPTOOL_PY.PATH}/${A.TOOLS.ESPTOOL_PY.CMD}" --chip esp32 elf2image --flash_mode "${A.BUILD.FLASH_MODE}" --flash_freq "${A.BUILD.FLASH_FREQ}" --flash_size "${A.BUILD.FLASH_SIZE}" -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.bin" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN.LINUX/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN.LINUX/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN.LINUX/value=python "${A.TOOLS.ESPTOOL_PY.PATH}/${A.TOOLS.ESPTOOL_PY.CMD}" --chip esp32 elf2image --flash_mode "${A.BUILD.FLASH_MODE}" --flash_freq "${A.BUILD.FLASH_FREQ}" --flash_size "${A.BUILD.FLASH_SIZE}" -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.bin" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OBJCOPY.HEX.PATTERN/value="${A.TOOLS.ESPTOOL_PY.PATH}/${A.TOOLS.ESPTOOL_PY.CMD}" --chip esp32 elf2image --flash_mode "${A.BUILD.FLASH_MODE}" --flash_freq "${A.BUILD.FLASH_FREQ}" --flash_size "${A.BUILD.FLASH_SIZE}" -o "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.bin" "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OUTPUT.SAVE_FILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OUTPUT.SAVE_FILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OUTPUT.SAVE_FILE/value=${A.BUILD.PROJECT_NAME}.${A.BUILD.VARIANT}.bin
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OUTPUT.TMP_FILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OUTPUT.TMP_FILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.OUTPUT.TMP_FILE/value=${A.BUILD.PROJECT_NAME}.bin
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.CPREPROCESSOR.FLAGS} ${A.COMPILER.S.FLAGS} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} -DARDUINO_BOARD\="${A.BUILD.BOARD}" -DARDUINO_VARIANT\="${A.BUILD.VARIANT}" ${A.COMPILER.S.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.2/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.2/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.2/value=\ -o
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.3/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.3/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN.3/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.S.O.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.C.CMD}" ${A.COMPILER.CPREPROCESSOR.FLAGS} ${A.COMPILER.S.FLAGS} -DF_CPU\=${A.BUILD.F_CPU} -DARDUINO\=${A.RUNTIME.IDE.VERSION} -DARDUINO_${A.BUILD.BOARD} -DARDUINO_ARCH_${A.BUILD.ARCH} -DARDUINO_BOARD\="${A.BUILD.BOARD}" -DARDUINO_VARIANT\="${A.BUILD.VARIANT}" ${A.COMPILER.S.EXTRA_FLAGS} ${A.BUILD.EXTRA_FLAGS} ${A.INCLUDES} "${A.SOURCE_FILE}" -o "${A.OBJECT_FILE}"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.PATTERN.1/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.PATTERN.1/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.PATTERN.1/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" -A "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.PATTERN/value="${A.COMPILER.PATH}${A.COMPILER.SIZE.CMD}" -A "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.elf"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.REGEX.DATA/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.REGEX.DATA/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.REGEX.DATA/value=^(?\:\\.dram0\\.data|\\.dram0\\.bss|\\.noinit)\\s+([0-9]+).*
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.REGEX/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.REGEX/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RECIPE.SIZE.REGEX/value=^(?\:\\.iram0\\.text|\\.iram0\\.vectors|\\.dram0\\.data|\\.flash\\.text|\\.flash\\.rodata|)\\s+([0-9]+).*
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.CORE.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.CORE.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.CORE.PATH/value=C\:\\dev\\git\\arduino-esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.UPLOAD.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.UPLOAD.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.UPLOAD.PATH/value=C\:\\dev\\git\\arduino-esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.VARIANT.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.VARIANT.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.REFERENCED.VARIANT.PATH/value=C\:\\dev\\git\\arduino-esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.HARDWARE.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.HARDWARE.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.HARDWARE.PATH/value=C\:/dev/git
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.IDE.VERSION/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.IDE.VERSION/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.IDE.VERSION/value=10802
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.PLATFORM.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.PLATFORM.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.PLATFORM.PATH/value=C\:/dev/git/arduino-esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA-1.2.1.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA-1.2.1.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA-1.2.1.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\arduinoOTA\\1.2.1
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\arduinoOTA\\1.2.1
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA1.2.1.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA1.2.1.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.ARDUINOOTA1.2.1.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\arduinoOTA\\1.2.1
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC-5.4.0-ATMEL3.6.1-ARDUINO2.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC-5.4.0-ATMEL3.6.1-ARDUINO2.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC-5.4.0-ATMEL3.6.1-ARDUINO2.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC5.4.0-ATMEL3.6.1-ARDUINO2.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC5.4.0-ATMEL3.6.1-ARDUINO2.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVR-GCC5.4.0-ATMEL3.6.1-ARDUINO2.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\avr-gcc\\5.4.0-atmel3.6.1-arduino2
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE-6.3.0-ARDUINO14.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE-6.3.0-ARDUINO14.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE-6.3.0-ARDUINO14.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\avrdude\\6.3.0-arduino14
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\avrdude\\6.3.0-arduino14
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE6.3.0-ARDUINO14.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE6.3.0-ARDUINO14.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.AVRDUDE6.3.0-ARDUINO14.PATH/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\packages\\arduino\\tools\\avrdude\\6.3.0-arduino14
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.XTENSA-ESP32-ELF-GCC.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.XTENSA-ESP32-ELF-GCC.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.RUNTIME.TOOLS.XTENSA-ESP32-ELF-GCC.PATH/value=${A.RUNTIME.PLATFORM.PATH}/tools/xtensa-esp32-elf
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.DISABLEDTR/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.DISABLEDTR/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.DISABLEDTR/value=true
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.DISABLERTS/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.DISABLERTS/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.DISABLERTS/value=true
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.PORT.FILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.PORT.FILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.PORT.FILE/value=${A.SERIAL.PORT}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.PORT/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.PORT/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SERIAL.PORT/value=${JANTJE.COM_PORT}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SOFTWARE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SOFTWARE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.SOFTWARE/value=ARDUINO
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.AVRDUDE_REMOTE.UPLOAD.VERBOSE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.AVRDUDE_REMOTE.UPLOAD.VERBOSE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.AVRDUDE_REMOTE.UPLOAD.VERBOSE/value=-v
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESP8266OTA.UPLOAD.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESP8266OTA.UPLOAD.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESP8266OTA.UPLOAD.PATTERN/value=${A.TOOLS.ESP8266OTA.TOOLS.ESPTOOL.UPLOAD.NETWORK_PATTERN}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESP8266OTA/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESP8266OTA/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESP8266OTA/value=${A.TOOLS.ESP8266OTA.TOOLS.ESPTOOL.NETWORK_CMD}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL.NETWORK.PASSWORD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL.NETWORK.PASSWORD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL.NETWORK.PASSWORD/value=${A.TOOLS.ESPTOOL.NETWORK.AUTH}
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.CMD.LINUX/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.CMD.LINUX/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.CMD.LINUX/value=esptool.py
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.CMD/value=esptool.exe
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.NETWORK_CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.NETWORK_CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.NETWORK_CMD/value="${A.RUNTIME.PLATFORM.PATH}/tools/espota.exe"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.PATH/value=${A.RUNTIME.PLATFORM.PATH}/tools/esptool
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.NETWORK_PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.NETWORK_PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.NETWORK_PATTERN/value=${A.TOOLS.ESPTOOL_PY.NETWORK_CMD} -i "${A.SERIAL.PORT}" -p "${A.NETWORK.PORT}" "--auth\=${A.NETWORK.PASSWORD}" -f "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.bin"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PARAMS.QUIET/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PARAMS.QUIET/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PARAMS.QUIET/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PARAMS.VERBOSE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PARAMS.VERBOSE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PARAMS.VERBOSE/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PATTERN.LINUX/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PATTERN.LINUX/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PATTERN.LINUX/value=python "${A.TOOLS.ESPTOOL_PY.PATH}/${A.TOOLS.ESPTOOL_PY.CMD}" --chip esp32 --port "${A.SERIAL.PORT}" --baud ${A.UPLOAD.SPEED} --before default_reset --after hard_reset write_flash -z --flash_mode ${A.BUILD.FLASH_MODE} --flash_freq ${A.BUILD.FLASH_FREQ} --flash_size detect 0xe000 "${A.RUNTIME.PLATFORM.PATH}/tools/partitions/boot_app0.bin" 0x1000 "${A.RUNTIME.PLATFORM.PATH}/tools/sdk/bin/bootloader_${A.BUILD.BOOT}_${A.BUILD.FLASH_FREQ}.bin" 0x10000 "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.bin" 0x8000 "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.partitions.bin"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PATTERN/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PATTERN/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PATTERN/value="${A.TOOLS.ESPTOOL_PY.PATH}/${A.TOOLS.ESPTOOL_PY.CMD}" --chip esp32 --port "${A.SERIAL.PORT}" --baud ${A.UPLOAD.SPEED} --before default_reset --after hard_reset write_flash -z --flash_mode ${A.BUILD.FLASH_MODE} --flash_freq ${A.BUILD.FLASH_FREQ} --flash_size detect 0xe000 "${A.RUNTIME.PLATFORM.PATH}/tools/partitions/boot_app0.bin" 0x1000 "${A.RUNTIME.PLATFORM.PATH}/tools/sdk/bin/bootloader_${A.BUILD.BOOT}_${A.BUILD.FLASH_FREQ}.bin" 0x10000 "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.bin" 0x8000 "${A.BUILD.PATH}/${A.BUILD.PROJECT_NAME}.partitions.bin"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PROTOCOL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PROTOCOL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.ESPTOOL_PY.UPLOAD.PROTOCOL/value=esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.GEN_ESP32PART.CMD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.GEN_ESP32PART.CMD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.TOOLS.GEN_ESP32PART.CMD/value="${A.RUNTIME.PLATFORM.PATH}/tools/gen_esp32part.exe"
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.ALTID/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.ALTID/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.ALTID/value=no_altID
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.MAXIMUM_DATA_SIZE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.MAXIMUM_DATA_SIZE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.MAXIMUM_DATA_SIZE/value=327680
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.MAXIMUM_SIZE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.MAXIMUM_SIZE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.MAXIMUM_SIZE/value=1310720
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.PROTOCOL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.PROTOCOL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.PROTOCOL/value=stk500v1
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.SPEED/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.SPEED/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.SPEED/value=921600
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.TOOL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.TOOL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.TOOL/value=esptool_py
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.USBID/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.USBID/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.USBID/value=no_altID
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.WAIT_FOR_UPLOAD_PORT/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.WAIT_FOR_UPLOAD_PORT/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.UPLOAD.WAIT_FOR_UPLOAD_PORT/value=true
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.VERSION/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.VERSION/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/A.VERSION/value=0.0.1
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.ARCHITECTURE_ID/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.ARCHITECTURE_ID/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.ARCHITECTURE_ID/value=arduino-esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARDS_FILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARDS_FILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARDS_FILE/value=C\:\\dev\\git\\arduino-esp32\\boards.txt
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARD_ID/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARD_ID/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARD_ID/value=lolin32
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARD_NAME/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARD_NAME/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.BOARD_NAME/value=WEMOS LOLIN32
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.COM_PORT/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.COM_PORT/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.COM_PORT/value=COM4
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.ECLIPSE_LOCATION/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.ECLIPSE_LOCATION/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.ECLIPSE_LOCATION/value=C\:\\dev\\sw\\eclipse2019-03\\
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ALL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ALL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ALL/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ARCHIVE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ARCHIVE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ARCHIVE/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ASSEMBLY/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ASSEMBLY/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.ASSEMBLY/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.C.COMPILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.C.COMPILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.C.COMPILE/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.COMPILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.COMPILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.COMPILE/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.CPP.COMPILE/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.CPP.COMPILE/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.CPP.COMPILE/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.LINK/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.LINK/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.EXTRA.LINK/value=
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.MAKE_LOCATION/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.MAKE_LOCATION/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.MAKE_LOCATION/value=C\:\\dev\\sw\\eclipse2019-03\\arduinoPlugin\\tools\\make\\
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.MENU/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.MENU/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.MENU/value=DebugLevel\=info\nFlashFreq\=40\nFlashMode\=dout\nFlashSize\=4M\nPartitionScheme\=default\nUploadSpeed\=921600
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.OBJCOPY/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.OBJCOPY/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.OBJCOPY/value=${A.RECIPE.OBJCOPY.EEP.PATTERN}\n\t${A.RECIPE.OBJCOPY.HEX.PATTERN}
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.OS_NAME/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.OS_NAME/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.OS_NAME/value=win32
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.PACKAGE_ID/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.PACKAGE_ID/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.PACKAGE_ID/value=git
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.PROJECT_NAME/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.PROJECT_NAME/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.PROJECT_NAME/value=esp32-geiger-counter
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.SELECTED.PLATFORM/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.SELECTED.PLATFORM/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.SELECTED.PLATFORM/value=C\:/dev/git/arduino-esp32
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.SIZE.SWITCH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.SIZE.SWITCH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.SIZE.SWITCH/value=${A.RECIPE.SIZE.PATTERN}
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.UPLOAD/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.UPLOAD/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.UPLOAD/value=Default
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.WARNING_LEVEL/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.WARNING_LEVEL/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.WARNING_LEVEL/value=true
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.WORKSPACE_LOCATION/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.WORKSPACE_LOCATION/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/JANTJE.WORKSPACE_LOCATION/value=C\:\\dev\\workspace-2019-03
-environment/project/io.sloeber.core.toolChain.release.2091291922/PATH/delimiter=;
-environment/project/io.sloeber.core.toolChain.release.2091291922/PATH/operation=replace
-environment/project/io.sloeber.core.toolChain.release.2091291922/PATH/value=${A.COMPILER.PATH}${PathDelimiter}${A.BUILD.GENERIC.PATH}${PathDelimiter}${SystemRoot}\\system32${PathDelimiter}${SystemRoot}${PathDelimiter}${SystemRoot}\\system32\\Wbem${PathDelimiter}${sloeber_path_extension}
-environment/project/io.sloeber.core.toolChain.release.2091291922/append=true
-environment/project/io.sloeber.core.toolChain.release.2091291922/appendContributed=true
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..7c486f1
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,67 @@
+# Continuous Integration (CI) is the practice, in software
+# engineering, of merging all developer working copies with a shared mainline
+# several times a day < https://docs.platformio.org/page/ci/index.html >
+#
+# Documentation:
+#
+# * Travis CI Embedded Builds with PlatformIO
+# < https://docs.travis-ci.com/user/integration/platformio/ >
+#
+# * PlatformIO integration with Travis CI
+# < https://docs.platformio.org/page/ci/travis.html >
+#
+# * User Guide for `platformio ci` command
+# < https://docs.platformio.org/page/userguide/cmd_ci.html >
+#
+#
+# Please choose one of the following templates (proposed below) and uncomment
+# it (remove "# " before each line) or use own configuration according to the
+# Travis CI documentation (see above).
+#
+
+
+#
+# Template #1: General project. Test it using existing `platformio.ini`.
+#
+
+# language: python
+# python:
+# - "2.7"
+#
+# sudo: false
+# cache:
+# directories:
+# - "~/.platformio"
+#
+# install:
+# - pip install -U platformio
+# - platformio update
+#
+# script:
+# - platformio run
+
+
+#
+# Template #2: The project is intended to be used as a library with examples.
+#
+
+# language: python
+# python:
+# - "2.7"
+#
+# sudo: false
+# cache:
+# directories:
+# - "~/.platformio"
+#
+# env:
+# - PLATFORMIO_CI_SRC=path/to/test/file.c
+# - PLATFORMIO_CI_SRC=examples/file.ino
+# - PLATFORMIO_CI_SRC=path/to/test/directory
+#
+# install:
+# - pip install -U platformio
+# - platformio update
+#
+# script:
+# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N
diff --git a/README.md b/README.md
index 0fd0314..df4ef6d 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Feel free to use this project as a base for your own projects AT YOUR OWN RISK!
# Software
-- Eclipse sloeber project using Arduino library, ESP-IDF for sleep functions and u8g2 for display output
+- PlatformIO project using Arduino library, ESP-IDF for sleep functions and U8g2 for display output
- Low-power mode uses light sleep, a wake-up for each signal pulse change and a wake-up every 1000 ms to update pulse statistics and OLED. This results in about 90% sleep. Could be improved using deep sleep and ULP. However, light sleep is already quite good and much easier.
- WiFi mode uses no sleep and simple interrupts for pulse counting. Pulse statistics and OLED are updated every 1000 ms, data is sent to thingspeak every 60 s.
- Credentials (WiFi SSID, password, thingspeak channel key) are only declared in `credentials.h` and must be defined in a `credentials.cpp`
diff --git a/GeigerData.h b/include/GeigerData.h
similarity index 89%
rename from GeigerData.h
rename to include/GeigerData.h
index 8c5573f..ddd1e80 100644
--- a/GeigerData.h
+++ b/include/GeigerData.h
@@ -1,37 +1,37 @@
-#ifndef GEIGERDATA_H_
-#define GEIGERDATA_H_
-
-#include "Arduino.h"
-
-// Russion STS-6 ("CTC-6") Geiger tube:
-// N = (2.28–3.42)*10^3 at 0.36 µR/h; Nmax = 6*10^4; Nf = 110
-const float STS6_CPM_PER_USPH = 875;
-
-// Holds pulse counter history and performs calculations
-class GeigerData {
-public:
- const uint16_t sampleCount;
- const uint16_t sampleSeconds;
- const float cpm_per_uSph;
-
-private:
- uint16_t currentSample;
- uint16_t *pulsesPerSample;
- uint16_t next(uint16_t index);
- uint16_t prev(uint16_t index);
-
-public:
-
- GeigerData(uint16_t sampleCount, uint16_t sampleSeconds,
- float cpm_per_uSph);
- virtual ~GeigerData();
-
- virtual void addPulses(uint16_t pulses);
- virtual void nextSample();
-
- virtual uint16_t getCurrentSample();
- virtual uint32_t getPreviousPulses(uint16_t offset, uint16_t samples);
- virtual float toMicroSievertPerHour(uint32_t pulses, uint16_t samples);
-};
-
-#endif /* GEIGERDATA_H_ */
+#ifndef GEIGERDATA_H_
+#define GEIGERDATA_H_
+
+#include "Arduino.h"
+
+// Russion STS-6 ("CTC-6") Geiger tube:
+// N = (2.28-3.42)*10^3 at 0.36 µR/h; Nmax = 6*10^4; Nf = 110
+const float STS6_CPM_PER_USPH = 875;
+
+// Holds pulse counter history and performs calculations
+class GeigerData {
+public:
+ const uint16_t sampleCount;
+ const uint16_t sampleSeconds;
+ const float cpm_per_uSph;
+
+private:
+ uint16_t currentSample;
+ uint16_t *pulsesPerSample;
+ uint16_t next(uint16_t index);
+ uint16_t prev(uint16_t index);
+
+public:
+
+ GeigerData(uint16_t sampleCount, uint16_t sampleSeconds,
+ float cpm_per_uSph);
+ virtual ~GeigerData();
+
+ virtual void addPulses(uint16_t pulses);
+ virtual void nextSample();
+
+ virtual uint16_t getCurrentSample();
+ virtual uint32_t getPreviousPulses(uint16_t offset, uint16_t samples);
+ virtual float toMicroSievertPerHour(uint32_t pulses, uint16_t samples);
+};
+
+#endif /* GEIGERDATA_H_ */
diff --git a/include/README b/include/README
new file mode 100644
index 0000000..194dcd4
--- /dev/null
+++ b/include/README
@@ -0,0 +1,39 @@
+
+This directory is intended for project header files.
+
+A header file is a file containing C declarations and macro definitions
+to be shared between several project source files. You request the use of a
+header file in your project source file (C, C++, etc) located in `src` folder
+by including it, with the C preprocessing directive `#include'.
+
+```src/main.c
+
+#include "header.h"
+
+int main (void)
+{
+ ...
+}
+```
+
+Including a header file produces the same results as copying the header file
+into each source file that needs it. Such copying would be time-consuming
+and error-prone. With a header file, the related declarations appear
+in only one place. If they need to be changed, they can be changed in one
+place, and programs that include the header file will automatically use the
+new version when next recompiled. The header file eliminates the labor of
+finding and changing all the copies as well as the risk that a failure to
+find one copy will result in inconsistencies within a program.
+
+In C, the usual convention is to give header files names that end with `.h'.
+It is most portable to use only letters, digits, dashes, and underscores in
+header file names, and at most one dot.
+
+Read more about using header files in official GCC documentation:
+
+* Include Syntax
+* Include Operation
+* Once-Only Headers
+* Computed Includes
+
+https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
diff --git a/credentials.h b/include/credentials.h
similarity index 95%
rename from credentials.h
rename to include/credentials.h
index 38c5476..863cd21 100644
--- a/credentials.h
+++ b/include/credentials.h
@@ -1,8 +1,8 @@
-#ifndef CREDENTIALS_H_
-#define CREDENTIALS_H_
-
-extern const char *wifiSsid;
-extern const char *wifiPassword;
-extern const char *thingspeakApiKey;
-
-#endif /* CREDENTIALS_H_ */
+#ifndef CREDENTIALS_H_
+#define CREDENTIALS_H_
+
+extern const char *wifiSsid;
+extern const char *wifiPassword;
+extern const char *thingspeakApiKey;
+
+#endif /* CREDENTIALS_H_ */
diff --git a/display.h b/include/display.h
similarity index 95%
rename from display.h
rename to include/display.h
index cee0649..03122a5 100644
--- a/display.h
+++ b/include/display.h
@@ -1,9 +1,9 @@
-#ifndef DISPLAY_H_
-#define DISPLAY_H_
-
-#include "GeigerData.h"
-
-void initDisplay();
-void updateDisplay(GeigerData &geigerData, char uSphStr[16], char cpmStr[16]);
-
-#endif /* DISPLAY_H_ */
+#ifndef DISPLAY_H_
+#define DISPLAY_H_
+
+#include "GeigerData.h"
+
+void initDisplay();
+void updateDisplay(GeigerData &geigerData, char uSphStr[16], char cpmStr[16]);
+
+#endif /* DISPLAY_H_ */
diff --git a/ingest.h b/include/ingest.h
similarity index 94%
rename from ingest.h
rename to include/ingest.h
index 9d1280e..f598e58 100644
--- a/ingest.h
+++ b/include/ingest.h
@@ -1,10 +1,10 @@
-#ifndef INGEST_H_
-#define INGEST_H_
-
-#include "GeigerData.h"
-
-void initIngest();
-void deinitIngest();
-void ingest(GeigerData &geigerData, uint16_t intervalSamples);
-
-#endif /* INGEST_H_ */
+#ifndef INGEST_H_
+#define INGEST_H_
+
+#include "GeigerData.h"
+
+void initIngest();
+void deinitIngest();
+void ingest(GeigerData &geigerData, uint16_t intervalSamples);
+
+#endif /* INGEST_H_ */
diff --git a/lib/README b/lib/README
new file mode 100644
index 0000000..6debab1
--- /dev/null
+++ b/lib/README
@@ -0,0 +1,46 @@
+
+This directory is intended for project specific (private) libraries.
+PlatformIO will compile them to static libraries and link into executable file.
+
+The source code of each library should be placed in a an own separate directory
+("lib/your_library_name/[here are source files]").
+
+For example, see a structure of the following two libraries `Foo` and `Bar`:
+
+|--lib
+| |
+| |--Bar
+| | |--docs
+| | |--examples
+| | |--src
+| | |- Bar.c
+| | |- Bar.h
+| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
+| |
+| |--Foo
+| | |- Foo.c
+| | |- Foo.h
+| |
+| |- README --> THIS FILE
+|
+|- platformio.ini
+|--src
+ |- main.c
+
+and a contents of `src/main.c`:
+```
+#include
+#include
+
+int main (void)
+{
+ ...
+}
+
+```
+
+PlatformIO Library Dependency Finder will find automatically dependent
+libraries scanning project source files.
+
+More information about PlatformIO Library Dependency Finder
+- https://docs.platformio.org/page/librarymanager/ldf.html
diff --git a/platformio.ini b/platformio.ini
new file mode 100644
index 0000000..06c2ef9
--- /dev/null
+++ b/platformio.ini
@@ -0,0 +1,18 @@
+; PlatformIO Project Configuration File
+;
+; Build options: build flags, source filter
+; Upload options: custom upload port, speed and extra flags
+; Library options: dependencies, extra library storages
+; Advanced options: extra scripting
+;
+; Please visit documentation for the other options and examples
+; https://docs.platformio.org/page/projectconf.html
+
+[env:lolin32]
+platform = espressif32
+board = lolin32
+framework = arduino
+
+monitor_speed = 921600
+
+lib_deps = U8g2@2.26.1
\ No newline at end of file
diff --git a/GeigerData.cpp b/src/GeigerData.cpp
similarity index 96%
rename from GeigerData.cpp
rename to src/GeigerData.cpp
index e1d8627..39e0002 100644
--- a/GeigerData.cpp
+++ b/src/GeigerData.cpp
@@ -1,53 +1,53 @@
-#include "GeigerData.h"
-
-GeigerData::GeigerData(uint16_t sampleCount, uint16_t sampleSeconds,
- float cpm_per_uSph) :
- sampleCount(sampleCount), sampleSeconds(sampleSeconds), cpm_per_uSph(
- cpm_per_uSph), pulsesPerSample(new uint16_t[sampleCount]) {
- currentSample = 0;
- for (int i = 0; i < sampleCount; i++) {
- pulsesPerSample[i] = 0;
- }
-}
-
-GeigerData::~GeigerData() {
- delete[] pulsesPerSample;
-}
-
-uint16_t GeigerData::next(uint16_t index) {
- return index + 1 < sampleCount ? index + 1 : 0;
-}
-
-uint16_t GeigerData::prev(uint16_t index) {
- return index > 0 ? index - 1 : sampleCount - 1;
-}
-
-void GeigerData::addPulses(uint16_t pulses) {
- if (pulsesPerSample[currentSample] <= UINT16_MAX - pulses)
- pulsesPerSample[currentSample] += pulses;
-}
-
-void GeigerData::nextSample() {
- currentSample = next(currentSample);
- pulsesPerSample[currentSample] = 0;
-}
-
-uint16_t GeigerData::getCurrentSample() {
- return currentSample;
-}
-
-uint32_t GeigerData::getPreviousPulses(uint16_t offset, uint16_t samples) {
- uint32_t pulses = 0;
- uint16_t index = (currentSample + sampleCount - offset) % sampleCount;
- for (uint16_t i = 0; i < samples; i++) {
- pulses += pulsesPerSample[index];
- index = prev(index);
- }
-
- return pulses;
-}
-
-float GeigerData::toMicroSievertPerHour(uint32_t pulses, uint16_t samples) {
- float cpm = pulses / (sampleSeconds / 60. * samples);
- return cpm / cpm_per_uSph;
-}
+#include "GeigerData.h"
+
+GeigerData::GeigerData(uint16_t sampleCount, uint16_t sampleSeconds,
+ float cpm_per_uSph) :
+ sampleCount(sampleCount), sampleSeconds(sampleSeconds), cpm_per_uSph(
+ cpm_per_uSph), pulsesPerSample(new uint16_t[sampleCount]) {
+ currentSample = 0;
+ for (int i = 0; i < sampleCount; i++) {
+ pulsesPerSample[i] = 0;
+ }
+}
+
+GeigerData::~GeigerData() {
+ delete[] pulsesPerSample;
+}
+
+uint16_t GeigerData::next(uint16_t index) {
+ return index + 1 < sampleCount ? index + 1 : 0;
+}
+
+uint16_t GeigerData::prev(uint16_t index) {
+ return index > 0 ? index - 1 : sampleCount - 1;
+}
+
+void GeigerData::addPulses(uint16_t pulses) {
+ if (pulsesPerSample[currentSample] <= UINT16_MAX - pulses)
+ pulsesPerSample[currentSample] += pulses;
+}
+
+void GeigerData::nextSample() {
+ currentSample = next(currentSample);
+ pulsesPerSample[currentSample] = 0;
+}
+
+uint16_t GeigerData::getCurrentSample() {
+ return currentSample;
+}
+
+uint32_t GeigerData::getPreviousPulses(uint16_t offset, uint16_t samples) {
+ uint32_t pulses = 0;
+ uint16_t index = (currentSample + sampleCount - offset) % sampleCount;
+ for (uint16_t i = 0; i < samples; i++) {
+ pulses += pulsesPerSample[index];
+ index = prev(index);
+ }
+
+ return pulses;
+}
+
+float GeigerData::toMicroSievertPerHour(uint32_t pulses, uint16_t samples) {
+ float cpm = pulses / (sampleSeconds / 60. * samples);
+ return cpm / cpm_per_uSph;
+}
diff --git a/display.cpp b/src/display.cpp
similarity index 94%
rename from display.cpp
rename to src/display.cpp
index 9c60774..eb91564 100644
--- a/display.cpp
+++ b/src/display.cpp
@@ -1,100 +1,100 @@
-#include "U8g2lib.h"
-
-#include "display.h"
-
-// OLED display 128x64 with SH1106 controller
-// on I2C GPIOs SCL 22 and SDA 21
-U8G2_SH1106_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, 22, 21);
-
-void initDisplay() {
- // high I2c clock still results in about 100ms buffer transmission to OLED:
- u8g2.setBusClock(1000000);
- u8g2.begin();
-}
-
-void renderDigits(char uSphStr[16], char cpmStr[16]) {
- uint16_t y = 14;
- uint16_t xCpm = 56;
- uint16_t xUSph = 127;
-
- u8g2.setFont(u8g2_font_crox4hb_tr);
- u8g2_uint_t w = u8g2.getStrWidth(uSphStr);
- u8g2.setCursor(xUSph - w, y);
- u8g2.print(uSphStr);
-
- w = u8g2.getStrWidth(cpmStr);
- u8g2.setCursor(xCpm - w, y);
- u8g2.print(cpmStr);
-
- y = 21;
- u8g2.setFont(u8g2_font_4x6_tf);
- w = u8g2.getStrWidth("µS/h");
- u8g2.setCursor(xUSph - w, y);
- u8g2.print("µS/h");
-
- w = u8g2.getStrWidth("cnt/min");
- u8g2.setCursor(xCpm - w, y);
- u8g2.print("cnt/min");
-}
-
-void renderHistoryBarGraph(GeigerData &geigerData) {
- const uint16_t bars = 120;
- const uint16_t maxBarHeight = 40;
- const uint16_t samplesPerBar = geigerData.sampleCount / bars;
- const uint16_t barsPerMinute = 60
- / (samplesPerBar * geigerData.sampleSeconds);
-
- // determine max value for y scale:
- uint16_t offset = geigerData.getCurrentSample() % samplesPerBar + 1;
- uint32_t maxPulses = 0;
- for (int16_t i = 0; i < bars - 1; i++) {
- const uint32_t prevPulses = geigerData.getPreviousPulses(offset,
- samplesPerBar);
- if (prevPulses > maxPulses)
- maxPulses = prevPulses;
-
- offset += samplesPerBar;
- }
-
- const float maxUSph = geigerData.toMicroSievertPerHour(maxPulses,
- samplesPerBar);
- const float uSphPerPixel = maxUSph > 40. ? 10. : maxUSph > 4. ? 1. :
- maxUSph > 0.4 ? 0.1 : 0.01;
- // labels and grid
- u8g2.setFont(u8g2_font_4x6_tn);
- char s[10];
- for (uint16_t i = 10; i <= maxBarHeight; i += 10) {
- u8g2.setCursor(0, 63 - i + 3);
- if (uSphPerPixel >= 0.1)
- sprintf(s, "%.0f", i * uSphPerPixel);
- else
- sprintf(s, ".%.0f", i * uSphPerPixel * 10);
-
- u8g2.print(s);
- for (int16_t x = 127 - barsPerMinute; x >= 8; x -= barsPerMinute) {
- u8g2.drawPixel(x, 63 - i);
- }
- }
-
- // bars
- offset = geigerData.getCurrentSample() % samplesPerBar + 1;
- for (int16_t i = 0; i < bars - 1; i++) {
- const uint32_t prevPulses = geigerData.getPreviousPulses(offset,
- samplesPerBar);
- const float uSph = geigerData.toMicroSievertPerHour(prevPulses,
- samplesPerBar);
- offset += samplesPerBar;
- uint16_t barHeight = 1 + (int) ((uSph / uSphPerPixel));
- if (barHeight > 40)
- barHeight = 40;
-
- u8g2.drawVLine(127 - i, 63 - barHeight, barHeight);
- }
-}
-
-void updateDisplay(GeigerData &geigerData, char uSphStr[16], char cpmStr[16]) {
- u8g2.clearBuffer();
- renderDigits(uSphStr, cpmStr);
- renderHistoryBarGraph(geigerData);
- u8g2.sendBuffer();
-}
+#include "U8g2lib.h"
+
+#include "display.h"
+
+// OLED display 128x64 with SH1106 controller
+// on I2C GPIOs SCL 22 and SDA 21
+U8G2_SH1106_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, 22, 21);
+
+void initDisplay() {
+ // high I2c clock still results in about 100ms buffer transmission to OLED:
+ u8g2.setBusClock(1000000);
+ u8g2.begin();
+}
+
+void renderDigits(char uSphStr[16], char cpmStr[16]) {
+ uint16_t y = 14;
+ uint16_t xCpm = 56;
+ uint16_t xUSph = 127;
+
+ u8g2.setFont(u8g2_font_crox4hb_tr);
+ u8g2_uint_t w = u8g2.getStrWidth(uSphStr);
+ u8g2.setCursor(xUSph - w, y);
+ u8g2.print(uSphStr);
+
+ w = u8g2.getStrWidth(cpmStr);
+ u8g2.setCursor(xCpm - w, y);
+ u8g2.print(cpmStr);
+
+ y = 21;
+ u8g2.setFont(u8g2_font_4x6_tf);
+ w = u8g2.getStrWidth("µS/h");
+ u8g2.setCursor(xUSph - w, y);
+ u8g2.print("µS/h");
+
+ w = u8g2.getStrWidth("cnt/min");
+ u8g2.setCursor(xCpm - w, y);
+ u8g2.print("cnt/min");
+}
+
+void renderHistoryBarGraph(GeigerData &geigerData) {
+ const uint16_t bars = 120;
+ const uint16_t maxBarHeight = 40;
+ const uint16_t samplesPerBar = geigerData.sampleCount / bars;
+ const uint16_t barsPerMinute = 60
+ / (samplesPerBar * geigerData.sampleSeconds);
+
+ // determine max value for y scale:
+ uint16_t offset = geigerData.getCurrentSample() % samplesPerBar + 1;
+ uint32_t maxPulses = 0;
+ for (int16_t i = 0; i < bars - 1; i++) {
+ const uint32_t prevPulses = geigerData.getPreviousPulses(offset,
+ samplesPerBar);
+ if (prevPulses > maxPulses)
+ maxPulses = prevPulses;
+
+ offset += samplesPerBar;
+ }
+
+ const float maxUSph = geigerData.toMicroSievertPerHour(maxPulses,
+ samplesPerBar);
+ const float uSphPerPixel = maxUSph > 40. ? 10. : maxUSph > 4. ? 1. :
+ maxUSph > 0.4 ? 0.1 : 0.01;
+ // labels and grid
+ u8g2.setFont(u8g2_font_4x6_tn);
+ char s[10];
+ for (uint16_t i = 10; i <= maxBarHeight; i += 10) {
+ u8g2.setCursor(0, 63 - i + 3);
+ if (uSphPerPixel >= 0.1)
+ sprintf(s, "%.0f", i * uSphPerPixel);
+ else
+ sprintf(s, ".%.0f", i * uSphPerPixel * 10);
+
+ u8g2.print(s);
+ for (int16_t x = 127 - barsPerMinute; x >= 8; x -= barsPerMinute) {
+ u8g2.drawPixel(x, 63 - i);
+ }
+ }
+
+ // bars
+ offset = geigerData.getCurrentSample() % samplesPerBar + 1;
+ for (int16_t i = 0; i < bars - 1; i++) {
+ const uint32_t prevPulses = geigerData.getPreviousPulses(offset,
+ samplesPerBar);
+ const float uSph = geigerData.toMicroSievertPerHour(prevPulses,
+ samplesPerBar);
+ offset += samplesPerBar;
+ uint16_t barHeight = 1 + (int) ((uSph / uSphPerPixel));
+ if (barHeight > 40)
+ barHeight = 40;
+
+ u8g2.drawVLine(127 - i, 63 - barHeight, barHeight);
+ }
+}
+
+void updateDisplay(GeigerData &geigerData, char uSphStr[16], char cpmStr[16]) {
+ u8g2.clearBuffer();
+ renderDigits(uSphStr, cpmStr);
+ renderHistoryBarGraph(geigerData);
+ u8g2.sendBuffer();
+}
diff --git a/ingest.cpp b/src/ingest.cpp
similarity index 95%
rename from ingest.cpp
rename to src/ingest.cpp
index 4bcd1b7..c7253a9 100644
--- a/ingest.cpp
+++ b/src/ingest.cpp
@@ -1,104 +1,104 @@
-#include
-
-#include "GeigerData.h"
-
-#include "credentials.h"
-
-const char *thingsPeakUrl = "api.thingspeak.com";
-
-bool connect() {
- uint16_t retries = 3;
- while (WiFi.status() != WL_CONNECTED && (--retries) > 0) {
- Serial.print("Trying to connect to ");
- Serial.print(wifiSsid);
- Serial.print(" ... ");
- WiFi.begin(wifiSsid, wifiPassword);
- uint16_t waitRemaining = 8;
- while (WiFi.status() != WL_CONNECTED && (--waitRemaining) > 0) {
- delay(500);
- }
- if (WiFi.status() == WL_CONNECTED) {
- Serial.println("successful");
- return true;
- } else {
- Serial.print("failed status=");
- Serial.println(WiFi.status());
- }
- }
-
- return WiFi.status() == WL_CONNECTED;
-}
-
-void initIngest() {
- connect();
-}
-
-void deinitIngest() {
- if (WiFi.status() == WL_CONNECTED) {
- Serial.println("Disconnecting WiFi");
- WiFi.disconnect(true, true);
- }
-}
-
-void ingest(GeigerData &geigerData, uint16_t intervalSamples) {
- if (!connect())
- return;
-
- WiFiClient client;
- if (!client.connect(thingsPeakUrl, 80)) {
- Serial.print("Connecting to ");
- Serial.print(thingsPeakUrl);
- Serial.println(" failed");
- } else {
-
- const uint32_t pulses = geigerData.getPreviousPulses(1,
- intervalSamples);
- const uint32_t cpm = uint32_t(
- pulses
- / ((float) intervalSamples * geigerData.sampleSeconds
- / 60.) + 0.5);
- const float uSph = geigerData.toMicroSievertPerHour(pulses,
- intervalSamples);
-
- const String content = "api_key=" + String(thingspeakApiKey)
- + "&field1=" + String(cpm) + "&field2=" + String(uSph, 3);
-
- Serial.print("Ingesting cpm=");
- Serial.print(cpm);
- Serial.print(" uSph=");
- Serial.print(uSph, 3);
- Serial.print(" ... ");
-
- client.print("POST /update HTTP/1.1\n");
-
- client.print("Host: ");
- client.print(thingsPeakUrl);
- client.print("\n");
-
- client.print("Connection: close\n");
-
- client.print("Content-Type: application/x-www-form-urlencoded\n");
- client.print("Content-Length: ");
- client.print(content.length());
- client.print("\n\n");
-
- client.print(content);
-
- uint16_t timeout = 40;
- while (client.available() == 0 && (--timeout) > 0) {
- delay(50);
- }
- if (client.available() == 0) {
- Serial.println("failed (no response)");
- }
-
- Serial.println("response:");
- while (client.available()) {
- char c = client.read();
- Serial.write(c);
- }
- Serial.println();
-
- client.stop();
- }
-}
+#include
+
+#include "GeigerData.h"
+
+#include "credentials.h"
+
+const char *thingsPeakUrl = "api.thingspeak.com";
+
+bool connect() {
+ uint16_t retries = 3;
+ while (WiFi.status() != WL_CONNECTED && (--retries) > 0) {
+ Serial.print("Trying to connect to ");
+ Serial.print(wifiSsid);
+ Serial.print(" ... ");
+ WiFi.begin(wifiSsid, wifiPassword);
+ uint16_t waitRemaining = 8;
+ while (WiFi.status() != WL_CONNECTED && (--waitRemaining) > 0) {
+ delay(500);
+ }
+ if (WiFi.status() == WL_CONNECTED) {
+ Serial.println("successful");
+ return true;
+ } else {
+ Serial.print("failed status=");
+ Serial.println(WiFi.status());
+ }
+ }
+
+ return WiFi.status() == WL_CONNECTED;
+}
+
+void initIngest() {
+ connect();
+}
+
+void deinitIngest() {
+ if (WiFi.status() == WL_CONNECTED) {
+ Serial.println("Disconnecting WiFi");
+ WiFi.disconnect(true, true);
+ }
+}
+
+void ingest(GeigerData &geigerData, uint16_t intervalSamples) {
+ if (!connect())
+ return;
+
+ WiFiClient client;
+ if (!client.connect(thingsPeakUrl, 80)) {
+ Serial.print("Connecting to ");
+ Serial.print(thingsPeakUrl);
+ Serial.println(" failed");
+ } else {
+
+ const uint32_t pulses = geigerData.getPreviousPulses(1,
+ intervalSamples);
+ const uint32_t cpm = uint32_t(
+ pulses
+ / ((float) intervalSamples * geigerData.sampleSeconds
+ / 60.) + 0.5);
+ const float uSph = geigerData.toMicroSievertPerHour(pulses,
+ intervalSamples);
+
+ const String content = "api_key=" + String(thingspeakApiKey)
+ + "&field1=" + String(cpm) + "&field2=" + String(uSph, 3);
+
+ Serial.print("Ingesting cpm=");
+ Serial.print(cpm);
+ Serial.print(" uSph=");
+ Serial.print(uSph, 3);
+ Serial.print(" ... ");
+
+ client.print("POST /update HTTP/1.1\n");
+
+ client.print("Host: ");
+ client.print(thingsPeakUrl);
+ client.print("\n");
+
+ client.print("Connection: close\n");
+
+ client.print("Content-Type: application/x-www-form-urlencoded\n");
+ client.print("Content-Length: ");
+ client.print(content.length());
+ client.print("\n\n");
+
+ client.print(content);
+
+ uint16_t timeout = 40;
+ while (client.available() == 0 && (--timeout) > 0) {
+ delay(50);
+ }
+ if (client.available() == 0) {
+ Serial.println("failed (no response)");
+ }
+
+ Serial.println("response:");
+ while (client.available()) {
+ char c = client.read();
+ Serial.write(c);
+ }
+ Serial.println();
+
+ client.stop();
+ }
+}
diff --git a/ESP32GeigerCounter.ino b/src/main.cpp
similarity index 92%
rename from ESP32GeigerCounter.ino
rename to src/main.cpp
index 2b65f88..59b6acf 100644
--- a/ESP32GeigerCounter.ino
+++ b/src/main.cpp
@@ -1,203 +1,219 @@
-#include "Arduino.h"
-
-#include "driver/pcnt.h"
-#include "driver/gpio.h"
-#include "driver/rtc_io.h"
-
-#include "display.h"
-#include "ingest.h"
-#include "GeigerData.h"
-
-// ~400µs high pulses from Geiger tube on GPIO 18
-#define PULSE_PIN 18
-#define PULSE_GPIO GPIO_NUM_18
-
-// switch input for WiFi on (low) and off (high)
-#define WIFI_SWITCH_PIN 4
-
-// Keep 600 samples of 1s in history (10 minutes),
-// calculate radiation for russian STS-6 ("CTC-6") Geiger tube
-GeigerData geigerData(600, 1, STS6_CPM_PER_USPH);
-
-// blinky state
-int blinky = 1;
-
-// Pulses counted by interrupt (while CPU is awake)
-volatile uint16_t intPulseCount = 0;
-// Pulses counted during ESP light sleep
-volatile uint16_t pulseCount = 0;
-
-// Sample duration in µs
-const uint32_t sampleMicros = geigerData.sampleSeconds * 1000000;
-// Absolute sample interval start micros
-uint32_t sampleStart = 0;
-
-const int16_t ingestInterval = 60;
-int16_t ingestCountdown;
-
-void setup() {
- Serial.begin(921600);
- Serial.println("Starting!");
-
- // OLED
- initDisplay();
-
- // blinky
- pinMode(LED_BUILTIN, OUTPUT);
-
- // Geiger pulse input
- pinMode(PULSE_PIN, INPUT);
-
- // WiFi switch input
- pinMode(WIFI_SWITCH_PIN, INPUT_PULLUP);
-
- if (wifiSwitchOn()) {
- initIngest();
- }
-
- // initialize sample start
- sampleStart = micros();
- ingestCountdown = ingestInterval;
-}
-
-// interrupt handler
-void pulse() {
- ++intPulseCount;
-}
-
-uint32_t calcRemainingWait() {
- const uint32_t remaining = sampleMicros - (micros() - sampleStart);
- return remaining > sampleMicros ? 0 : remaining;
-}
-
-boolean wifiSwitchOn() {
- return digitalRead(WIFI_SWITCH_PIN) == 0;
-}
-
-uint16_t takeSampleNoSleep() {
- attachInterrupt(PULSE_PIN, pulse, RISING);
-
- int32_t remainingWait = calcRemainingWait();
- delayMicroseconds(remainingWait);
- sampleStart = micros();
- noInterrupts();
- const int16_t pulses = intPulseCount;
- intPulseCount = 0;
- interrupts();
-
- return pulses;
-}
-
-uint16_t takeSampleLowPower() {
- // To save battery power, use light sleep as much as possible.
- // During light sleep, no counters or interrupts are working.
- // Therefore simply wake up on each pulse signal change. This
- // is fast enough for the low frequencies from a Geiger tube
- // (below 2kHz):
- // Wake up at end of sample period. Also
- // wake up on pulse getting high and getting low.
- // Waking up directly on rising/falling edges is not possible,
- // so wait until level change.
- // Switch to interrupt counting while awake for calculations
- // and display update.
-
- // stop interrupt (switch to active wakeup counting loop):
- detachInterrupt(PULSE_PIN);
-
- int32_t remainingWait = calcRemainingWait();
- esp_sleep_wakeup_cause_t cause = ESP_SLEEP_WAKEUP_UNDEFINED;
- while (cause != ESP_SLEEP_WAKEUP_TIMER && remainingWait > 0) {
-
- if (digitalRead(PULSE_PIN)) {
- // wait for low pulse start or sample time end
- esp_sleep_enable_timer_wakeup(remainingWait);
- gpio_wakeup_enable(PULSE_GPIO, GPIO_INTR_LOW_LEVEL);
- esp_sleep_enable_gpio_wakeup();
- esp_light_sleep_start();
- cause = esp_sleep_get_wakeup_cause();
- }
-
- remainingWait = calcRemainingWait();
- if (cause != ESP_SLEEP_WAKEUP_TIMER && remainingWait > 0) {
- // wait for high pulse start or sample time end
- esp_sleep_enable_timer_wakeup(remainingWait);
- gpio_wakeup_enable(PULSE_GPIO, GPIO_INTR_HIGH_LEVEL);
- esp_sleep_enable_gpio_wakeup();
- esp_light_sleep_start();
- cause = esp_sleep_get_wakeup_cause();
- if (cause == ESP_SLEEP_WAKEUP_GPIO) {
- ++pulseCount;
- }
- }
-
- remainingWait = calcRemainingWait();
- }
-
- // take sample and add to statistics
-
- sampleStart = micros();
- const int16_t pulses = pulseCount + intPulseCount;
- // Serial.print("pc=");
- // Serial.print(pulseCount);
- // Serial.print(" ipc=");
- // Serial.println(intPulseCount);
- attachInterrupt(PULSE_PIN, pulse, RISING);
- interrupts();
- // reset counters AFTER enabling interrupt to avoid double-counting on high signal
- pulseCount = 0;
- intPulseCount = 0;
-
- return pulses;
-}
-
-void loop() {
-
- // blinky
-
- digitalWrite(LED_BUILTIN, blinky);
- blinky = !blinky;
-
- const uint16_t pulses =
- wifiSwitchOn() ? takeSampleNoSleep() : takeSampleLowPower();
-
- geigerData.addPulses(pulses);
- geigerData.nextSample();
-
- if (wifiSwitchOn()) {
- ingestCountdown--;
- if (ingestCountdown <= 0) {
- ingestCountdown = ingestInterval;
- ingest(geigerData, ingestInterval);
- }
- } else {
- deinitIngest();
- }
-
- // determine current value, average 6 seconds
- // because this is very near to the 5 seconds history
- // bar width and gives nicely rounded count values
-
- const uint16_t samples = 6;
- const uint32_t prevPulses = geigerData.getPreviousPulses(1, samples);
- const uint32_t cpm = prevPulses * (60 / samples);
- const float uSph = geigerData.toMicroSievertPerHour(prevPulses, samples);
-
- // test for display layout:
- // const uint32_t cpm = 1000*60;
- // const float uSph = geigerData.toMicroSievertPerHour(cpm, 60);
-
- char cpmStr[16];
- ltoa(cpm, cpmStr, 10);
- char uSphStr[16];
- sprintf(uSphStr, "%.2f", uSph);
-
- // serial output cpm and µS/h
-
- Serial.print(pulses);
- Serial.print(" ");
- Serial.print(cpmStr);
- Serial.print(" ");
- Serial.println(uSphStr);
-
- updateDisplay(geigerData, uSphStr, cpmStr);
-}
+#include
+#include "driver/pcnt.h"
+#include "driver/gpio.h"
+#include "driver/rtc_io.h"
+#include "display.h"
+#include "ingest.h"
+#include "GeigerData.h"
+
+void setup() ;
+void pulse() ;
+uint32_t calcRemainingWait() ;
+boolean wifiSwitchOn() ;
+uint16_t takeSampleNoSleep() ;
+uint16_t takeSampleLowPower() ;
+void loop() ;
+
+#include "Arduino.h"
+
+#include "driver/pcnt.h"
+#include "driver/gpio.h"
+#include "driver/rtc_io.h"
+
+#include "display.h"
+#include "ingest.h"
+#include "GeigerData.h"
+
+// ~400µs high pulses from Geiger tube on GPIO 18
+#define PULSE_PIN 18
+#define PULSE_GPIO GPIO_NUM_18
+
+// switch input for WiFi on (low) and off (high)
+#define WIFI_SWITCH_PIN 4
+
+// Keep 600 samples of 1s in history (10 minutes),
+// calculate radiation for russian STS-6 ("CTC-6") Geiger tube
+GeigerData geigerData(600, 1, STS6_CPM_PER_USPH);
+
+// blinky state
+int blinky = 1;
+
+// Pulses counted by interrupt (while CPU is awake)
+volatile uint16_t intPulseCount = 0;
+// Pulses counted during ESP light sleep
+volatile uint16_t pulseCount = 0;
+
+// Sample duration in µs
+const uint32_t sampleMicros = geigerData.sampleSeconds * 1000000;
+// Absolute sample interval start micros
+uint32_t sampleStart = 0;
+
+const int16_t ingestInterval = 60;
+int16_t ingestCountdown;
+
+void setup() {
+ Serial.begin(921600);
+ Serial.println("Starting!");
+
+ // OLED
+ initDisplay();
+
+ // blinky
+ pinMode(LED_BUILTIN, OUTPUT);
+
+ // Geiger pulse input
+ pinMode(PULSE_PIN, INPUT);
+
+ // WiFi switch input
+ pinMode(WIFI_SWITCH_PIN, INPUT_PULLUP);
+
+ if (wifiSwitchOn()) {
+ initIngest();
+ }
+
+ // initialize sample start
+ sampleStart = micros();
+ ingestCountdown = ingestInterval;
+}
+
+// interrupt handler
+void pulse() {
+ ++intPulseCount;
+}
+
+uint32_t calcRemainingWait() {
+ const uint32_t remaining = sampleMicros - (micros() - sampleStart);
+ return remaining > sampleMicros ? 0 : remaining;
+}
+
+boolean wifiSwitchOn() {
+ return digitalRead(WIFI_SWITCH_PIN) == 0;
+}
+
+uint16_t takeSampleNoSleep() {
+ attachInterrupt(PULSE_PIN, pulse, RISING);
+
+ int32_t remainingWait = calcRemainingWait();
+ delayMicroseconds(remainingWait);
+ sampleStart = micros();
+ noInterrupts();
+ const int16_t pulses = intPulseCount;
+ intPulseCount = 0;
+ interrupts();
+
+ return pulses;
+}
+
+uint16_t takeSampleLowPower() {
+ // To save battery power, use light sleep as much as possible.
+ // During light sleep, no counters or interrupts are working.
+ // Therefore simply wake up on each pulse signal change. This
+ // is fast enough for the low frequencies from a Geiger tube
+ // (below 2kHz):
+ // Wake up at end of sample period. Also
+ // wake up on pulse getting high and getting low.
+ // Waking up directly on rising/falling edges is not possible,
+ // so wait until level change.
+ // Switch to interrupt counting while awake for calculations
+ // and display update.
+
+ // stop interrupt (switch to active wakeup counting loop):
+ detachInterrupt(PULSE_PIN);
+
+ int32_t remainingWait = calcRemainingWait();
+ esp_sleep_wakeup_cause_t cause = ESP_SLEEP_WAKEUP_UNDEFINED;
+ while (cause != ESP_SLEEP_WAKEUP_TIMER && remainingWait > 0) {
+
+ if (digitalRead(PULSE_PIN)) {
+ // wait for low pulse start or sample time end
+ esp_sleep_enable_timer_wakeup(remainingWait);
+ gpio_wakeup_enable(PULSE_GPIO, GPIO_INTR_LOW_LEVEL);
+ esp_sleep_enable_gpio_wakeup();
+ esp_light_sleep_start();
+ cause = esp_sleep_get_wakeup_cause();
+ }
+
+ remainingWait = calcRemainingWait();
+ if (cause != ESP_SLEEP_WAKEUP_TIMER && remainingWait > 0) {
+ // wait for high pulse start or sample time end
+ esp_sleep_enable_timer_wakeup(remainingWait);
+ gpio_wakeup_enable(PULSE_GPIO, GPIO_INTR_HIGH_LEVEL);
+ esp_sleep_enable_gpio_wakeup();
+ esp_light_sleep_start();
+ cause = esp_sleep_get_wakeup_cause();
+ if (cause == ESP_SLEEP_WAKEUP_GPIO) {
+ ++pulseCount;
+ }
+ }
+
+ remainingWait = calcRemainingWait();
+ }
+
+ // take sample and add to statistics
+
+ sampleStart = micros();
+ const int16_t pulses = pulseCount + intPulseCount;
+ // Serial.print("pc=");
+ // Serial.print(pulseCount);
+ // Serial.print(" ipc=");
+ // Serial.println(intPulseCount);
+ attachInterrupt(PULSE_PIN, pulse, RISING);
+ interrupts();
+ // reset counters AFTER enabling interrupt to avoid double-counting on high signal
+ pulseCount = 0;
+ intPulseCount = 0;
+
+ return pulses;
+}
+
+void loop() {
+
+ // blinky
+
+ digitalWrite(LED_BUILTIN, blinky);
+ blinky = !blinky;
+
+ const uint16_t pulses =
+ wifiSwitchOn() ? takeSampleNoSleep() : takeSampleLowPower();
+
+ geigerData.addPulses(pulses);
+ geigerData.nextSample();
+
+ if (wifiSwitchOn()) {
+ ingestCountdown--;
+ if (ingestCountdown <= 0) {
+ ingestCountdown = ingestInterval;
+ ingest(geigerData, ingestInterval);
+ }
+ } else {
+ deinitIngest();
+ }
+
+ // determine current value, average 6 seconds
+ // because this is very near to the 5 seconds history
+ // bar width and gives nicely rounded count values
+
+ const uint16_t samples = 6;
+ const uint32_t prevPulses = geigerData.getPreviousPulses(1, samples);
+ const uint32_t cpm = prevPulses * (60 / samples);
+ const float uSph = geigerData.toMicroSievertPerHour(prevPulses, samples);
+
+ // test for display layout:
+ // const uint32_t cpm = 1000*60;
+ // const float uSph = geigerData.toMicroSievertPerHour(cpm, 60);
+
+ char cpmStr[16];
+ ltoa(cpm, cpmStr, 10);
+ char uSphStr[16];
+ sprintf(uSphStr, "%.2f", uSph);
+
+ // serial output cpm and µS/h
+
+ Serial.print(pulses);
+ Serial.print(" ");
+ Serial.print(cpmStr);
+ Serial.print(" ");
+ Serial.println(uSphStr);
+
+ updateDisplay(geigerData, uSphStr, cpmStr);
+}
diff --git a/test/README b/test/README
new file mode 100644
index 0000000..df5066e
--- /dev/null
+++ b/test/README
@@ -0,0 +1,11 @@
+
+This directory is intended for PIO Unit Testing and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PIO Unit Testing:
+- https://docs.platformio.org/page/plus/unit-testing.html