svalavuo 1 hónapja
szülő
commit
4ae33b57ff
100 módosított fájl, 8614 hozzáadás és 0 törlés
  1. BIN
      .pio/build/esp32dev/.sconsign312.dblite
  2. BIN
      .pio/build/esp32dev/bootloader.bin
  3. 138 0
      .pio/build/esp32dev/lib137/Adafruit Unified Sensor/Adafruit_Sensor.cpp.d
  4. BIN
      .pio/build/esp32dev/lib137/Adafruit Unified Sensor/Adafruit_Sensor.cpp.o
  5. 138 0
      .pio/build/esp32dev/lib292/PubSubClient/PubSubClient.cpp.d
  6. BIN
      .pio/build/esp32dev/lib292/PubSubClient/PubSubClient.cpp.o
  7. BIN
      .pio/build/esp32dev/partitions.bin
  8. 1 0
      .pio/build/project.checksum
  9. 46 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/.github/ISSUE_TEMPLATE.md
  10. 26 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/.github/PULL_REQUEST_TEMPLATE.md
  11. 32 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/.github/workflows/githubci.yml
  12. 1 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/.piopm
  13. 311 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/Adafruit_BMP085.cpp
  14. 112 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/Adafruit_BMP085.h
  15. 32 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/README.md
  16. 65 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/examples/BMP085test/BMP085test.ino
  17. 10 0
      .pio/libdeps/esp32dev/Adafruit BMP085 Library/library.properties
  18. 243 0
      .pio/libdeps/esp32dev/Adafruit BusIO/.clang-format
  19. 46 0
      .pio/libdeps/esp32dev/Adafruit BusIO/.github/ISSUE_TEMPLATE.md
  20. 26 0
      .pio/libdeps/esp32dev/Adafruit BusIO/.github/PULL_REQUEST_TEMPLATE.md
  21. 33 0
      .pio/libdeps/esp32dev/Adafruit BusIO/.github/workflows/githubci.yml
  22. 1 0
      .pio/libdeps/esp32dev/Adafruit BusIO/.piopm
  23. 384 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_BusIO_Register.cpp
  24. 117 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_BusIO_Register.h
  25. 90 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_GenericDevice.cpp
  26. 56 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_GenericDevice.h
  27. 320 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_I2CDevice.cpp
  28. 36 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_I2CDevice.h
  29. 10 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_I2CRegister.h
  30. 512 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_SPIDevice.cpp
  31. 149 0
      .pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_SPIDevice.h
  32. 11 0
      .pio/libdeps/esp32dev/Adafruit BusIO/CMakeLists.txt
  33. 21 0
      .pio/libdeps/esp32dev/Adafruit BusIO/LICENSE
  34. 8 0
      .pio/libdeps/esp32dev/Adafruit BusIO/README.md
  35. 1 0
      .pio/libdeps/esp32dev/Adafruit BusIO/component.mk
  36. 0 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uartregtest/.uno.test.skip
  37. 219 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uartregtest/genericdevice_uartregtest.ino
  38. 0 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uarttest/.uno.test.skip
  39. 98 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uarttest/genericdevice_uarttest.ino
  40. 22 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/i2c_address_detect/i2c_address_detect.ino
  41. 45 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/i2c_readwrite/i2c_readwrite.ino
  42. 43 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/i2c_registers/i2c_registers.ino
  43. 40 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/i2corspi_register/i2corspi_register.ino
  44. 35 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_modetest/spi_modetest.ino
  45. 43 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_readwrite/spi_readwrite.ino
  46. 268 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_register_bits/spi_register_bits.ino
  47. 40 0
      .pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_registers/spi_registers.ino
  48. 9 0
      .pio/libdeps/esp32dev/Adafruit BusIO/library.properties
  49. 108 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/.gitignore
  50. 120 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/Adafruit_Sensor.cpp
  51. 224 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/Adafruit_Sensor.h
  52. 202 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/LICENSE.txt
  53. 271 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/README.md
  54. 153 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/examples/sensortest/sensortest.ino
  55. 11 0
      .pio/libdeps/esp32dev/Adafruit Unified Sensor/library.properties
  56. 13 0
      .pio/libdeps/esp32dev/DHT sensor library/.clang-format
  57. 46 0
      .pio/libdeps/esp32dev/DHT sensor library/.github/ISSUE_TEMPLATE.md
  58. 26 0
      .pio/libdeps/esp32dev/DHT sensor library/.github/PULL_REQUEST_TEMPLATE.md
  59. 52 0
      .pio/libdeps/esp32dev/DHT sensor library/.github/workflows/githubci.yml
  60. 8 0
      .pio/libdeps/esp32dev/DHT sensor library/.gitignore
  61. 1 0
      .pio/libdeps/esp32dev/DHT sensor library/.piopm
  62. 13 0
      .pio/libdeps/esp32dev/DHT sensor library/CONTRIBUTING.md
  63. 394 0
      .pio/libdeps/esp32dev/DHT sensor library/DHT.cpp
  64. 109 0
      .pio/libdeps/esp32dev/DHT sensor library/DHT.h
  65. 243 0
      .pio/libdeps/esp32dev/DHT sensor library/DHT_U.cpp
  66. 105 0
      .pio/libdeps/esp32dev/DHT sensor library/DHT_U.h
  67. 58 0
      .pio/libdeps/esp32dev/DHT sensor library/README.md
  68. 127 0
      .pio/libdeps/esp32dev/DHT sensor library/code-of-conduct.md
  69. 85 0
      .pio/libdeps/esp32dev/DHT sensor library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino
  70. 74 0
      .pio/libdeps/esp32dev/DHT sensor library/examples/DHTtester/DHTtester.ino
  71. 22 0
      .pio/libdeps/esp32dev/DHT sensor library/keywords.txt
  72. 10 0
      .pio/libdeps/esp32dev/DHT sensor library/library.properties
  73. 20 0
      .pio/libdeps/esp32dev/DHT sensor library/license.txt
  74. 1 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/.piopm
  75. 332 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp
  76. 131 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/LiquidCrystal_I2C.h
  77. 5 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/README.md
  78. 70 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/examples/CustomChars/CustomChars.pde
  79. 26 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.pde
  80. 34 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.pde
  81. 46 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/keywords.txt
  82. 15 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/library.json
  83. 9 0
      .pio/libdeps/esp32dev/LiquidCrystal_I2C/library.properties
  84. 5 0
      .pio/libdeps/esp32dev/PubSubClient/.gitignore
  85. 1 0
      .pio/libdeps/esp32dev/PubSubClient/.piopm
  86. 7 0
      .pio/libdeps/esp32dev/PubSubClient/.travis.yml
  87. 85 0
      .pio/libdeps/esp32dev/PubSubClient/CHANGES.txt
  88. 20 0
      .pio/libdeps/esp32dev/PubSubClient/LICENSE.txt
  89. 50 0
      .pio/libdeps/esp32dev/PubSubClient/README.md
  90. 43 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_auth/mqtt_auth.ino
  91. 77 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_basic/mqtt_basic.ino
  92. 129 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_esp8266/mqtt_esp8266.ino
  93. 179 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_large_message/mqtt_large_message.ino
  94. 60 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_publish_in_callback/mqtt_publish_in_callback.ino
  95. 67 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_reconnect_nonblocking/mqtt_reconnect_nonblocking.ino
  96. 57 0
      .pio/libdeps/esp32dev/PubSubClient/examples/mqtt_stream/mqtt_stream.ino
  97. 36 0
      .pio/libdeps/esp32dev/PubSubClient/keywords.txt
  98. 18 0
      .pio/libdeps/esp32dev/PubSubClient/library.json
  99. 9 0
      .pio/libdeps/esp32dev/PubSubClient/library.properties
  100. 769 0
      .pio/libdeps/esp32dev/PubSubClient/src/PubSubClient.cpp

BIN
.pio/build/esp32dev/.sconsign312.dblite


BIN
.pio/build/esp32dev/bootloader.bin


+ 138 - 0
.pio/build/esp32dev/lib137/Adafruit Unified Sensor/Adafruit_Sensor.cpp.d

@@ -0,0 +1,138 @@
+.pio/build/esp32dev/lib137/Adafruit\ Unified\ Sensor/Adafruit_Sensor.cpp.o: \
+ .pio/libdeps/esp32dev/Adafruit\ Unified\ Sensor/Adafruit_Sensor.cpp \
+ .pio/libdeps/esp32dev/Adafruit\ Unified\ Sensor/Adafruit_Sensor.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp_arduino_version.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/FreeRTOS.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_compiler.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig_arch.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/xtensa_config.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/hal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/core.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa-versions.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/core-isa.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/core-matmap.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/tie.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/system.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/xtensa_context.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa_context.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/corebits.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime-frames.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp_rom_sys.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/reset_reasons.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32/rom/ets_sys.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/projdefs.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/portable.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/deprecated_definitions.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/specreg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime-core-state.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xt_instr_macros.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/spinlock.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/cpu.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_cpu.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/cpu_hal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_err.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_compiler.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/soc_caps.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/cpu_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/esp32/include/hal/cpu_ll.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_attr.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/extreg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_bit_defs.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/compare_set.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include/soc/soc_memory_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/soc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_assert.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include/esp_private/crosscore_int.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_timer/include/esp_timer.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include/esp_newlib.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include/esp_heap_caps.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include/multi_heap.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include/esp_system.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_idf_version.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_mac.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_chip_info.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_random.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portbenchmark.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa_api.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa_context.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro_deprecated.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/mpu_wrappers.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/task.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/list.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/task_snapshot.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/semphr.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/queue.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/task.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_sleep.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/touch_sensor_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/gpio_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include/soc/gpio_periph.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/io_mux_reg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/gpio_struct.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/gpio_reg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/gpio_sig_map.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/queue.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/event_groups.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/timers.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-log.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include/esp_log.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include/esp_log_internal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-matrix.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/uart_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-gpio.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/variants/esp32/pins_arduino.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-touch.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-dac.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/include/driver/gpio.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_intr_alloc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32/rom/gpio.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-adc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-ledc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-rmt.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-sigmadelta.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-timer.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-bt.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-psram.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-rgb-led.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-cpu.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp8266-compat.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/stdlib_noniso.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/binary.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/WCharacter.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/WString.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/pgmspace.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Print.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Printable.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/IPAddress.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/WString.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Printable.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Client.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Server.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Udp.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/IPAddress.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/HWCDC.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/USBCDC.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Esp.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_partition.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_flash.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/spi_flash_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/esp_flash_err.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_spi_flash.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_spi_flash_counters.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/esp32/spiram.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/io_pin_remap.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Print.h

BIN
.pio/build/esp32dev/lib137/Adafruit Unified Sensor/Adafruit_Sensor.cpp.o


+ 138 - 0
.pio/build/esp32dev/lib292/PubSubClient/PubSubClient.cpp.d

@@ -0,0 +1,138 @@
+.pio/build/esp32dev/lib292/PubSubClient/PubSubClient.cpp.o: \
+ .pio/libdeps/esp32dev/PubSubClient/src/PubSubClient.cpp \
+ .pio/libdeps/esp32dev/PubSubClient/src/PubSubClient.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp_arduino_version.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/FreeRTOS.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/FreeRTOSConfig.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_compiler.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/FreeRTOSConfig_arch.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/xtensa_config.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/hal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/core.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa-versions.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/core-isa.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/core-matmap.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/tie.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/system.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/xtensa_context.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa_context.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/corebits.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime-frames.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp_rom_sys.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/reset_reasons.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32/rom/ets_sys.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/projdefs.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/portable.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/deprecated_definitions.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/specreg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime-core-state.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xt_instr_macros.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtruntime.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/spinlock.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/cpu.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_cpu.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/cpu_hal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_err.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_compiler.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/soc_caps.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/cpu_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/esp32/include/hal/cpu_ll.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_attr.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/esp32/include/xtensa/config/extreg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_bit_defs.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/compare_set.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include/soc/soc_memory_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/soc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_assert.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include/esp_private/crosscore_int.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_timer/include/esp_timer.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/newlib/platform_include/esp_newlib.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include/esp_heap_caps.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/heap/include/multi_heap.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_system/include/esp_system.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_idf_version.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_mac.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_chip_info.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_random.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portbenchmark.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa_api.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/xtensa/include/xtensa/xtensa_context.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/port/xtensa/include/freertos/portmacro_deprecated.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/mpu_wrappers.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/task.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/list.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/esp_additions/freertos/task_snapshot.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/semphr.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/queue.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/task.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_sleep.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/touch_sensor_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/gpio_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/include/soc/gpio_periph.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/io_mux_reg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/gpio_struct.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/gpio_reg.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/soc/esp32/include/soc/gpio_sig_map.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/queue.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/event_groups.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/freertos/include/freertos/timers.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-log.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include/esp_log.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/log/include/esp_log_internal.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-matrix.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-uart.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/uart_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-gpio.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/variants/esp32/pins_arduino.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-touch.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-dac.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/driver/include/driver/gpio.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/esp_intr_alloc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_common/include/esp_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_rom/include/esp32/rom/gpio.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-adc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-spi.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-i2c.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-ledc.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-rmt.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-sigmadelta.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-timer.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-bt.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-psram.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-rgb-led.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp32-hal-cpu.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/esp8266-compat.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/stdlib_noniso.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/binary.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/WCharacter.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/WString.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/pgmspace.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Print.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Printable.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/IPAddress.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/WString.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Printable.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Client.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Server.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Udp.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Stream.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/IPAddress.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/HardwareSerial.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/HWCDC.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/USBCDC.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Esp.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_partition.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_flash.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/spi_flash_types.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/hal/include/hal/esp_flash_err.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_spi_flash.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/spi_flash/include/esp_spi_flash_counters.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/tools/sdk/esp32/include/esp_hw_support/include/soc/esp32/spiram.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/io_pin_remap.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Arduino.h \
+ /home/samuli/.platformio/packages/framework-arduinoespressif32/cores/esp32/Client.h

BIN
.pio/build/esp32dev/lib292/PubSubClient/PubSubClient.cpp.o


BIN
.pio/build/esp32dev/partitions.bin


+ 1 - 0
.pio/build/project.checksum

@@ -0,0 +1 @@
+b5faccf5a33f48e048dada5bcc6c5bcdad40479e

+ 46 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,46 @@
+Thank you for opening an issue on an Adafruit Arduino library repository.  To
+improve the speed of resolution please review the following guidelines and
+common troubleshooting steps below before creating the issue:
+
+- **Do not use GitHub issues for troubleshooting projects and issues.**  Instead use
+  the forums at http://forums.adafruit.com to ask questions and troubleshoot why
+  something isn't working as expected.  In many cases the problem is a common issue
+  that you will more quickly receive help from the forum community.  GitHub issues
+  are meant for known defects in the code.  If you don't know if there is a defect
+  in the code then start with troubleshooting on the forum first.
+
+- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
+  check all of the steps and commands to run have been followed.  Consult the
+  forum if you're unsure or have questions about steps in a guide/tutorial.
+
+- **For Arduino projects check these very common issues to ensure they don't apply**:
+
+  - For uploading sketches or communicating with the board make sure you're using
+    a **USB data cable** and **not** a **USB charge-only cable**.  It is sometimes
+    very hard to tell the difference between a data and charge cable!  Try using the
+    cable with other devices or swapping to another cable to confirm it is not
+    the problem.
+
+  - **Be sure you are supplying adequate power to the board.**  Check the specs of
+    your board and plug in an external power supply.  In many cases just
+    plugging a board into your computer is not enough to power it and other
+    peripherals.
+
+  - **Double check all soldering joints and connections.**  Flakey connections
+    cause many mysterious problems.  See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
+
+  - **Ensure you are using an official Arduino or Adafruit board.** We can't
+    guarantee a clone board will have the same functionality and work as expected
+    with this code and don't support them.
+
+If you're sure this issue is a defect in the code and checked the steps above
+please fill in the following fields to provide enough troubleshooting information.
+You may delete the guideline and text above to just leave the following details:
+
+- Arduino board:  **INSERT ARDUINO BOARD NAME/TYPE HERE**
+
+- Arduino IDE version (found in Arduino -> About Arduino menu):  **INSERT ARDUINO
+  VERSION HERE**
+
+- List the steps to reproduce the problem below (if possible attach a sketch or
+  copy the sketch code in too): **LIST REPRO STEPS BELOW**

+ 26 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,26 @@
+Thank you for creating a pull request to contribute to Adafruit's GitHub code!
+Before you open the request please review the following guidelines and tips to
+help it be more easily integrated:
+
+- **Describe the scope of your change--i.e. what the change does and what parts
+  of the code were modified.**  This will help us understand any risks of integrating
+  the code.
+
+- **Describe any known limitations with your change.**  For example if the change
+  doesn't apply to a supported platform of the library please mention it.
+
+- **Please run any tests or examples that can exercise your modified code.**  We
+  strive to not break users of the code and running tests/examples helps with this
+  process.
+
+Thank you again for contributing!  We will try to test and integrate the change
+as soon as we can, but be aware we have many GitHub repositories to manage and
+can't immediately respond to every request.  There is no need to bump or check in
+on a pull request (it will clutter the discussion of the request).
+
+Also don't be worried if the request is closed or not integrated--sometimes the
+priorities of Adafruit's GitHub code (education, ease of use) might not match the
+priorities of the pull request.  Don't fret, the open source community thrives on
+forks and GitHub makes it easy to keep your changes in a forked repo.
+
+After reviewing the guidelines above you can delete this text from the pull request.

+ 32 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/.github/workflows/githubci.yml

@@ -0,0 +1,32 @@
+name: Arduino Library CI
+
+on: [pull_request, push, repository_dispatch]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    
+    steps:
+    - uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
+    - uses: actions/checkout@v3
+    - uses: actions/checkout@v3
+      with:
+         repository: adafruit/ci-arduino
+         path: ci
+
+    - name: pre-install
+      run: bash ci/actions_install.sh
+
+    - name: test platforms
+      run: python3 ci/build_platform.py main_platforms
+
+    - name: clang
+      run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 
+
+    - name: doxygen
+      env:
+        GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
+        PRETTYNAME : "Adafruit BMP085 Library"
+      run: bash ci/doxy_gen_and_deploy.sh

+ 1 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/.piopm

@@ -0,0 +1 @@
+{"type": "library", "name": "Adafruit BMP085 Library", "version": "1.2.4", "spec": {"owner": "adafruit", "id": 525, "name": "Adafruit BMP085 Library", "requirements": null, "uri": null}}

+ 311 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/Adafruit_BMP085.cpp

@@ -0,0 +1,311 @@
+/*!
+ * @file Adafruit_BMP085.cpp
+ *
+ * @mainpage Adafruit BMP085 Library
+ *
+ * @section intro_sec Introduction
+ *
+ * This is a library for the Adafruit BMP085/BMP180 Barometric Pressure + Temp
+ * sensor
+ *
+ * Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout
+ * ----> http://www.adafruit.com/products/391
+ * ----> http://www.adafruit.com/products/1603
+ *
+ * These displays use I2C to communicate, 2 pins are required to
+ * interface
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * @section author Author
+ *
+ * Written by Limor Fried/Ladyada for Adafruit Industries.
+ * Updated by Samy Kamkar for cross-platform support.
+ *
+ * @section license License
+ *
+ * BSD license, all text above must be included in any redistribution
+ */
+
+#include "Adafruit_BMP085.h"
+#include <Adafruit_I2CDevice.h>
+
+Adafruit_BMP085::Adafruit_BMP085() { i2c_dev = nullptr; }
+
+bool Adafruit_BMP085::begin(uint8_t mode, TwoWire *wire) {
+  if (mode > BMP085_ULTRAHIGHRES)
+    mode = BMP085_ULTRAHIGHRES;
+  oversampling = mode;
+
+  if (i2c_dev) {
+    delete i2c_dev; // remove old interface
+  }
+
+  i2c_dev = new Adafruit_I2CDevice(BMP085_I2CADDR, wire);
+
+  if (!i2c_dev->begin()) {
+    return false;
+  }
+
+  if (read8(0xD0) != 0x55)
+    return false;
+
+  /* read calibration data */
+  ac1 = read16(BMP085_CAL_AC1);
+  ac2 = read16(BMP085_CAL_AC2);
+  ac3 = read16(BMP085_CAL_AC3);
+  ac4 = read16(BMP085_CAL_AC4);
+  ac5 = read16(BMP085_CAL_AC5);
+  ac6 = read16(BMP085_CAL_AC6);
+
+  b1 = read16(BMP085_CAL_B1);
+  b2 = read16(BMP085_CAL_B2);
+
+  mb = read16(BMP085_CAL_MB);
+  mc = read16(BMP085_CAL_MC);
+  md = read16(BMP085_CAL_MD);
+#if (BMP085_DEBUG == 1)
+  Serial.print("ac1 = ");
+  Serial.println(ac1, DEC);
+  Serial.print("ac2 = ");
+  Serial.println(ac2, DEC);
+  Serial.print("ac3 = ");
+  Serial.println(ac3, DEC);
+  Serial.print("ac4 = ");
+  Serial.println(ac4, DEC);
+  Serial.print("ac5 = ");
+  Serial.println(ac5, DEC);
+  Serial.print("ac6 = ");
+  Serial.println(ac6, DEC);
+
+  Serial.print("b1 = ");
+  Serial.println(b1, DEC);
+  Serial.print("b2 = ");
+  Serial.println(b2, DEC);
+
+  Serial.print("mb = ");
+  Serial.println(mb, DEC);
+  Serial.print("mc = ");
+  Serial.println(mc, DEC);
+  Serial.print("md = ");
+  Serial.println(md, DEC);
+#endif
+
+  return true;
+}
+
+int32_t Adafruit_BMP085::computeB5(int32_t UT) {
+  int32_t X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) >> 15;
+  int32_t X2 = ((int32_t)mc << 11) / (X1 + (int32_t)md);
+  return X1 + X2;
+}
+
+uint16_t Adafruit_BMP085::readRawTemperature(void) {
+  write8(BMP085_CONTROL, BMP085_READTEMPCMD);
+  delay(5);
+#if BMP085_DEBUG == 1
+  Serial.print("Raw temp: ");
+  Serial.println(read16(BMP085_TEMPDATA));
+#endif
+  return read16(BMP085_TEMPDATA);
+}
+
+uint32_t Adafruit_BMP085::readRawPressure(void) {
+  uint32_t raw;
+
+  write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));
+
+  if (oversampling == BMP085_ULTRALOWPOWER)
+    delay(5);
+  else if (oversampling == BMP085_STANDARD)
+    delay(8);
+  else if (oversampling == BMP085_HIGHRES)
+    delay(14);
+  else
+    delay(26);
+
+  raw = read16(BMP085_PRESSUREDATA);
+
+  raw <<= 8;
+  raw |= read8(BMP085_PRESSUREDATA + 2);
+  raw >>= (8 - oversampling);
+
+  /* this pull broke stuff, look at it later?
+   if (oversampling==0) {
+     raw <<= 8;
+     raw |= read8(BMP085_PRESSUREDATA+2);
+     raw >>= (8 - oversampling);
+   }
+  */
+
+#if BMP085_DEBUG == 1
+  Serial.print("Raw pressure: ");
+  Serial.println(raw);
+#endif
+  return raw;
+}
+
+int32_t Adafruit_BMP085::readPressure(void) {
+  int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
+  uint32_t B4, B7;
+
+  UT = readRawTemperature();
+  UP = readRawPressure();
+
+#if BMP085_DEBUG == 1
+  // use datasheet numbers!
+  UT = 27898;
+  UP = 23843;
+  ac6 = 23153;
+  ac5 = 32757;
+  mc = -8711;
+  md = 2868;
+  b1 = 6190;
+  b2 = 4;
+  ac3 = -14383;
+  ac2 = -72;
+  ac1 = 408;
+  ac4 = 32741;
+  oversampling = 0;
+#endif
+
+  B5 = computeB5(UT);
+
+#if BMP085_DEBUG == 1
+  Serial.print("X1 = ");
+  Serial.println(X1);
+  Serial.print("X2 = ");
+  Serial.println(X2);
+  Serial.print("B5 = ");
+  Serial.println(B5);
+#endif
+
+  // do pressure calcs
+  B6 = B5 - 4000;
+  X1 = ((int32_t)b2 * ((B6 * B6) >> 12)) >> 11;
+  X2 = ((int32_t)ac2 * B6) >> 11;
+  X3 = X1 + X2;
+  B3 = ((((int32_t)ac1 * 4 + X3) << oversampling) + 2) / 4;
+
+#if BMP085_DEBUG == 1
+  Serial.print("B6 = ");
+  Serial.println(B6);
+  Serial.print("X1 = ");
+  Serial.println(X1);
+  Serial.print("X2 = ");
+  Serial.println(X2);
+  Serial.print("B3 = ");
+  Serial.println(B3);
+#endif
+
+  X1 = ((int32_t)ac3 * B6) >> 13;
+  X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
+  X3 = ((X1 + X2) + 2) >> 2;
+  B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
+  B7 = ((uint32_t)UP - B3) * (uint32_t)(50000UL >> oversampling);
+
+#if BMP085_DEBUG == 1
+  Serial.print("X1 = ");
+  Serial.println(X1);
+  Serial.print("X2 = ");
+  Serial.println(X2);
+  Serial.print("B4 = ");
+  Serial.println(B4);
+  Serial.print("B7 = ");
+  Serial.println(B7);
+#endif
+
+  if (B7 < 0x80000000) {
+    p = (B7 * 2) / B4;
+  } else {
+    p = (B7 / B4) * 2;
+  }
+  X1 = (p >> 8) * (p >> 8);
+  X1 = (X1 * 3038) >> 16;
+  X2 = (-7357 * p) >> 16;
+
+#if BMP085_DEBUG == 1
+  Serial.print("p = ");
+  Serial.println(p);
+  Serial.print("X1 = ");
+  Serial.println(X1);
+  Serial.print("X2 = ");
+  Serial.println(X2);
+#endif
+
+  p = p + ((X1 + X2 + (int32_t)3791) >> 4);
+#if BMP085_DEBUG == 1
+  Serial.print("p = ");
+  Serial.println(p);
+#endif
+  return p;
+}
+
+int32_t Adafruit_BMP085::readSealevelPressure(float altitude_meters) {
+  float pressure = readPressure();
+  return (int32_t)(pressure / pow(1.0 - altitude_meters / 44330, 5.255));
+}
+
+float Adafruit_BMP085::readTemperature(void) {
+  int32_t UT, B5; // following ds convention
+  float temp;
+
+  UT = readRawTemperature();
+
+#if BMP085_DEBUG == 1
+  // use datasheet numbers!
+  UT = 27898;
+  ac6 = 23153;
+  ac5 = 32757;
+  mc = -8711;
+  md = 2868;
+#endif
+
+  B5 = computeB5(UT);
+  temp = (B5 + 8) >> 4;
+  temp /= 10;
+
+  return temp;
+}
+
+float Adafruit_BMP085::readAltitude(float sealevelPressure) {
+  float altitude;
+
+  float pressure = readPressure();
+
+  altitude = 44330 * (1.0 - pow(pressure / sealevelPressure, 0.1903));
+
+  return altitude;
+}
+
+/*********************************************************************/
+
+uint8_t Adafruit_BMP085::read8(uint8_t a) {
+  uint8_t ret;
+
+  // send 1 byte, reset i2c, read 1 byte
+  i2c_dev->write_then_read(&a, 1, &ret, 1, true);
+
+  return ret;
+}
+
+uint16_t Adafruit_BMP085::read16(uint8_t a) {
+  uint8_t retbuf[2];
+  uint16_t ret;
+
+  // send 1 byte, reset i2c, read 2 bytes
+  // we could typecast uint16_t as uint8_t array but would need to ensure proper
+  // endianness
+  i2c_dev->write_then_read(&a, 1, retbuf, 2, true);
+
+  // write_then_read uses uint8_t array
+  ret = retbuf[1] | (retbuf[0] << 8);
+
+  return ret;
+}
+
+void Adafruit_BMP085::write8(uint8_t a, uint8_t d) {
+  // send d prefixed with a (a d [stop])
+  i2c_dev->write(&d, 1, true, &a, 1);
+}

+ 112 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/Adafruit_BMP085.h

@@ -0,0 +1,112 @@
+/*!
+ * @file Adafruit_BMP085.h
+ *
+ * This is a library for the Adafruit BMP085/BMP180 Barometric Pressure + Temp
+ * sensor
+ *
+ * Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout
+ * ----> http://www.adafruit.com/products/391
+ * ----> http://www.adafruit.com/products/1603
+ *
+ * These displays use I2C to communicate, 2 pins are required to
+ * interface
+ * Adafruit invests time and resources providing this open source code,
+ * please support Adafruit and open-source hardware by purchasing
+ * products from Adafruit!
+ *
+ * Written by Limor Fried/Ladyada for Adafruit Industries.
+ * BSD license, all text above must be included in any redistribution
+ */
+
+#ifndef ADAFRUIT_BMP085_H
+#define ADAFRUIT_BMP085_H
+
+#include <Adafruit_I2CDevice.h>
+#include <Arduino.h>
+
+#define BMP085_DEBUG 0 //!< Debug mode
+
+#define BMP085_I2CADDR 0x77 //!< BMP085 I2C address
+
+#define BMP085_ULTRALOWPOWER 0 //!< Ultra low power mode
+#define BMP085_STANDARD 1      //!< Standard mode
+#define BMP085_HIGHRES 2       //!< High-res mode
+#define BMP085_ULTRAHIGHRES 3  //!< Ultra high-res mode
+#define BMP085_CAL_AC1 0xAA    //!< R   Calibration data (16 bits)
+#define BMP085_CAL_AC2 0xAC    //!< R   Calibration data (16 bits)
+#define BMP085_CAL_AC3 0xAE    //!< R   Calibration data (16 bits)
+#define BMP085_CAL_AC4 0xB0    //!< R   Calibration data (16 bits)
+#define BMP085_CAL_AC5 0xB2    //!< R   Calibration data (16 bits)
+#define BMP085_CAL_AC6 0xB4    //!< R   Calibration data (16 bits)
+#define BMP085_CAL_B1 0xB6     //!< R   Calibration data (16 bits)
+#define BMP085_CAL_B2 0xB8     //!< R   Calibration data (16 bits)
+#define BMP085_CAL_MB 0xBA     //!< R   Calibration data (16 bits)
+#define BMP085_CAL_MC 0xBC     //!< R   Calibration data (16 bits)
+#define BMP085_CAL_MD 0xBE     //!< R   Calibration data (16 bits)
+
+#define BMP085_CONTROL 0xF4         //!< Control register
+#define BMP085_TEMPDATA 0xF6        //!< Temperature data register
+#define BMP085_PRESSUREDATA 0xF6    //!< Pressure data register
+#define BMP085_READTEMPCMD 0x2E     //!< Read temperature control register value
+#define BMP085_READPRESSURECMD 0x34 //!< Read pressure control register value
+
+/*!
+ * @brief Main BMP085 class
+ */
+class Adafruit_BMP085 {
+public:
+  Adafruit_BMP085();
+  /*!
+   * @brief Starts I2C connection
+   * @param mode Mode to set, ultra high-res by default
+   * @param wire The I2C interface to use, defaults to Wire
+   * @return Returns true if successful
+   */
+  bool begin(uint8_t mode = BMP085_ULTRAHIGHRES, TwoWire *wire = &Wire);
+  /*!
+   * @brief Gets the temperature over I2C from the BMP085
+   * @return Returns the temperature
+   */
+  float readTemperature(void);
+  /*!
+   * @brief Gets the pressure over I2C from the BMP085
+   * @return Returns the pressure
+   */
+  int32_t readPressure(void);
+  /*!
+   * @brief Calculates the pressure at sea level
+   * @param altitude_meters Current altitude (in meters)
+   * @return Returns the calculated pressure at sea level
+   */
+  int32_t readSealevelPressure(float altitude_meters = 0);
+  /*!
+   * @brief Reads the altitude
+   * @param sealevelPressure Pressure at sea level, measured in pascals
+   * @return Returns the altitude
+   */
+  float readAltitude(float sealevelPressure = 101325); // std atmosphere
+  /*!
+   * @brief Reads the raw temperature
+   * @return Returns the raw temperature
+   */
+  uint16_t readRawTemperature(void);
+  /*!
+   * @brief Reads the raw pressure
+   * @return Returns the raw pressure
+   */
+  uint32_t readRawPressure(void);
+
+private:
+  int32_t computeB5(int32_t UT);
+  uint8_t read8(uint8_t addr);
+  uint16_t read16(uint8_t addr);
+  void write8(uint8_t addr, uint8_t data);
+
+  Adafruit_I2CDevice *i2c_dev;
+  uint8_t oversampling;
+
+  int16_t ac1, ac2, ac3, b1, b2, mb, mc, md;
+  uint16_t ac4, ac5, ac6;
+};
+
+#endif //  ADAFRUIT_BMP085_H

+ 32 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/README.md

@@ -0,0 +1,32 @@
+# Adafruit BMP085 Library [![Build Status](https://github.com/adafruit/Adafruit-BMP085-Library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit-BMP085-Library/actions)[![Documentation](https://github.com/adafruit/ci-arduino/blob/master/assets/doxygen_badge.svg)](http://adafruit.github.io/Adafruit-BMP085-Library/html/index.html)
+
+This is a library for the Adafruit BMP085/BMP180 Barometric Pressure + Temp sensor
+
+Designed specifically to work with the Adafruit BMP085 or BMP180 Breakout
+  ----> http://www.adafruit.com/products/391
+  ----> http://www.adafruit.com/products/1603
+
+These displays use I2C to communicate, 2 pins are required to interface
+Adafruit invests time and resources providing this open source code,
+please support Adafruit and open-source hardware by purchasing
+products from Adafruit!
+
+Check out the links above for our tutorials and wiring diagrams
+
+Requires the https://github.com/adafruit/Adafruit_BusIO library for I2C abstraction
+
+Adafruit invests time and resources providing this open source code,
+please support Adafruit and open-source hardware by purchasing
+products from Adafruit!
+
+Written by Limor Fried/Ladyada for Adafruit Industries.
+BSD license, all text above must be included in any redistribution
+
+To download. click the DOWNLOAD ZIP button, rename the uncompressed folder Adafruit_BMP085.
+Check that the Adafruit_BMP085 folder contains Adafruit_BMP085.cpp and Adafruit_BMP085.h
+
+Place the Adafruit_BMP085 library folder your arduinosketchfolder/libraries/ folder.
+You may need to create the libraries subfolder if its your first library. Restart the IDE.
+
+We also have a great tutorial on Arduino library installation at:
+http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use

+ 65 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/examples/BMP085test/BMP085test.ino

@@ -0,0 +1,65 @@
+#include <Adafruit_BMP085.h>
+
+/*************************************************** 
+  This is an example for the BMP085 Barometric Pressure & Temp Sensor
+
+  Designed specifically to work with the Adafruit BMP085 Breakout 
+  ----> https://www.adafruit.com/products/391
+
+  These pressure and temperature sensors use I2C to communicate, 2 pins
+  are required to interface
+  Adafruit invests time and resources providing this open source code, 
+  please support Adafruit and open-source hardware by purchasing 
+  products from Adafruit!
+
+  Written by Limor Fried/Ladyada for Adafruit Industries.  
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+
+// Connect VCC of the BMP085 sensor to 3.3V (NOT 5.0V!)
+// Connect GND to Ground
+// Connect SCL to i2c clock - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 5
+// Connect SDA to i2c data - on '168/'328 Arduino Uno/Duemilanove/etc thats Analog 4
+// EOC is not used, it signifies an end of conversion
+// XCLR is a reset pin, also not used here
+
+Adafruit_BMP085 bmp;
+  
+void setup() {
+  Serial.begin(9600);
+  if (!bmp.begin()) {
+	Serial.println("Could not find a valid BMP085 sensor, check wiring!");
+	while (1) {}
+  }
+}
+  
+void loop() {
+    Serial.print("Temperature = ");
+    Serial.print(bmp.readTemperature());
+    Serial.println(" *C");
+    
+    Serial.print("Pressure = ");
+    Serial.print(bmp.readPressure());
+    Serial.println(" Pa");
+    
+    // Calculate altitude assuming 'standard' barometric
+    // pressure of 1013.25 millibar = 101325 Pascal
+    Serial.print("Altitude = ");
+    Serial.print(bmp.readAltitude());
+    Serial.println(" meters");
+
+    Serial.print("Pressure at sealevel (calculated) = ");
+    Serial.print(bmp.readSealevelPressure());
+    Serial.println(" Pa");
+
+  // you can get a more precise measurement of altitude
+  // if you know the current sea level pressure which will
+  // vary with weather and such. If it is 1015 millibars
+  // that is equal to 101500 Pascals.
+    Serial.print("Real altitude = ");
+    Serial.print(bmp.readAltitude(101500));
+    Serial.println(" meters");
+    
+    Serial.println();
+    delay(500);
+}

+ 10 - 0
.pio/libdeps/esp32dev/Adafruit BMP085 Library/library.properties

@@ -0,0 +1,10 @@
+name=Adafruit BMP085 Library
+version=1.2.4
+author=Adafruit
+maintainer=Adafruit <info@adafruit.com>
+sentence=A powerful but easy to use BMP085/BMP180 Library
+paragraph=A powerful but easy to use BMP085/BMP180 Library
+category=Sensors
+url=https://github.com/adafruit/Adafruit-BMP085-Library
+architectures=*
+depends=Adafruit Unified Sensor, Adafruit BusIO

+ 243 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/.clang-format

@@ -0,0 +1,243 @@
+Language:        Cpp
+# BasedOnStyle:  LLVM
+AccessModifierOffset: -2
+AlignAfterOpenBracket: Align
+AlignArrayOfStructures: None
+AlignConsecutiveAssignments:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionPointers: false
+  PadOperators:    true
+AlignConsecutiveBitFields:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveDeclarations:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveMacros:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCompound:   false
+  AlignFunctionPointers: false
+  PadOperators:    false
+AlignConsecutiveShortCaseStatements:
+  Enabled:         false
+  AcrossEmptyLines: false
+  AcrossComments:  false
+  AlignCaseColons: false
+AlignEscapedNewlines: Right
+AlignOperands:   Align
+AlignTrailingComments:
+  Kind:            Always
+  OverEmptyLines:  0
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowBreakBeforeNoexceptSpecifier: Never
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortCompoundRequirementOnASingleLine: true
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: false
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: false
+AlwaysBreakTemplateDeclarations: MultiLine
+AttributeMacros:
+  - __capability
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: Both
+BraceWrapping:
+  AfterCaseLabel:  false
+  AfterClass:      false
+  AfterControlStatement: Never
+  AfterEnum:       false
+  AfterExternBlock: false
+  AfterFunction:   false
+  AfterNamespace:  false
+  AfterObjCDeclaration: false
+  AfterStruct:     false
+  AfterUnion:      false
+  BeforeCatch:     false
+  BeforeElse:      false
+  BeforeLambdaBody: false
+  BeforeWhile:     false
+  IndentBraces:    false
+  SplitEmptyFunction: true
+  SplitEmptyRecord: true
+  SplitEmptyNamespace: true
+BreakAdjacentStringLiterals: true
+BreakAfterAttributes: Leave
+BreakAfterJavaFieldAnnotations: false
+BreakArrays:     true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: Always
+BreakBeforeBraces: Attach
+BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+ColumnLimit:     80
+CommentPragmas:  '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat:   false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+  - foreach
+  - Q_FOREACH
+  - BOOST_FOREACH
+IfMacros:
+  - KJ_IF_MAYBE
+IncludeBlocks:   Preserve
+IncludeCategories:
+  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
+    Priority:        2
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
+    Priority:        3
+    SortPriority:    0
+    CaseSensitive:   false
+  - Regex:           '.*'
+    Priority:        1
+    SortPriority:    0
+    CaseSensitive:   false
+IncludeIsMainRegex: '(Test)?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseBlocks: false
+IndentCaseLabels: false
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: None
+IndentRequiresClause: true
+IndentWidth:     2
+IndentWrappedFunctionNames: false
+InsertBraces:    false
+InsertNewlineAtEOF: false
+InsertTrailingCommas: None
+IntegerLiteralSeparator:
+  Binary:          0
+  BinaryMinDigits: 0
+  Decimal:         0
+  DecimalMinDigits: 0
+  Hex:             0
+  HexMinDigits:    0
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: true
+KeepEmptyLinesAtEOF: false
+LambdaBodyIndentation: Signature
+LineEnding:      DeriveLF
+MacroBlockBegin: ''
+MacroBlockEnd:   ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Auto
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PackConstructorInitializers: BinPack
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 19
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakScopeResolution: 500
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 60
+PointerAlignment: Right
+PPIndentWidth:   -1
+QualifierAlignment: Leave
+ReferenceAlignment: Pointer
+ReflowComments:  true
+RemoveBracesLLVM: false
+RemoveParentheses: Leave
+RemoveSemicolon: false
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: OuterScope
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SkipMacroDefinitionBody: false
+SortIncludes:    CaseSensitive
+SortJavaStaticImport: Before
+SortUsingDeclarations: LexicographicNumeric
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeJsonColon: false
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+  AfterControlStatements: true
+  AfterForeachMacros: true
+  AfterFunctionDefinitionName: false
+  AfterFunctionDeclarationName: false
+  AfterIfMacros:   true
+  AfterOverloadedOperator: false
+  AfterPlacementOperator: true
+  AfterRequiresInClause: false
+  AfterRequiresInExpression: false
+  BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpacesBeforeTrailingComments: 1
+SpacesInAngles:  Never
+SpacesInContainerLiterals: true
+SpacesInLineCommentPrefix:
+  Minimum:         1
+  Maximum:         -1
+SpacesInParens:  Never
+SpacesInParensOptions:
+  InCStyleCasts:   false
+  InConditionalStatements: false
+  InEmptyParentheses: false
+  Other:           false
+SpacesInSquareBrackets: false
+Standard:        Latest
+StatementAttributeLikeMacros:
+  - Q_EMIT
+StatementMacros:
+  - Q_UNUSED
+  - QT_REQUIRE_VERSION
+TabWidth:        8
+UseTab:          Never
+VerilogBreakBetweenInstancePorts: true
+WhitespaceSensitiveMacros:
+  - BOOST_PP_STRINGIZE
+  - CF_SWIFT_NAME
+  - NS_SWIFT_NAME
+  - PP_STRINGIZE
+  - STRINGIZE

+ 46 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,46 @@
+Thank you for opening an issue on an Adafruit Arduino library repository.  To
+improve the speed of resolution please review the following guidelines and
+common troubleshooting steps below before creating the issue:
+
+- **Do not use GitHub issues for troubleshooting projects and issues.**  Instead use
+  the forums at http://forums.adafruit.com to ask questions and troubleshoot why
+  something isn't working as expected.  In many cases the problem is a common issue
+  that you will more quickly receive help from the forum community.  GitHub issues
+  are meant for known defects in the code.  If you don't know if there is a defect
+  in the code then start with troubleshooting on the forum first.
+
+- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
+  check all of the steps and commands to run have been followed.  Consult the
+  forum if you're unsure or have questions about steps in a guide/tutorial.
+
+- **For Arduino projects check these very common issues to ensure they don't apply**:
+
+  - For uploading sketches or communicating with the board make sure you're using
+    a **USB data cable** and **not** a **USB charge-only cable**.  It is sometimes
+    very hard to tell the difference between a data and charge cable!  Try using the
+    cable with other devices or swapping to another cable to confirm it is not
+    the problem.
+
+  - **Be sure you are supplying adequate power to the board.**  Check the specs of
+    your board and plug in an external power supply.  In many cases just
+    plugging a board into your computer is not enough to power it and other
+    peripherals.
+
+  - **Double check all soldering joints and connections.**  Flakey connections
+    cause many mysterious problems.  See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
+
+  - **Ensure you are using an official Arduino or Adafruit board.** We can't
+    guarantee a clone board will have the same functionality and work as expected
+    with this code and don't support them.
+
+If you're sure this issue is a defect in the code and checked the steps above
+please fill in the following fields to provide enough troubleshooting information.
+You may delete the guideline and text above to just leave the following details:
+
+- Arduino board:  **INSERT ARDUINO BOARD NAME/TYPE HERE**
+
+- Arduino IDE version (found in Arduino -> About Arduino menu):  **INSERT ARDUINO
+  VERSION HERE**
+
+- List the steps to reproduce the problem below (if possible attach a sketch or
+  copy the sketch code in too): **LIST REPRO STEPS BELOW**

+ 26 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,26 @@
+Thank you for creating a pull request to contribute to Adafruit's GitHub code!
+Before you open the request please review the following guidelines and tips to
+help it be more easily integrated:
+
+- **Describe the scope of your change--i.e. what the change does and what parts
+  of the code were modified.**  This will help us understand any risks of integrating
+  the code.
+
+- **Describe any known limitations with your change.**  For example if the change
+  doesn't apply to a supported platform of the library please mention it.
+
+- **Please run any tests or examples that can exercise your modified code.**  We
+  strive to not break users of the code and running tests/examples helps with this
+  process.
+
+Thank you again for contributing!  We will try to test and integrate the change
+as soon as we can, but be aware we have many GitHub repositories to manage and
+can't immediately respond to every request.  There is no need to bump or check in
+on a pull request (it will clutter the discussion of the request).
+
+Also don't be worried if the request is closed or not integrated--sometimes the
+priorities of Adafruit's GitHub code (education, ease of use) might not match the
+priorities of the pull request.  Don't fret, the open source community thrives on
+forks and GitHub makes it easy to keep your changes in a forked repo.
+
+After reviewing the guidelines above you can delete this text from the pull request.

+ 33 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/.github/workflows/githubci.yml

@@ -0,0 +1,33 @@
+name: Arduino Library CI
+
+on: [pull_request, push, repository_dispatch]
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    
+    steps:
+    - uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
+    - uses: actions/checkout@v3
+    - uses: actions/checkout@v3
+      with:
+         repository: adafruit/ci-arduino
+         path: ci
+
+    - name: Install the prerequisites
+      run: bash ci/actions_install.sh
+
+    - name: Check for correct code formatting with clang-format
+      run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r .
+
+    - name: Check for correct documentation with doxygen
+      env:
+        GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
+        PRETTYNAME : "Adafruit Bus IO Library"
+      run: bash ci/doxy_gen_and_deploy.sh
+
+    - name: Test the code on supported platforms
+      run: python3 ci/build_platform.py main_platforms zero feather32u4
+

+ 1 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/.piopm

@@ -0,0 +1 @@
+{"type": "library", "name": "Adafruit BusIO", "version": "1.17.4", "spec": {"owner": "adafruit", "id": 6214, "name": "Adafruit BusIO", "requirements": null, "uri": null}}

+ 384 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_BusIO_Register.cpp

@@ -0,0 +1,384 @@
+#include <Adafruit_BusIO_Register.h>
+
+#if !defined(SPI_INTERFACES_COUNT) ||                                          \
+    (defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
+
+/*!
+ *    @brief  Create a register we access over an I2C Device (which defines the
+ * bus and address)
+ *    @param  i2cdevice The I2CDevice to use for underlying I2C access
+ *    @param  reg_addr The address pointer value for the I2C/SMBus register, can
+ * be 8 or 16 bits
+ *    @param  width    The width of the register data itself, defaults to 1 byte
+ *    @param  byteorder The byte order of the register (used when width is > 1),
+ * defaults to LSBFIRST
+ *    @param  address_width The width of the register address itself, defaults
+ * to 1 byte
+ */
+Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
+                                                 uint16_t reg_addr,
+                                                 uint8_t width,
+                                                 uint8_t byteorder,
+                                                 uint8_t address_width) {
+  _i2cdevice = i2cdevice;
+  _spidevice = nullptr;
+  _addrwidth = address_width;
+  _address = reg_addr;
+  _byteorder = byteorder;
+  _width = width;
+}
+
+/*!
+ *    @brief  Create a register we access over an SPI Device (which defines the
+ * bus and CS pin)
+ *    @param  spidevice The SPIDevice to use for underlying SPI access
+ *    @param  reg_addr The address pointer value for the SPI register, can
+ * be 8 or 16 bits
+ *    @param  type     The method we use to read/write data to SPI (which is not
+ * as well defined as I2C)
+ *    @param  width    The width of the register data itself, defaults to 1 byte
+ *    @param  byteorder The byte order of the register (used when width is > 1),
+ * defaults to LSBFIRST
+ *    @param  address_width The width of the register address itself, defaults
+ * to 1 byte
+ */
+Adafruit_BusIO_Register::Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice,
+                                                 uint16_t reg_addr,
+                                                 Adafruit_BusIO_SPIRegType type,
+                                                 uint8_t width,
+                                                 uint8_t byteorder,
+                                                 uint8_t address_width) {
+  _spidevice = spidevice;
+  _spiregtype = type;
+  _i2cdevice = nullptr;
+  _addrwidth = address_width;
+  _address = reg_addr;
+  _byteorder = byteorder;
+  _width = width;
+}
+
+/*!
+ *    @brief  Create a register we access over an I2C or SPI Device. This is a
+ * handy function because we can pass in nullptr for the unused interface,
+ * allowing libraries to mass-define all the registers
+ *    @param  i2cdevice The I2CDevice to use for underlying I2C access, if
+ * nullptr we use SPI
+ *    @param  spidevice The SPIDevice to use for underlying SPI access, if
+ * nullptr we use I2C
+ *    @param  reg_addr The address pointer value for the I2C/SMBus/SPI register,
+ * can be 8 or 16 bits
+ *    @param  type     The method we use to read/write data to SPI (which is not
+ * as well defined as I2C)
+ *    @param  width    The width of the register data itself, defaults to 1 byte
+ *    @param  byteorder The byte order of the register (used when width is > 1),
+ * defaults to LSBFIRST
+ *    @param  address_width The width of the register address itself, defaults
+ * to 1 byte
+ */
+Adafruit_BusIO_Register::Adafruit_BusIO_Register(
+    Adafruit_I2CDevice *i2cdevice, Adafruit_SPIDevice *spidevice,
+    Adafruit_BusIO_SPIRegType type, uint16_t reg_addr, uint8_t width,
+    uint8_t byteorder, uint8_t address_width) {
+  _spidevice = spidevice;
+  _i2cdevice = i2cdevice;
+  _spiregtype = type;
+  _addrwidth = address_width;
+  _address = reg_addr;
+  _byteorder = byteorder;
+  _width = width;
+}
+
+/*!
+ * @brief Create a register we access over a GenericDevice
+ * @param genericdevice Generic device to use
+ * @param reg_addr Register address we will read/write
+ * @param width Width of the register in bytes (1-4)
+ * @param byteorder Byte order of register data (LSBFIRST or MSBFIRST)
+ * @param address_width Width of the register address in bytes (1 or 2)
+ */
+Adafruit_BusIO_Register::Adafruit_BusIO_Register(
+    Adafruit_GenericDevice *genericdevice, uint16_t reg_addr, uint8_t width,
+    uint8_t byteorder, uint8_t address_width) {
+  _i2cdevice = nullptr;
+  _spidevice = nullptr;
+  _genericdevice = genericdevice;
+  _addrwidth = address_width;
+  _address = reg_addr;
+  _byteorder = byteorder;
+  _width = width;
+}
+
+/*!
+ *    @brief  Write a buffer of data to the register location
+ *    @param  buffer Pointer to data to write
+ *    @param  len Number of bytes to write
+ *    @return True on successful write (only really useful for I2C as SPI is
+ * uncheckable)
+ */
+bool Adafruit_BusIO_Register::write(uint8_t *buffer, uint8_t len) {
+  uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
+                           (uint8_t)(_address >> 8)};
+  if (_i2cdevice) {
+    return _i2cdevice->write(buffer, len, true, addrbuffer, _addrwidth);
+  }
+  if (_spidevice) {
+    if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
+      // very special case!
+      // pass the special opcode address which we set as the high byte of the
+      // regaddr
+      addrbuffer[0] =
+          (uint8_t)(_address >> 8) & ~0x01; // set bottom bit low to write
+      // the 'actual' reg addr is the second byte then
+      addrbuffer[1] = (uint8_t)(_address & 0xFF);
+      // the address appears to be a byte longer
+      return _spidevice->write(buffer, len, addrbuffer, _addrwidth + 1);
+    }
+    if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
+      addrbuffer[0] &= ~0x80;
+    }
+    if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) {
+      addrbuffer[0] |= 0x80;
+    }
+    if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) {
+      addrbuffer[0] &= ~0x80;
+      addrbuffer[0] |= 0x40;
+    }
+    return _spidevice->write(buffer, len, addrbuffer, _addrwidth);
+  }
+  if (_genericdevice) {
+    return _genericdevice->writeRegister(addrbuffer, _addrwidth, buffer, len);
+  }
+  return false;
+}
+
+/*!
+ *    @brief  Write up to 4 bytes of data to the register location
+ *    @param  value Data to write
+ *    @param  numbytes How many bytes from 'value' to write
+ *    @return True on successful write (only really useful for I2C as SPI is
+ * uncheckable)
+ */
+bool Adafruit_BusIO_Register::write(uint32_t value, uint8_t numbytes) {
+  if (numbytes == 0) {
+    numbytes = _width;
+  }
+  if (numbytes > 4) {
+    return false;
+  }
+
+  // store a copy
+  _cached = value;
+
+  for (int i = 0; i < numbytes; i++) {
+    if (_byteorder == LSBFIRST) {
+      _buffer[i] = value & 0xFF;
+    } else {
+      _buffer[numbytes - i - 1] = value & 0xFF;
+    }
+    value >>= 8;
+  }
+  return write(_buffer, numbytes);
+}
+
+/*!
+ *    @brief  Read data from the register location. This does not do any error
+ * checking!
+ *    @return Returns 0xFFFFFFFF on failure, value otherwise
+ */
+uint32_t Adafruit_BusIO_Register::read(void) {
+  if (!read(_buffer, _width)) {
+    return -1;
+  }
+
+  uint32_t value = 0;
+
+  for (int i = 0; i < _width; i++) {
+    value <<= 8;
+    if (_byteorder == LSBFIRST) {
+      value |= _buffer[_width - i - 1];
+    } else {
+      value |= _buffer[i];
+    }
+  }
+
+  return value;
+}
+
+/*!
+ *    @brief  Read cached data from last time we wrote to this register
+ *    @return Returns 0xFFFFFFFF on failure, value otherwise
+ */
+uint32_t Adafruit_BusIO_Register::readCached(void) { return _cached; }
+
+/*!
+   @brief Read a number of bytes from a register into a buffer
+   @param buffer Buffer to read data into
+   @param len Number of bytes to read into the buffer
+   @return true on successful read, otherwise false
+*/
+bool Adafruit_BusIO_Register::read(uint8_t *buffer, uint8_t len) {
+  uint8_t addrbuffer[2] = {(uint8_t)(_address & 0xFF),
+                           (uint8_t)(_address >> 8)};
+  if (_i2cdevice) {
+    return _i2cdevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
+  }
+  if (_spidevice) {
+    if (_spiregtype == ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE) {
+      // very special case!
+      // pass the special opcode address which we set as the high byte of the
+      // regaddr
+      addrbuffer[0] =
+          (uint8_t)(_address >> 8) | 0x01; // set bottom bit high to read
+      // the 'actual' reg addr is the second byte then
+      addrbuffer[1] = (uint8_t)(_address & 0xFF);
+      // the address appears to be a byte longer
+      return _spidevice->write_then_read(addrbuffer, _addrwidth + 1, buffer,
+                                         len);
+    }
+    if (_spiregtype == ADDRBIT8_HIGH_TOREAD) {
+      addrbuffer[0] |= 0x80;
+    }
+    if (_spiregtype == ADDRBIT8_HIGH_TOWRITE) {
+      addrbuffer[0] &= ~0x80;
+    }
+    if (_spiregtype == AD8_HIGH_TOREAD_AD7_HIGH_TOINC) {
+      addrbuffer[0] |= 0x80 | 0x40;
+    }
+    return _spidevice->write_then_read(addrbuffer, _addrwidth, buffer, len);
+  }
+  if (_genericdevice) {
+    return _genericdevice->readRegister(addrbuffer, _addrwidth, buffer, len);
+  }
+  return false;
+}
+
+/*!
+ *    @brief  Read 2 bytes of data from the register location
+ *    @param  value Pointer to uint16_t variable to read into
+ *    @return True on successful write (only really useful for I2C as SPI is
+ * uncheckable)
+ */
+bool Adafruit_BusIO_Register::read(uint16_t *value) {
+  if (!read(_buffer, 2)) {
+    return false;
+  }
+
+  if (_byteorder == LSBFIRST) {
+    *value = _buffer[1];
+    *value <<= 8;
+    *value |= _buffer[0];
+  } else {
+    *value = _buffer[0];
+    *value <<= 8;
+    *value |= _buffer[1];
+  }
+  return true;
+}
+
+/*!
+ *    @brief  Read 1 byte of data from the register location
+ *    @param  value Pointer to uint8_t variable to read into
+ *    @return True on successful write (only really useful for I2C as SPI is
+ * uncheckable)
+ */
+bool Adafruit_BusIO_Register::read(uint8_t *value) {
+  if (!read(_buffer, 1)) {
+    return false;
+  }
+
+  *value = _buffer[0];
+  return true;
+}
+
+/*!
+ *    @brief  Pretty printer for this register
+ *    @param  s The Stream to print to, defaults to &Serial
+ */
+void Adafruit_BusIO_Register::print(Stream *s) {
+  uint32_t val = read();
+  s->print("0x");
+  s->print(val, HEX);
+}
+
+/*!
+ *    @brief  Pretty printer for this register
+ *    @param  s The Stream to print to, defaults to &Serial
+ */
+void Adafruit_BusIO_Register::println(Stream *s) {
+  print(s);
+  s->println();
+}
+
+/*!
+ *    @brief  Create a slice of the register that we can address without
+ * touching other bits
+ *    @param  reg The Adafruit_BusIO_Register which defines the bus/register
+ *    @param  bits The number of bits wide we are slicing
+ *    @param  shift The number of bits that our bit-slice is shifted from LSB
+ */
+Adafruit_BusIO_RegisterBits::Adafruit_BusIO_RegisterBits(
+    Adafruit_BusIO_Register *reg, uint8_t bits, uint8_t shift) {
+  _register = reg;
+  _bits = bits;
+  _shift = shift;
+}
+
+/*!
+ *    @brief  Read 4 bytes of data from the register
+ *    @return  data The 4 bytes to read
+ */
+uint32_t Adafruit_BusIO_RegisterBits::read(void) {
+  uint32_t val = _register->read();
+  val >>= _shift;
+  return val & ((1 << (_bits)) - 1);
+}
+
+/*!
+ *    @brief  Write 4 bytes of data to the register
+ *    @param  data The 4 bytes to write
+ *    @return True on successful write (only really useful for I2C as SPI is
+ * uncheckable)
+ */
+bool Adafruit_BusIO_RegisterBits::write(uint32_t data) {
+  uint32_t val = _register->read();
+
+  // mask off the data before writing
+  uint32_t mask = (1 << (_bits)) - 1;
+  data &= mask;
+
+  mask <<= _shift;
+  val &= ~mask;          // remove the current data at that spot
+  val |= data << _shift; // and add in the new data
+
+  return _register->write(val, _register->width());
+}
+
+/*!
+ *    @brief  The width of the register data, helpful for doing calculations
+ *    @returns The data width used when initializing the register
+ */
+uint8_t Adafruit_BusIO_Register::width(void) { return _width; }
+
+/*!
+ *    @brief  Set the default width of data
+ *    @param width the default width of data read from register
+ */
+void Adafruit_BusIO_Register::setWidth(uint8_t width) { _width = width; }
+
+/*!
+ *    @brief  Set register address
+ *    @param address the address from register
+ */
+void Adafruit_BusIO_Register::setAddress(uint16_t address) {
+  _address = address;
+}
+
+/*!
+ *    @brief  Set the width of register address
+ *    @param address_width the width for register address
+ */
+void Adafruit_BusIO_Register::setAddressWidth(uint16_t address_width) {
+  _addrwidth = address_width;
+}
+
+#endif // SPI exists

+ 117 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_BusIO_Register.h

@@ -0,0 +1,117 @@
+#ifndef Adafruit_BusIO_Register_h
+#define Adafruit_BusIO_Register_h
+
+#include <Arduino.h>
+
+#if !defined(SPI_INTERFACES_COUNT) ||                                          \
+    (defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
+
+#include <Adafruit_GenericDevice.h>
+#include <Adafruit_I2CDevice.h>
+#include <Adafruit_SPIDevice.h>
+
+typedef enum _Adafruit_BusIO_SPIRegType {
+  ADDRBIT8_HIGH_TOREAD = 0,
+  /*!<
+   * ADDRBIT8_HIGH_TOREAD
+   * When reading a register you must actually send the value 0x80 + register
+   * address to the device. e.g. To read the register 0x0B the register value
+   * 0x8B is sent and to write 0x0B is sent.
+   */
+  AD8_HIGH_TOREAD_AD7_HIGH_TOINC = 1,
+
+  /*!<
+   * ADDRBIT8_HIGH_TOWRITE
+   * When writing to a register you must actually send the value 0x80 +
+   * the register address to the device. e.g. To write to the register 0x19 the
+   * register value 0x99 is sent and to read 0x19 is sent.
+   */
+  ADDRBIT8_HIGH_TOWRITE = 2,
+
+  /*!<
+   * ADDRESSED_OPCODE_LOWBIT_TO_WRITE
+   * Used by the MCP23S series, we send 0x40 |'rd with the opcode
+   * Then set the lowest bit to write
+   */
+  ADDRESSED_OPCODE_BIT0_LOW_TO_WRITE = 3,
+
+} Adafruit_BusIO_SPIRegType;
+
+/*!
+ * @brief The class which defines a device register (a location to read/write
+ * data from)
+ */
+class Adafruit_BusIO_Register {
+public:
+  Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice, uint16_t reg_addr,
+                          uint8_t width = 1, uint8_t byteorder = LSBFIRST,
+                          uint8_t address_width = 1);
+
+  Adafruit_BusIO_Register(Adafruit_SPIDevice *spidevice, uint16_t reg_addr,
+                          Adafruit_BusIO_SPIRegType type, uint8_t width = 1,
+                          uint8_t byteorder = LSBFIRST,
+                          uint8_t address_width = 1);
+
+  Adafruit_BusIO_Register(Adafruit_I2CDevice *i2cdevice,
+                          Adafruit_SPIDevice *spidevice,
+                          Adafruit_BusIO_SPIRegType type, uint16_t reg_addr,
+                          uint8_t width = 1, uint8_t byteorder = LSBFIRST,
+                          uint8_t address_width = 1);
+
+  Adafruit_BusIO_Register(Adafruit_GenericDevice *genericdevice,
+                          uint16_t reg_addr, uint8_t width = 1,
+                          uint8_t byteorder = LSBFIRST,
+                          uint8_t address_width = 1);
+
+  bool read(uint8_t *buffer, uint8_t len);
+  bool read(uint8_t *value);
+  bool read(uint16_t *value);
+  uint32_t read(void);
+  uint32_t readCached(void);
+  bool write(uint8_t *buffer, uint8_t len);
+  bool write(uint32_t value, uint8_t numbytes = 0);
+
+  uint8_t width(void);
+
+  void setWidth(uint8_t width);
+  void setAddress(uint16_t address);
+  void setAddressWidth(uint16_t address_width);
+
+#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SERIAL)
+  void print(Stream *s = &Serial);
+  void println(Stream *s = &Serial);
+#else
+  void print(Stream *s);
+  void println(Stream *s);
+#endif
+
+private:
+  Adafruit_I2CDevice *_i2cdevice;
+  Adafruit_SPIDevice *_spidevice;
+  Adafruit_GenericDevice *_genericdevice;
+  Adafruit_BusIO_SPIRegType _spiregtype;
+  uint16_t _address;
+  uint8_t _width, _addrwidth, _byteorder;
+  uint8_t _buffer[4]; // we won't support anything larger than uint32 for
+                      // non-buffered read
+  uint32_t _cached = 0;
+};
+
+/*!
+ * @brief The class which defines a slice of bits from within a device register
+ * (a location to read/write data from)
+ */
+class Adafruit_BusIO_RegisterBits {
+public:
+  Adafruit_BusIO_RegisterBits(Adafruit_BusIO_Register *reg, uint8_t bits,
+                              uint8_t shift);
+  bool write(uint32_t value);
+  uint32_t read(void);
+
+private:
+  Adafruit_BusIO_Register *_register;
+  uint8_t _bits, _shift;
+};
+
+#endif // SPI exists
+#endif // BusIO_Register_h

+ 90 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_GenericDevice.cpp

@@ -0,0 +1,90 @@
+/*
+   Written with help by Claude!
+  https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
+  chats are not shareable :(
+*/
+
+#include "Adafruit_GenericDevice.h"
+
+/*!
+ * @brief Create a Generic device with the provided read/write functions
+ * @param obj Pointer to object instance
+ * @param read_func Function pointer for reading raw data
+ * @param write_func Function pointer for writing raw data
+ * @param readreg_func Function pointer for reading registers (optional)
+ * @param writereg_func Function pointer for writing registers (optional) */
+Adafruit_GenericDevice::Adafruit_GenericDevice(
+    void *obj, busio_genericdevice_read_t read_func,
+    busio_genericdevice_write_t write_func,
+    busio_genericdevice_readreg_t readreg_func,
+    busio_genericdevice_writereg_t writereg_func) {
+  _obj = obj;
+  _read_func = read_func;
+  _write_func = write_func;
+  _readreg_func = readreg_func;
+  _writereg_func = writereg_func;
+  _begun = false;
+}
+
+/*! @brief Simple begin function (doesn't do much at this time)
+    @return true always
+*/
+bool Adafruit_GenericDevice::begin(void) {
+  _begun = true;
+  return true;
+}
+
+/*!
+@brief Marks the GenericDevice as no longer in use.
+@note: Since this is a GenericDevice, if you are using this with a Serial
+object, this does NOT disable serial communication or release the RX/TX pins.
+That must be done manually by calling Serial.end().
+*/
+void Adafruit_GenericDevice::end(void) { _begun = false; }
+
+/*! @brief Write a buffer of data
+   @param buffer Pointer to buffer of data to write
+   @param len Number of bytes to write
+   @return true if write was successful, otherwise false */
+bool Adafruit_GenericDevice::write(const uint8_t *buffer, size_t len) {
+  if (!_begun)
+    return false;
+  return _write_func(_obj, buffer, len);
+}
+
+/*! @brief Read data into a buffer
+   @param buffer Pointer to buffer to read data into
+   @param len Number of bytes to read
+   @return true if read was successful, otherwise false */
+bool Adafruit_GenericDevice::read(uint8_t *buffer, size_t len) {
+  if (!_begun)
+    return false;
+  return _read_func(_obj, buffer, len);
+}
+
+/*! @brief Read from a register location
+   @param addr_buf Buffer containing register address
+   @param addrsiz Size of register address in bytes
+   @param buf Buffer to store read data
+   @param bufsiz Size of data to read in bytes
+   @return true if read was successful, otherwise false */
+bool Adafruit_GenericDevice::readRegister(uint8_t *addr_buf, uint8_t addrsiz,
+                                          uint8_t *buf, uint16_t bufsiz) {
+  if (!_begun || !_readreg_func)
+    return false;
+  return _readreg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
+}
+
+/*! @brief Write to a register location
+   @param addr_buf Buffer containing register address
+   @param addrsiz Size of register address in bytes
+   @param buf Buffer containing data to write
+   @param bufsiz Size of data to write in bytes
+   @return true if write was successful, otherwise false */
+bool Adafruit_GenericDevice::writeRegister(uint8_t *addr_buf, uint8_t addrsiz,
+                                           const uint8_t *buf,
+                                           uint16_t bufsiz) {
+  if (!_begun || !_writereg_func)
+    return false;
+  return _writereg_func(_obj, addr_buf, addrsiz, buf, bufsiz);
+}

+ 56 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_GenericDevice.h

@@ -0,0 +1,56 @@
+#ifndef ADAFRUIT_GENERICDEVICE_H
+#define ADAFRUIT_GENERICDEVICE_H
+
+#include <Arduino.h>
+
+typedef bool (*busio_genericdevice_read_t)(void *obj, uint8_t *buffer,
+                                           size_t len);
+typedef bool (*busio_genericdevice_write_t)(void *obj, const uint8_t *buffer,
+                                            size_t len);
+typedef bool (*busio_genericdevice_readreg_t)(void *obj, uint8_t *addr_buf,
+                                              uint8_t addrsiz, uint8_t *data,
+                                              uint16_t datalen);
+typedef bool (*busio_genericdevice_writereg_t)(void *obj, uint8_t *addr_buf,
+                                               uint8_t addrsiz,
+                                               const uint8_t *data,
+                                               uint16_t datalen);
+
+/*!
+ * @brief Class for communicating with a device via generic read/write functions
+ */
+class Adafruit_GenericDevice {
+public:
+  Adafruit_GenericDevice(
+      void *obj, busio_genericdevice_read_t read_func,
+      busio_genericdevice_write_t write_func,
+      busio_genericdevice_readreg_t readreg_func = nullptr,
+      busio_genericdevice_writereg_t writereg_func = nullptr);
+
+  bool begin(void);
+  void end(void);
+
+  bool read(uint8_t *buffer, size_t len);
+  bool write(const uint8_t *buffer, size_t len);
+  bool readRegister(uint8_t *addr_buf, uint8_t addrsiz, uint8_t *buf,
+                    uint16_t bufsiz);
+  bool writeRegister(uint8_t *addr_buf, uint8_t addrsiz, const uint8_t *buf,
+                     uint16_t bufsiz);
+
+protected:
+  /*! @brief Function pointer for reading raw data from the device */
+  busio_genericdevice_read_t _read_func;
+  /*! @brief Function pointer for writing raw data to the device */
+  busio_genericdevice_write_t _write_func;
+  /*! @brief Function pointer for reading a 'register' from the device */
+  busio_genericdevice_readreg_t _readreg_func;
+  /*! @brief Function pointer for writing a 'register' to the device */
+  busio_genericdevice_writereg_t _writereg_func;
+
+  bool _begun; ///< whether we have initialized yet (in case the function needs
+               ///< to do something)
+
+private:
+  void *_obj; ///< Pointer to object instance
+};
+
+#endif // ADAFRUIT_GENERICDEVICE_H

+ 320 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_I2CDevice.cpp

@@ -0,0 +1,320 @@
+#include "Adafruit_I2CDevice.h"
+
+// #define DEBUG_SERIAL Serial
+
+/*!
+ *    @brief  Create an I2C device at a given address
+ *    @param  addr The 7-bit I2C address for the device
+ *    @param  theWire The I2C bus to use, defaults to &Wire
+ */
+Adafruit_I2CDevice::Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire) {
+  _addr = addr;
+  _wire = theWire;
+  _begun = false;
+#ifdef ARDUINO_ARCH_SAMD
+  _maxBufferSize = 250; // as defined in Wire.h's RingBuffer
+#elif defined(ESP32)
+  _maxBufferSize = I2C_BUFFER_LENGTH;
+#else
+  _maxBufferSize = 32;
+#endif
+}
+
+/*!
+ *    @brief  Initializes and does basic address detection
+ *    @param  addr_detect Whether we should attempt to detect the I2C address
+ * with a scan. 99% of sensors/devices don't mind, but once in a while they
+ * don't respond well to a scan!
+ *    @return True if I2C initialized and a device with the addr found
+ */
+bool Adafruit_I2CDevice::begin(bool addr_detect) {
+  _wire->begin();
+  _begun = true;
+
+  if (addr_detect) {
+    return detected();
+  }
+  return true;
+}
+
+/*!
+ *    @brief  De-initialize device, turn off the Wire interface
+ */
+void Adafruit_I2CDevice::end(void) {
+  // Not all port implement Wire::end(), such as
+  // - ESP8266
+  // - AVR core without WIRE_HAS_END
+  // - ESP32: end() is implemented since 2.0.1 which is latest at the moment.
+  // Temporarily disable for now to give time for user to update.
+#if !(defined(ESP8266) ||                                                      \
+      (defined(ARDUINO_ARCH_AVR) && !defined(WIRE_HAS_END)) ||                 \
+      defined(ARDUINO_ARCH_ESP32))
+  _wire->end();
+  _begun = false;
+#endif
+}
+
+/*!
+ *    @brief  Scans I2C for the address - note will give a false-positive
+ *    if there's no pullups on I2C
+ *    @return True if I2C initialized and a device with the addr found
+ */
+bool Adafruit_I2CDevice::detected(void) {
+  // Init I2C if not done yet
+  if (!_begun && !begin()) {
+    return false;
+  }
+
+  // A basic scanner, see if it ACK's
+  _wire->beginTransmission(_addr);
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.print(F("Address 0x"));
+  DEBUG_SERIAL.print(_addr, HEX);
+#endif
+#ifdef ARDUINO_ARCH_MBED
+  _wire->write(0); // forces a write request instead of a read
+#endif
+  if (_wire->endTransmission() == 0) {
+#ifdef DEBUG_SERIAL
+    DEBUG_SERIAL.println(F(" Detected"));
+#endif
+    return true;
+  }
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.println(F(" Not detected"));
+#endif
+  return false;
+}
+
+/*!
+ *    @brief  Write a buffer or two to the I2C device. Cannot be more than
+ * maxBufferSize() bytes.
+ *    @param  buffer Pointer to buffer of data to write. This is const to
+ *            ensure the content of this buffer doesn't change.
+ *    @param  len Number of bytes from buffer to write
+ *    @param  prefix_buffer Pointer to optional array of data to write before
+ * buffer. Cannot be more than maxBufferSize() bytes. This is const to
+ *            ensure the content of this buffer doesn't change.
+ *    @param  prefix_len Number of bytes from prefix buffer to write
+ *    @param  stop Whether to send an I2C STOP signal on write
+ *    @return True if write was successful, otherwise false.
+ */
+bool Adafruit_I2CDevice::write(const uint8_t *buffer, size_t len, bool stop,
+                               const uint8_t *prefix_buffer,
+                               size_t prefix_len) {
+  if ((len + prefix_len) > maxBufferSize()) {
+    // currently not guaranteed to work if more than 32 bytes!
+    // we will need to find out if some platforms have larger
+    // I2C buffer sizes :/
+#ifdef DEBUG_SERIAL
+    DEBUG_SERIAL.println(F("\tI2CDevice could not write such a large buffer"));
+#endif
+    return false;
+  }
+
+  _wire->beginTransmission(_addr);
+
+  // Write the prefix data (usually an address)
+  if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
+    if (_wire->write(prefix_buffer, prefix_len) != prefix_len) {
+#ifdef DEBUG_SERIAL
+      DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
+#endif
+      return false;
+    }
+  }
+
+  // Write the data itself
+  if (_wire->write(buffer, len) != len) {
+#ifdef DEBUG_SERIAL
+    DEBUG_SERIAL.println(F("\tI2CDevice failed to write"));
+#endif
+    return false;
+  }
+
+#ifdef DEBUG_SERIAL
+
+  DEBUG_SERIAL.print(F("\tI2CWRITE @ 0x"));
+  DEBUG_SERIAL.print(_addr, HEX);
+  DEBUG_SERIAL.print(F(" :: "));
+  if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
+    for (uint16_t i = 0; i < prefix_len; i++) {
+      DEBUG_SERIAL.print(F("0x"));
+      DEBUG_SERIAL.print(prefix_buffer[i], HEX);
+      DEBUG_SERIAL.print(F(", "));
+    }
+  }
+  for (uint16_t i = 0; i < len; i++) {
+    DEBUG_SERIAL.print(F("0x"));
+    DEBUG_SERIAL.print(buffer[i], HEX);
+    DEBUG_SERIAL.print(F(", "));
+    if (i % 32 == 31) {
+      DEBUG_SERIAL.println();
+    }
+  }
+
+  if (stop) {
+    DEBUG_SERIAL.print("\tSTOP");
+  }
+#endif
+
+  if (_wire->endTransmission(stop) == 0) {
+#ifdef DEBUG_SERIAL
+    DEBUG_SERIAL.println();
+    // DEBUG_SERIAL.println("Sent!");
+#endif
+    return true;
+  } else {
+#ifdef DEBUG_SERIAL
+    DEBUG_SERIAL.println("\tFailed to send!");
+#endif
+    return false;
+  }
+}
+
+/*!
+ *    @brief  Read from I2C into a buffer from the I2C device.
+ *    Cannot be more than maxBufferSize() bytes.
+ *    @param  buffer Pointer to buffer of data to read into
+ *    @param  len Number of bytes from buffer to read.
+ *    @param  stop Whether to send an I2C STOP signal on read
+ *    @return True if read was successful, otherwise false.
+ */
+bool Adafruit_I2CDevice::read(uint8_t *buffer, size_t len, bool stop) {
+  size_t pos = 0;
+  while (pos < len) {
+    size_t read_len =
+        ((len - pos) > maxBufferSize()) ? maxBufferSize() : (len - pos);
+    bool read_stop = (pos < (len - read_len)) ? false : stop;
+    if (!_read(buffer + pos, read_len, read_stop))
+      return false;
+    pos += read_len;
+  }
+  return true;
+}
+
+bool Adafruit_I2CDevice::_read(uint8_t *buffer, size_t len, bool stop) {
+#if defined(TinyWireM_h)
+  size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len);
+#elif defined(ARDUINO_ARCH_MEGAAVR)
+  size_t recv = _wire->requestFrom(_addr, len, stop);
+#else
+  size_t recv = _wire->requestFrom((uint8_t)_addr, (uint8_t)len, (uint8_t)stop);
+#endif
+
+  if (recv != len) {
+    // Not enough data available to fulfill our obligation!
+#ifdef DEBUG_SERIAL
+    DEBUG_SERIAL.print(F("\tI2CDevice did not receive enough data: "));
+    DEBUG_SERIAL.println(recv);
+#endif
+    return false;
+  }
+
+  for (uint16_t i = 0; i < len; i++) {
+    buffer[i] = _wire->read();
+  }
+
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.print(F("\tI2CREAD  @ 0x"));
+  DEBUG_SERIAL.print(_addr, HEX);
+  DEBUG_SERIAL.print(F(" :: "));
+  for (uint16_t i = 0; i < len; i++) {
+    DEBUG_SERIAL.print(F("0x"));
+    DEBUG_SERIAL.print(buffer[i], HEX);
+    DEBUG_SERIAL.print(F(", "));
+    if (len % 32 == 31) {
+      DEBUG_SERIAL.println();
+    }
+  }
+  DEBUG_SERIAL.println();
+#endif
+
+  return true;
+}
+
+/*!
+ *    @brief  Write some data, then read some data from I2C into another buffer.
+ *    Cannot be more than maxBufferSize() bytes. The buffers can point to
+ *    same/overlapping locations.
+ *    @param  write_buffer Pointer to buffer of data to write from
+ *    @param  write_len Number of bytes from buffer to write.
+ *    @param  read_buffer Pointer to buffer of data to read into.
+ *    @param  read_len Number of bytes from buffer to read.
+ *    @param  stop Whether to send an I2C STOP signal between the write and read
+ *    @return True if write & read was successful, otherwise false.
+ */
+bool Adafruit_I2CDevice::write_then_read(const uint8_t *write_buffer,
+                                         size_t write_len, uint8_t *read_buffer,
+                                         size_t read_len, bool stop) {
+  if (!write(write_buffer, write_len, stop)) {
+    return false;
+  }
+
+  return read(read_buffer, read_len);
+}
+
+/*!
+ *    @brief  Returns the 7-bit address of this device
+ *    @return The 7-bit address of this device
+ */
+uint8_t Adafruit_I2CDevice::address(void) { return _addr; }
+
+/*!
+ *    @brief  Change the I2C clock speed to desired (relies on
+ *    underlying Wire support!
+ *    @param desiredclk The desired I2C SCL frequency
+ *    @return True if this platform supports changing I2C speed.
+ *    Not necessarily that the speed was achieved!
+ */
+bool Adafruit_I2CDevice::setSpeed(uint32_t desiredclk) {
+#if defined(__AVR_ATmega328__) ||                                              \
+    defined(__AVR_ATmega328P__) // fix arduino core set clock
+  // calculate TWBR correctly
+
+  if ((F_CPU / 18) < desiredclk) {
+#ifdef DEBUG_SERIAL
+    Serial.println(F("I2C.setSpeed too high."));
+#endif
+    return false;
+  }
+  uint32_t atwbr = ((F_CPU / desiredclk) - 16) / 2;
+  if (atwbr > 16320) {
+#ifdef DEBUG_SERIAL
+    Serial.println(F("I2C.setSpeed too low."));
+#endif
+    return false;
+  }
+
+  if (atwbr <= 255) {
+    atwbr /= 1;
+    TWSR = 0x0;
+  } else if (atwbr <= 1020) {
+    atwbr /= 4;
+    TWSR = 0x1;
+  } else if (atwbr <= 4080) {
+    atwbr /= 16;
+    TWSR = 0x2;
+  } else { //  if (atwbr <= 16320)
+    atwbr /= 64;
+    TWSR = 0x3;
+  }
+  TWBR = atwbr;
+
+#ifdef DEBUG_SERIAL
+  Serial.print(F("TWSR prescaler = "));
+  Serial.println(pow(4, TWSR));
+  Serial.print(F("TWBR = "));
+  Serial.println(atwbr);
+#endif
+  return true;
+#elif (ARDUINO >= 157) && !defined(ARDUINO_STM32_FEATHER) &&                   \
+    !defined(TinyWireM_h)
+  _wire->setClock(desiredclk);
+  return true;
+
+#else
+  (void)desiredclk;
+  return false;
+#endif
+}

+ 36 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_I2CDevice.h

@@ -0,0 +1,36 @@
+#ifndef Adafruit_I2CDevice_h
+#define Adafruit_I2CDevice_h
+
+#include <Arduino.h>
+#include <Wire.h>
+
+///< The class which defines how we will talk to this device over I2C
+class Adafruit_I2CDevice {
+public:
+  Adafruit_I2CDevice(uint8_t addr, TwoWire *theWire = &Wire);
+  uint8_t address(void);
+  bool begin(bool addr_detect = true);
+  void end(void);
+  bool detected(void);
+
+  bool read(uint8_t *buffer, size_t len, bool stop = true);
+  bool write(const uint8_t *buffer, size_t len, bool stop = true,
+             const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
+  bool write_then_read(const uint8_t *write_buffer, size_t write_len,
+                       uint8_t *read_buffer, size_t read_len,
+                       bool stop = false);
+  bool setSpeed(uint32_t desiredclk);
+
+  /*!   @brief  How many bytes we can read in a transaction
+   *    @return The size of the Wire receive/transmit buffer */
+  size_t maxBufferSize() { return _maxBufferSize; }
+
+private:
+  uint8_t _addr;
+  TwoWire *_wire;
+  bool _begun;
+  size_t _maxBufferSize;
+  bool _read(uint8_t *buffer, size_t len, bool stop);
+};
+
+#endif // Adafruit_I2CDevice_h

+ 10 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_I2CRegister.h

@@ -0,0 +1,10 @@
+#ifndef _ADAFRUIT_I2C_REGISTER_H_
+#define _ADAFRUIT_I2C_REGISTER_H_
+
+#include <Adafruit_BusIO_Register.h>
+#include <Arduino.h>
+
+typedef Adafruit_BusIO_Register Adafruit_I2CRegister;
+typedef Adafruit_BusIO_RegisterBits Adafruit_I2CRegisterBits;
+
+#endif

+ 512 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_SPIDevice.cpp

@@ -0,0 +1,512 @@
+#include "Adafruit_SPIDevice.h"
+
+// #define DEBUG_SERIAL Serial
+
+#ifdef BUSIO_USE_FAST_PINIO
+#define BUSIO_SET_CLOCK_LOW() (*clkPort = *clkPort & ~clkPinMask)
+#define BUSIO_SET_CLOCK_HIGH() (*clkPort = *clkPort | clkPinMask)
+#define BUSIO_READ_MISO() (*misoPort & misoPinMask)
+#define BUSIO_WRITE_MOSI(value)                                                \
+  do {                                                                         \
+    if (value)                                                                 \
+      *mosiPort = *mosiPort | mosiPinMask;                                     \
+    else                                                                       \
+      *mosiPort = *mosiPort & ~mosiPinMask;                                    \
+  } while (0)
+#else
+#define BUSIO_SET_CLOCK_LOW() digitalWrite(_sck, LOW)
+#define BUSIO_SET_CLOCK_HIGH() digitalWrite(_sck, HIGH)
+#define BUSIO_READ_MISO() digitalRead(_miso)
+#define BUSIO_WRITE_MOSI(value) digitalWrite(_mosi, value)
+#endif
+
+/*!
+ *    @brief  Create an SPI device with the given CS pin and settings
+ *    @param  cspin The arduino pin number to use for chip select
+ *    @param  freq The SPI clock frequency to use, defaults to 1MHz
+ *    @param  dataOrder The SPI data order to use for bits within each byte,
+ * defaults to SPI_BITORDER_MSBFIRST
+ *    @param  dataMode The SPI mode to use, defaults to SPI_MODE0
+ *    @param  theSPI The SPI bus to use, defaults to &theSPI
+ */
+Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, uint32_t freq,
+                                       BusIOBitOrder dataOrder,
+                                       uint8_t dataMode, SPIClass *theSPI) {
+#ifdef BUSIO_HAS_HW_SPI
+  _cs = cspin;
+  _sck = _mosi = _miso = -1;
+  _spi = theSPI;
+  _begun = false;
+  _spiSetting = new SPISettings(freq, dataOrder, dataMode);
+  _freq = freq;
+  _dataOrder = dataOrder;
+  _dataMode = dataMode;
+#else
+  // unused, but needed to suppress compiler warns
+  (void)cspin;
+  (void)freq;
+  (void)dataOrder;
+  (void)dataMode;
+  (void)theSPI;
+#endif
+}
+
+/*!
+ *    @brief  Create an SPI device with the given CS pin and settings
+ *    @param  cspin The arduino pin number to use for chip select
+ *    @param  sckpin The arduino pin number to use for SCK
+ *    @param  misopin The arduino pin number to use for MISO, set to -1 if not
+ * used
+ *    @param  mosipin The arduino pin number to use for MOSI, set to -1 if not
+ * used
+ *    @param  freq The SPI clock frequency to use, defaults to 1MHz
+ *    @param  dataOrder The SPI data order to use for bits within each byte,
+ * defaults to SPI_BITORDER_MSBFIRST
+ *    @param  dataMode The SPI mode to use, defaults to SPI_MODE0
+ */
+Adafruit_SPIDevice::Adafruit_SPIDevice(int8_t cspin, int8_t sckpin,
+                                       int8_t misopin, int8_t mosipin,
+                                       uint32_t freq, BusIOBitOrder dataOrder,
+                                       uint8_t dataMode) {
+  _cs = cspin;
+  _sck = sckpin;
+  _miso = misopin;
+  _mosi = mosipin;
+
+#ifdef BUSIO_USE_FAST_PINIO
+  csPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(cspin));
+  csPinMask = digitalPinToBitMask(cspin);
+  if (mosipin != -1) {
+    mosiPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(mosipin));
+    mosiPinMask = digitalPinToBitMask(mosipin);
+  }
+  if (misopin != -1) {
+    misoPort = (BusIO_PortReg *)portInputRegister(digitalPinToPort(misopin));
+    misoPinMask = digitalPinToBitMask(misopin);
+  }
+  clkPort = (BusIO_PortReg *)portOutputRegister(digitalPinToPort(sckpin));
+  clkPinMask = digitalPinToBitMask(sckpin);
+#endif
+
+  _freq = freq;
+  _dataOrder = dataOrder;
+  _dataMode = dataMode;
+  _begun = false;
+}
+
+/*!
+ *    @brief  Release memory allocated in constructors
+ */
+Adafruit_SPIDevice::~Adafruit_SPIDevice() {
+  if (_spiSetting)
+    delete _spiSetting;
+}
+
+/*!
+ *    @brief  Initializes SPI bus and sets CS pin high
+ *    @return Always returns true because there's no way to test success of SPI
+ * init
+ */
+bool Adafruit_SPIDevice::begin(void) {
+  if (_cs != -1) {
+    pinMode(_cs, OUTPUT);
+    digitalWrite(_cs, HIGH);
+  }
+
+  if (_spi) { // hardware SPI
+#ifdef BUSIO_HAS_HW_SPI
+    _spi->begin();
+#endif
+  } else {
+    pinMode(_sck, OUTPUT);
+
+    if ((_dataMode == SPI_MODE0) || (_dataMode == SPI_MODE1)) {
+      // idle low on mode 0 and 1
+      digitalWrite(_sck, LOW);
+    } else {
+      // idle high on mode 2 or 3
+      digitalWrite(_sck, HIGH);
+    }
+    if (_mosi != -1) {
+      pinMode(_mosi, OUTPUT);
+      digitalWrite(_mosi, HIGH);
+    }
+    if (_miso != -1) {
+      pinMode(_miso, INPUT);
+    }
+  }
+
+  _begun = true;
+  return true;
+}
+
+/*!
+ *    @brief  Transfer (send/receive) a buffer over hard/soft SPI, without
+ * transaction management
+ *    @param  buffer The buffer to send and receive at the same time
+ *    @param  len    The number of bytes to transfer
+ */
+void Adafruit_SPIDevice::transfer(uint8_t *buffer, size_t len) {
+  //
+  // HARDWARE SPI
+  //
+  if (_spi) {
+#ifdef BUSIO_HAS_HW_SPI
+#if defined(SPARK)
+    _spi->transfer(buffer, buffer, len, nullptr);
+#elif defined(STM32)
+    for (size_t i = 0; i < len; i++) {
+      _spi->transfer(buffer[i]);
+    }
+#else
+    _spi->transfer(buffer, len);
+#endif
+    return;
+#endif
+  }
+
+  //
+  // SOFTWARE SPI
+  //
+  uint8_t startbit;
+  if (_dataOrder == SPI_BITORDER_LSBFIRST) {
+    startbit = 0x1;
+  } else {
+    startbit = 0x80;
+  }
+
+  bool towrite, lastmosi = !(buffer[0] & startbit);
+  uint8_t bitdelay_us = (1000000 / _freq) / 2;
+
+  for (size_t i = 0; i < len; i++) {
+    uint8_t reply = 0;
+    uint8_t send = buffer[i];
+
+    /*
+    Serial.print("\tSending software SPI byte 0x");
+    Serial.print(send, HEX);
+    Serial.print(" -> 0x");
+    */
+
+    // Serial.print(send, HEX);
+    for (uint8_t b = startbit; b != 0;
+         b = (_dataOrder == SPI_BITORDER_LSBFIRST) ? b << 1 : b >> 1) {
+
+      if (bitdelay_us) {
+        delayMicroseconds(bitdelay_us);
+      }
+
+      if (_dataMode == SPI_MODE0 || _dataMode == SPI_MODE2) {
+        towrite = send & b;
+        if ((_mosi != -1) && (lastmosi != towrite)) {
+          BUSIO_WRITE_MOSI(towrite);
+          lastmosi = towrite;
+        }
+
+        BUSIO_SET_CLOCK_HIGH();
+
+        if (bitdelay_us) {
+          delayMicroseconds(bitdelay_us);
+        }
+
+        if (_miso != -1) {
+          if (BUSIO_READ_MISO())
+            reply |= b;
+        }
+
+        BUSIO_SET_CLOCK_LOW();
+
+      } else if (_dataMode == SPI_MODE3) {
+
+        if (_mosi != -1) { // transmit on falling edge
+          BUSIO_WRITE_MOSI(send & b);
+        }
+
+        BUSIO_SET_CLOCK_LOW();
+
+        if (bitdelay_us) {
+          delayMicroseconds(bitdelay_us);
+        }
+
+        BUSIO_SET_CLOCK_HIGH();
+
+        if (bitdelay_us) {
+          delayMicroseconds(bitdelay_us);
+        }
+
+        if (_miso != -1) { // read on rising edge
+          if (BUSIO_READ_MISO()) {
+            reply |= b;
+          }
+        }
+
+      } else { // || _dataMode == SPI_MODE1)
+
+        BUSIO_SET_CLOCK_HIGH();
+
+        if (bitdelay_us) {
+          delayMicroseconds(bitdelay_us);
+        }
+
+        if (_mosi != -1) {
+          BUSIO_WRITE_MOSI(send & b);
+        }
+
+        BUSIO_SET_CLOCK_LOW();
+
+        if (_miso != -1) {
+          if (BUSIO_READ_MISO()) {
+            reply |= b;
+          }
+        }
+      }
+    }
+    if (_miso != -1) {
+      buffer[i] = reply;
+    }
+  }
+  return;
+}
+
+/*!
+ *    @brief  Transfer (send/receive) one byte over hard/soft SPI, without
+ * transaction management
+ *    @param  send The byte to send
+ *    @return The byte received while transmitting
+ */
+uint8_t Adafruit_SPIDevice::transfer(uint8_t send) {
+  uint8_t data = send;
+  transfer(&data, 1);
+  return data;
+}
+
+/*!
+ *    @brief  Manually begin a transaction (calls beginTransaction if hardware
+ * SPI)
+ */
+void Adafruit_SPIDevice::beginTransaction(void) {
+  if (_spi) {
+#ifdef BUSIO_HAS_HW_SPI
+    _spi->beginTransaction(*_spiSetting);
+#endif
+  }
+}
+
+/*!
+ *    @brief  Manually end a transaction (calls endTransaction if hardware SPI)
+ */
+void Adafruit_SPIDevice::endTransaction(void) {
+  if (_spi) {
+#ifdef BUSIO_HAS_HW_SPI
+    _spi->endTransaction();
+#endif
+  }
+}
+
+/*!
+ *    @brief  Assert/Deassert the CS pin if it is defined
+ *    @param  value The state the CS is set to
+ */
+void Adafruit_SPIDevice::setChipSelect(int value) {
+  if (_cs != -1) {
+    digitalWrite(_cs, value);
+  }
+}
+
+/*!
+ *    @brief  Write a buffer or two to the SPI device, with transaction
+ * management.
+ *    @brief  Manually begin a transaction (calls beginTransaction if hardware
+ *            SPI) with asserting the CS pin
+ */
+void Adafruit_SPIDevice::beginTransactionWithAssertingCS() {
+  beginTransaction();
+  setChipSelect(LOW);
+}
+
+/*!
+ *    @brief  Manually end a transaction (calls endTransaction if hardware SPI)
+ *            with deasserting the CS pin
+ */
+void Adafruit_SPIDevice::endTransactionWithDeassertingCS() {
+  setChipSelect(HIGH);
+  endTransaction();
+}
+
+/*!
+ *    @brief  Write a buffer or two to the SPI device, with transaction
+ * management.
+ *    @param  buffer Pointer to buffer of data to write
+ *    @param  len Number of bytes from buffer to write
+ *    @param  prefix_buffer Pointer to optional array of data to write before
+ * buffer.
+ *    @param  prefix_len Number of bytes from prefix buffer to write
+ *    @return Always returns true because there's no way to test success of SPI
+ * writes
+ */
+bool Adafruit_SPIDevice::write(const uint8_t *buffer, size_t len,
+                               const uint8_t *prefix_buffer,
+                               size_t prefix_len) {
+  beginTransactionWithAssertingCS();
+
+  // do the writing
+#if defined(ARDUINO_ARCH_ESP32)
+  if (_spi) {
+    if (prefix_len > 0) {
+      _spi->transferBytes((uint8_t *)prefix_buffer, nullptr, prefix_len);
+    }
+    if (len > 0) {
+      _spi->transferBytes((uint8_t *)buffer, nullptr, len);
+    }
+  } else
+#endif
+  {
+    for (size_t i = 0; i < prefix_len; i++) {
+      transfer(prefix_buffer[i]);
+    }
+    for (size_t i = 0; i < len; i++) {
+      transfer(buffer[i]);
+    }
+  }
+  endTransactionWithDeassertingCS();
+
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
+  if ((prefix_len != 0) && (prefix_buffer != nullptr)) {
+    for (uint16_t i = 0; i < prefix_len; i++) {
+      DEBUG_SERIAL.print(F("0x"));
+      DEBUG_SERIAL.print(prefix_buffer[i], HEX);
+      DEBUG_SERIAL.print(F(", "));
+    }
+  }
+  for (uint16_t i = 0; i < len; i++) {
+    DEBUG_SERIAL.print(F("0x"));
+    DEBUG_SERIAL.print(buffer[i], HEX);
+    DEBUG_SERIAL.print(F(", "));
+    if (i % 32 == 31) {
+      DEBUG_SERIAL.println();
+    }
+  }
+  DEBUG_SERIAL.println();
+#endif
+
+  return true;
+}
+
+/*!
+ *    @brief  Read from SPI into a buffer from the SPI device, with transaction
+ * management.
+ *    @param  buffer Pointer to buffer of data to read into
+ *    @param  len Number of bytes from buffer to read.
+ *    @param  sendvalue The 8-bits of data to write when doing the data read,
+ * defaults to 0xFF
+ *    @return Always returns true because there's no way to test success of SPI
+ * writes
+ */
+bool Adafruit_SPIDevice::read(uint8_t *buffer, size_t len, uint8_t sendvalue) {
+  memset(buffer, sendvalue, len); // clear out existing buffer
+
+  beginTransactionWithAssertingCS();
+  transfer(buffer, len);
+  endTransactionWithDeassertingCS();
+
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
+  for (uint16_t i = 0; i < len; i++) {
+    DEBUG_SERIAL.print(F("0x"));
+    DEBUG_SERIAL.print(buffer[i], HEX);
+    DEBUG_SERIAL.print(F(", "));
+    if (len % 32 == 31) {
+      DEBUG_SERIAL.println();
+    }
+  }
+  DEBUG_SERIAL.println();
+#endif
+
+  return true;
+}
+
+/*!
+ *    @brief  Write some data, then read some data from SPI into another buffer,
+ * with transaction management. The buffers can point to same/overlapping
+ * locations. This does not transmit-receive at the same time!
+ *    @param  write_buffer Pointer to buffer of data to write from
+ *    @param  write_len Number of bytes from buffer to write.
+ *    @param  read_buffer Pointer to buffer of data to read into.
+ *    @param  read_len Number of bytes from buffer to read.
+ *    @param  sendvalue The 8-bits of data to write when doing the data read,
+ * defaults to 0xFF
+ *    @return Always returns true because there's no way to test success of SPI
+ * writes
+ */
+bool Adafruit_SPIDevice::write_then_read(const uint8_t *write_buffer,
+                                         size_t write_len, uint8_t *read_buffer,
+                                         size_t read_len, uint8_t sendvalue) {
+  beginTransactionWithAssertingCS();
+  // do the writing
+#if defined(ARDUINO_ARCH_ESP32)
+  if (_spi) {
+    if (write_len > 0) {
+      _spi->transferBytes((uint8_t *)write_buffer, nullptr, write_len);
+    }
+  } else
+#endif
+  {
+    for (size_t i = 0; i < write_len; i++) {
+      transfer(write_buffer[i]);
+    }
+  }
+
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.print(F("\tSPIDevice Wrote: "));
+  for (uint16_t i = 0; i < write_len; i++) {
+    DEBUG_SERIAL.print(F("0x"));
+    DEBUG_SERIAL.print(write_buffer[i], HEX);
+    DEBUG_SERIAL.print(F(", "));
+    if (write_len % 32 == 31) {
+      DEBUG_SERIAL.println();
+    }
+  }
+  DEBUG_SERIAL.println();
+#endif
+
+  // do the reading
+  for (size_t i = 0; i < read_len; i++) {
+    read_buffer[i] = transfer(sendvalue);
+  }
+
+#ifdef DEBUG_SERIAL
+  DEBUG_SERIAL.print(F("\tSPIDevice Read: "));
+  for (uint16_t i = 0; i < read_len; i++) {
+    DEBUG_SERIAL.print(F("0x"));
+    DEBUG_SERIAL.print(read_buffer[i], HEX);
+    DEBUG_SERIAL.print(F(", "));
+    if (read_len % 32 == 31) {
+      DEBUG_SERIAL.println();
+    }
+  }
+  DEBUG_SERIAL.println();
+#endif
+
+  endTransactionWithDeassertingCS();
+
+  return true;
+}
+
+/*!
+ *    @brief  Write some data and read some data at the same time from SPI
+ * into the same buffer, with transaction management. This is basicaly a wrapper
+ * for transfer() with CS-pin and transaction management. This /does/
+ * transmit-receive at the same time!
+ *    @param  buffer Pointer to buffer of data to write/read to/from
+ *    @param  len Number of bytes from buffer to write/read.
+ *    @return Always returns true because there's no way to test success of SPI
+ * writes
+ */
+bool Adafruit_SPIDevice::write_and_read(uint8_t *buffer, size_t len) {
+  beginTransactionWithAssertingCS();
+  transfer(buffer, len);
+  endTransactionWithDeassertingCS();
+
+  return true;
+}

+ 149 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/Adafruit_SPIDevice.h

@@ -0,0 +1,149 @@
+#ifndef Adafruit_SPIDevice_h
+#define Adafruit_SPIDevice_h
+
+#include <Arduino.h>
+
+#if !defined(SPI_INTERFACES_COUNT) ||                                          \
+    (defined(SPI_INTERFACES_COUNT) && (SPI_INTERFACES_COUNT > 0))
+// HW SPI available
+#include <SPI.h>
+#define BUSIO_HAS_HW_SPI
+#else
+// SW SPI ONLY
+enum { SPI_MODE0, SPI_MODE1, SPI_MODE2, SPI_MODE3 };
+typedef uint8_t SPIClass;
+#endif
+
+// some modern SPI definitions don't have BitOrder enum
+#if (defined(__AVR__) && !defined(ARDUINO_ARCH_MEGAAVR)) ||                    \
+    defined(ESP8266) || defined(TEENSYDUINO) || defined(SPARK) ||              \
+    defined(ARDUINO_ARCH_SPRESENSE) || defined(MEGATINYCORE) ||                \
+    defined(DXCORE) || defined(ARDUINO_AVR_ATmega4809) ||                      \
+    defined(ARDUINO_AVR_ATmega4808) || defined(ARDUINO_AVR_ATmega3209) ||      \
+    defined(ARDUINO_AVR_ATmega3208) || defined(ARDUINO_AVR_ATmega1609) ||      \
+    defined(ARDUINO_AVR_ATmega1608) || defined(ARDUINO_AVR_ATmega809) ||       \
+    defined(ARDUINO_AVR_ATmega808) || defined(ARDUINO_ARCH_ARC32) ||           \
+    defined(ARDUINO_ARCH_XMC)
+
+typedef enum _BitOrder {
+  SPI_BITORDER_MSBFIRST = MSBFIRST,
+  SPI_BITORDER_LSBFIRST = LSBFIRST,
+} BusIOBitOrder;
+
+#elif defined(ESP32) || defined(__ASR6501__) || defined(__ASR6502__)
+
+// some modern SPI definitions don't have BitOrder enum and have different SPI
+// mode defines
+typedef enum _BitOrder {
+  SPI_BITORDER_MSBFIRST = SPI_MSBFIRST,
+  SPI_BITORDER_LSBFIRST = SPI_LSBFIRST,
+} BusIOBitOrder;
+
+#else
+// Some platforms have a BitOrder enum but its named MSBFIRST/LSBFIRST
+#define SPI_BITORDER_MSBFIRST MSBFIRST
+#define SPI_BITORDER_LSBFIRST LSBFIRST
+typedef BitOrder BusIOBitOrder;
+#endif
+
+#if defined(__IMXRT1062__) // Teensy 4.x
+// *Warning* I disabled the usage of FAST_PINIO as the set/clear operations
+// used in the cpp file are not atomic and can effect multiple IO pins
+// and if an interrupt happens in between the time the code reads the register
+//  and writes out the updated value, that changes one or more other IO pins
+// on that same IO port, those change will be clobbered when the updated
+// values are written back.  A fast version can be implemented that uses the
+// ports set and clear registers which are atomic.
+// typedef volatile uint32_t BusIO_PortReg;
+// typedef uint32_t BusIO_PortMask;
+// #define BUSIO_USE_FAST_PINIO
+
+#elif defined(__MBED__) || defined(__ZEPHYR__)
+// Boards based on RTOS cores like mbed or Zephyr are not going to expose the
+// low level registers needed for fast pin manipulation
+#undef BUSIO_USE_FAST_PINIO
+
+#elif defined(ARDUINO_ARCH_XMC)
+#undef BUSIO_USE_FAST_PINIO
+
+#elif defined(__AVR__) || defined(TEENSYDUINO)
+typedef volatile uint8_t BusIO_PortReg;
+typedef uint8_t BusIO_PortMask;
+#define BUSIO_USE_FAST_PINIO
+
+#elif defined(ESP8266) || defined(ESP32) || defined(__SAM3X8E__) ||            \
+    defined(ARDUINO_ARCH_SAMD)
+typedef volatile uint32_t BusIO_PortReg;
+typedef uint32_t BusIO_PortMask;
+#define BUSIO_USE_FAST_PINIO
+
+#elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) &&                      \
+    !defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_SILABS) &&               \
+    !defined(ARDUINO_UNOR4_MINIMA) && !defined(ARDUINO_UNOR4_WIFI) &&          \
+    !defined(PORTDUINO)
+typedef volatile uint32_t BusIO_PortReg;
+typedef uint32_t BusIO_PortMask;
+#if !defined(__ASR6501__) && !defined(__ASR6502__)
+#define BUSIO_USE_FAST_PINIO
+#endif
+
+#else
+#undef BUSIO_USE_FAST_PINIO
+#endif
+
+/**! The class which defines how we will talk to this device over SPI **/
+class Adafruit_SPIDevice {
+public:
+#ifdef BUSIO_HAS_HW_SPI
+  Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
+                     BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
+                     uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = &SPI);
+#else
+  Adafruit_SPIDevice(int8_t cspin, uint32_t freq = 1000000,
+                     BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
+                     uint8_t dataMode = SPI_MODE0, SPIClass *theSPI = nullptr);
+#endif
+  Adafruit_SPIDevice(int8_t cspin, int8_t sck, int8_t miso, int8_t mosi,
+                     uint32_t freq = 1000000,
+                     BusIOBitOrder dataOrder = SPI_BITORDER_MSBFIRST,
+                     uint8_t dataMode = SPI_MODE0);
+  ~Adafruit_SPIDevice();
+
+  bool begin(void);
+  bool read(uint8_t *buffer, size_t len, uint8_t sendvalue = 0xFF);
+  bool write(const uint8_t *buffer, size_t len,
+             const uint8_t *prefix_buffer = nullptr, size_t prefix_len = 0);
+  bool write_then_read(const uint8_t *write_buffer, size_t write_len,
+                       uint8_t *read_buffer, size_t read_len,
+                       uint8_t sendvalue = 0xFF);
+  bool write_and_read(uint8_t *buffer, size_t len);
+
+  uint8_t transfer(uint8_t send);
+  void transfer(uint8_t *buffer, size_t len);
+  void beginTransaction(void);
+  void endTransaction(void);
+  void beginTransactionWithAssertingCS();
+  void endTransactionWithDeassertingCS();
+
+private:
+#ifdef BUSIO_HAS_HW_SPI
+  SPIClass *_spi = nullptr;
+  SPISettings *_spiSetting = nullptr;
+#else
+  uint8_t *_spi = nullptr;
+  uint8_t *_spiSetting = nullptr;
+#endif
+  uint32_t _freq;
+  BusIOBitOrder _dataOrder;
+  uint8_t _dataMode;
+  void setChipSelect(int value);
+
+  int8_t _cs, _sck, _mosi, _miso;
+#ifdef BUSIO_USE_FAST_PINIO
+  BusIO_PortReg *mosiPort, *clkPort, *misoPort, *csPort;
+  BusIO_PortMask mosiPinMask, misoPinMask, clkPinMask, csPinMask;
+#endif
+  bool _begun;
+};
+
+#endif // Adafruit_SPIDevice_h

+ 11 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/CMakeLists.txt

@@ -0,0 +1,11 @@
+# Adafruit Bus IO Library
+# https://github.com/adafruit/Adafruit_BusIO
+# MIT License
+
+cmake_minimum_required(VERSION 3.5)
+
+idf_component_register(SRCS "Adafruit_I2CDevice.cpp" "Adafruit_BusIO_Register.cpp" "Adafruit_SPIDevice.cpp" "Adafruit_GenericDevice.cpp"
+                       INCLUDE_DIRS "."
+                       REQUIRES arduino-esp32)
+
+project(Adafruit_BusIO)

+ 21 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/LICENSE

@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2017 Adafruit Industries
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 8 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/README.md

@@ -0,0 +1,8 @@
+# Adafruit Bus IO Library [![Build Status](https://github.com/adafruit/Adafruit_BusIO/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/Adafruit_BusIO/actions)
+
+
+This is a helper library to abstract away I2C, SPI, and 'generic transport' (e.g. UART) transactions and registers
+
+Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!
+
+MIT license, all text above must be included in any redistribution

+ 1 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/component.mk

@@ -0,0 +1 @@
+COMPONENT_ADD_INCLUDEDIRS = .

+ 0 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uartregtest/.uno.test.skip


+ 219 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uartregtest/genericdevice_uartregtest.ino

@@ -0,0 +1,219 @@
+/*
+   Advanced example of using bstracted transport for reading and writing
+   register data from a UART-based device such as a TMC2209
+
+   Written with help by Claude!
+  https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
+  chats are not shareable :(
+*/
+
+#include "Adafruit_BusIO_Register.h"
+#include "Adafruit_GenericDevice.h"
+
+// Debugging macros
+#define DEBUG_SERIAL Serial
+
+#ifdef DEBUG_SERIAL
+#define DEBUG_PRINT(x) DEBUG_SERIAL.print(x)
+#define DEBUG_PRINTLN(x) DEBUG_SERIAL.println(x)
+#define DEBUG_PRINT_HEX(x)                                                     \
+  do {                                                                         \
+    if (x < 0x10)                                                              \
+      DEBUG_SERIAL.print('0');                                                 \
+    DEBUG_SERIAL.print(x, HEX);                                                \
+    DEBUG_SERIAL.print(' ');                                                   \
+  } while (0)
+#else
+#define DEBUG_PRINT(x)
+#define DEBUG_PRINTLN(x)
+#define DEBUG_PRINT_HEX(x)
+#endif
+
+#define TMC2209_IOIN 0x06
+
+class TMC2209_UART {
+private:
+  Stream *_uart_stream;
+  uint8_t _addr;
+
+  static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
+    TMC2209_UART *dev = (TMC2209_UART *)thiz;
+    uint16_t timeout = 100;
+    while (dev->_uart_stream->available() < len && timeout--) {
+      delay(1);
+    }
+    if (timeout == 0) {
+      DEBUG_PRINTLN("Read timeout!");
+      return false;
+    }
+
+    DEBUG_PRINT("Reading: ");
+    for (size_t i = 0; i < len; i++) {
+      buffer[i] = dev->_uart_stream->read();
+      DEBUG_PRINT_HEX(buffer[i]);
+    }
+    DEBUG_PRINTLN("");
+
+    return true;
+  }
+
+  static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
+    TMC2209_UART *dev = (TMC2209_UART *)thiz;
+    DEBUG_PRINT("Writing: ");
+    for (size_t i = 0; i < len; i++) {
+      DEBUG_PRINT_HEX(buffer[i]);
+    }
+    DEBUG_PRINTLN("");
+
+    dev->_uart_stream->write(buffer, len);
+    return true;
+  }
+
+  static bool uart_readreg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
+                           uint8_t *data, uint16_t datalen) {
+    TMC2209_UART *dev = (TMC2209_UART *)thiz;
+    while (dev->_uart_stream->available())
+      dev->_uart_stream->read();
+
+    uint8_t packet[4] = {0x05, uint8_t(dev->_addr << 1), addr_buf[0], 0x00};
+
+    packet[3] = calcCRC(packet, 3);
+    if (!uart_write(thiz, packet, 4))
+      return false;
+
+    // Read back echo
+    uint8_t echo[4];
+    if (!uart_read(thiz, echo, 4))
+      return false;
+
+    // Verify echo
+    for (uint8_t i = 0; i < 4; i++) {
+      if (echo[i] != packet[i]) {
+        DEBUG_PRINTLN("Echo mismatch");
+        return false;
+      }
+    }
+
+    uint8_t response[8]; // sync + 0xFF + reg + 4 data bytes + CRC
+    if (!uart_read(thiz, response, 8))
+      return false;
+
+    // Verify response
+    if (response[0] != 0x05) {
+      DEBUG_PRINTLN("Invalid sync byte");
+      return false;
+    }
+
+    if (response[1] != 0xFF) {
+      DEBUG_PRINTLN("Invalid reply address");
+      return false;
+    }
+
+    if (response[2] != addr_buf[0]) {
+      DEBUG_PRINTLN("Register mismatch");
+      return false;
+    }
+
+    uint8_t crc = calcCRC(response, 7);
+    if (crc != response[7]) {
+      DEBUG_PRINTLN("CRC mismatch");
+      return false;
+    }
+
+    memcpy(data, &response[3], 4);
+    return true;
+  }
+
+  static bool uart_writereg(void *thiz, uint8_t *addr_buf, uint8_t addrsiz,
+                            const uint8_t *data, uint16_t datalen) {
+    TMC2209_UART *dev = (TMC2209_UART *)thiz;
+    while (dev->_uart_stream->available())
+      dev->_uart_stream->read();
+
+    uint8_t packet[8] = {0x05,
+                         uint8_t(dev->_addr << 1),
+                         uint8_t(addr_buf[0] | 0x80),
+                         data[0],
+                         data[1],
+                         data[2],
+                         data[3],
+                         0x00};
+
+    packet[7] = calcCRC(packet, 7);
+    if (!uart_write(thiz, packet, 8))
+      return false;
+
+    uint8_t echo[8];
+    if (!uart_read(thiz, echo, 8))
+      return false;
+
+    for (uint8_t i = 0; i < 8; i++) {
+      if (echo[i] != packet[i]) {
+        DEBUG_PRINTLN("Write echo mismatch");
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  static uint8_t calcCRC(uint8_t *data, uint8_t length) {
+    uint8_t crc = 0;
+    for (uint8_t i = 0; i < length; i++) {
+      uint8_t currentByte = data[i];
+      for (uint8_t j = 0; j < 8; j++) {
+        if ((crc >> 7) ^ (currentByte & 0x01)) {
+          crc = (crc << 1) ^ 0x07;
+        } else {
+          crc = crc << 1;
+        }
+        currentByte = currentByte >> 1;
+      }
+    }
+    return crc;
+  }
+
+public:
+  TMC2209_UART(Stream *serial, uint8_t addr)
+      : _uart_stream(serial), _addr(addr) {}
+
+  Adafruit_GenericDevice *createDevice() {
+    return new Adafruit_GenericDevice(this, uart_read, uart_write, uart_readreg,
+                                      uart_writereg);
+  }
+};
+
+void setup() {
+  Serial.begin(115200);
+  while (!Serial)
+    ;
+  delay(100);
+  Serial.println("TMC2209 Generic Device register read/write test!");
+
+  Serial1.begin(115200);
+
+  TMC2209_UART uart(&Serial1, 0);
+  Adafruit_GenericDevice *device = uart.createDevice();
+  device->begin();
+
+  // Create register object for IOIN
+  Adafruit_BusIO_Register ioin_reg(device,
+                                   TMC2209_IOIN, // device and register address
+                                   4,            // width = 4 bytes
+                                   MSBFIRST,     // byte order
+                                   1);           // address width = 1 byte
+  Serial.print("IOIN = 0x");
+  Serial.println(ioin_reg.read(), HEX);
+
+  // Create RegisterBits for VERSION field (bits 31:24)
+  Adafruit_BusIO_RegisterBits version_bits(
+      &ioin_reg, 8, 24); // 8 bits wide, starting at bit 24
+
+  Serial.println("Reading VERSION...");
+  uint8_t version = version_bits.read();
+
+  Serial.print("VERSION = 0x");
+  Serial.println(version, HEX);
+}
+
+void loop() { delay(1000); }

+ 0 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uarttest/.uno.test.skip


+ 98 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/genericdevice_uarttest/genericdevice_uarttest.ino

@@ -0,0 +1,98 @@
+/*
+   Abstracted transport for reading and writing data from a UART-based
+   device such as a TMC2209
+
+   Written with help by Claude!
+  https://claude.ai/chat/335f50b1-3dd8-435e-9139-57ec7ca26a3c (at this time
+  chats are not shareable :(
+*/
+
+#include "Adafruit_GenericDevice.h"
+
+/**
+ * Basic UART device class that demonstrates using GenericDevice with a Stream
+ * interface. This example shows how to wrap a Stream (like HardwareSerial or
+ * SoftwareSerial) with read/write callbacks that can be used by BusIO's
+ * register functions.
+ */
+class UARTDevice {
+public:
+  UARTDevice(Stream *serial) : _serial(serial) {}
+
+  // Static callback for writing data to UART
+  // Called by GenericDevice when data needs to be sent
+  static bool uart_write(void *thiz, const uint8_t *buffer, size_t len) {
+    UARTDevice *dev = (UARTDevice *)thiz;
+    dev->_serial->write(buffer, len);
+    return true;
+  }
+
+  // Static callback for reading data from UART
+  // Includes timeout and will return false if not enough data available
+  static bool uart_read(void *thiz, uint8_t *buffer, size_t len) {
+    UARTDevice *dev = (UARTDevice *)thiz;
+    uint16_t timeout = 100;
+    while (dev->_serial->available() < len && timeout--) {
+      delay(1);
+    }
+    if (timeout == 0) {
+      return false;
+    }
+    for (size_t i = 0; i < len; i++) {
+      buffer[i] = dev->_serial->read();
+    }
+    return true;
+  }
+
+  // Create a GenericDevice instance using our callbacks
+  Adafruit_GenericDevice *createDevice() {
+    return new Adafruit_GenericDevice(this, uart_read, uart_write);
+  }
+
+private:
+  Stream *_serial; // Underlying Stream instance (HardwareSerial, etc)
+};
+
+void setup() {
+  Serial.begin(115200);
+  while (!Serial)
+    ;
+  delay(100);
+
+  Serial.println("Generic Device test!");
+
+  // Initialize UART for device communication
+  Serial1.begin(115200);
+
+  // Create UART wrapper and BusIO device
+  UARTDevice uart(&Serial1);
+  Adafruit_GenericDevice *device = uart.createDevice();
+  device->begin();
+
+  // Test write/read cycle
+  uint8_t write_buf[4] = {0x5, 0x0, 0x0, 0x48};
+  uint8_t read_buf[8];
+
+  Serial.println("Writing data...");
+  if (!device->write(write_buf, 4)) {
+    Serial.println("Write failed!");
+    return;
+  }
+
+  Serial.println("Reading response...");
+  if (!device->read(read_buf, 8)) {
+    Serial.println("Read failed!");
+    return;
+  }
+
+  // Print response bytes
+  Serial.print("Got response: ");
+  for (int i = 0; i < 8; i++) {
+    Serial.print("0x");
+    Serial.print(read_buf[i], HEX);
+    Serial.print(" ");
+  }
+  Serial.println();
+}
+
+void loop() { delay(1000); }

+ 22 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/i2c_address_detect/i2c_address_detect.ino

@@ -0,0 +1,22 @@
+#include <Adafruit_I2CDevice.h>
+
+Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(0x10);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("I2C address detection test");
+
+  if (!i2c_dev.begin()) {
+    Serial.print("Did not find device at 0x");
+    Serial.println(i2c_dev.address(), HEX);
+    while (1)
+      ;
+  }
+  Serial.print("Device found on address 0x");
+  Serial.println(i2c_dev.address(), HEX);
+}
+
+void loop() {}

+ 45 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/i2c_readwrite/i2c_readwrite.ino

@@ -0,0 +1,45 @@
+#include <Adafruit_I2CDevice.h>
+
+#define I2C_ADDRESS 0x60
+Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("I2C device read and write test");
+
+  if (!i2c_dev.begin()) {
+    Serial.print("Did not find device at 0x");
+    Serial.println(i2c_dev.address(), HEX);
+    while (1)
+      ;
+  }
+  Serial.print("Device found on address 0x");
+  Serial.println(i2c_dev.address(), HEX);
+
+  uint8_t buffer[32];
+  // Try to read 32 bytes
+  i2c_dev.read(buffer, 32);
+  Serial.print("Read: ");
+  for (uint8_t i = 0; i < 32; i++) {
+    Serial.print("0x");
+    Serial.print(buffer[i], HEX);
+    Serial.print(", ");
+  }
+  Serial.println();
+
+  // read a register by writing first, then reading
+  buffer[0] = 0x0C; // we'll reuse the same buffer
+  i2c_dev.write_then_read(buffer, 1, buffer, 2, false);
+  Serial.print("Write then Read: ");
+  for (uint8_t i = 0; i < 2; i++) {
+    Serial.print("0x");
+    Serial.print(buffer[i], HEX);
+    Serial.print(", ");
+  }
+  Serial.println();
+}
+
+void loop() {}

+ 43 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/i2c_registers/i2c_registers.ino

@@ -0,0 +1,43 @@
+#include <Adafruit_BusIO_Register.h>
+#include <Adafruit_I2CDevice.h>
+
+#define I2C_ADDRESS 0x60
+Adafruit_I2CDevice i2c_dev = Adafruit_I2CDevice(I2C_ADDRESS);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("I2C device register test");
+
+  if (!i2c_dev.begin()) {
+    Serial.print("Did not find device at 0x");
+    Serial.println(i2c_dev.address(), HEX);
+    while (1)
+      ;
+  }
+  Serial.print("Device found on address 0x");
+  Serial.println(i2c_dev.address(), HEX);
+
+  Adafruit_BusIO_Register id_reg =
+      Adafruit_BusIO_Register(&i2c_dev, 0x0C, 2, LSBFIRST);
+  uint16_t id;
+  id_reg.read(&id);
+  Serial.print("ID register = 0x");
+  Serial.println(id, HEX);
+
+  Adafruit_BusIO_Register thresh_reg =
+      Adafruit_BusIO_Register(&i2c_dev, 0x01, 2, LSBFIRST);
+  uint16_t thresh;
+  thresh_reg.read(&thresh);
+  Serial.print("Initial threshold register = 0x");
+  Serial.println(thresh, HEX);
+
+  thresh_reg.write(~thresh);
+
+  Serial.print("Post threshold register = 0x");
+  Serial.println(thresh_reg.read(), HEX);
+}
+
+void loop() {}

+ 40 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/i2corspi_register/i2corspi_register.ino

@@ -0,0 +1,40 @@
+#include <Adafruit_BusIO_Register.h>
+
+// Define which interface to use by setting the unused interface to NULL!
+
+#define SPIDEVICE_CS 10
+Adafruit_SPIDevice *spi_dev = NULL; // new Adafruit_SPIDevice(SPIDEVICE_CS);
+
+#define I2C_ADDRESS 0x5D
+Adafruit_I2CDevice *i2c_dev = new Adafruit_I2CDevice(I2C_ADDRESS);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("I2C or SPI device register test");
+
+  if (spi_dev && !spi_dev->begin()) {
+    Serial.println("Could not initialize SPI device");
+  }
+
+  if (i2c_dev) {
+    if (i2c_dev->begin()) {
+      Serial.print("Device found on I2C address 0x");
+      Serial.println(i2c_dev->address(), HEX);
+    } else {
+      Serial.print("Did not find I2C device at 0x");
+      Serial.println(i2c_dev->address(), HEX);
+    }
+  }
+
+  Adafruit_BusIO_Register id_reg =
+      Adafruit_BusIO_Register(i2c_dev, spi_dev, ADDRBIT8_HIGH_TOREAD, 0x0F);
+  uint8_t id = 0;
+  id_reg.read(&id);
+  Serial.print("ID register = 0x");
+  Serial.println(id, HEX);
+}
+
+void loop() {}

+ 35 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_modetest/spi_modetest.ino

@@ -0,0 +1,35 @@
+#include <Adafruit_SPIDevice.h>
+
+#define SPIDEVICE_CS 10
+Adafruit_SPIDevice spi_dev =
+    Adafruit_SPIDevice(SPIDEVICE_CS, 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
+// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS, 13, 12, 11,
+// 100000, SPI_BITORDER_MSBFIRST, SPI_MODE1);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("SPI device mode test");
+
+  if (!spi_dev.begin()) {
+    Serial.println("Could not initialize SPI device");
+    while (1)
+      ;
+  }
+}
+
+void loop() {
+  Serial.println("\n\nTransfer test");
+  for (uint16_t x = 0; x <= 0xFF; x++) {
+    uint8_t i = x;
+    Serial.print("0x");
+    Serial.print(i, HEX);
+    spi_dev.read(&i, 1, i);
+    Serial.print("/");
+    Serial.print(i, HEX);
+    Serial.print(", ");
+    delay(25);
+  }
+}

+ 43 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_readwrite/spi_readwrite.ino

@@ -0,0 +1,43 @@
+#include <Adafruit_SPIDevice.h>
+
+#define SPIDEVICE_CS 10
+Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("SPI device read and write test");
+
+  if (!spi_dev.begin()) {
+    Serial.println("Could not initialize SPI device");
+    while (1)
+      ;
+  }
+
+  uint8_t buffer[32];
+
+  // Try to read 32 bytes
+  spi_dev.read(buffer, 32);
+  Serial.print("Read: ");
+  for (uint8_t i = 0; i < 32; i++) {
+    Serial.print("0x");
+    Serial.print(buffer[i], HEX);
+    Serial.print(", ");
+  }
+  Serial.println();
+
+  // read a register by writing first, then reading
+  buffer[0] = 0x8F; // we'll reuse the same buffer
+  spi_dev.write_then_read(buffer, 1, buffer, 2, false);
+  Serial.print("Write then Read: ");
+  for (uint8_t i = 0; i < 2; i++) {
+    Serial.print("0x");
+    Serial.print(buffer[i], HEX);
+    Serial.print(", ");
+  }
+  Serial.println();
+}
+
+void loop() {}

+ 268 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_register_bits/spi_register_bits.ino

@@ -0,0 +1,268 @@
+/***************************************************
+
+  This is an example for how to use Adafruit_BusIO_RegisterBits from
+ Adafruit_BusIO library.
+
+  Designed specifically to work with the Adafruit RTD Sensor
+  ----> https://www.adafruit.com/products/3328
+  uisng a MAX31865 RTD-to-Digital Converter
+  ----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf
+
+  This sensor uses SPI to communicate, 4 pins are required to
+  interface.
+  A fifth pin helps to detect when a new conversion is ready.
+
+  Adafruit invests time and resources providing this open source code,
+  please support Adafruit and open-source hardware by purchasing
+  products from Adafruit!
+
+  Example written (2020/3) by Andreas Hardtung/AnHard.
+  BSD license, all text above must be included in any redistribution
+ ****************************************************/
+
+#include <Adafruit_BusIO_Register.h>
+#include <Adafruit_SPIDevice.h>
+
+#define MAX31865_SPI_SPEED (5000000)
+#define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST)
+#define MAX31865_SPI_MODE (SPI_MODE1)
+
+#define MAX31865_SPI_CS (10)
+#define MAX31865_READY_PIN (2)
+
+Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(
+    MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER,
+    MAX31865_SPI_MODE, &SPI); // Hardware SPI
+// Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11,
+// MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software
+// SPI
+
+// MAX31865 chip related
+// *********************************************************************************************
+Adafruit_BusIO_Register config_reg =
+    Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
+Adafruit_BusIO_RegisterBits bias_bit =
+    Adafruit_BusIO_RegisterBits(&config_reg, 1, 7);
+Adafruit_BusIO_RegisterBits auto_bit =
+    Adafruit_BusIO_RegisterBits(&config_reg, 1, 6);
+Adafruit_BusIO_RegisterBits oneS_bit =
+    Adafruit_BusIO_RegisterBits(&config_reg, 1, 5);
+Adafruit_BusIO_RegisterBits wire_bit =
+    Adafruit_BusIO_RegisterBits(&config_reg, 1, 4);
+Adafruit_BusIO_RegisterBits faultT_bits =
+    Adafruit_BusIO_RegisterBits(&config_reg, 2, 2);
+Adafruit_BusIO_RegisterBits faultR_bit =
+    Adafruit_BusIO_RegisterBits(&config_reg, 1, 1);
+Adafruit_BusIO_RegisterBits fi50hz_bit =
+    Adafruit_BusIO_RegisterBits(&config_reg, 1, 0);
+
+Adafruit_BusIO_Register rRatio_reg =
+    Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
+Adafruit_BusIO_RegisterBits rRatio_bits =
+    Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1);
+Adafruit_BusIO_RegisterBits fault_bit =
+    Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0);
+
+Adafruit_BusIO_Register maxRratio_reg =
+    Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
+Adafruit_BusIO_RegisterBits maxRratio_bits =
+    Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1);
+
+Adafruit_BusIO_Register minRratio_reg =
+    Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST);
+Adafruit_BusIO_RegisterBits minRratio_bits =
+    Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1);
+
+Adafruit_BusIO_Register fault_reg =
+    Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST);
+Adafruit_BusIO_RegisterBits range_high_fault_bit =
+    Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7);
+Adafruit_BusIO_RegisterBits range_low_fault_bit =
+    Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6);
+Adafruit_BusIO_RegisterBits refin_high_fault_bit =
+    Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5);
+Adafruit_BusIO_RegisterBits refin_low_fault_bit =
+    Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4);
+Adafruit_BusIO_RegisterBits rtdin_low_fault_bit =
+    Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3);
+Adafruit_BusIO_RegisterBits voltage_fault_bit =
+    Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2);
+
+// Print the details of the configuration register.
+void printConfig(void) {
+  Serial.print("BIAS: ");
+  if (bias_bit.read())
+    Serial.print("ON");
+  else
+    Serial.print("OFF");
+  Serial.print(", AUTO: ");
+  if (auto_bit.read())
+    Serial.print("ON");
+  else
+    Serial.print("OFF");
+  Serial.print(", ONES: ");
+  if (oneS_bit.read())
+    Serial.print("ON");
+  else
+    Serial.print("OFF");
+  Serial.print(", WIRE: ");
+  if (wire_bit.read())
+    Serial.print("3");
+  else
+    Serial.print("2/4");
+  Serial.print(", FAULTCLEAR: ");
+  if (faultR_bit.read())
+    Serial.print("ON");
+  else
+    Serial.print("OFF");
+  Serial.print(", ");
+  if (fi50hz_bit.read())
+    Serial.print("50HZ");
+  else
+    Serial.print("60HZ");
+  Serial.println();
+}
+
+// Check and print faults. Then clear them.
+void checkFaults(void) {
+  if (fault_bit.read()) {
+    Serial.print("MAX: ");
+    Serial.println(maxRratio_bits.read());
+    Serial.print("VAL: ");
+    Serial.println(rRatio_bits.read());
+    Serial.print("MIN: ");
+    Serial.println(minRratio_bits.read());
+
+    if (range_high_fault_bit.read())
+      Serial.println("Range high fault");
+    if (range_low_fault_bit.read())
+      Serial.println("Range low fault");
+    if (refin_high_fault_bit.read())
+      Serial.println("REFIN high fault");
+    if (refin_low_fault_bit.read())
+      Serial.println("REFIN low fault");
+    if (rtdin_low_fault_bit.read())
+      Serial.println("RTDIN low fault");
+    if (voltage_fault_bit.read())
+      Serial.println("Voltage fault");
+
+    faultR_bit.write(1); // clear fault
+  }
+}
+
+void setup() {
+#if (MAX31865_1_READY_PIN != -1)
+  pinMode(MAX31865_READY_PIN, INPUT_PULLUP);
+#endif
+
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865");
+
+  if (!spi_dev.begin()) {
+    Serial.println("Could not initialize SPI device");
+    while (1)
+      ;
+  }
+
+  // Set up for automode 50Hz. We don't care about selfheating. We want the
+  // highest possible sampling rate.
+  auto_bit.write(0);   // Don't switch filtermode while auto_mode is on.
+  fi50hz_bit.write(1); // Set filter to 50Hz mode.
+  faultR_bit.write(1); // Clear faults.
+  bias_bit.write(1); // In automode we want to have the bias current always on.
+  delay(5);          // Wait until bias current settles down.
+                     // 10.5 time constants of the input RC network is required.
+  // 10ms worst case for 10kω reference resistor and a 0.1µF capacitor
+  // across the RTD inputs. Adafruit Module has 0.1µF and only
+  // 430/4300ω So here 0.43/4.3ms
+  auto_bit.write(
+      1); // Now we can set automode. Automatically starting first conversion.
+
+// Test the READY_PIN
+#if (defined(MAX31865_READY_PIN) && (MAX31865_READY_PIN != -1))
+  int i = 0;
+  while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) {
+    delay(1);
+  }
+  if (i >= 100) {
+    Serial.print("ERROR: Max31865 Pin detection does not work. PIN:");
+    Serial.println(MAX31865_READY_PIN);
+  }
+#else
+  delay(100);
+#endif
+
+  // Set ratio range.
+  // Setting the temperatures would need some more calculation - not related to
+  // Adafruit_BusIO_RegisterBits.
+  uint16_t ratio = rRatio_bits.read();
+  maxRratio_bits.write((ratio < 0x8fffu - 1000u) ? ratio + 1000u : 0x8fffu);
+  minRratio_bits.write((ratio > 1000u) ? ratio - 1000u : 0u);
+
+  printConfig();
+  checkFaults();
+}
+
+void loop() {
+#if (defined(MAX31865_READY_PIN) && (MAX31865_1_READY_PIN != -1))
+  // Is conversion ready?
+  if (!digitalRead(MAX31865_READY_PIN))
+#else
+  // Warant conversion is ready.
+  delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode.
+#endif
+  {
+    // Read ratio, calculate temperature, scale, filter and print.
+    Serial.println(rRatio2C(rRatio_bits.read()) * 100.0f,
+                   0); // Temperature scaled by 100
+    // Check, print, clear faults.
+    checkFaults();
+  }
+
+  // Do something else.
+  // delay(15000);
+}
+
+// Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C
+// *****************************
+float rRatio2C(uint16_t ratio) {
+  // A simple linear conversion.
+  const float R0 = 100.0f;
+  const float Rref = 430.0f;
+  const float alphaPT = 0.003850f;
+  const float ADCmax = (1u << 15) - 1.0f;
+  const float rscale = Rref / ADCmax;
+  // Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0.
+  // Rref and MAX at about 22±2°C. Measured temperature in ice/water bath 0.76°C
+  // with factor a = 1 and b = 0. Rref and MAX at about 22±2°C.
+  // const float a = 1.0f / (alphaPT * R0);
+  const float a = (100.0f / 101.08f) / (alphaPT * R0);
+  // const float b = 0.0f;  // 101.08
+  const float b = -0.76f; // 100.32 > 101.08
+
+  return filterRing(((ratio * rscale) - R0) * a + b);
+}
+
+// General purpose
+// *********************************************************************************************
+#define RINGLENGTH 250
+float filterRing(float newVal) {
+  static float ring[RINGLENGTH] = {0.0};
+  static uint8_t ringIndex = 0;
+  static bool ringFull = false;
+
+  if (ringIndex == RINGLENGTH) {
+    ringFull = true;
+    ringIndex = 0;
+  }
+  ring[ringIndex] = newVal;
+  uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1;
+  float ringSum = 0.0f;
+  for (uint8_t i = 0; i < loopEnd; i++)
+    ringSum += ring[i];
+  ringIndex++;
+  return ringSum / loopEnd;
+}

+ 40 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/examples/spi_registers/spi_registers.ino

@@ -0,0 +1,40 @@
+#include <Adafruit_BusIO_Register.h>
+#include <Adafruit_SPIDevice.h>
+
+#define SPIDEVICE_CS 10
+Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice(SPIDEVICE_CS);
+
+void setup() {
+  while (!Serial) {
+    delay(10);
+  }
+  Serial.begin(115200);
+  Serial.println("SPI device register test");
+
+  if (!spi_dev.begin()) {
+    Serial.println("Could not initialize SPI device");
+    while (1)
+      ;
+  }
+
+  Adafruit_BusIO_Register id_reg =
+      Adafruit_BusIO_Register(&spi_dev, 0x0F, ADDRBIT8_HIGH_TOREAD);
+  uint8_t id = 0;
+  id_reg.read(&id);
+  Serial.print("ID register = 0x");
+  Serial.println(id, HEX);
+
+  Adafruit_BusIO_Register thresh_reg = Adafruit_BusIO_Register(
+      &spi_dev, 0x0C, ADDRBIT8_HIGH_TOREAD, 2, LSBFIRST);
+  uint16_t thresh = 0;
+  thresh_reg.read(&thresh);
+  Serial.print("Initial threshold register = 0x");
+  Serial.println(thresh, HEX);
+
+  thresh_reg.write(~thresh);
+
+  Serial.print("Post threshold register = 0x");
+  Serial.println(thresh_reg.read(), HEX);
+}
+
+void loop() {}

+ 9 - 0
.pio/libdeps/esp32dev/Adafruit BusIO/library.properties

@@ -0,0 +1,9 @@
+name=Adafruit BusIO
+version=1.17.4
+author=Adafruit
+maintainer=Adafruit <info@adafruit.com>
+sentence=This is a library for abstracting away UART, I2C and SPI interfacing
+paragraph=This is a library for abstracting away UART, I2C and SPI interfacing
+category=Signal Input/Output
+url=https://github.com/adafruit/Adafruit_BusIO
+architectures=*

+ 108 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/.gitignore

@@ -0,0 +1,108 @@
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# NOTE! Please use 'git ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
+# Normal rules
+#
+.*
+*.o
+*.o.*
+*.a
+*.s
+*.ko
+*.so
+*.so.dbg
+*.mod.c
+*.i
+*.lst
+*.symtypes
+*.order
+modules.builtin
+*.elf
+*.bin
+*.gz
+*.bz2
+*.lzma
+*.patch
+*.gcno
+
+#
+# Top-level generic files
+#
+/tags
+/TAGS
+/linux
+/vmlinux
+/vmlinuz
+/System.map
+/Module.markers
+/Module.symvers
+
+#
+# git files that we don't want to ignore even it they are dot-files
+#
+!.gitignore
+!.mailmap
+
+#
+# Generated include files
+#
+include/config
+include/linux/version.h
+include/generated
+
+# stgit generated dirs
+patches-*
+
+# quilt's files
+patches
+series
+
+# cscope files
+cscope.*
+ncscope.*
+
+# gnu global files
+GPATH
+GRTAGS
+GSYMS
+GTAGS
+
+# QT-Creator files
+Makefile.am.user
+*.config
+*.creator
+*.creator.user
+*.files
+*.includes
+
+*.orig
+*~
+\#*#
+*.lo
+*.la
+Makefile
+Makefile.in
+aclocal.m4
+autoconfig.h
+autoconfig.h.in
+autom4te.cache/
+build-aux/
+config.log
+config.status
+configure
+libtool
+libupnp.pc
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+stamp-h1
+docs/doxygen
+

+ 120 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/Adafruit_Sensor.cpp

@@ -0,0 +1,120 @@
+#include "Adafruit_Sensor.h"
+
+/**************************************************************************/
+/*!
+    @brief  Prints sensor information to serial console
+*/
+/**************************************************************************/
+void Adafruit_Sensor::printSensorDetails(void) {
+  sensor_t sensor;
+  getSensor(&sensor);
+  Serial.println(F("------------------------------------"));
+  Serial.print(F("Sensor:       "));
+  Serial.println(sensor.name);
+  Serial.print(F("Type:         "));
+  switch ((sensors_type_t)sensor.type) {
+  case SENSOR_TYPE_ACCELEROMETER:
+    Serial.print(F("Acceleration (m/s2)"));
+    break;
+  case SENSOR_TYPE_MAGNETIC_FIELD:
+    Serial.print(F("Magnetic (uT)"));
+    break;
+  case SENSOR_TYPE_ORIENTATION:
+    Serial.print(F("Orientation (degrees)"));
+    break;
+  case SENSOR_TYPE_GYROSCOPE:
+    Serial.print(F("Gyroscopic (rad/s)"));
+    break;
+  case SENSOR_TYPE_LIGHT:
+    Serial.print(F("Light (lux)"));
+    break;
+  case SENSOR_TYPE_PRESSURE:
+    Serial.print(F("Pressure (hPa)"));
+    break;
+  case SENSOR_TYPE_PROXIMITY:
+    Serial.print(F("Distance (cm)"));
+    break;
+  case SENSOR_TYPE_GRAVITY:
+    Serial.print(F("Gravity (m/s2)"));
+    break;
+  case SENSOR_TYPE_LINEAR_ACCELERATION:
+    Serial.print(F("Linear Acceleration (m/s2)"));
+    break;
+  case SENSOR_TYPE_ROTATION_VECTOR:
+    Serial.print(F("Rotation vector"));
+    break;
+  case SENSOR_TYPE_RELATIVE_HUMIDITY:
+    Serial.print(F("Relative Humidity (%)"));
+    break;
+  case SENSOR_TYPE_AMBIENT_TEMPERATURE:
+    Serial.print(F("Ambient Temp (C)"));
+    break;
+  case SENSOR_TYPE_OBJECT_TEMPERATURE:
+    Serial.print(F("Object Temp (C)"));
+    break;
+  case SENSOR_TYPE_VOLTAGE:
+    Serial.print(F("Voltage (V)"));
+    break;
+  case SENSOR_TYPE_CURRENT:
+    Serial.print(F("Current (mA)"));
+    break;
+  case SENSOR_TYPE_COLOR:
+    Serial.print(F("Color (RGBA)"));
+    break;
+  case SENSOR_TYPE_TVOC:
+    Serial.print(F("Total Volatile Organic Compounds (ppb)"));
+    break;
+  case SENSOR_TYPE_VOC_INDEX:
+    Serial.print(F("Volatile Organic Compounds (Index)"));
+    break;
+  case SENSOR_TYPE_NOX_INDEX:
+    Serial.print(F("Nitrogen Oxides (Index)"));
+    break;
+  case SENSOR_TYPE_CO2:
+    Serial.print(F("Carbon Dioxide (ppm)"));
+    break;
+  case SENSOR_TYPE_ECO2:
+    Serial.print(F("Equivalent/estimated CO2 (ppm)"));
+    break;
+  case SENSOR_TYPE_PM10_STD:
+    Serial.print(F("Standard Particulate Matter 1.0 (ppm)"));
+    break;
+  case SENSOR_TYPE_PM25_STD:
+    Serial.print(F("Standard Particulate Matter 2.5 (ppm)"));
+    break;
+  case SENSOR_TYPE_PM100_STD:
+    Serial.print(F("Standard Particulate Matter 10.0 (ppm)"));
+    break;
+  case SENSOR_TYPE_PM10_ENV:
+    Serial.print(F("Environmental Particulate Matter 1.0 (ppm)"));
+    break;
+  case SENSOR_TYPE_PM25_ENV:
+    Serial.print(F("Environmental Particulate Matter 2.5 (ppm)"));
+    break;
+  case SENSOR_TYPE_PM100_ENV:
+    Serial.print(F("Environmental Particulate Matter 10.0 (ppm)"));
+    break;
+  case SENSOR_TYPE_GAS_RESISTANCE:
+    Serial.print(F("Gas Resistance (ohms)"));
+    break;
+  case SENSOR_TYPE_UNITLESS_PERCENT:
+    Serial.print(F("Unitless Percent (%)"));
+    break;
+  case SENSOR_TYPE_ALTITUDE:
+    Serial.print(F("Altitude (m)"));
+    break;
+  }
+
+  Serial.println();
+  Serial.print(F("Driver Ver:   "));
+  Serial.println(sensor.version);
+  Serial.print(F("Unique ID:    "));
+  Serial.println(sensor.sensor_id);
+  Serial.print(F("Min Value:    "));
+  Serial.println(sensor.min_value);
+  Serial.print(F("Max Value:    "));
+  Serial.println(sensor.max_value);
+  Serial.print(F("Resolution:   "));
+  Serial.println(sensor.resolution);
+  Serial.println(F("------------------------------------\n"));
+}

+ 224 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/Adafruit_Sensor.h

@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software< /span>
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Update by K. Townsend (Adafruit Industries) for lighter typedefs, and
+ * extended sensor support to include color, voltage and current */
+
+#ifndef _ADAFRUIT_SENSOR_H
+#define _ADAFRUIT_SENSOR_H
+
+#ifndef ARDUINO
+#include <stdint.h>
+#elif ARDUINO >= 100
+#include "Arduino.h"
+#include "Print.h"
+#else
+#include "WProgram.h"
+#endif
+
+/* Constants */
+#define SENSORS_GRAVITY_EARTH (9.80665F) /**< Earth's gravity in m/s^2 */
+#define SENSORS_GRAVITY_MOON (1.6F)      /**< The moon's gravity in m/s^2 */
+#define SENSORS_GRAVITY_SUN (275.0F)     /**< The sun's gravity in m/s^2 */
+#define SENSORS_GRAVITY_STANDARD (SENSORS_GRAVITY_EARTH)
+#define SENSORS_MAGFIELD_EARTH_MAX                                             \
+  (60.0F) /**< Maximum magnetic field on Earth's surface */
+#define SENSORS_MAGFIELD_EARTH_MIN                                             \
+  (30.0F) /**< Minimum magnetic field on Earth's surface */
+#define SENSORS_PRESSURE_SEALEVELHPA                                           \
+  (1013.25F) /**< Average sea level pressure is 1013.25 hPa */
+#define SENSORS_DPS_TO_RADS                                                    \
+  (0.017453293F) /**< Degrees/s to rad/s multiplier                            \
+                  */
+#define SENSORS_RADS_TO_DPS                                                    \
+  (57.29577793F) /**< Rad/s to degrees/s  multiplier */
+#define SENSORS_GAUSS_TO_MICROTESLA                                            \
+  (100) /**< Gauss to micro-Tesla multiplier */
+
+/** Sensor types */
+typedef enum {
+  SENSOR_TYPE_ACCELEROMETER = (1), /**< Gravity + linear acceleration */
+  SENSOR_TYPE_MAGNETIC_FIELD = (2),
+  SENSOR_TYPE_ORIENTATION = (3),
+  SENSOR_TYPE_GYROSCOPE = (4),
+  SENSOR_TYPE_LIGHT = (5),
+  SENSOR_TYPE_PRESSURE = (6),
+  SENSOR_TYPE_PROXIMITY = (8),
+  SENSOR_TYPE_GRAVITY = (9),
+  SENSOR_TYPE_LINEAR_ACCELERATION =
+      (10), /**< Acceleration not including gravity */
+  SENSOR_TYPE_ROTATION_VECTOR = (11),
+  SENSOR_TYPE_RELATIVE_HUMIDITY = (12),
+  SENSOR_TYPE_AMBIENT_TEMPERATURE = (13),
+  SENSOR_TYPE_OBJECT_TEMPERATURE = (14),
+  SENSOR_TYPE_VOLTAGE = (15),
+  SENSOR_TYPE_CURRENT = (16),
+  SENSOR_TYPE_COLOR = (17),
+  SENSOR_TYPE_TVOC = (18),
+  SENSOR_TYPE_VOC_INDEX = (19),
+  SENSOR_TYPE_NOX_INDEX = (20),
+  SENSOR_TYPE_CO2 = (21),
+  SENSOR_TYPE_ECO2 = (22),
+  SENSOR_TYPE_PM10_STD = (23),
+  SENSOR_TYPE_PM25_STD = (24),
+  SENSOR_TYPE_PM100_STD = (25),
+  SENSOR_TYPE_PM10_ENV = (26),
+  SENSOR_TYPE_PM25_ENV = (27),
+  SENSOR_TYPE_PM100_ENV = (28),
+  SENSOR_TYPE_GAS_RESISTANCE = (29),
+  SENSOR_TYPE_UNITLESS_PERCENT = (30),
+  SENSOR_TYPE_ALTITUDE = (31)
+} sensors_type_t;
+
+/** struct sensors_vec_s is used to return a vector in a common format. */
+typedef struct {
+  union {
+    float v[3]; ///< 3D vector elements
+    struct {
+      float x; ///< X component of vector
+      float y; ///< Y component of vector
+      float z; ///< Z component of vector
+    };         ///< Struct for holding XYZ component
+    /* Orientation sensors */
+    struct {
+      float roll; /**< Rotation around the longitudinal axis (the plane body, 'X
+                     axis'). Roll is positive and increasing when moving
+                     downward. -90 degrees <= roll <= 90 degrees */
+      float pitch;   /**< Rotation around the lateral axis (the wing span, 'Y
+                        axis'). Pitch is positive and increasing when moving
+                        upwards. -180 degrees <= pitch <= 180 degrees) */
+      float heading; /**< Angle between the longitudinal axis (the plane body)
+                        and magnetic north, measured clockwise when viewing from
+                        the top of the device. 0-359 degrees */
+    };               ///< Struct for holding roll/pitch/heading
+  };                 ///< Union that can hold 3D vector array, XYZ components or
+                     ///< roll/pitch/heading
+  int8_t status;     ///< Status byte
+  uint8_t reserved[3]; ///< Reserved
+} sensors_vec_t;
+
+/** struct sensors_color_s is used to return color data in a common format. */
+typedef struct {
+  union {
+    float c[3]; ///< Raw 3-element data
+    /* RGB color space */
+    struct {
+      float r;   /**< Red component */
+      float g;   /**< Green component */
+      float b;   /**< Blue component */
+    };           ///< RGB data in floating point notation
+  };             ///< Union of various ways to describe RGB colorspace
+  uint32_t rgba; /**< 24-bit RGBA value */
+} sensors_color_t;
+
+/* Sensor event (36 bytes) */
+/** struct sensor_event_s is used to provide a single sensor event in a common
+ * format. */
+typedef struct {
+  int32_t version;   /**< must be sizeof(struct sensors_event_t) */
+  int32_t sensor_id; /**< unique sensor identifier */
+  int32_t type;      /**< sensor type */
+  int32_t reserved0; /**< reserved */
+  int32_t timestamp; /**< time is in milliseconds */
+  union {
+    float data[4];              ///< Raw data */
+    sensors_vec_t acceleration; /**< acceleration values are in meter per second
+                                   per second (m/s^2) */
+    sensors_vec_t
+        magnetic; /**< magnetic vector values are in micro-Tesla (uT) */
+    sensors_vec_t orientation; /**< orientation values are in degrees */
+    sensors_vec_t gyro;        /**< gyroscope values are in rad/s */
+    float temperature; /**< temperature is in degrees centigrade (Celsius) */
+    float distance;    /**< distance in centimeters */
+    float light;       /**< light in SI lux units */
+    float pressure;    /**< pressure in hectopascal (hPa) */
+    float relative_humidity; /**< relative humidity in percent */
+    float current;           /**< current in milliamps (mA) */
+    float voltage;           /**< voltage in volts (V) */
+    float tvoc;              /**< Total Volatile Organic Compounds, in ppb */
+    float voc_index; /**< VOC (Volatile Organic Compound) index where 100 is
+                          normal (unitless) */
+    float nox_index; /**< NOx (Nitrogen Oxides) index where 1 is normal
+                          (unitless) */
+    float CO2;       /**< Measured CO2 in parts per million (ppm) */
+    float eCO2;      /**< equivalent/estimated CO2 in parts per million (ppm
+                        estimated from some other measurement) */
+    float pm10_std;  /**< Standard Particulate Matter <=1.0 in parts per million
+                        (ppm) */
+    float pm25_std;  /**< Standard Particulate Matter <=2.5 in parts per million
+                        (ppm) */
+    float pm100_std; /**< Standard Particulate Matter <=10.0 in parts per
+                        million (ppm) */
+    float pm10_env;  /**< Environmental Particulate Matter <=1.0 in parts per
+                        million (ppm) */
+    float pm25_env;  /**< Environmental Particulate Matter <=2.5 in parts per
+                        million (ppm) */
+    float pm100_env; /**< Environmental Particulate Matter <=10.0 in parts per
+                        million (ppm) */
+    float gas_resistance;   /**< Proportional to the amount of VOC particles in
+                               the air (Ohms) */
+    float unitless_percent; /**<Percentage, unit-less (%) */
+    sensors_color_t color;  /**< color in RGB component values */
+    float altitude; /**< Distance between a reference datum and a point or
+                       object, in meters. */
+  };                ///< Union for the wide ranges of data we can carry
+} sensors_event_t;
+
+/* Sensor details (40 bytes) */
+/** struct sensor_s is used to describe basic information about a specific
+ * sensor. */
+typedef struct {
+  char name[12];     /**< sensor name */
+  int32_t version;   /**< version of the hardware + driver */
+  int32_t sensor_id; /**< unique sensor identifier */
+  int32_t type;      /**< this sensor's type (ex. SENSOR_TYPE_LIGHT) */
+  float max_value;   /**< maximum value of this sensor's value in SI units */
+  float min_value;   /**< minimum value of this sensor's value in SI units */
+  float resolution; /**< smallest difference between two values reported by this
+                       sensor */
+  int32_t min_delay; /**< min delay in microseconds between events. zero = not a
+                        constant rate */
+} sensor_t;
+
+/** @brief Common sensor interface to unify various sensors.
+ * Intentionally modeled after sensors.h in the Android API:
+ * https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/sensors.h
+ */
+class Adafruit_Sensor {
+public:
+  // Constructor(s)
+  Adafruit_Sensor() {}
+  virtual ~Adafruit_Sensor() {}
+
+  // These must be defined by the subclass
+
+  /*! @brief Whether we should automatically change the range (if possible) for
+     higher precision
+      @param enabled True if we will try to autorange */
+  virtual void enableAutoRange(bool enabled) {
+    (void)enabled; /* suppress unused warning */
+  };
+
+  /*! @brief Get the latest sensor event
+      @returns True if able to fetch an event */
+  virtual bool getEvent(sensors_event_t *) = 0;
+  /*! @brief Get info about the sensor itself */
+  virtual void getSensor(sensor_t *) = 0;
+
+  void printSensorDetails(void);
+};
+
+#endif

+ 202 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/LICENSE.txt

@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 271 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/README.md

@@ -0,0 +1,271 @@
+# Adafruit Unified Sensor Driver #
+
+Many small embedded systems exist to collect data from sensors, analyse the data, and either take an appropriate action or send that sensor data to another system for processing.
+
+One of the many challenges of embedded systems design is the fact that parts you used today may be out of production tomorrow, or system requirements may change and you may need to choose a different sensor down the road.
+
+Creating new drivers is a relatively easy task, but integrating them into existing systems is both error prone and time consuming since sensors rarely use the exact same units of measurement.
+
+By reducing all data to a single **sensors\_event\_t** 'type' and settling on specific, **standardised SI units** for each sensor family the same sensor types return values that are comparable with any other similar sensor.  This enables you to switch sensor models with very little impact on the rest of the system, which can help mitigate some of the risks and problems of sensor availability and code reuse.
+
+The unified sensor abstraction layer is also useful for data-logging and data-transmission since you only have one well-known type to log or transmit over the air or wire.
+
+## Unified Sensor Drivers ##
+
+The following drivers are based on the Adafruit Unified Sensor Driver:
+
+**Accelerometers**
+  - [Adafruit\_ADXL345](https://github.com/adafruit/Adafruit_ADXL345)
+  - [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
+  - [Adafruit\_MMA8451\_Library](https://github.com/adafruit/Adafruit_MMA8451_Library)
+
+**Gyroscope**
+  - [Adafruit\_L3GD20\_U](https://github.com/adafruit/Adafruit_L3GD20_U)
+
+**Light**
+  - [Adafruit\_TSL2561](https://github.com/adafruit/Adafruit_TSL2561)
+  - [Adafruit\_TSL2591\_Library](https://github.com/adafruit/Adafruit_TSL2591_Library)
+
+**Magnetometers**
+  - [Adafruit\_LSM303DLHC](https://github.com/adafruit/Adafruit_LSM303DLHC)
+  - [Adafruit\_HMC5883\_Unified](https://github.com/adafruit/Adafruit_HMC5883_Unified)
+  
+**Barometric Pressure**
+  - [Adafruit\_BMP085\_Unified](https://github.com/adafruit/Adafruit_BMP085_Unified)
+  - [Adafruit\_BMP183\_Unified\_Library](https://github.com/adafruit/Adafruit_BMP183_Unified_Library)
+
+**Humidity & Temperature**
+  - [DHT-sensor-library](https://github.com/adafruit/DHT-sensor-library)
+
+**Humidity, Temperature, & Barometric Pressure**
+  - [Adafruit_BME280_Library](https://github.com/adafruit/Adafruit_BME280_Library/)
+
+**Orientation**
+ - [Adafruit_BNO055](https://github.com/adafruit/Adafruit_BNO055)
+
+**All in one device**
+- [Adafruit_LSM9DS0](https://github.com/adafruit/Adafruit_LSM9DS0_Library) (accelerometer, gyroscope, magnetometer)
+- [Adafruit_LSM9DS1](https://github.com/adafruit/Adafruit_LSM9DS1/) (accelerometer, gyroscope, magnetometer)
+
+
+## How Does it Work? ##
+
+Any driver that supports the Adafruit unified sensor abstraction layer will implement the Adafruit\_Sensor base class.  There are two main typedefs and one enum defined in Adafruit_Sensor.h that are used to 'abstract' away the sensor details and values:
+
+## Sensor Types (`sensors_type_t`)
+
+These pre-defined sensor types are used to properly handle the two related typedefs below, and allows us determine what types of units the sensor uses, etc.
+
+```c++
+/** Sensor types */
+typedef enum
+{
+  SENSOR_TYPE_ACCELEROMETER         = (1),
+  SENSOR_TYPE_MAGNETIC_FIELD        = (2),
+  SENSOR_TYPE_ORIENTATION           = (3),
+  SENSOR_TYPE_GYROSCOPE             = (4),
+  SENSOR_TYPE_LIGHT                 = (5),
+  SENSOR_TYPE_PRESSURE              = (6),
+  SENSOR_TYPE_PROXIMITY             = (8),
+  SENSOR_TYPE_GRAVITY               = (9),
+  SENSOR_TYPE_LINEAR_ACCELERATION   = (10),
+  SENSOR_TYPE_ROTATION_VECTOR       = (11),
+  SENSOR_TYPE_RELATIVE_HUMIDITY     = (12),
+  SENSOR_TYPE_AMBIENT_TEMPERATURE   = (13),
+  SENSOR_TYPE_VOLTAGE               = (15),
+  SENSOR_TYPE_CURRENT               = (16),
+  SENSOR_TYPE_COLOR                 = (17),
+  SENSOR_TYPE_TVOC                  = (18),
+  SENSOR_TYPE_VOC_INDEX             = (19),
+  SENSOR_TYPE_NOX_INDEX             = (20),
+  SENSOR_TYPE_CO2                   = (21),
+  SENSOR_TYPE_ECO2                  = (22),
+  SENSOR_TYPE_PM10_STD              = (23),
+  SENSOR_TYPE_PM25_STD              = (24),
+  SENSOR_TYPE_PM100_STD             = (25),
+  SENSOR_TYPE_PM10_ENV              = (26),
+  SENSOR_TYPE_PM25_ENV              = (27),
+  SENSOR_TYPE_PM100_ENV             = (28),
+  SENSOR_TYPE_GAS_RESISTANCE        = (29),
+  SENSOR_TYPE_UNITLESS_PERCENT      = (30),
+  SENSOR_TYPE_ALTITUDE              = (31),
+} sensors_type_t;
+```
+
+## Sensor Details (`sensor_t`)
+
+This typedef describes the specific capabilities of this sensor, and allows us to know what sensor we are using beneath the abstraction layer.
+
+```c++
+/* Sensor details (40 bytes) */
+/** struct sensor_s is used to describe basic information about a specific sensor. */
+typedef struct
+{
+    char     name[12];
+    int32_t  version;
+    int32_t  sensor_id;
+    int32_t  type;
+    float    max_value;
+    float    min_value;
+    float    resolution;
+    int32_t  min_delay;
+} sensor_t;
+```
+
+The individual fields are intended to be used as follows:
+
+- **name**: The sensor name or ID, up to a maximum of twelve characters (ex. "MPL115A2")
+- **version**: The version of the sensor HW and the driver to allow us to differentiate versions of the board or driver
+- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network
+- **type**: The sensor type, based on **sensors\_type\_t** in sensors.h
+- **max\_value**: The maximum value that this sensor can return (in the appropriate SI unit)
+- **min\_value**: The minimum value that this sensor can return (in the appropriate SI unit)
+- **resolution**: The smallest difference between two values that this sensor can report (in the appropriate SI unit)
+- **min\_delay**: The minimum delay in microseconds between two sensor events, or '0' if there is no constant sensor rate
+
+## Sensor Data/Events (`sensors_event_t`)
+
+This typedef is used to return sensor data from any sensor supported by the abstraction layer, using standard SI units and scales.
+
+```c++
+/* Sensor event (36 bytes) */
+/** struct sensor_event_s is used to provide a single sensor event in a common format. */
+typedef struct
+{
+    int32_t version;
+    int32_t sensor_id;
+    int32_t type;
+    int32_t reserved0;
+    int32_t timestamp;
+    union
+    {
+        float           data[4];
+        sensors_vec_t   acceleration;
+        sensors_vec_t   magnetic;
+        sensors_vec_t   orientation;
+        sensors_vec_t   gyro;
+        float           temperature;
+        float           distance;
+        float           light;
+        float           pressure;
+        float           relative_humidity;
+        float           current;
+        float           voltage;
+        float           tvoc;
+        float           voc_index;
+        float           nox_index;
+        float           CO2,
+        float           eCO2,
+        float           pm10_std,
+        float           pm25_std,
+        float           pm100_std,
+        float           pm10_env,
+        float           pm25_env,
+        float           pm100_env,
+        float           gas_resistance,
+        float           unitless_percent,
+        float           altitude,
+        sensors_color_t color;
+    };
+} sensors_event_t;
+```
+It includes the following fields:
+
+- **version**: Contain 'sizeof(sensors\_event\_t)' to identify which version of the API we're using in case this changes in the future
+- **sensor\_id**: A unique sensor identifier that is used to differentiate this specific sensor instance from any others that are present on the system or in the sensor network (must match the sensor\_id value in the corresponding sensor\_t enum above!)
+- **type**: the sensor type, based on **sensors\_type\_t** in sensors.h
+- **timestamp**: time in milliseconds when the sensor value was read
+- **data[4]**: An array of four 32-bit values that allows us to encapsulate any type of sensor data via a simple union (further described below)
+
+## Required Functions
+
+In addition to the two standard types and the sensor type enum, all drivers based on Adafruit_Sensor must also implement the following two functions:
+
+```c++
+bool getEvent(sensors_event_t*);
+```
+Calling this function will populate the supplied sensors\_event\_t reference with the latest available sensor data.  You should call this function as often as you want to update your data.
+
+```c++
+void getSensor(sensor_t*);
+```
+Calling this function will provide some basic information about the sensor (the sensor name, driver version, min and max values, etc.
+
+## Standardised SI values for `sensors_event_t`
+
+A key part of the abstraction layer is the standardization of values on SI units of a particular scale, which is accomplished via the data[4] union in sensors\_event\_t above.  This 16 byte union includes fields for each main sensor type, and uses the following SI units and scales:
+
+- **acceleration**: values are in **meter per second per second** (m/s^2)
+- **magnetic**: values are in **micro-Tesla** (uT)
+- **orientation**: values are in **degrees**
+- **gyro**: values are in **rad/s**
+- **temperature**: values in **degrees centigrade** (Celsius) 
+- **distance**: values are in **centimeters**
+- **light**: values are in **SI lux** units
+- **pressure**: values are in **hectopascal** (hPa)
+- **relative\_humidity**: values are in **percent**
+- **current**: values are in **milliamps** (mA)
+- **voltage**: values are in **volts** (V)
+- **color**: values are in 0..1.0 RGB channel luminosity and 32-bit RGBA format
+- **tvoc**: values are in **parts per billion** (ppb)
+- **voc_index**: values are an **index** from 1-500 with 100 being normal
+- **nox_index**: values are an **index** from 1-500 with 100 being normal
+- **CO2**: values are in **parts per million** (ppm)
+- **eCO2**: values are in **parts per million** (ppm)
+- **pm10_std**: values are in **parts per million** (ppm)
+- **pm25_std**: values are in **parts per million** (ppm)
+- **pm100_std**: values are in **parts per million** (ppm)
+- **pm10_env**: values are in **parts per million** (ppm)
+- **pm25_env**: values are in **parts per million** (ppm)
+- **pm100_env**: values are in **parts per million** (ppm)
+- **gas_resistance**: values are in **ohms**
+- **unitless_percent**: values are in **%**
+- **altitude**: values are in **meters** (m)
+
+## The Unified Driver Abstraction Layer in Practice ##
+
+Using the unified sensor abstraction layer is relatively easy once a compliant driver has been created.
+
+Every compliant sensor can now be read using a single, well-known 'type' (sensors\_event\_t), and there is a standardized way of interrogating a sensor about its specific capabilities (via sensor\_t).
+
+An example of reading the [TSL2561](https://github.com/adafruit/Adafruit_TSL2561) light sensor can be seen below:
+
+```c++
+ Adafruit_TSL2561 tsl = Adafruit_TSL2561(TSL2561_ADDR_FLOAT, 12345);
+ ...
+ /* Get a new sensor event */ 
+ sensors_event_t event;
+ tsl.getEvent(&event);
+ 
+ /* Display the results (light is measured in lux) */
+ if (event.light)
+ {
+   Serial.print(event.light); Serial.println(" lux");
+ }
+ else
+ {
+   /* If event.light = 0 lux the sensor is probably saturated
+      and no reliable data could be generated! */
+   Serial.println("Sensor overload");
+ }
+```
+
+Similarly, we can get the basic technical capabilities of this sensor with the following code:
+
+```c++
+ sensor_t sensor;
+ 
+ sensor_t sensor;
+ tsl.getSensor(&sensor);
+
+ /* Display the sensor details */
+ Serial.println("------------------------------------");
+ Serial.print  ("Sensor:       "); Serial.println(sensor.name);
+ Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
+ Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
+ Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" lux");
+ Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" lux");
+ Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" lux");  
+ Serial.println("------------------------------------");
+ Serial.println("");
+```

+ 153 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/examples/sensortest/sensortest.ino

@@ -0,0 +1,153 @@
+#include <Wire.h>
+#include <Adafruit_Sensor.h>
+#include <Adafruit_ADXL343.h>
+
+/* Assign a unique ID to this sensor at the same time */
+/* Uncomment following line for default Wire bus      */
+Adafruit_ADXL343 accel = Adafruit_ADXL343(12345);
+
+/* NeoTrellis M4, etc.                    */
+/* Uncomment following line for Wire1 bus */
+//Adafruit_ADXL343 accel = Adafruit_ADXL343(12345, &Wire1);
+
+void displaySensorDetails(void)
+{
+  sensor_t sensor;
+  accel.getSensor(&sensor);
+  Serial.println("------------------------------------");
+  Serial.print  ("Sensor:       "); Serial.println(sensor.name);
+  Serial.print  ("Driver Ver:   "); Serial.println(sensor.version);
+  Serial.print  ("Unique ID:    "); Serial.println(sensor.sensor_id);
+  Serial.print  ("Max Value:    "); Serial.print(sensor.max_value); Serial.println(" m/s^2");
+  Serial.print  ("Min Value:    "); Serial.print(sensor.min_value); Serial.println(" m/s^2");
+  Serial.print  ("Resolution:   "); Serial.print(sensor.resolution); Serial.println(" m/s^2");
+  Serial.println("------------------------------------");
+  Serial.println("");
+  delay(500);
+}
+
+void displayDataRate(void)
+{
+  Serial.print  ("Data Rate:    ");
+
+  switch(accel.getDataRate())
+  {
+    case ADXL343_DATARATE_3200_HZ:
+      Serial.print  ("3200 ");
+      break;
+    case ADXL343_DATARATE_1600_HZ:
+      Serial.print  ("1600 ");
+      break;
+    case ADXL343_DATARATE_800_HZ:
+      Serial.print  ("800 ");
+      break;
+    case ADXL343_DATARATE_400_HZ:
+      Serial.print  ("400 ");
+      break;
+    case ADXL343_DATARATE_200_HZ:
+      Serial.print  ("200 ");
+      break;
+    case ADXL343_DATARATE_100_HZ:
+      Serial.print  ("100 ");
+      break;
+    case ADXL343_DATARATE_50_HZ:
+      Serial.print  ("50 ");
+      break;
+    case ADXL343_DATARATE_25_HZ:
+      Serial.print  ("25 ");
+      break;
+    case ADXL343_DATARATE_12_5_HZ:
+      Serial.print  ("12.5 ");
+      break;
+    case ADXL343_DATARATE_6_25HZ:
+      Serial.print  ("6.25 ");
+      break;
+    case ADXL343_DATARATE_3_13_HZ:
+      Serial.print  ("3.13 ");
+      break;
+    case ADXL343_DATARATE_1_56_HZ:
+      Serial.print  ("1.56 ");
+      break;
+    case ADXL343_DATARATE_0_78_HZ:
+      Serial.print  ("0.78 ");
+      break;
+    case ADXL343_DATARATE_0_39_HZ:
+      Serial.print  ("0.39 ");
+      break;
+    case ADXL343_DATARATE_0_20_HZ:
+      Serial.print  ("0.20 ");
+      break;
+    case ADXL343_DATARATE_0_10_HZ:
+      Serial.print  ("0.10 ");
+      break;
+    default:
+      Serial.print  ("???? ");
+      break;
+  }
+  Serial.println(" Hz");
+}
+
+void displayRange(void)
+{
+  Serial.print  ("Range:         +/- ");
+
+  switch(accel.getRange())
+  {
+    case ADXL343_RANGE_16_G:
+      Serial.print  ("16 ");
+      break;
+    case ADXL343_RANGE_8_G:
+      Serial.print  ("8 ");
+      break;
+    case ADXL343_RANGE_4_G:
+      Serial.print  ("4 ");
+      break;
+    case ADXL343_RANGE_2_G:
+      Serial.print  ("2 ");
+      break;
+    default:
+      Serial.print  ("?? ");
+      break;
+  }
+  Serial.println(" g");
+}
+
+void setup(void)
+{
+  Serial.begin(9600);
+  while (!Serial);
+  Serial.println("Accelerometer Test"); Serial.println("");
+
+  /* Initialise the sensor */
+  if(!accel.begin())
+  {
+    /* There was a problem detecting the ADXL343 ... check your connections */
+    Serial.println("Ooops, no ADXL343 detected ... Check your wiring!");
+    while(1);
+  }
+
+  /* Set the range to whatever is appropriate for your project */
+  accel.setRange(ADXL343_RANGE_16_G);
+  // accel.setRange(ADXL343_RANGE_8_G);
+  // accel.setRange(ADXL343_RANGE_4_G);
+  // accel.setRange(ADXL343_RANGE_2_G);
+
+  /* Display some basic information on this sensor */
+  displaySensorDetails();
+  displayDataRate();
+  displayRange();
+  Serial.println("");
+}
+
+void loop(void)
+{
+  /* Get a new sensor event */
+  sensors_event_t event;
+  accel.getEvent(&event);
+
+  /* Display the results (acceleration is measured in m/s^2) */
+  Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print("  ");
+  Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print("  ");
+  Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print("  ");Serial.println("m/s^2 ");
+  delay(500);
+}

+ 11 - 0
.pio/libdeps/esp32dev/Adafruit Unified Sensor/library.properties

@@ -0,0 +1,11 @@
+name=Adafruit Unified Sensor
+version=1.1.15
+author=Adafruit <info@adafruit.com>
+maintainer=Adafruit <info@adafruit.com>
+sentence=Required for all Adafruit Unified Sensor based libraries.
+paragraph=A unified sensor abstraction layer used by many Adafruit sensor libraries.
+category=Sensors
+url=https://github.com/adafruit/Adafruit_Sensor
+architectures=*
+includes=Adafruit_Sensor.h
+

+ 13 - 0
.pio/libdeps/esp32dev/DHT sensor library/.clang-format

@@ -0,0 +1,13 @@
+Language: Cpp
+BasedOnStyle: Google
+IndentWidth: 2
+ColumnLimit: 80
+AllowShortFunctionsOnASingleLine: Empty
+AllowShortIfStatementsOnASingleLine: false
+AllowShortLoopsOnASingleLine: false
+BinPackArguments: true
+BinPackParameters: true
+BreakBeforeBraces: Attach
+DerivePointerAlignment: false
+PointerAlignment: Left
+SpacesBeforeTrailingComments: 1

+ 46 - 0
.pio/libdeps/esp32dev/DHT sensor library/.github/ISSUE_TEMPLATE.md

@@ -0,0 +1,46 @@
+Thank you for opening an issue on an Adafruit Arduino library repository.  To
+improve the speed of resolution please review the following guidelines and
+common troubleshooting steps below before creating the issue:
+
+- **Do not use GitHub issues for troubleshooting projects and issues.**  Instead use
+  the forums at http://forums.adafruit.com to ask questions and troubleshoot why
+  something isn't working as expected.  In many cases the problem is a common issue
+  that you will more quickly receive help from the forum community.  GitHub issues
+  are meant for known defects in the code.  If you don't know if there is a defect
+  in the code then start with troubleshooting on the forum first.
+
+- **If following a tutorial or guide be sure you didn't miss a step.** Carefully
+  check all of the steps and commands to run have been followed.  Consult the
+  forum if you're unsure or have questions about steps in a guide/tutorial.
+
+- **For Arduino projects check these very common issues to ensure they don't apply**:
+
+  - For uploading sketches or communicating with the board make sure you're using
+    a **USB data cable** and **not** a **USB charge-only cable**.  It is sometimes
+    very hard to tell the difference between a data and charge cable!  Try using the
+    cable with other devices or swapping to another cable to confirm it is not
+    the problem.
+
+  - **Be sure you are supplying adequate power to the board.**  Check the specs of
+    your board and plug in an external power supply.  In many cases just
+    plugging a board into your computer is not enough to power it and other
+    peripherals.
+
+  - **Double check all soldering joints and connections.**  Flakey connections
+    cause many mysterious problems.  See the [guide to excellent soldering](https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools) for examples of good solder joints.
+
+  - **Ensure you are using an official Arduino or Adafruit board.** We can't
+    guarantee a clone board will have the same functionality and work as expected
+    with this code and don't support them.
+
+If you're sure this issue is a defect in the code and checked the steps above
+please fill in the following fields to provide enough troubleshooting information.
+You may delete the guideline and text above to just leave the following details:
+
+- Arduino board:  **INSERT ARDUINO BOARD NAME/TYPE HERE**
+
+- Arduino IDE version (found in Arduino -> About Arduino menu):  **INSERT ARDUINO
+  VERSION HERE**
+
+- List the steps to reproduce the problem below (if possible attach a sketch or
+  copy the sketch code in too): **LIST REPRO STEPS BELOW**

+ 26 - 0
.pio/libdeps/esp32dev/DHT sensor library/.github/PULL_REQUEST_TEMPLATE.md

@@ -0,0 +1,26 @@
+Thank you for creating a pull request to contribute to Adafruit's GitHub code!
+Before you open the request please review the following guidelines and tips to
+help it be more easily integrated:
+
+- **Describe the scope of your change--i.e. what the change does and what parts
+  of the code were modified.**  This will help us understand any risks of integrating
+  the code.
+
+- **Describe any known limitations with your change.**  For example if the change
+  doesn't apply to a supported platform of the library please mention it.
+
+- **Please run any tests or examples that can exercise your modified code.**  We
+  strive to not break users of the code and running tests/examples helps with this
+  process.
+
+Thank you again for contributing!  We will try to test and integrate the change
+as soon as we can, but be aware we have many GitHub repositories to manage and
+can't immediately respond to every request.  There is no need to bump or check in
+on a pull request (it will clutter the discussion of the request).
+
+Also don't be worried if the request is closed or not integrated--sometimes the
+priorities of Adafruit's GitHub code (education, ease of use) might not match the
+priorities of the pull request.  Don't fret, the open source community thrives on
+forks and GitHub makes it easy to keep your changes in a forked repo.
+
+After reviewing the guidelines above you can delete this text from the pull request.

+ 52 - 0
.pio/libdeps/esp32dev/DHT sensor library/.github/workflows/githubci.yml

@@ -0,0 +1,52 @@
+name: Arduino Library CI
+
+on: [pull_request, push, repository_dispatch]
+
+jobs:
+  clang-format:
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
+    - uses: actions/checkout@v3
+    - uses: actions/checkout@v3
+      with:
+         repository: adafruit/ci-arduino
+         path: ci
+
+    - name: pre-install
+      run: bash ci/actions_install.sh
+
+    - name: clang
+      run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 
+
+  build:
+    runs-on: ubuntu-latest
+    needs: clang-format
+    
+    steps:
+    - uses: actions/setup-python@v4
+      with:
+        python-version: '3.x'
+    - uses: actions/checkout@v3
+    - uses: actions/checkout@v3
+      with:
+         repository: adafruit/ci-arduino
+         path: ci
+
+    - name: pre-install
+      run: bash ci/actions_install.sh
+
+    - name: test platforms
+      run: python3 ci/build_platform.py main_platforms
+
+    - name: clang
+      run: python3 ci/run-clang-format.py -e "ci/*" -e "bin/*" -r . 
+
+    - name: doxygen
+      env:
+        GH_REPO_TOKEN: ${{ secrets.GH_REPO_TOKEN }}
+        PRETTYNAME : "DHT sensor library"
+      run: bash ci/doxy_gen_and_deploy.sh

+ 8 - 0
.pio/libdeps/esp32dev/DHT sensor library/.gitignore

@@ -0,0 +1,8 @@
+# osx
+.DS_Store
+
+# doxygen
+Doxyfile*
+doxygen_sqlite3.db
+html
+*.tmp

+ 1 - 0
.pio/libdeps/esp32dev/DHT sensor library/.piopm

@@ -0,0 +1 @@
+{"type": "library", "name": "DHT sensor library", "version": "1.4.7", "spec": {"owner": "adafruit", "id": 19, "name": "DHT sensor library", "requirements": null, "uri": null}}

+ 13 - 0
.pio/libdeps/esp32dev/DHT sensor library/CONTRIBUTING.md

@@ -0,0 +1,13 @@
+# Contribution Guidlines
+
+This library is the culmination of the expertise of many members of the open source community who have dedicated their time and hard work. The best way to ask for help or propose a new idea is to [create a new issue](https://github.com/adafruit/DHT-sensor-library/issues/new) while creating a Pull Request with your code changes allows you to share your own innovations with the rest of the community.
+
+The following are some guidelines to observe when creating issues or PRs:
+
+- Be friendly; it is important that we can all enjoy a safe space as we are all working on the same project and it is okay for people to have different ideas
+
+- [Use code blocks](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code); it helps us help you when we can read your code! On that note also refrain from pasting more than 30 lines of code in a post, instead [create a gist](https://gist.github.com/) if you need to share large snippets
+
+- Use reasonable titles; refrain from using overly long or capitalized titles as they are usually annoying and do little to encourage others to help :smile:
+
+- Be detailed; refrain from mentioning code problems without sharing your source code and always give information regarding your board and version of the library

+ 394 - 0
.pio/libdeps/esp32dev/DHT sensor library/DHT.cpp

@@ -0,0 +1,394 @@
+/*!
+ *  @file DHT.cpp
+ *
+ *  @mainpage DHT series of low cost temperature/humidity sensors.
+ *
+ *  @section intro_sec Introduction
+ *
+ *  This is a library for DHT series of low cost temperature/humidity sensors.
+ *
+ *  You must have Adafruit Unified Sensor Library library installed to use this
+ * class.
+ *
+ *  Adafruit invests time and resources providing this open source code,
+ *  please support Adafruit andopen-source hardware by purchasing products
+ *  from Adafruit!
+ *
+ *  @section author Author
+ *
+ *  Written by Adafruit Industries.
+ *
+ *  @section license License
+ *
+ *  MIT license, all text above must be included in any redistribution
+ */
+
+#include "DHT.h"
+
+#define MIN_INTERVAL 2000 /**< min interval value */
+#define TIMEOUT                                      \
+  UINT32_MAX /**< Used programmatically for timeout. \
+                   Not a timeout duration. Type: uint32_t. */
+
+/*!
+ *  @brief  Instantiates a new DHT class
+ *  @param  pin
+ *          pin number that sensor is connected
+ *  @param  type
+ *          type of sensor
+ *  @param  count
+ *          number of sensors
+ */
+DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
+  (void)count; // Workaround to avoid compiler warning.
+  _pin = pin;
+  _type = type;
+#ifdef __AVR
+  _bit = digitalPinToBitMask(pin);
+  _port = digitalPinToPort(pin);
+#endif
+  _maxcycles =
+      microsecondsToClockCycles(1000); // 1 millisecond timeout for
+                                       // reading pulses from DHT sensor.
+  // Note that count is now ignored as the DHT reading algorithm adjusts itself
+  // based on the speed of the processor.
+}
+
+/*!
+ *  @brief  Setup sensor pins and set pull timings
+ *  @param  usec
+ *          Optionally pass pull-up time (in microseconds) before DHT reading
+ *starts. Default is 55 (see function declaration in DHT.h).
+ */
+void DHT::begin(uint8_t usec) {
+  // set up the pins!
+  pinMode(_pin, INPUT_PULLUP);
+  // Using this value makes sure that millis() - lastreadtime will be
+  // >= MIN_INTERVAL right away. Note that this assignment wraps around,
+  // but so will the subtraction.
+  _lastreadtime = millis() - MIN_INTERVAL;
+  DEBUG_PRINT("DHT max clock cycles: ");
+  DEBUG_PRINTLN(_maxcycles, DEC);
+  pullTime = usec;
+}
+
+/*!
+ *  @brief  Read temperature
+ *  @param  S
+ *          Scale. Boolean value:
+ *					- true = Fahrenheit
+ *					- false = Celcius
+ *  @param  force
+ *          true if in force mode
+ *	@return Temperature value in selected scale
+ */
+float DHT::readTemperature(bool S, bool force) {
+  float f = NAN;
+
+  if (read(force)) {
+    switch (_type) {
+      case DHT11:
+        f = data[2];
+        if (data[3] & 0x80) {
+          f = -1 - f;
+        }
+        f += (data[3] & 0x0f) * 0.1;
+        if (S) {
+          f = convertCtoF(f);
+        }
+        break;
+      case DHT12:
+        f = data[2];
+        f += (data[3] & 0x0f) * 0.1;
+        if (data[2] & 0x80) {
+          f *= -1;
+        }
+        if (S) {
+          f = convertCtoF(f);
+        }
+        break;
+      case DHT22:
+      case DHT21:
+        f = ((word)(data[2] & 0x7F)) << 8 | data[3];
+        f *= 0.1;
+        if (data[2] & 0x80) {
+          f *= -1;
+        }
+        if (S) {
+          f = convertCtoF(f);
+        }
+        break;
+    }
+  }
+  return f;
+}
+
+/*!
+ *  @brief  Converts Celcius to Fahrenheit
+ *  @param  c
+ *					value in Celcius
+ *	@return float value in Fahrenheit
+ */
+float DHT::convertCtoF(float c) {
+  return c * 1.8 + 32;
+}
+
+/*!
+ *  @brief  Converts Fahrenheit to Celcius
+ *  @param  f
+ *					value in Fahrenheit
+ *	@return float value in Celcius
+ */
+float DHT::convertFtoC(float f) {
+  return (f - 32) * 0.55555;
+}
+
+/*!
+ *  @brief  Read Humidity
+ *  @param  force
+ *					force read mode
+ *	@return float value - humidity in percent
+ */
+float DHT::readHumidity(bool force) {
+  float f = NAN;
+  if (read(force)) {
+    switch (_type) {
+      case DHT11:
+      case DHT12:
+        f = data[0] + data[1] * 0.1;
+        break;
+      case DHT22:
+      case DHT21:
+        f = ((word)data[0]) << 8 | data[1];
+        f *= 0.1;
+        break;
+    }
+  }
+  return f;
+}
+
+/*!
+ *  @brief  Compute Heat Index
+ *          Simplified version that reads temp and humidity from sensor
+ *  @param  isFahrenheit
+ * 					true if fahrenheit, false if celcius
+ *(default true)
+ *	@return float heat index
+ */
+float DHT::computeHeatIndex(bool isFahrenheit) {
+  float hi = computeHeatIndex(readTemperature(isFahrenheit), readHumidity(),
+                              isFahrenheit);
+  return hi;
+}
+
+/*!
+ *  @brief  Compute Heat Index
+ *  				Using both Rothfusz and Steadman's equations
+ *					(http://www.wpc.ncep.noaa.gov/html/heatindex_equation.shtml)
+ *  @param  temperature
+ *          temperature in selected scale
+ *  @param  percentHumidity
+ *          humidity in percent
+ *  @param  isFahrenheit
+ * 					true if fahrenheit, false if celcius
+ *	@return float heat index
+ */
+float DHT::computeHeatIndex(float temperature, float percentHumidity,
+                            bool isFahrenheit) {
+  float hi;
+
+  if (!isFahrenheit)
+    temperature = convertCtoF(temperature);
+
+  hi = 0.5 * (temperature + 61.0 + ((temperature - 68.0) * 1.2) +
+              (percentHumidity * 0.094));
+
+  if (hi > 79) {
+    hi = -42.379 + 2.04901523 * temperature + 10.14333127 * percentHumidity +
+         -0.22475541 * temperature * percentHumidity +
+         -0.00683783 * pow(temperature, 2) +
+         -0.05481717 * pow(percentHumidity, 2) +
+         0.00122874 * pow(temperature, 2) * percentHumidity +
+         0.00085282 * temperature * pow(percentHumidity, 2) +
+         -0.00000199 * pow(temperature, 2) * pow(percentHumidity, 2);
+
+    if ((percentHumidity < 13) && (temperature >= 80.0) &&
+        (temperature <= 112.0))
+      hi -= ((13.0 - percentHumidity) * 0.25) *
+            sqrt((17.0 - abs(temperature - 95.0)) * 0.05882);
+
+    else if ((percentHumidity > 85.0) && (temperature >= 80.0) &&
+             (temperature <= 87.0))
+      hi += ((percentHumidity - 85.0) * 0.1) * ((87.0 - temperature) * 0.2);
+  }
+
+  return isFahrenheit ? hi : convertFtoC(hi);
+}
+
+/*!
+ *  @brief  Read value from sensor or return last one from less than two
+ *seconds.
+ *  @param  force
+ *          true if using force mode
+ *	@return float value
+ */
+bool DHT::read(bool force) {
+  // Check if sensor was read less than two seconds ago and return early
+  // to use last reading.
+  uint32_t currenttime = millis();
+  if (!force && ((currenttime - _lastreadtime) < MIN_INTERVAL)) {
+    return _lastresult; // return last correct measurement
+  }
+  _lastreadtime = currenttime;
+
+  // Reset 40 bits of received data to zero.
+  data[0] = data[1] = data[2] = data[3] = data[4] = 0;
+
+#if defined(ESP8266)
+  yield(); // Handle WiFi / reset software watchdog
+#endif
+
+  // Send start signal.  See DHT datasheet for full signal diagram:
+  //   http://www.adafruit.com/datasheets/Digital%20humidity%20and%20temperature%20sensor%20AM2302.pdf
+
+  // Go into high impedence state to let pull-up raise data line level and
+  // start the reading process.
+  pinMode(_pin, INPUT_PULLUP);
+  delay(1);
+
+  // First set data line low for a period according to sensor type
+  pinMode(_pin, OUTPUT);
+  digitalWrite(_pin, LOW);
+  switch (_type) {
+    case DHT22:
+    case DHT21:
+      delayMicroseconds(1100); // data sheet says "at least 1ms"
+      break;
+    case DHT11:
+    default:
+      delay(20); // data sheet says at least 18ms, 20ms just to be safe
+      break;
+  }
+
+  uint32_t cycles[80];
+  {
+    // End the start signal by setting data line high for 40 microseconds.
+    pinMode(_pin, INPUT_PULLUP);
+
+    // Delay a moment to let sensor pull data line low.
+    delayMicroseconds(pullTime);
+
+    // Now start reading the data line to get the value from the DHT sensor.
+
+    // Turn off interrupts temporarily because the next sections
+    // are timing critical and we don't want any interruptions.
+    InterruptLock lock;
+
+    // First expect a low signal for ~80 microseconds followed by a high signal
+    // for ~80 microseconds again.
+    if (expectPulse(LOW) == TIMEOUT) {
+      DEBUG_PRINTLN(F("DHT timeout waiting for start signal low pulse."));
+      _lastresult = false;
+      return _lastresult;
+    }
+    if (expectPulse(HIGH) == TIMEOUT) {
+      DEBUG_PRINTLN(F("DHT timeout waiting for start signal high pulse."));
+      _lastresult = false;
+      return _lastresult;
+    }
+
+    // Now read the 40 bits sent by the sensor.  Each bit is sent as a 50
+    // microsecond low pulse followed by a variable length high pulse.  If the
+    // high pulse is ~28 microseconds then it's a 0 and if it's ~70 microseconds
+    // then it's a 1.  We measure the cycle count of the initial 50us low pulse
+    // and use that to compare to the cycle count of the high pulse to determine
+    // if the bit is a 0 (high state cycle count < low state cycle count), or a
+    // 1 (high state cycle count > low state cycle count). Note that for speed
+    // all the pulses are read into a array and then examined in a later step.
+    for (int i = 0; i < 80; i += 2) {
+      cycles[i] = expectPulse(LOW);
+      cycles[i + 1] = expectPulse(HIGH);
+    }
+  } // Timing critical code is now complete.
+
+  // Inspect pulses and determine which ones are 0 (high state cycle count < low
+  // state cycle count), or 1 (high state cycle count > low state cycle count).
+  for (int i = 0; i < 40; ++i) {
+    uint32_t lowCycles = cycles[2 * i];
+    uint32_t highCycles = cycles[2 * i + 1];
+    if ((lowCycles == TIMEOUT) || (highCycles == TIMEOUT)) {
+      DEBUG_PRINTLN(F("DHT timeout waiting for pulse."));
+      _lastresult = false;
+      return _lastresult;
+    }
+    data[i / 8] <<= 1;
+    // Now compare the low and high cycle times to see if the bit is a 0 or 1.
+    if (highCycles > lowCycles) {
+      // High cycles are greater than 50us low cycle count, must be a 1.
+      data[i / 8] |= 1;
+    }
+    // Else high cycles are less than (or equal to, a weird case) the 50us low
+    // cycle count so this must be a zero.  Nothing needs to be changed in the
+    // stored data.
+  }
+
+  DEBUG_PRINTLN(F("Received from DHT:"));
+  DEBUG_PRINT(data[0], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[1], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[2], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[3], HEX);
+  DEBUG_PRINT(F(", "));
+  DEBUG_PRINT(data[4], HEX);
+  DEBUG_PRINT(F(" =? "));
+  DEBUG_PRINTLN((data[0] + data[1] + data[2] + data[3]) & 0xFF, HEX);
+
+  // Check we read 40 bits and that the checksum matches.
+  if (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) {
+    _lastresult = true;
+    return _lastresult;
+  } else {
+    DEBUG_PRINTLN(F("DHT checksum failure!"));
+    _lastresult = false;
+    return _lastresult;
+  }
+}
+
+// Expect the signal line to be at the specified level for a period of time and
+// return a count of loop cycles spent at that level (this cycle count can be
+// used to compare the relative time of two pulses).  If more than a millisecond
+// ellapses without the level changing then the call fails with a 0 response.
+// This is adapted from Arduino's pulseInLong function (which is only available
+// in the very latest IDE versions):
+//   https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring_pulse.c
+uint32_t DHT::expectPulse(bool level) {
+// F_CPU is not be known at compile time on platforms such as STM32F103.
+// The preprocessor seems to evaluate it to zero in that case.
+#if (F_CPU > 16000000L) || (F_CPU == 0L)
+  uint32_t count = 0;
+#else
+  uint16_t count = 0; // To work fast enough on slower AVR boards
+#endif
+// On AVR platforms use direct GPIO port access as it's much faster and better
+// for catching pulses that are 10's of microseconds in length:
+#ifdef __AVR
+  uint8_t portState = level ? _bit : 0;
+  while ((*portInputRegister(_port) & _bit) == portState) {
+    if (count++ >= _maxcycles) {
+      return TIMEOUT; // Exceeded timeout, fail.
+    }
+  }
+// Otherwise fall back to using digitalRead (this seems to be necessary on
+// ESP8266 right now, perhaps bugs in direct port access functions?).
+#else
+  while (digitalRead(_pin) == level) {
+    if (count++ >= _maxcycles) {
+      return TIMEOUT; // Exceeded timeout, fail.
+    }
+  }
+#endif
+
+  return count;
+}

+ 109 - 0
.pio/libdeps/esp32dev/DHT sensor library/DHT.h

@@ -0,0 +1,109 @@
+/*!
+ *  @file DHT.h
+ *
+ *  This is a library for DHT series of low cost temperature/humidity sensors.
+ *
+ *  You must have Adafruit Unified Sensor Library library installed to use this
+ * class.
+ *
+ *  Adafruit invests time and resources providing this open source code,
+ *  please support Adafruit andopen-source hardware by purchasing products
+ *  from Adafruit!
+ *
+ *  Written by Adafruit Industries.
+ *
+ *  MIT license, all text above must be included in any redistribution
+ */
+
+#ifndef DHT_H
+#define DHT_H
+
+#include "Arduino.h"
+
+/* Uncomment to enable printing out nice debug messages. */
+// #define DHT_DEBUG
+
+#define DEBUG_PRINTER                                    \
+  Serial /**< Define where debug output will be printed. \
+          */
+
+/* Setup debug printing macros. */
+#ifdef DHT_DEBUG
+#define DEBUG_PRINT(...) \
+  { DEBUG_PRINTER.print(__VA_ARGS__); }
+#define DEBUG_PRINTLN(...) \
+  { DEBUG_PRINTER.println(__VA_ARGS__); }
+#else
+#define DEBUG_PRINT(...) \
+  {} /**< Debug Print Placeholder if Debug is disabled */
+#define DEBUG_PRINTLN(...) \
+  {} /**< Debug Print Line Placeholder if Debug is disabled */
+#endif
+
+/* Define types of sensors. */
+static const uint8_t DHT11{11};  /**< DHT TYPE 11 */
+static const uint8_t DHT12{12};  /**< DHY TYPE 12 */
+static const uint8_t DHT21{21};  /**< DHT TYPE 21 */
+static const uint8_t DHT22{22};  /**< DHT TYPE 22 */
+static const uint8_t AM2301{21}; /**< AM2301 */
+
+#if defined(TARGET_NAME) && (TARGET_NAME == ARDUINO_NANO33BLE)
+#ifndef microsecondsToClockCycles
+/*!
+ * As of 7 Sep 2020 the Arduino Nano 33 BLE boards do not have
+ * microsecondsToClockCycles defined.
+ */
+#define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L))
+#endif
+#endif
+
+/*!
+ *  @brief  Class that stores state and functions for DHT
+ */
+class DHT {
+ public:
+  DHT(uint8_t pin, uint8_t type, uint8_t count = 6);
+  void begin(uint8_t usec = 55);
+  float readTemperature(bool S = false, bool force = false);
+  float convertCtoF(float);
+  float convertFtoC(float);
+  float computeHeatIndex(bool isFahrenheit = true);
+  float computeHeatIndex(float temperature, float percentHumidity,
+                         bool isFahrenheit = true);
+  float readHumidity(bool force = false);
+  bool read(bool force = false);
+
+ private:
+  uint8_t data[5];
+  uint8_t _pin, _type;
+#ifdef __AVR
+  // Use direct GPIO access on an 8-bit AVR so keep track of the port and
+  // bitmask for the digital pin connected to the DHT.  Other platforms will use
+  // digitalRead.
+  uint8_t _bit, _port;
+#endif
+  uint32_t _lastreadtime, _maxcycles;
+  bool _lastresult;
+  uint8_t pullTime; // Time (in usec) to pull up data line before reading
+
+  uint32_t expectPulse(bool level);
+};
+
+/*!
+ *  @brief  Class that defines Interrupt Lock Avaiability
+ */
+class InterruptLock {
+ public:
+  InterruptLock() {
+#if !defined(ARDUINO_ARCH_NRF52)
+    noInterrupts();
+#endif
+  }
+  ~InterruptLock() {
+#if !defined(ARDUINO_ARCH_NRF52)
+    interrupts();
+#endif
+  }
+};
+
+#endif

+ 243 - 0
.pio/libdeps/esp32dev/DHT sensor library/DHT_U.cpp

@@ -0,0 +1,243 @@
+/*!
+ *  @file DHT_U.cpp
+ *
+ *  Temperature & Humidity Unified Sensor Library
+ *
+ *  This is a library for DHT series of low cost temperature/humidity sensors.
+ *
+ *  You must have Adafruit Unified Sensor Library library installed to use this
+ * class.
+ *
+ *  Adafruit invests time and resources providing this open source code,
+ *  please support Adafruit andopen-source hardware by purchasing products
+ *  from Adafruit!
+ */
+#include "DHT_U.h"
+
+/*!
+ *  @brief  Instantiates a new DHT_Unified class
+ *  @param  pin
+ *          pin number that sensor is connected
+ *  @param  type
+ *          type of sensor
+ *  @param  count
+ *          number of sensors
+ *  @param  tempSensorId
+ *          temperature sensor id
+ *  @param  humiditySensorId
+ *          humidity sensor id
+ */
+DHT_Unified::DHT_Unified(uint8_t pin, uint8_t type, uint8_t count,
+                         int32_t tempSensorId, int32_t humiditySensorId)
+    : _dht(pin, type, count),
+      _type(type),
+      _temp(this, tempSensorId),
+      _humidity(this, humiditySensorId) {}
+
+/*!
+ *  @brief  Setup sensor (calls begin on It)
+ */
+void DHT_Unified::begin() {
+  _dht.begin();
+}
+
+/*!
+ *  @brief  Sets sensor name
+ *  @param  sensor
+ *          Sensor that will be set
+ */
+void DHT_Unified::setName(sensor_t* sensor) {
+  switch (_type) {
+    case DHT11:
+      strncpy(sensor->name, "DHT11", sizeof(sensor->name) - 1);
+      break;
+    case DHT12:
+      strncpy(sensor->name, "DHT12", sizeof(sensor->name) - 1);
+      break;
+    case DHT21:
+      strncpy(sensor->name, "DHT21", sizeof(sensor->name) - 1);
+      break;
+    case DHT22:
+      strncpy(sensor->name, "DHT22", sizeof(sensor->name) - 1);
+      break;
+    default:
+      // TODO: Perhaps this should be an error?  However main DHT library
+      // doesn't enforce restrictions on the sensor type value.  Pick a generic
+      // name for now.
+      strncpy(sensor->name, "DHT?", sizeof(sensor->name) - 1);
+      break;
+  }
+  sensor->name[sizeof(sensor->name) - 1] = 0;
+}
+
+/*!
+ *  @brief  Sets Minimum Delay Value
+ *  @param  sensor
+ *          Sensor that will be set
+ */
+void DHT_Unified::setMinDelay(sensor_t* sensor) {
+  switch (_type) {
+    case DHT11:
+      sensor->min_delay = 1000000L; // 1 second (in microseconds)
+      break;
+    case DHT12:
+      sensor->min_delay = 2000000L; // 2 second (in microseconds)
+      break;
+    case DHT21:
+      sensor->min_delay = 2000000L; // 2 seconds (in microseconds)
+      break;
+    case DHT22:
+      sensor->min_delay = 2000000L; // 2 seconds (in microseconds)
+      break;
+    default:
+      // Default to slowest sample rate in case of unknown type.
+      sensor->min_delay = 2000000L; // 2 seconds (in microseconds)
+      break;
+  }
+}
+
+/*!
+ *  @brief  Instantiates a new DHT_Unified Temperature Class
+ *  @param  parent
+ *          Parent Sensor
+ *  @param  id
+ *          Sensor id
+ */
+DHT_Unified::Temperature::Temperature(DHT_Unified* parent, int32_t id)
+    : _parent(parent), _id(id) {}
+
+/*!
+ *  @brief  Reads the sensor and returns the data as a sensors_event_t
+ *  @param  event
+ *  @return always returns true
+ */
+bool DHT_Unified::Temperature::getEvent(sensors_event_t* event) {
+  // Clear event definition.
+  memset(event, 0, sizeof(sensors_event_t));
+  // Populate sensor reading values.
+  event->version = sizeof(sensors_event_t);
+  event->sensor_id = _id;
+  event->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
+  event->timestamp = millis();
+  event->temperature = _parent->_dht.readTemperature();
+
+  return true;
+}
+
+/*!
+ *  @brief  Provides the sensor_t data for this sensor
+ *  @param  sensor
+ */
+void DHT_Unified::Temperature::getSensor(sensor_t* sensor) {
+  // Clear sensor definition.
+  memset(sensor, 0, sizeof(sensor_t));
+  // Set sensor name.
+  _parent->setName(sensor);
+  // Set version and ID
+  sensor->version = DHT_SENSOR_VERSION;
+  sensor->sensor_id = _id;
+  // Set type and characteristics.
+  sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE;
+  _parent->setMinDelay(sensor);
+  switch (_parent->_type) {
+    case DHT11:
+      sensor->max_value = 50.0F;
+      sensor->min_value = 0.0F;
+      sensor->resolution = 2.0F;
+      break;
+    case DHT12:
+      sensor->max_value = 60.0F;
+      sensor->min_value = -20.0F;
+      sensor->resolution = 0.5F;
+      break;
+    case DHT21:
+      sensor->max_value = 80.0F;
+      sensor->min_value = -40.0F;
+      sensor->resolution = 0.1F;
+      break;
+    case DHT22:
+      sensor->max_value = 125.0F;
+      sensor->min_value = -40.0F;
+      sensor->resolution = 0.1F;
+      break;
+    default:
+      // Unknown type, default to 0.
+      sensor->max_value = 0.0F;
+      sensor->min_value = 0.0F;
+      sensor->resolution = 0.0F;
+      break;
+  }
+}
+
+/*!
+ *  @brief  Instantiates a new DHT_Unified Humidity Class
+ *  @param  parent
+ *          Parent Sensor
+ *  @param  id
+ *          Sensor id
+ */
+DHT_Unified::Humidity::Humidity(DHT_Unified* parent, int32_t id)
+    : _parent(parent), _id(id) {}
+
+/*!
+ *  @brief  Reads the sensor and returns the data as a sensors_event_t
+ *  @param  event
+ *  @return always returns true
+ */
+bool DHT_Unified::Humidity::getEvent(sensors_event_t* event) {
+  // Clear event definition.
+  memset(event, 0, sizeof(sensors_event_t));
+  // Populate sensor reading values.
+  event->version = sizeof(sensors_event_t);
+  event->sensor_id = _id;
+  event->type = SENSOR_TYPE_RELATIVE_HUMIDITY;
+  event->timestamp = millis();
+  event->relative_humidity = _parent->_dht.readHumidity();
+
+  return true;
+}
+
+/*!
+ *  @brief  Provides the sensor_t data for this sensor
+ *  @param  sensor
+ */
+void DHT_Unified::Humidity::getSensor(sensor_t* sensor) {
+  // Clear sensor definition.
+  memset(sensor, 0, sizeof(sensor_t));
+  // Set sensor name.
+  _parent->setName(sensor);
+  // Set version and ID
+  sensor->version = DHT_SENSOR_VERSION;
+  sensor->sensor_id = _id;
+  // Set type and characteristics.
+  sensor->type = SENSOR_TYPE_RELATIVE_HUMIDITY;
+  _parent->setMinDelay(sensor);
+  switch (_parent->_type) {
+    case DHT11:
+      sensor->max_value = 80.0F;
+      sensor->min_value = 20.0F;
+      sensor->resolution = 5.0F;
+      break;
+    case DHT12:
+      sensor->max_value = 95.0F;
+      sensor->min_value = 20.0F;
+      sensor->resolution = 5.0F;
+      break;
+    case DHT21:
+      sensor->max_value = 100.0F;
+      sensor->min_value = 0.0F;
+      sensor->resolution = 0.1F;
+      break;
+    case DHT22:
+      sensor->max_value = 100.0F;
+      sensor->min_value = 0.0F;
+      sensor->resolution = 0.1F;
+      break;
+    default:
+      // Unknown type, default to 0.
+      sensor->max_value = 0.0F;
+      sensor->min_value = 0.0F;
+      sensor->resolution = 0.0F;
+      break;
+  }
+}

+ 105 - 0
.pio/libdeps/esp32dev/DHT sensor library/DHT_U.h

@@ -0,0 +1,105 @@
+/*!
+ *  @file DHT_U.h
+ *
+ *  DHT Temperature & Humidity Unified Sensor Library<Paste>
+ *
+ *  Adafruit invests time and resources providing this open source code,
+ *  please support Adafruit andopen-source hardware by purchasing products
+ *  from Adafruit!
+ *
+ *  Written by Tony DiCola (Adafruit Industries) 2014.
+ *
+ *  MIT license, all text above must be included in any redistribution
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a copy
+ *  of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ *  furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef DHT_U_H
+#define DHT_U_H
+
+#include <Adafruit_Sensor.h>
+#include <DHT.h>
+
+#define DHT_SENSOR_VERSION 1 /**< Sensor Version */
+
+/*!
+ *  @brief  Class that stores state and functions for interacting with
+ * DHT_Unified.
+ */
+class DHT_Unified {
+ public:
+  DHT_Unified(uint8_t pin, uint8_t type, uint8_t count = 6,
+              int32_t tempSensorId = -1, int32_t humiditySensorId = -1);
+  void begin();
+
+  /*!
+   *  @brief  Class that stores state and functions about Temperature
+   */
+  class Temperature : public Adafruit_Sensor {
+   public:
+    Temperature(DHT_Unified* parent, int32_t id);
+    bool getEvent(sensors_event_t* event);
+    void getSensor(sensor_t* sensor);
+
+   private:
+    DHT_Unified* _parent;
+    int32_t _id;
+  };
+
+  /*!
+   *  @brief  Class that stores state and functions about Humidity
+   */
+  class Humidity : public Adafruit_Sensor {
+   public:
+    Humidity(DHT_Unified* parent, int32_t id);
+    bool getEvent(sensors_event_t* event);
+    void getSensor(sensor_t* sensor);
+
+   private:
+    DHT_Unified* _parent;
+    int32_t _id;
+  };
+
+  /*!
+   *  @brief  Returns temperature stored in _temp
+   *  @return Temperature value
+   */
+  Temperature temperature() {
+    return _temp;
+  }
+
+  /*!
+   *  @brief  Returns humidity stored in _humidity
+   *  @return Humidity value
+   */
+  Humidity humidity() {
+    return _humidity;
+  }
+
+ private:
+  DHT _dht;
+  uint8_t _type;
+  Temperature _temp;
+  Humidity _humidity;
+
+  void setName(sensor_t* sensor);
+  void setMinDelay(sensor_t* sensor);
+};
+
+#endif

+ 58 - 0
.pio/libdeps/esp32dev/DHT sensor library/README.md

@@ -0,0 +1,58 @@
+# DHT sensor library [![Build Status](https://github.com/adafruit/DHT-sensor-library/workflows/Arduino%20Library%20CI/badge.svg)](https://github.com/adafruit/DHT-sensor-library/actions)
+
+## Description
+
+An Arduino library for the DHT series of low-cost temperature/humidity sensors.
+
+You can find DHT tutorials [here](https://learn.adafruit.com/dht).
+
+# Dependencies
+ * [Adafruit Unified Sensor Driver](https://github.com/adafruit/Adafruit_Sensor)
+
+# Contributing
+
+Contributions are welcome!  Not only you’ll encourage the development of the library, but you’ll also learn how to best use the library and probably some C++ too
+
+Please read our [Code of Conduct](https://github.com/adafruit/DHT-sensor-library/blob/master/CODE_OF_CONDUCT.md>)
+before contributing to help this project stay welcoming.
+
+## Documentation and doxygen
+Documentation is produced by doxygen. Contributions should include documentation for any new code added.
+
+Some examples of how to use doxygen can be found in these guide pages:
+
+https://learn.adafruit.com/the-well-automated-arduino-library/doxygen
+
+https://learn.adafruit.com/the-well-automated-arduino-library/doxygen-tips
+
+Written by Adafruit Industries based on work by:
+
+ * T. DiCola
+ * P. Y. Dragon
+ * L. Fried
+ * J. Hoffmann
+ * M. Kooijman
+ * J. M. Dana
+ * S. Conaway
+ * S. IJskes
+ * T. Forbes
+ * B. C
+ * T. J Myers
+ * L. Sørup
+ * per1234
+ * O. Duffy
+ * matthiasdanner
+ * J. Lim
+ * G. Ambrozio
+ * chelmi
+ * adams13x13
+ * Spacefish
+ * I. Scheller
+ * C. Miller
+ * 7eggert
+
+
+MIT license, check license.txt for more information
+All text above must be included in any redistribution
+
+To install, use the Arduino Library Manager and search for "DHT sensor library" and install the library.

+ 127 - 0
.pio/libdeps/esp32dev/DHT sensor library/code-of-conduct.md

@@ -0,0 +1,127 @@
+# Adafruit Community Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as
+contributors and leaders pledge to making participation in our project and
+our community a harassment-free experience for everyone, regardless of age, body
+size, disability, ethnicity, gender identity and expression, level or type of
+experience, education, socio-economic status, nationality, personal appearance,
+race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+We are committed to providing a friendly, safe and welcoming environment for
+all.
+
+Examples of behavior that contributes to creating a positive environment
+include:
+
+* Be kind and courteous to others
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Collaborating with other community members
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and sexual attention or advances
+* The use of inappropriate images, including in a community member's avatar
+* The use of inappropriate language, including in a community member's nickname
+* Any spamming, flaming, baiting or other attention-stealing behavior
+* Excessive or unwelcome helping; answering outside the scope of the question
+  asked
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic
+  address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate
+
+The goal of the standards and moderation guidelines outlined here is to build
+and maintain a respectful community. We ask that you don’t just aim to be
+"technically unimpeachable", but rather try to be your best self. 
+
+We value many things beyond technical expertise, including collaboration and
+supporting others within our community. Providing a positive experience for
+other community members can have a much more significant impact than simply
+providing the correct answer.
+
+## Our Responsibilities
+
+Project leaders are responsible for clarifying the standards of acceptable
+behavior and are expected to take appropriate and fair corrective action in
+response to any instances of unacceptable behavior.
+
+Project leaders have the right and responsibility to remove, edit, or
+reject messages, comments, commits, code, issues, and other contributions
+that are not aligned to this Code of Conduct, or to ban temporarily or
+permanently any community member for other behaviors that they deem
+inappropriate, threatening, offensive, or harmful.
+
+## Moderation
+
+Instances of behaviors that violate the Adafruit Community Code of Conduct
+may be reported by any member of the community. Community members are
+encouraged to report these situations, including situations they witness
+involving other community members.
+
+You may report in the following ways:
+
+In any situation, you may send an email to <support@adafruit.com>.
+
+On the Adafruit Discord, you may send an open message from any channel
+to all Community Helpers by tagging @community helpers. You may also send an
+open message from any channel, or a direct message to @kattni#1507,
+@tannewt#4653, @Dan Halbert#1614, @cater#2442, @sommersoft#0222, or
+@Andon#8175.
+
+Email and direct message reports will be kept confidential.
+
+In situations on Discord where the issue is particularly egregious, possibly
+illegal, requires immediate action, or violates the Discord terms of service,
+you should also report the message directly to Discord.
+
+These are the steps for upholding our community’s standards of conduct.
+
+1. Any member of the community may report any situation that violates the
+Adafruit Community Code of Conduct. All reports will be reviewed and
+investigated.
+2. If the behavior is an egregious violation, the community member who
+committed the violation may be banned immediately, without warning.
+3. Otherwise, moderators will first respond to such behavior with a warning.
+4. Moderators follow a soft "three strikes" policy - the community member may
+be given another chance, if they are receptive to the warning and change their
+behavior.
+5. If the community member is unreceptive or unreasonable when warned by a
+moderator, or the warning goes unheeded, they may be banned for a first or
+second offense. Repeated offenses will result in the community member being
+banned.
+
+## Scope
+
+This Code of Conduct and the enforcement policies listed above apply to all
+Adafruit Community venues. This includes but is not limited to any community
+spaces (both public and private), the entire Adafruit Discord server, and
+Adafruit GitHub repositories. Examples of Adafruit Community spaces include
+but are not limited to meet-ups, audio chats on the Adafruit Discord, or
+interaction at a conference.
+
+This Code of Conduct applies both within project spaces and in public spaces
+when an individual is representing the project or its community. As a community
+member, you are representing our community, and are expected to behave
+accordingly.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 1.4, available at
+<https://www.contributor-covenant.org/version/1/4/code-of-conduct.html>,
+and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html).
+
+For other projects adopting the Adafruit Community Code of
+Conduct, please contact the maintainers of those projects for enforcement.
+If you wish to use this code of conduct for your own project, consider
+explicitly mentioning your moderation policy or making a copy with your
+own moderation policy so as to avoid confusion.

+ 85 - 0
.pio/libdeps/esp32dev/DHT sensor library/examples/DHT_Unified_Sensor/DHT_Unified_Sensor.ino

@@ -0,0 +1,85 @@
+// DHT Temperature & Humidity Sensor
+// Unified Sensor Library Example
+// Written by Tony DiCola for Adafruit Industries
+// Released under an MIT license.
+
+// REQUIRES the following Arduino libraries:
+// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
+// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor
+
+#include <Adafruit_Sensor.h>
+#include <DHT.h>
+#include <DHT_U.h>
+
+#define DHTPIN 2     // Digital pin connected to the DHT sensor 
+// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
+// Pin 15 can work but DHT must be disconnected during program upload.
+
+// Uncomment the type of sensor in use:
+//#define DHTTYPE    DHT11     // DHT 11
+#define DHTTYPE    DHT22     // DHT 22 (AM2302)
+//#define DHTTYPE    DHT21     // DHT 21 (AM2301)
+
+// See guide for details on sensor wiring and usage:
+//   https://learn.adafruit.com/dht/overview
+
+DHT_Unified dht(DHTPIN, DHTTYPE);
+
+uint32_t delayMS;
+
+void setup() {
+  Serial.begin(9600);
+  // Initialize device.
+  dht.begin();
+  Serial.println(F("DHTxx Unified Sensor Example"));
+  // Print temperature sensor details.
+  sensor_t sensor;
+  dht.temperature().getSensor(&sensor);
+  Serial.println(F("------------------------------------"));
+  Serial.println(F("Temperature Sensor"));
+  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
+  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
+  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
+  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("°C"));
+  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("°C"));
+  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("°C"));
+  Serial.println(F("------------------------------------"));
+  // Print humidity sensor details.
+  dht.humidity().getSensor(&sensor);
+  Serial.println(F("Humidity Sensor"));
+  Serial.print  (F("Sensor Type: ")); Serial.println(sensor.name);
+  Serial.print  (F("Driver Ver:  ")); Serial.println(sensor.version);
+  Serial.print  (F("Unique ID:   ")); Serial.println(sensor.sensor_id);
+  Serial.print  (F("Max Value:   ")); Serial.print(sensor.max_value); Serial.println(F("%"));
+  Serial.print  (F("Min Value:   ")); Serial.print(sensor.min_value); Serial.println(F("%"));
+  Serial.print  (F("Resolution:  ")); Serial.print(sensor.resolution); Serial.println(F("%"));
+  Serial.println(F("------------------------------------"));
+  // Set delay between sensor readings based on sensor details.
+  delayMS = sensor.min_delay / 1000;
+}
+
+void loop() {
+  // Delay between measurements.
+  delay(delayMS);
+  // Get temperature event and print its value.
+  sensors_event_t event;
+  dht.temperature().getEvent(&event);
+  if (isnan(event.temperature)) {
+    Serial.println(F("Error reading temperature!"));
+  }
+  else {
+    Serial.print(F("Temperature: "));
+    Serial.print(event.temperature);
+    Serial.println(F("°C"));
+  }
+  // Get humidity event and print its value.
+  dht.humidity().getEvent(&event);
+  if (isnan(event.relative_humidity)) {
+    Serial.println(F("Error reading humidity!"));
+  }
+  else {
+    Serial.print(F("Humidity: "));
+    Serial.print(event.relative_humidity);
+    Serial.println(F("%"));
+  }
+}

+ 74 - 0
.pio/libdeps/esp32dev/DHT sensor library/examples/DHTtester/DHTtester.ino

@@ -0,0 +1,74 @@
+// Example testing sketch for various DHT humidity/temperature sensors
+// Written by ladyada, public domain
+
+// REQUIRES the following Arduino libraries:
+// - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library
+// - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor
+
+#include "DHT.h"
+
+#define DHTPIN 2     // Digital pin connected to the DHT sensor
+// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
+// Pin 15 can work but DHT must be disconnected during program upload.
+
+// Uncomment whatever type you're using!
+//#define DHTTYPE DHT11   // DHT 11
+#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
+//#define DHTTYPE DHT21   // DHT 21 (AM2301)
+
+// Connect pin 1 (on the left) of the sensor to +5V
+// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
+// to 3.3V instead of 5V!
+// Connect pin 2 of the sensor to whatever your DHTPIN is
+// Connect pin 3 (on the right) of the sensor to GROUND (if your sensor has 3 pins)
+// Connect pin 4 (on the right) of the sensor to GROUND and leave the pin 3 EMPTY (if your sensor has 4 pins)
+// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor
+
+// Initialize DHT sensor.
+// Note that older versions of this library took an optional third parameter to
+// tweak the timings for faster processors.  This parameter is no longer needed
+// as the current DHT reading algorithm adjusts itself to work on faster procs.
+DHT dht(DHTPIN, DHTTYPE);
+
+void setup() {
+  Serial.begin(9600);
+  Serial.println(F("DHTxx test!"));
+
+  dht.begin();
+}
+
+void loop() {
+  // Wait a few seconds between measurements.
+  delay(2000);
+
+  // Reading temperature or humidity takes about 250 milliseconds!
+  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
+  float h = dht.readHumidity();
+  // Read temperature as Celsius (the default)
+  float t = dht.readTemperature();
+  // Read temperature as Fahrenheit (isFahrenheit = true)
+  float f = dht.readTemperature(true);
+
+  // Check if any reads failed and exit early (to try again).
+  if (isnan(h) || isnan(t) || isnan(f)) {
+    Serial.println(F("Failed to read from DHT sensor!"));
+    return;
+  }
+
+  // Compute heat index in Fahrenheit (the default)
+  float hif = dht.computeHeatIndex(f, h);
+  // Compute heat index in Celsius (isFahreheit = false)
+  float hic = dht.computeHeatIndex(t, h, false);
+
+  Serial.print(F("Humidity: "));
+  Serial.print(h);
+  Serial.print(F("%  Temperature: "));
+  Serial.print(t);
+  Serial.print(F("°C "));
+  Serial.print(f);
+  Serial.print(F("°F  Heat index: "));
+  Serial.print(hic);
+  Serial.print(F("°C "));
+  Serial.print(hif);
+  Serial.println(F("°F"));
+}

+ 22 - 0
.pio/libdeps/esp32dev/DHT sensor library/keywords.txt

@@ -0,0 +1,22 @@
+###########################################
+# Syntax Coloring Map For DHT-sensor-library
+###########################################
+
+###########################################
+# Datatypes (KEYWORD1)
+###########################################
+
+DHT	KEYWORD1
+
+###########################################
+# Methods and Functions (KEYWORD2)
+###########################################
+
+begin	KEYWORD2
+readTemperature	KEYWORD2
+convertCtoF	KEYWORD2
+convertFtoC	KEYWORD2
+computeHeatIndex	KEYWORD2
+readHumidity	KEYWORD2
+read	KEYWORD2
+

+ 10 - 0
.pio/libdeps/esp32dev/DHT sensor library/library.properties

@@ -0,0 +1,10 @@
+name=DHT sensor library
+version=1.4.7
+author=Adafruit
+maintainer=Adafruit <info@adafruit.com>
+sentence=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors
+paragraph=Arduino library for DHT11, DHT22, etc Temp & Humidity Sensors
+category=Sensors
+url=https://github.com/adafruit/DHT-sensor-library
+architectures=*
+depends=Adafruit Unified Sensor

+ 20 - 0
.pio/libdeps/esp32dev/DHT sensor library/license.txt

@@ -0,0 +1,20 @@
+Copyright (c) 2020 Adafruit Industries
+
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
+OR OTHER DEALINGS IN THE SOFTWARE.

+ 1 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/.piopm

@@ -0,0 +1 @@
+{"type": "library", "name": "LiquidCrystal_I2C", "version": "1.1.4", "spec": {"owner": "marcoschwartz", "id": 576, "name": "LiquidCrystal_I2C", "requirements": null, "uri": null}}

+ 332 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/LiquidCrystal_I2C.cpp

@@ -0,0 +1,332 @@
+// Based on the work by DFRobot
+
+#include "LiquidCrystal_I2C.h"
+#include <inttypes.h>
+#if defined(ARDUINO) && ARDUINO >= 100
+
+#include "Arduino.h"
+
+#define printIIC(args)	Wire.write(args)
+inline size_t LiquidCrystal_I2C::write(uint8_t value) {
+	send(value, Rs);
+	return 1;
+}
+
+#else
+#include "WProgram.h"
+
+#define printIIC(args)	Wire.send(args)
+inline void LiquidCrystal_I2C::write(uint8_t value) {
+	send(value, Rs);
+}
+
+#endif
+#include "Wire.h"
+
+
+
+// When the display powers up, it is configured as follows:
+//
+// 1. Display clear
+// 2. Function set: 
+//    DL = 1; 8-bit interface data 
+//    N = 0; 1-line display 
+//    F = 0; 5x8 dot character font 
+// 3. Display on/off control: 
+//    D = 0; Display off 
+//    C = 0; Cursor off 
+//    B = 0; Blinking off 
+// 4. Entry mode set: 
+//    I/D = 1; Increment by 1
+//    S = 0; No shift 
+//
+// Note, however, that resetting the Arduino doesn't reset the LCD, so we
+// can't assume that its in that state when a sketch starts (and the
+// LiquidCrystal constructor is called).
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows)
+{
+  _Addr = lcd_Addr;
+  _cols = lcd_cols;
+  _rows = lcd_rows;
+  _backlightval = LCD_NOBACKLIGHT;
+}
+
+void LiquidCrystal_I2C::oled_init(){
+  _oled = true;
+	init_priv();
+}
+
+void LiquidCrystal_I2C::init(){
+	init_priv();
+}
+
+void LiquidCrystal_I2C::init_priv()
+{
+	Wire.begin();
+	_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
+	begin(_cols, _rows);  
+}
+
+void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
+	if (lines > 1) {
+		_displayfunction |= LCD_2LINE;
+	}
+	_numlines = lines;
+
+	// for some 1 line displays you can select a 10 pixel high font
+	if ((dotsize != 0) && (lines == 1)) {
+		_displayfunction |= LCD_5x10DOTS;
+	}
+
+	// SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
+	// according to datasheet, we need at least 40ms after power rises above 2.7V
+	// before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
+	delay(50); 
+  
+	// Now we pull both RS and R/W low to begin commands
+	expanderWrite(_backlightval);	// reset expanderand turn backlight off (Bit 8 =1)
+	delay(1000);
+
+  	//put the LCD into 4 bit mode
+	// this is according to the hitachi HD44780 datasheet
+	// figure 24, pg 46
+	
+	  // we start in 8bit mode, try to set 4 bit mode
+   write4bits(0x03 << 4);
+   delayMicroseconds(4500); // wait min 4.1ms
+   
+   // second try
+   write4bits(0x03 << 4);
+   delayMicroseconds(4500); // wait min 4.1ms
+   
+   // third go!
+   write4bits(0x03 << 4); 
+   delayMicroseconds(150);
+   
+   // finally, set to 4-bit interface
+   write4bits(0x02 << 4); 
+
+
+	// set # lines, font size, etc.
+	command(LCD_FUNCTIONSET | _displayfunction);  
+	
+	// turn the display on with no cursor or blinking default
+	_displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
+	display();
+	
+	// clear it off
+	clear();
+	
+	// Initialize to default text direction (for roman languages)
+	_displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
+	
+	// set the entry mode
+	command(LCD_ENTRYMODESET | _displaymode);
+	
+	home();
+  
+}
+
+/********** high level commands, for the user! */
+void LiquidCrystal_I2C::clear(){
+	command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
+	delayMicroseconds(2000);  // this command takes a long time!
+  if (_oled) setCursor(0,0);
+}
+
+void LiquidCrystal_I2C::home(){
+	command(LCD_RETURNHOME);  // set cursor position to zero
+	delayMicroseconds(2000);  // this command takes a long time!
+}
+
+void LiquidCrystal_I2C::setCursor(uint8_t col, uint8_t row){
+	int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+	if ( row > _numlines ) {
+		row = _numlines-1;    // we count rows starting w/0
+	}
+	command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
+}
+
+// Turn the display on/off (quickly)
+void LiquidCrystal_I2C::noDisplay() {
+	_displaycontrol &= ~LCD_DISPLAYON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal_I2C::display() {
+	_displaycontrol |= LCD_DISPLAYON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turns the underline cursor on/off
+void LiquidCrystal_I2C::noCursor() {
+	_displaycontrol &= ~LCD_CURSORON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal_I2C::cursor() {
+	_displaycontrol |= LCD_CURSORON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turn on and off the blinking cursor
+void LiquidCrystal_I2C::noBlink() {
+	_displaycontrol &= ~LCD_BLINKON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal_I2C::blink() {
+	_displaycontrol |= LCD_BLINKON;
+	command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// These commands scroll the display without changing the RAM
+void LiquidCrystal_I2C::scrollDisplayLeft(void) {
+	command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
+}
+void LiquidCrystal_I2C::scrollDisplayRight(void) {
+	command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
+}
+
+// This is for text that flows Left to Right
+void LiquidCrystal_I2C::leftToRight(void) {
+	_displaymode |= LCD_ENTRYLEFT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This is for text that flows Right to Left
+void LiquidCrystal_I2C::rightToLeft(void) {
+	_displaymode &= ~LCD_ENTRYLEFT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'right justify' text from the cursor
+void LiquidCrystal_I2C::autoscroll(void) {
+	_displaymode |= LCD_ENTRYSHIFTINCREMENT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'left justify' text from the cursor
+void LiquidCrystal_I2C::noAutoscroll(void) {
+	_displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
+	command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// Allows us to fill the first 8 CGRAM locations
+// with custom characters
+void LiquidCrystal_I2C::createChar(uint8_t location, uint8_t charmap[]) {
+	location &= 0x7; // we only have 8 locations 0-7
+	command(LCD_SETCGRAMADDR | (location << 3));
+	for (int i=0; i<8; i++) {
+		write(charmap[i]);
+	}
+}
+
+//createChar with PROGMEM input
+void LiquidCrystal_I2C::createChar(uint8_t location, const char *charmap) {
+	location &= 0x7; // we only have 8 locations 0-7
+	command(LCD_SETCGRAMADDR | (location << 3));
+	for (int i=0; i<8; i++) {
+	    	write(pgm_read_byte_near(charmap++));
+	}
+}
+
+// Turn the (optional) backlight off/on
+void LiquidCrystal_I2C::noBacklight(void) {
+	_backlightval=LCD_NOBACKLIGHT;
+	expanderWrite(0);
+}
+
+void LiquidCrystal_I2C::backlight(void) {
+	_backlightval=LCD_BACKLIGHT;
+	expanderWrite(0);
+}
+
+
+
+/*********** mid level commands, for sending data/cmds */
+
+inline void LiquidCrystal_I2C::command(uint8_t value) {
+	send(value, 0);
+}
+
+
+/************ low level data pushing commands **********/
+
+// write either command or data
+void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode) {
+	uint8_t highnib=value&0xf0;
+	uint8_t lownib=(value<<4)&0xf0;
+       write4bits((highnib)|mode);
+	write4bits((lownib)|mode); 
+}
+
+void LiquidCrystal_I2C::write4bits(uint8_t value) {
+	expanderWrite(value);
+	pulseEnable(value);
+}
+
+void LiquidCrystal_I2C::expanderWrite(uint8_t _data){                                        
+	Wire.beginTransmission(_Addr);
+	printIIC((int)(_data) | _backlightval);
+	Wire.endTransmission();   
+}
+
+void LiquidCrystal_I2C::pulseEnable(uint8_t _data){
+	expanderWrite(_data | En);	// En high
+	delayMicroseconds(1);		// enable pulse must be >450ns
+	
+	expanderWrite(_data & ~En);	// En low
+	delayMicroseconds(50);		// commands need > 37us to settle
+} 
+
+
+// Alias functions
+
+void LiquidCrystal_I2C::cursor_on(){
+	cursor();
+}
+
+void LiquidCrystal_I2C::cursor_off(){
+	noCursor();
+}
+
+void LiquidCrystal_I2C::blink_on(){
+	blink();
+}
+
+void LiquidCrystal_I2C::blink_off(){
+	noBlink();
+}
+
+void LiquidCrystal_I2C::load_custom_character(uint8_t char_num, uint8_t *rows){
+		createChar(char_num, rows);
+}
+
+void LiquidCrystal_I2C::setBacklight(uint8_t new_val){
+	if(new_val){
+		backlight();		// turn backlight on
+	}else{
+		noBacklight();		// turn backlight off
+	}
+}
+
+void LiquidCrystal_I2C::printstr(const char c[]){
+	//This function is not identical to the function used for "real" I2C displays
+	//it's here so the user sketch doesn't have to be changed 
+	print(c);
+}
+
+
+// unsupported API functions
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+void LiquidCrystal_I2C::off(){}
+void LiquidCrystal_I2C::on(){}
+void LiquidCrystal_I2C::setDelay (int cmdDelay,int charDelay) {}
+uint8_t LiquidCrystal_I2C::status(){return 0;}
+uint8_t LiquidCrystal_I2C::keypad (){return 0;}
+uint8_t LiquidCrystal_I2C::init_bargraph(uint8_t graphtype){return 0;}
+void LiquidCrystal_I2C::draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end){}
+void LiquidCrystal_I2C::draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_row_end){}
+void LiquidCrystal_I2C::setContrast(uint8_t new_val){}
+#pragma GCC diagnostic pop
+	

+ 131 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/LiquidCrystal_I2C.h

@@ -0,0 +1,131 @@
+//YWROBOT
+#ifndef LiquidCrystal_I2C_h
+#define LiquidCrystal_I2C_h
+
+#include <inttypes.h>
+#include "Print.h" 
+#include <Wire.h>
+
+// commands
+#define LCD_CLEARDISPLAY 0x01
+#define LCD_RETURNHOME 0x02
+#define LCD_ENTRYMODESET 0x04
+#define LCD_DISPLAYCONTROL 0x08
+#define LCD_CURSORSHIFT 0x10
+#define LCD_FUNCTIONSET 0x20
+#define LCD_SETCGRAMADDR 0x40
+#define LCD_SETDDRAMADDR 0x80
+
+// flags for display entry mode
+#define LCD_ENTRYRIGHT 0x00
+#define LCD_ENTRYLEFT 0x02
+#define LCD_ENTRYSHIFTINCREMENT 0x01
+#define LCD_ENTRYSHIFTDECREMENT 0x00
+
+// flags for display on/off control
+#define LCD_DISPLAYON 0x04
+#define LCD_DISPLAYOFF 0x00
+#define LCD_CURSORON 0x02
+#define LCD_CURSOROFF 0x00
+#define LCD_BLINKON 0x01
+#define LCD_BLINKOFF 0x00
+
+// flags for display/cursor shift
+#define LCD_DISPLAYMOVE 0x08
+#define LCD_CURSORMOVE 0x00
+#define LCD_MOVERIGHT 0x04
+#define LCD_MOVELEFT 0x00
+
+// flags for function set
+#define LCD_8BITMODE 0x10
+#define LCD_4BITMODE 0x00
+#define LCD_2LINE 0x08
+#define LCD_1LINE 0x00
+#define LCD_5x10DOTS 0x04
+#define LCD_5x8DOTS 0x00
+
+// flags for backlight control
+#define LCD_BACKLIGHT 0x08
+#define LCD_NOBACKLIGHT 0x00
+
+#define En B00000100  // Enable bit
+#define Rw B00000010  // Read/Write bit
+#define Rs B00000001  // Register select bit
+
+class LiquidCrystal_I2C : public Print {
+public:
+  LiquidCrystal_I2C(uint8_t lcd_Addr,uint8_t lcd_cols,uint8_t lcd_rows);
+  void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS );
+  void clear();
+  void home();
+  void noDisplay();
+  void display();
+  void noBlink();
+  void blink();
+  void noCursor();
+  void cursor();
+  void scrollDisplayLeft();
+  void scrollDisplayRight();
+  void printLeft();
+  void printRight();
+  void leftToRight();
+  void rightToLeft();
+  void shiftIncrement();
+  void shiftDecrement();
+  void noBacklight();
+  void backlight();
+  void autoscroll();
+  void noAutoscroll(); 
+  void createChar(uint8_t, uint8_t[]);
+  void createChar(uint8_t location, const char *charmap);
+  // Example: 	const char bell[8] PROGMEM = {B00100,B01110,B01110,B01110,B11111,B00000,B00100,B00000};
+  
+  void setCursor(uint8_t, uint8_t); 
+#if defined(ARDUINO) && ARDUINO >= 100
+  virtual size_t write(uint8_t);
+#else
+  virtual void write(uint8_t);
+#endif
+  void command(uint8_t);
+  void init();
+  void oled_init();
+
+////compatibility API function aliases
+void blink_on();						// alias for blink()
+void blink_off();       					// alias for noBlink()
+void cursor_on();      	 					// alias for cursor()
+void cursor_off();      					// alias for noCursor()
+void setBacklight(uint8_t new_val);				// alias for backlight() and nobacklight()
+void load_custom_character(uint8_t char_num, uint8_t *rows);	// alias for createChar()
+void printstr(const char[]);
+
+////Unsupported API functions (not implemented in this library)
+uint8_t status();
+void setContrast(uint8_t new_val);
+uint8_t keypad();
+void setDelay(int,int);
+void on();
+void off();
+uint8_t init_bargraph(uint8_t graphtype);
+void draw_horizontal_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end);
+void draw_vertical_graph(uint8_t row, uint8_t column, uint8_t len,  uint8_t pixel_col_end);
+	 
+
+private:
+  void init_priv();
+  void send(uint8_t, uint8_t);
+  void write4bits(uint8_t);
+  void expanderWrite(uint8_t);
+  void pulseEnable(uint8_t);
+  uint8_t _Addr;
+  uint8_t _displayfunction;
+  uint8_t _displaycontrol;
+  uint8_t _displaymode;
+  uint8_t _numlines;
+  bool _oled = false;
+  uint8_t _cols;
+  uint8_t _rows;
+  uint8_t _backlightval;
+};
+
+#endif

+ 5 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/README.md

@@ -0,0 +1,5 @@
+# LiquidCrystal_I2C
+
+LiquidCrystal Arduino library for the DFRobot I2C LCD displays
+
+**This library is no longer actively maintained, I only put it here so everyone can access it via the Arduino library manger. If you would like to take the role of the maintainer/owner of the library, please send me a message!**

+ 70 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/examples/CustomChars/CustomChars.pde

@@ -0,0 +1,70 @@
+//YWROBOT
+//Compatible with the Arduino IDE 1.0
+//Library version:1.1
+#include <Wire.h>
+#include <LiquidCrystal_I2C.h>
+
+#if defined(ARDUINO) && ARDUINO >= 100
+#define printByte(args)  write(args);
+#else
+#define printByte(args)  print(args,BYTE);
+#endif
+
+uint8_t bell[8]  = {0x4,0xe,0xe,0xe,0x1f,0x0,0x4};
+uint8_t note[8]  = {0x2,0x3,0x2,0xe,0x1e,0xc,0x0};
+uint8_t clock[8] = {0x0,0xe,0x15,0x17,0x11,0xe,0x0};
+uint8_t heart[8] = {0x0,0xa,0x1f,0x1f,0xe,0x4,0x0};
+uint8_t duck[8]  = {0x0,0xc,0x1d,0xf,0xf,0x6,0x0};
+uint8_t check[8] = {0x0,0x1,0x3,0x16,0x1c,0x8,0x0};
+uint8_t cross[8] = {0x0,0x1b,0xe,0x4,0xe,0x1b,0x0};
+uint8_t retarrow[8] = {	0x1,0x1,0x5,0x9,0x1f,0x8,0x4};
+  
+LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
+
+void setup()
+{
+  lcd.init();                      // initialize the lcd 
+  lcd.backlight();
+  
+  lcd.createChar(0, bell);
+  lcd.createChar(1, note);
+  lcd.createChar(2, clock);
+  lcd.createChar(3, heart);
+  lcd.createChar(4, duck);
+  lcd.createChar(5, check);
+  lcd.createChar(6, cross);
+  lcd.createChar(7, retarrow);
+  lcd.home();
+  
+  lcd.print("Hello world...");
+  lcd.setCursor(0, 1);
+  lcd.print(" i ");
+  lcd.printByte(3);
+  lcd.print(" arduinos!");
+  delay(5000);
+  displayKeyCodes();
+  
+}
+
+// display all keycodes
+void displayKeyCodes(void) {
+  uint8_t i = 0;
+  while (1) {
+    lcd.clear();
+    lcd.print("Codes 0x"); lcd.print(i, HEX);
+    lcd.print("-0x"); lcd.print(i+15, HEX);
+    lcd.setCursor(0, 1);
+    for (int j=0; j<16; j++) {
+      lcd.printByte(i+j);
+    }
+    i+=16;
+    
+    delay(4000);
+  }
+}
+
+void loop()
+{
+
+}
+

+ 26 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/examples/HelloWorld/HelloWorld.pde

@@ -0,0 +1,26 @@
+//YWROBOT
+//Compatible with the Arduino IDE 1.0
+//Library version:1.1
+#include <LiquidCrystal_I2C.h>
+
+LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
+
+void setup()
+{
+  lcd.init();                      // initialize the lcd 
+  // Print a message to the LCD.
+  lcd.backlight();
+  lcd.setCursor(3,0);
+  lcd.print("Hello, world!");
+  lcd.setCursor(2,1);
+  lcd.print("Ywrobot Arduino!");
+   lcd.setCursor(0,2);
+  lcd.print("Arduino LCM IIC 2004");
+   lcd.setCursor(2,3);
+  lcd.print("Power By Ec-yuan!");
+}
+
+
+void loop()
+{
+}

+ 34 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/examples/SerialDisplay/SerialDisplay.pde

@@ -0,0 +1,34 @@
+/*
+ * Displays text sent over the serial port (e.g. from the Serial Monitor) on
+ * an attached LCD.
+ * YWROBOT
+ *Compatible with the Arduino IDE 1.0
+ *Library version:1.1
+ */
+#include <Wire.h> 
+#include <LiquidCrystal_I2C.h>
+
+LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display
+
+void setup()
+{
+  lcd.init();                      // initialize the lcd 
+  lcd.backlight();
+  Serial.begin(9600);
+}
+
+void loop()
+{
+  // when characters arrive over the serial port...
+  if (Serial.available()) {
+    // wait a bit for the entire message to arrive
+    delay(100);
+    // clear the screen
+    lcd.clear();
+    // read all the available characters
+    while (Serial.available() > 0) {
+      // display each character to the LCD
+      lcd.write(Serial.read());
+    }
+  }
+}

+ 46 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/keywords.txt

@@ -0,0 +1,46 @@
+###########################################
+# Syntax Coloring Map For LiquidCrystal_I2C
+###########################################
+
+###########################################
+# Datatypes (KEYWORD1)
+###########################################
+
+LiquidCrystal_I2C	KEYWORD1
+
+###########################################
+# Methods and Functions (KEYWORD2)
+###########################################
+init	KEYWORD2
+begin	KEYWORD2
+clear	KEYWORD2
+home	KEYWORD2
+noDisplay	KEYWORD2
+display	KEYWORD2
+noBlink	KEYWORD2
+blink	KEYWORD2
+noCursor	KEYWORD2
+cursor	KEYWORD2
+scrollDisplayLeft	KEYWORD2
+scrollDisplayRight	KEYWORD2
+leftToRight	KEYWORD2
+rightToLeft	KEYWORD2
+shiftIncrement	KEYWORD2
+shiftDecrement	KEYWORD2
+noBacklight	KEYWORD2
+backlight	KEYWORD2
+autoscroll	KEYWORD2
+noAutoscroll	KEYWORD2
+createChar	KEYWORD2
+setCursor	KEYWORD2
+print	KEYWORD2
+blink_on	KEYWORD2
+blink_off	KEYWORD2
+cursor_on	KEYWORD2
+cursor_off	KEYWORD2
+setBacklight	KEYWORD2
+load_custom_character	KEYWORD2
+printstr	KEYWORD2
+###########################################
+# Constants (LITERAL1)
+###########################################

+ 15 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/library.json

@@ -0,0 +1,15 @@
+{
+    "name": "LiquidCrystal_I2C",
+    "keywords": "LCD, liquidcrystal, I2C",
+    "description": "A library for DFRobot I2C LCD displays",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/marcoschwartz/LiquidCrystal_I2C.git"
+    },
+    "frameworks": "arduino",
+    "platforms": [
+        "atmelavr",
+        "espressif8266"
+    ],
+    "version": "1.1.4"
+}

+ 9 - 0
.pio/libdeps/esp32dev/LiquidCrystal_I2C/library.properties

@@ -0,0 +1,9 @@
+name=LiquidCrystal_I2C
+version=1.1.4
+author=Frank de Brabander
+maintainer=Marco Schwartz <marcolivier.schwartz@gmail.com>
+sentence=A library for I2C LCD displays.
+paragraph= The library allows to control I2C displays with functions extremely similar to LiquidCrystal library. THIS LIBRARY MIGHT NOT BE COMPATIBLE WITH EXISTING SKETCHES.
+category=Display
+url=https://github.com/marcoschwartz/LiquidCrystal_I2C
+architectures=avr

+ 5 - 0
.pio/libdeps/esp32dev/PubSubClient/.gitignore

@@ -0,0 +1,5 @@
+tests/bin
+.pioenvs
+.piolibdeps
+.clang_complete
+.gcc-flags.json

+ 1 - 0
.pio/libdeps/esp32dev/PubSubClient/.piopm

@@ -0,0 +1 @@
+{"type": "library", "name": "PubSubClient", "version": "2.8.0", "spec": {"owner": "knolleary", "id": 89, "name": "PubSubClient", "requirements": null, "uri": null}}

+ 7 - 0
.pio/libdeps/esp32dev/PubSubClient/.travis.yml

@@ -0,0 +1,7 @@
+sudo: false
+language: cpp
+compiler:
+  - g++
+script: cd tests && make && make test
+os:
+  - linux

+ 85 - 0
.pio/libdeps/esp32dev/PubSubClient/CHANGES.txt

@@ -0,0 +1,85 @@
+2.8
+   * Add setBufferSize() to override MQTT_MAX_PACKET_SIZE
+   * Add setKeepAlive() to override MQTT_KEEPALIVE
+   * Add setSocketTimeout() to overide MQTT_SOCKET_TIMEOUT
+   * Added check to prevent subscribe/unsubscribe to empty topics
+   * Declare wifi mode prior to connect in ESP example
+   * Use `strnlen` to avoid overruns
+   * Support pre-connected Client objects
+
+2.7
+   * Fix remaining-length handling to prevent buffer overrun
+   * Add large-payload API - beginPublish/write/publish/endPublish
+   * Add yield call to improve reliability on ESP
+   * Add Clean Session flag to connect options
+   * Add ESP32 support for functional callback signature
+   * Various other fixes
+
+2.4
+   * Add MQTT_SOCKET_TIMEOUT to prevent it blocking indefinitely
+     whilst waiting for inbound data
+   * Fixed return code when publishing >256 bytes
+
+2.3
+   * Add publish(topic,payload,retained) function
+
+2.2
+   * Change code layout to match Arduino Library reqs
+
+2.1
+   * Add MAX_TRANSFER_SIZE def to chunk messages if needed
+   * Reject topic/payloads that exceed MQTT_MAX_PACKET_SIZE
+
+2.0
+   * Add (and default to) MQTT 3.1.1 support
+   * Fix PROGMEM handling for Intel Galileo/ESP8266
+   * Add overloaded constructors for convenience
+   * Add chainable setters for server/callback/client/stream
+   * Add state function to return connack return code
+
+1.9
+   * Do not split MQTT packets over multiple calls to _client->write()
+   * API change: All constructors now require an instance of Client
+      to be passed in.
+   * Fixed example to match 1.8 api changes - dpslwk
+   * Added username/password support - WilHall
+   * Added publish_P - publishes messages from PROGMEM - jobytaffey
+
+1.8
+    * KeepAlive interval is configurable in PubSubClient.h
+    * Maximum packet size is configurable in PubSubClient.h
+    * API change: Return boolean rather than int from various functions
+    * API change: Length parameter in message callback changed
+       from int to unsigned int
+    * Various internal tidy-ups around types
+1.7
+    * Improved keepalive handling
+    * Updated to the Arduino-1.0 API
+1.6
+    * Added the ability to publish a retained message
+
+1.5
+    * Added default constructor
+    * Fixed compile error when used with arduino-0021 or later
+
+1.4
+    * Fixed connection lost handling
+
+1.3
+    * Fixed packet reading bug in PubSubClient.readPacket
+
+1.2
+    * Fixed compile error when used with arduino-0016 or later
+
+
+1.1
+    * Reduced size of library
+    * Added support for Will messages
+    * Clarified licensing - see LICENSE.txt
+
+
+1.0
+    * Only Quality of Service (QOS) 0 messaging is supported
+    * The maximum message size, including header, is 128 bytes
+    * The keepalive interval is set to 30 seconds
+    * No support for Will messages

+ 20 - 0
.pio/libdeps/esp32dev/PubSubClient/LICENSE.txt

@@ -0,0 +1,20 @@
+Copyright (c) 2008-2020 Nicholas O'Leary
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ 50 - 0
.pio/libdeps/esp32dev/PubSubClient/README.md

@@ -0,0 +1,50 @@
+# Arduino Client for MQTT
+
+This library provides a client for doing simple publish/subscribe messaging with
+a server that supports MQTT.
+
+## Examples
+
+The library comes with a number of example sketches. See File > Examples > PubSubClient
+within the Arduino application.
+
+Full API documentation is available here: https://pubsubclient.knolleary.net
+
+## Limitations
+
+ - It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.
+ - The maximum message size, including header, is **256 bytes** by default. This
+   is configurable via `MQTT_MAX_PACKET_SIZE` in `PubSubClient.h` or can be changed
+   by calling `PubSubClient::setBufferSize(size)`.
+ - The keepalive interval is set to 15 seconds by default. This is configurable
+   via `MQTT_KEEPALIVE` in `PubSubClient.h` or can be changed by calling
+   `PubSubClient::setKeepAlive(keepAlive)`.
+ - The client uses MQTT 3.1.1 by default. It can be changed to use MQTT 3.1 by
+   changing value of `MQTT_VERSION` in `PubSubClient.h`.
+
+
+## Compatible Hardware
+
+The library uses the Arduino Ethernet Client api for interacting with the
+underlying network hardware. This means it Just Works with a growing number of
+boards and shields, including:
+
+ - Arduino Ethernet
+ - Arduino Ethernet Shield
+ - Arduino YUN – use the included `YunClient` in place of `EthernetClient`, and
+   be sure to do a `Bridge.begin()` first
+ - Arduino WiFi Shield - if you want to send packets > 90 bytes with this shield,
+   enable the `MQTT_MAX_TRANSFER_SIZE` define in `PubSubClient.h`.
+ - Sparkfun WiFly Shield – [library](https://github.com/dpslwk/WiFly)
+ - TI CC3000 WiFi - [library](https://github.com/sparkfun/SFE_CC3000_Library)
+ - Intel Galileo/Edison
+ - ESP8266
+ - ESP32
+
+The library cannot currently be used with hardware based on the ENC28J60 chip –
+such as the Nanode or the Nuelectronics Ethernet Shield. For those, there is an
+[alternative library](https://github.com/njh/NanodeMQTT) available.
+
+## License
+
+This code is released under the MIT License.

+ 43 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_auth/mqtt_auth.ino

@@ -0,0 +1,43 @@
+/*
+ Basic MQTT example with Authentication
+
+  - connects to an MQTT server, providing username
+    and password
+  - publishes "hello world" to the topic "outTopic"
+  - subscribes to the topic "inTopic"
+*/
+
+#include <SPI.h>
+#include <Ethernet.h>
+#include <PubSubClient.h>
+
+// Update these with values suitable for your network.
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
+IPAddress ip(172, 16, 0, 100);
+IPAddress server(172, 16, 0, 2);
+
+void callback(char* topic, byte* payload, unsigned int length) {
+  // handle message arrived
+}
+
+EthernetClient ethClient;
+PubSubClient client(server, 1883, callback, ethClient);
+
+void setup()
+{
+  Ethernet.begin(mac, ip);
+  // Note - the default maximum packet size is 128 bytes. If the
+  // combined length of clientId, username and password exceed this use the
+  // following to increase the buffer size:
+  // client.setBufferSize(255);
+  
+  if (client.connect("arduinoClient", "testuser", "testpass")) {
+    client.publish("outTopic","hello world");
+    client.subscribe("inTopic");
+  }
+}
+
+void loop()
+{
+  client.loop();
+}

+ 77 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_basic/mqtt_basic.ino

@@ -0,0 +1,77 @@
+/*
+ Basic MQTT example
+
+ This sketch demonstrates the basic capabilities of the library.
+ It connects to an MQTT server then:
+  - publishes "hello world" to the topic "outTopic"
+  - subscribes to the topic "inTopic", printing out any messages
+    it receives. NB - it assumes the received payloads are strings not binary
+
+ It will reconnect to the server if the connection is lost using a blocking
+ reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
+ achieve the same result without blocking the main loop.
+ 
+*/
+
+#include <SPI.h>
+#include <Ethernet.h>
+#include <PubSubClient.h>
+
+// Update these with values suitable for your network.
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
+IPAddress ip(172, 16, 0, 100);
+IPAddress server(172, 16, 0, 2);
+
+void callback(char* topic, byte* payload, unsigned int length) {
+  Serial.print("Message arrived [");
+  Serial.print(topic);
+  Serial.print("] ");
+  for (int i=0;i<length;i++) {
+    Serial.print((char)payload[i]);
+  }
+  Serial.println();
+}
+
+EthernetClient ethClient;
+PubSubClient client(ethClient);
+
+void reconnect() {
+  // Loop until we're reconnected
+  while (!client.connected()) {
+    Serial.print("Attempting MQTT connection...");
+    // Attempt to connect
+    if (client.connect("arduinoClient")) {
+      Serial.println("connected");
+      // Once connected, publish an announcement...
+      client.publish("outTopic","hello world");
+      // ... and resubscribe
+      client.subscribe("inTopic");
+    } else {
+      Serial.print("failed, rc=");
+      Serial.print(client.state());
+      Serial.println(" try again in 5 seconds");
+      // Wait 5 seconds before retrying
+      delay(5000);
+    }
+  }
+}
+
+void setup()
+{
+  Serial.begin(57600);
+
+  client.setServer(server, 1883);
+  client.setCallback(callback);
+
+  Ethernet.begin(mac, ip);
+  // Allow the hardware to sort itself out
+  delay(1500);
+}
+
+void loop()
+{
+  if (!client.connected()) {
+    reconnect();
+  }
+  client.loop();
+}

+ 129 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_esp8266/mqtt_esp8266.ino

@@ -0,0 +1,129 @@
+/*
+ Basic ESP8266 MQTT example
+ This sketch demonstrates the capabilities of the pubsub library in combination
+ with the ESP8266 board/library.
+ It connects to an MQTT server then:
+  - publishes "hello world" to the topic "outTopic" every two seconds
+  - subscribes to the topic "inTopic", printing out any messages
+    it receives. NB - it assumes the received payloads are strings not binary
+  - If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
+    else switch it off
+ It will reconnect to the server if the connection is lost using a blocking
+ reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
+ achieve the same result without blocking the main loop.
+ To install the ESP8266 board, (using Arduino 1.6.4+):
+  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
+       http://arduino.esp8266.com/stable/package_esp8266com_index.json
+  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
+  - Select your ESP8266 in "Tools -> Board"
+*/
+
+#include <ESP8266WiFi.h>
+#include <PubSubClient.h>
+
+// Update these with values suitable for your network.
+
+const char* ssid = "........";
+const char* password = "........";
+const char* mqtt_server = "broker.mqtt-dashboard.com";
+
+WiFiClient espClient;
+PubSubClient client(espClient);
+unsigned long lastMsg = 0;
+#define MSG_BUFFER_SIZE	(50)
+char msg[MSG_BUFFER_SIZE];
+int value = 0;
+
+void setup_wifi() {
+
+  delay(10);
+  // We start by connecting to a WiFi network
+  Serial.println();
+  Serial.print("Connecting to ");
+  Serial.println(ssid);
+
+  WiFi.mode(WIFI_STA);
+  WiFi.begin(ssid, password);
+
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+  }
+
+  randomSeed(micros());
+
+  Serial.println("");
+  Serial.println("WiFi connected");
+  Serial.println("IP address: ");
+  Serial.println(WiFi.localIP());
+}
+
+void callback(char* topic, byte* payload, unsigned int length) {
+  Serial.print("Message arrived [");
+  Serial.print(topic);
+  Serial.print("] ");
+  for (int i = 0; i < length; i++) {
+    Serial.print((char)payload[i]);
+  }
+  Serial.println();
+
+  // Switch on the LED if an 1 was received as first character
+  if ((char)payload[0] == '1') {
+    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
+    // but actually the LED is on; this is because
+    // it is active low on the ESP-01)
+  } else {
+    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
+  }
+
+}
+
+void reconnect() {
+  // Loop until we're reconnected
+  while (!client.connected()) {
+    Serial.print("Attempting MQTT connection...");
+    // Create a random client ID
+    String clientId = "ESP8266Client-";
+    clientId += String(random(0xffff), HEX);
+    // Attempt to connect
+    if (client.connect(clientId.c_str())) {
+      Serial.println("connected");
+      // Once connected, publish an announcement...
+      client.publish("outTopic", "hello world");
+      // ... and resubscribe
+      client.subscribe("inTopic");
+    } else {
+      Serial.print("failed, rc=");
+      Serial.print(client.state());
+      Serial.println(" try again in 5 seconds");
+      // Wait 5 seconds before retrying
+      delay(5000);
+    }
+  }
+}
+
+void setup() {
+  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
+  Serial.begin(115200);
+  setup_wifi();
+  client.setServer(mqtt_server, 1883);
+  client.setCallback(callback);
+}
+
+void loop() {
+
+  if (!client.connected()) {
+    reconnect();
+  }
+  client.loop();
+
+  unsigned long now = millis();
+  if (now - lastMsg > 2000) {
+    lastMsg = now;
+    ++value;
+    snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
+    Serial.print("Publish message: ");
+    Serial.println(msg);
+    client.publish("outTopic", msg);
+  }
+}

+ 179 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_large_message/mqtt_large_message.ino

@@ -0,0 +1,179 @@
+/*
+ Long message ESP8266 MQTT example
+
+ This sketch demonstrates sending arbitrarily large messages in combination
+ with the ESP8266 board/library.
+
+ It connects to an MQTT server then:
+  - publishes "hello world" to the topic "outTopic"
+  - subscribes to the topic "greenBottles/#", printing out any messages
+    it receives. NB - it assumes the received payloads are strings not binary
+  - If the sub-topic is a number, it publishes a "greenBottles/lyrics" message
+    with a payload consisting of the lyrics to "10 green bottles", replacing
+    10 with the number given in the sub-topic.
+
+ It will reconnect to the server if the connection is lost using a blocking
+ reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
+ achieve the same result without blocking the main loop.
+
+ To install the ESP8266 board, (using Arduino 1.6.4+):
+  - Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
+       http://arduino.esp8266.com/stable/package_esp8266com_index.json
+  - Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
+  - Select your ESP8266 in "Tools -> Board"
+
+*/
+
+#include <ESP8266WiFi.h>
+#include <PubSubClient.h>
+
+// Update these with values suitable for your network.
+
+const char* ssid = "........";
+const char* password = "........";
+const char* mqtt_server = "broker.mqtt-dashboard.com";
+
+WiFiClient espClient;
+PubSubClient client(espClient);
+long lastMsg = 0;
+char msg[50];
+int value = 0;
+
+void setup_wifi() {
+
+  delay(10);
+  // We start by connecting to a WiFi network
+  Serial.println();
+  Serial.print("Connecting to ");
+  Serial.println(ssid);
+
+  WiFi.begin(ssid, password);
+
+  while (WiFi.status() != WL_CONNECTED) {
+    delay(500);
+    Serial.print(".");
+  }
+
+  randomSeed(micros());
+
+  Serial.println("");
+  Serial.println("WiFi connected");
+  Serial.println("IP address: ");
+  Serial.println(WiFi.localIP());
+}
+
+void callback(char* topic, byte* payload, unsigned int length) {
+  Serial.print("Message arrived [");
+  Serial.print(topic);
+  Serial.print("] ");
+  for (int i = 0; i < length; i++) {
+    Serial.print((char)payload[i]);
+  }
+  Serial.println();
+
+  // Find out how many bottles we should generate lyrics for
+  String topicStr(topic);
+  int bottleCount = 0; // assume no bottles unless we correctly parse a value from the topic
+  if (topicStr.indexOf('/') >= 0) {
+    // The topic includes a '/', we'll try to read the number of bottles from just after that
+    topicStr.remove(0, topicStr.indexOf('/')+1);
+    // Now see if there's a number of bottles after the '/'
+    bottleCount = topicStr.toInt();
+  }
+
+  if (bottleCount > 0) {
+    // Work out how big our resulting message will be
+    int msgLen = 0;
+    for (int i = bottleCount; i > 0; i--) {
+      String numBottles(i);
+      msgLen += 2*numBottles.length();
+      if (i == 1) {
+        msgLen += 2*String(" green bottle, standing on the wall\n").length();
+      } else {
+        msgLen += 2*String(" green bottles, standing on the wall\n").length();
+      }
+      msgLen += String("And if one green bottle should accidentally fall\nThere'll be ").length();
+      switch (i) {
+      case 1:
+        msgLen += String("no green bottles, standing on the wall\n\n").length();
+        break;
+      case 2:
+        msgLen += String("1 green bottle, standing on the wall\n\n").length();
+        break;
+      default:
+        numBottles = i-1;
+        msgLen += numBottles.length();
+        msgLen += String(" green bottles, standing on the wall\n\n").length();
+        break;
+      };
+    }
+  
+    // Now we can start to publish the message
+    client.beginPublish("greenBottles/lyrics", msgLen, false);
+    for (int i = bottleCount; i > 0; i--) {
+      for (int j = 0; j < 2; j++) {
+        client.print(i);
+        if (i == 1) {
+          client.print(" green bottle, standing on the wall\n");
+        } else {
+          client.print(" green bottles, standing on the wall\n");
+        }
+      }
+      client.print("And if one green bottle should accidentally fall\nThere'll be ");
+      switch (i) {
+      case 1:
+        client.print("no green bottles, standing on the wall\n\n");
+        break;
+      case 2:
+        client.print("1 green bottle, standing on the wall\n\n");
+        break;
+      default:
+        client.print(i-1);
+        client.print(" green bottles, standing on the wall\n\n");
+        break;
+      };
+    }
+    // Now we're done!
+    client.endPublish();
+  }
+}
+
+void reconnect() {
+  // Loop until we're reconnected
+  while (!client.connected()) {
+    Serial.print("Attempting MQTT connection...");
+    // Create a random client ID
+    String clientId = "ESP8266Client-";
+    clientId += String(random(0xffff), HEX);
+    // Attempt to connect
+    if (client.connect(clientId.c_str())) {
+      Serial.println("connected");
+      // Once connected, publish an announcement...
+      client.publish("outTopic", "hello world");
+      // ... and resubscribe
+      client.subscribe("greenBottles/#");
+    } else {
+      Serial.print("failed, rc=");
+      Serial.print(client.state());
+      Serial.println(" try again in 5 seconds");
+      // Wait 5 seconds before retrying
+      delay(5000);
+    }
+  }
+}
+
+void setup() {
+  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
+  Serial.begin(115200);
+  setup_wifi();
+  client.setServer(mqtt_server, 1883);
+  client.setCallback(callback);
+}
+
+void loop() {
+
+  if (!client.connected()) {
+    reconnect();
+  }
+  client.loop();
+}

+ 60 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_publish_in_callback/mqtt_publish_in_callback.ino

@@ -0,0 +1,60 @@
+/*
+ Publishing in the callback
+
+  - connects to an MQTT server
+  - subscribes to the topic "inTopic"
+  - when a message is received, republishes it to "outTopic"
+
+  This example shows how to publish messages within the
+  callback function. The callback function header needs to
+  be declared before the PubSubClient constructor and the
+  actual callback defined afterwards.
+  This ensures the client reference in the callback function
+  is valid.
+
+*/
+
+#include <SPI.h>
+#include <Ethernet.h>
+#include <PubSubClient.h>
+
+// Update these with values suitable for your network.
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
+IPAddress ip(172, 16, 0, 100);
+IPAddress server(172, 16, 0, 2);
+
+// Callback function header
+void callback(char* topic, byte* payload, unsigned int length);
+
+EthernetClient ethClient;
+PubSubClient client(server, 1883, callback, ethClient);
+
+// Callback function
+void callback(char* topic, byte* payload, unsigned int length) {
+  // In order to republish this payload, a copy must be made
+  // as the orignal payload buffer will be overwritten whilst
+  // constructing the PUBLISH packet.
+
+  // Allocate the correct amount of memory for the payload copy
+  byte* p = (byte*)malloc(length);
+  // Copy the payload to the new buffer
+  memcpy(p,payload,length);
+  client.publish("outTopic", p, length);
+  // Free the memory
+  free(p);
+}
+
+void setup()
+{
+
+  Ethernet.begin(mac, ip);
+  if (client.connect("arduinoClient")) {
+    client.publish("outTopic","hello world");
+    client.subscribe("inTopic");
+  }
+}
+
+void loop()
+{
+  client.loop();
+}

+ 67 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_reconnect_nonblocking/mqtt_reconnect_nonblocking.ino

@@ -0,0 +1,67 @@
+/*
+ Reconnecting MQTT example - non-blocking
+
+ This sketch demonstrates how to keep the client connected
+ using a non-blocking reconnect function. If the client loses
+ its connection, it attempts to reconnect every 5 seconds
+ without blocking the main loop.
+
+*/
+
+#include <SPI.h>
+#include <Ethernet.h>
+#include <PubSubClient.h>
+
+// Update these with values suitable for your hardware/network.
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
+IPAddress ip(172, 16, 0, 100);
+IPAddress server(172, 16, 0, 2);
+
+void callback(char* topic, byte* payload, unsigned int length) {
+  // handle message arrived
+}
+
+EthernetClient ethClient;
+PubSubClient client(ethClient);
+
+long lastReconnectAttempt = 0;
+
+boolean reconnect() {
+  if (client.connect("arduinoClient")) {
+    // Once connected, publish an announcement...
+    client.publish("outTopic","hello world");
+    // ... and resubscribe
+    client.subscribe("inTopic");
+  }
+  return client.connected();
+}
+
+void setup()
+{
+  client.setServer(server, 1883);
+  client.setCallback(callback);
+
+  Ethernet.begin(mac, ip);
+  delay(1500);
+  lastReconnectAttempt = 0;
+}
+
+
+void loop()
+{
+  if (!client.connected()) {
+    long now = millis();
+    if (now - lastReconnectAttempt > 5000) {
+      lastReconnectAttempt = now;
+      // Attempt to reconnect
+      if (reconnect()) {
+        lastReconnectAttempt = 0;
+      }
+    }
+  } else {
+    // Client connected
+
+    client.loop();
+  }
+
+}

+ 57 - 0
.pio/libdeps/esp32dev/PubSubClient/examples/mqtt_stream/mqtt_stream.ino

@@ -0,0 +1,57 @@
+/*
+ Example of using a Stream object to store the message payload
+
+ Uses SRAM library: https://github.com/ennui2342/arduino-sram
+ but could use any Stream based class such as SD
+
+  - connects to an MQTT server
+  - publishes "hello world" to the topic "outTopic"
+  - subscribes to the topic "inTopic"
+*/
+
+#include <SPI.h>
+#include <Ethernet.h>
+#include <PubSubClient.h>
+#include <SRAM.h>
+
+// Update these with values suitable for your network.
+byte mac[]    = {  0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
+IPAddress ip(172, 16, 0, 100);
+IPAddress server(172, 16, 0, 2);
+
+SRAM sram(4, SRAM_1024);
+
+void callback(char* topic, byte* payload, unsigned int length) {
+  sram.seek(1);
+
+  // do something with the message
+  for(uint8_t i=0; i<length; i++) {
+    Serial.write(sram.read());
+  }
+  Serial.println();
+
+  // Reset position for the next message to be stored
+  sram.seek(1);
+}
+
+EthernetClient ethClient;
+PubSubClient client(server, 1883, callback, ethClient, sram);
+
+void setup()
+{
+  Ethernet.begin(mac, ip);
+  if (client.connect("arduinoClient")) {
+    client.publish("outTopic","hello world");
+    client.subscribe("inTopic");
+  }
+
+  sram.begin();
+  sram.seek(1);
+
+  Serial.begin(9600);
+}
+
+void loop()
+{
+  client.loop();
+}

+ 36 - 0
.pio/libdeps/esp32dev/PubSubClient/keywords.txt

@@ -0,0 +1,36 @@
+#######################################
+# Syntax Coloring Map For PubSubClient
+#######################################
+
+#######################################
+# Datatypes (KEYWORD1)
+#######################################
+
+PubSubClient	KEYWORD1
+
+#######################################
+# Methods and Functions (KEYWORD2)
+#######################################
+
+connect 	KEYWORD2
+disconnect 	KEYWORD2
+publish 	KEYWORD2
+publish_P 	KEYWORD2
+beginPublish 	KEYWORD2
+endPublish 	KEYWORD2
+write	 	KEYWORD2
+subscribe 	KEYWORD2
+unsubscribe 	KEYWORD2
+loop 	KEYWORD2
+connected 	KEYWORD2
+setServer	KEYWORD2
+setCallback	KEYWORD2
+setClient	KEYWORD2
+setStream	KEYWORD2
+setKeepAlive 	KEYWORD2
+setBufferSize 	KEYWORD2
+setSocketTimeout 	KEYWORD2
+
+#######################################
+# Constants (LITERAL1)
+#######################################

+ 18 - 0
.pio/libdeps/esp32dev/PubSubClient/library.json

@@ -0,0 +1,18 @@
+{
+    "name": "PubSubClient",
+    "keywords": "ethernet, mqtt, m2m, iot",
+    "description": "A client library for MQTT messaging. MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.",
+    "repository": {
+        "type": "git",
+        "url": "https://github.com/knolleary/pubsubclient.git"
+    },
+    "version": "2.8",
+    "exclude": "tests",
+    "examples": "examples/*/*.ino",
+    "frameworks": "arduino",
+    "platforms": [
+        "atmelavr",
+        "espressif8266",
+        "espressif32"
+    ]
+}

+ 9 - 0
.pio/libdeps/esp32dev/PubSubClient/library.properties

@@ -0,0 +1,9 @@
+name=PubSubClient
+version=2.8
+author=Nick O'Leary <nick.oleary@gmail.com>
+maintainer=Nick O'Leary <nick.oleary@gmail.com>
+sentence=A client library for MQTT messaging.
+paragraph=MQTT is a lightweight messaging protocol ideal for small devices. This library allows you to send and receive MQTT messages. It supports the latest MQTT 3.1.1 protocol and can be configured to use the older MQTT 3.1 if needed. It supports all Arduino Ethernet Client compatible hardware, including the Intel Galileo/Edison, ESP8266 and TI CC3000.
+category=Communication
+url=http://pubsubclient.knolleary.net
+architectures=*

+ 769 - 0
.pio/libdeps/esp32dev/PubSubClient/src/PubSubClient.cpp

@@ -0,0 +1,769 @@
+/*
+
+  PubSubClient.cpp - A simple client for MQTT.
+  Nick O'Leary
+  http://knolleary.net
+*/
+
+#include "PubSubClient.h"
+#include "Arduino.h"
+
+PubSubClient::PubSubClient() {
+    this->_state = MQTT_DISCONNECTED;
+    this->_client = NULL;
+    this->stream = NULL;
+    setCallback(NULL);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+
+PubSubClient::PubSubClient(Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(addr, port);
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(addr,port);
+    setClient(client);
+    setStream(stream);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(addr, port);
+    setCallback(callback);
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(addr,port);
+    setCallback(callback);
+    setClient(client);
+    setStream(stream);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(ip, port);
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(ip,port);
+    setClient(client);
+    setStream(stream);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(ip, port);
+    setCallback(callback);
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(ip,port);
+    setCallback(callback);
+    setClient(client);
+    setStream(stream);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+
+PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(domain,port);
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(domain,port);
+    setClient(client);
+    setStream(stream);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(domain,port);
+    setCallback(callback);
+    setClient(client);
+    this->stream = NULL;
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
+    this->_state = MQTT_DISCONNECTED;
+    setServer(domain,port);
+    setCallback(callback);
+    setClient(client);
+    setStream(stream);
+    this->bufferSize = 0;
+    setBufferSize(MQTT_MAX_PACKET_SIZE);
+    setKeepAlive(MQTT_KEEPALIVE);
+    setSocketTimeout(MQTT_SOCKET_TIMEOUT);
+}
+
+PubSubClient::~PubSubClient() {
+  free(this->buffer);
+}
+
+boolean PubSubClient::connect(const char *id) {
+    return connect(id,NULL,NULL,0,0,0,0,1);
+}
+
+boolean PubSubClient::connect(const char *id, const char *user, const char *pass) {
+    return connect(id,user,pass,0,0,0,0,1);
+}
+
+boolean PubSubClient::connect(const char *id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
+    return connect(id,NULL,NULL,willTopic,willQos,willRetain,willMessage,1);
+}
+
+boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage) {
+    return connect(id,user,pass,willTopic,willQos,willRetain,willMessage,1);
+}
+
+boolean PubSubClient::connect(const char *id, const char *user, const char *pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession) {
+    if (!connected()) {
+        int result = 0;
+
+
+        if(_client->connected()) {
+            result = 1;
+        } else {
+            if (domain != NULL) {
+                result = _client->connect(this->domain, this->port);
+            } else {
+                result = _client->connect(this->ip, this->port);
+            }
+        }
+
+        if (result == 1) {
+            nextMsgId = 1;
+            // Leave room in the buffer for header and variable length field
+            uint16_t length = MQTT_MAX_HEADER_SIZE;
+            unsigned int j;
+
+#if MQTT_VERSION == MQTT_VERSION_3_1
+            uint8_t d[9] = {0x00,0x06,'M','Q','I','s','d','p', MQTT_VERSION};
+#define MQTT_HEADER_VERSION_LENGTH 9
+#elif MQTT_VERSION == MQTT_VERSION_3_1_1
+            uint8_t d[7] = {0x00,0x04,'M','Q','T','T',MQTT_VERSION};
+#define MQTT_HEADER_VERSION_LENGTH 7
+#endif
+            for (j = 0;j<MQTT_HEADER_VERSION_LENGTH;j++) {
+                this->buffer[length++] = d[j];
+            }
+
+            uint8_t v;
+            if (willTopic) {
+                v = 0x04|(willQos<<3)|(willRetain<<5);
+            } else {
+                v = 0x00;
+            }
+            if (cleanSession) {
+                v = v|0x02;
+            }
+
+            if(user != NULL) {
+                v = v|0x80;
+
+                if(pass != NULL) {
+                    v = v|(0x80>>1);
+                }
+            }
+            this->buffer[length++] = v;
+
+            this->buffer[length++] = ((this->keepAlive) >> 8);
+            this->buffer[length++] = ((this->keepAlive) & 0xFF);
+
+            CHECK_STRING_LENGTH(length,id)
+            length = writeString(id,this->buffer,length);
+            if (willTopic) {
+                CHECK_STRING_LENGTH(length,willTopic)
+                length = writeString(willTopic,this->buffer,length);
+                CHECK_STRING_LENGTH(length,willMessage)
+                length = writeString(willMessage,this->buffer,length);
+            }
+
+            if(user != NULL) {
+                CHECK_STRING_LENGTH(length,user)
+                length = writeString(user,this->buffer,length);
+                if(pass != NULL) {
+                    CHECK_STRING_LENGTH(length,pass)
+                    length = writeString(pass,this->buffer,length);
+                }
+            }
+
+            write(MQTTCONNECT,this->buffer,length-MQTT_MAX_HEADER_SIZE);
+
+            lastInActivity = lastOutActivity = millis();
+
+            while (!_client->available()) {
+                unsigned long t = millis();
+                if (t-lastInActivity >= ((int32_t) this->socketTimeout*1000UL)) {
+                    _state = MQTT_CONNECTION_TIMEOUT;
+                    _client->stop();
+                    return false;
+                }
+            }
+            uint8_t llen;
+            uint32_t len = readPacket(&llen);
+
+            if (len == 4) {
+                if (buffer[3] == 0) {
+                    lastInActivity = millis();
+                    pingOutstanding = false;
+                    _state = MQTT_CONNECTED;
+                    return true;
+                } else {
+                    _state = buffer[3];
+                }
+            }
+            _client->stop();
+        } else {
+            _state = MQTT_CONNECT_FAILED;
+        }
+        return false;
+    }
+    return true;
+}
+
+// reads a byte into result
+boolean PubSubClient::readByte(uint8_t * result) {
+   uint32_t previousMillis = millis();
+   while(!_client->available()) {
+     yield();
+     uint32_t currentMillis = millis();
+     if(currentMillis - previousMillis >= ((int32_t) this->socketTimeout * 1000)){
+       return false;
+     }
+   }
+   *result = _client->read();
+   return true;
+}
+
+// reads a byte into result[*index] and increments index
+boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
+  uint16_t current_index = *index;
+  uint8_t * write_address = &(result[current_index]);
+  if(readByte(write_address)){
+    *index = current_index + 1;
+    return true;
+  }
+  return false;
+}
+
+uint32_t PubSubClient::readPacket(uint8_t* lengthLength) {
+    uint16_t len = 0;
+    if(!readByte(this->buffer, &len)) return 0;
+    bool isPublish = (this->buffer[0]&0xF0) == MQTTPUBLISH;
+    uint32_t multiplier = 1;
+    uint32_t length = 0;
+    uint8_t digit = 0;
+    uint16_t skip = 0;
+    uint32_t start = 0;
+
+    do {
+        if (len == 5) {
+            // Invalid remaining length encoding - kill the connection
+            _state = MQTT_DISCONNECTED;
+            _client->stop();
+            return 0;
+        }
+        if(!readByte(&digit)) return 0;
+        this->buffer[len++] = digit;
+        length += (digit & 127) * multiplier;
+        multiplier <<=7; //multiplier *= 128
+    } while ((digit & 128) != 0);
+    *lengthLength = len-1;
+
+    if (isPublish) {
+        // Read in topic length to calculate bytes to skip over for Stream writing
+        if(!readByte(this->buffer, &len)) return 0;
+        if(!readByte(this->buffer, &len)) return 0;
+        skip = (this->buffer[*lengthLength+1]<<8)+this->buffer[*lengthLength+2];
+        start = 2;
+        if (this->buffer[0]&MQTTQOS1) {
+            // skip message id
+            skip += 2;
+        }
+    }
+    uint32_t idx = len;
+
+    for (uint32_t i = start;i<length;i++) {
+        if(!readByte(&digit)) return 0;
+        if (this->stream) {
+            if (isPublish && idx-*lengthLength-2>skip) {
+                this->stream->write(digit);
+            }
+        }
+
+        if (len < this->bufferSize) {
+            this->buffer[len] = digit;
+            len++;
+        }
+        idx++;
+    }
+
+    if (!this->stream && idx > this->bufferSize) {
+        len = 0; // This will cause the packet to be ignored.
+    }
+    return len;
+}
+
+boolean PubSubClient::loop() {
+    if (connected()) {
+        unsigned long t = millis();
+        if ((t - lastInActivity > this->keepAlive*1000UL) || (t - lastOutActivity > this->keepAlive*1000UL)) {
+            if (pingOutstanding) {
+                this->_state = MQTT_CONNECTION_TIMEOUT;
+                _client->stop();
+                return false;
+            } else {
+                this->buffer[0] = MQTTPINGREQ;
+                this->buffer[1] = 0;
+                _client->write(this->buffer,2);
+                lastOutActivity = t;
+                lastInActivity = t;
+                pingOutstanding = true;
+            }
+        }
+        if (_client->available()) {
+            uint8_t llen;
+            uint16_t len = readPacket(&llen);
+            uint16_t msgId = 0;
+            uint8_t *payload;
+            if (len > 0) {
+                lastInActivity = t;
+                uint8_t type = this->buffer[0]&0xF0;
+                if (type == MQTTPUBLISH) {
+                    if (callback) {
+                        uint16_t tl = (this->buffer[llen+1]<<8)+this->buffer[llen+2]; /* topic length in bytes */
+                        memmove(this->buffer+llen+2,this->buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
+                        this->buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
+                        char *topic = (char*) this->buffer+llen+2;
+                        // msgId only present for QOS>0
+                        if ((this->buffer[0]&0x06) == MQTTQOS1) {
+                            msgId = (this->buffer[llen+3+tl]<<8)+this->buffer[llen+3+tl+1];
+                            payload = this->buffer+llen+3+tl+2;
+                            callback(topic,payload,len-llen-3-tl-2);
+
+                            this->buffer[0] = MQTTPUBACK;
+                            this->buffer[1] = 2;
+                            this->buffer[2] = (msgId >> 8);
+                            this->buffer[3] = (msgId & 0xFF);
+                            _client->write(this->buffer,4);
+                            lastOutActivity = t;
+
+                        } else {
+                            payload = this->buffer+llen+3+tl;
+                            callback(topic,payload,len-llen-3-tl);
+                        }
+                    }
+                } else if (type == MQTTPINGREQ) {
+                    this->buffer[0] = MQTTPINGRESP;
+                    this->buffer[1] = 0;
+                    _client->write(this->buffer,2);
+                } else if (type == MQTTPINGRESP) {
+                    pingOutstanding = false;
+                }
+            } else if (!connected()) {
+                // readPacket has closed the connection
+                return false;
+            }
+        }
+        return true;
+    }
+    return false;
+}
+
+boolean PubSubClient::publish(const char* topic, const char* payload) {
+    return publish(topic,(const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0,false);
+}
+
+boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
+    return publish(topic,(const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0,retained);
+}
+
+boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) {
+    return publish(topic, payload, plength, false);
+}
+
+boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
+    if (connected()) {
+        if (this->bufferSize < MQTT_MAX_HEADER_SIZE + 2+strnlen(topic, this->bufferSize) + plength) {
+            // Too long
+            return false;
+        }
+        // Leave room in the buffer for header and variable length field
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
+        length = writeString(topic,this->buffer,length);
+
+        // Add payload
+        uint16_t i;
+        for (i=0;i<plength;i++) {
+            this->buffer[length++] = payload[i];
+        }
+
+        // Write the header
+        uint8_t header = MQTTPUBLISH;
+        if (retained) {
+            header |= 1;
+        }
+        return write(header,this->buffer,length-MQTT_MAX_HEADER_SIZE);
+    }
+    return false;
+}
+
+boolean PubSubClient::publish_P(const char* topic, const char* payload, boolean retained) {
+    return publish_P(topic, (const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0, retained);
+}
+
+boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
+    uint8_t llen = 0;
+    uint8_t digit;
+    unsigned int rc = 0;
+    uint16_t tlen;
+    unsigned int pos = 0;
+    unsigned int i;
+    uint8_t header;
+    unsigned int len;
+    int expectedLength;
+
+    if (!connected()) {
+        return false;
+    }
+
+    tlen = strnlen(topic, this->bufferSize);
+
+    header = MQTTPUBLISH;
+    if (retained) {
+        header |= 1;
+    }
+    this->buffer[pos++] = header;
+    len = plength + 2 + tlen;
+    do {
+        digit = len  & 127; //digit = len %128
+        len >>= 7; //len = len / 128
+        if (len > 0) {
+            digit |= 0x80;
+        }
+        this->buffer[pos++] = digit;
+        llen++;
+    } while(len>0);
+
+    pos = writeString(topic,this->buffer,pos);
+
+    rc += _client->write(this->buffer,pos);
+
+    for (i=0;i<plength;i++) {
+        rc += _client->write((char)pgm_read_byte_near(payload + i));
+    }
+
+    lastOutActivity = millis();
+
+    expectedLength = 1 + llen + 2 + tlen + plength;
+
+    return (rc == expectedLength);
+}
+
+boolean PubSubClient::beginPublish(const char* topic, unsigned int plength, boolean retained) {
+    if (connected()) {
+        // Send the header and variable length field
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
+        length = writeString(topic,this->buffer,length);
+        uint8_t header = MQTTPUBLISH;
+        if (retained) {
+            header |= 1;
+        }
+        size_t hlen = buildHeader(header, this->buffer, plength+length-MQTT_MAX_HEADER_SIZE);
+        uint16_t rc = _client->write(this->buffer+(MQTT_MAX_HEADER_SIZE-hlen),length-(MQTT_MAX_HEADER_SIZE-hlen));
+        lastOutActivity = millis();
+        return (rc == (length-(MQTT_MAX_HEADER_SIZE-hlen)));
+    }
+    return false;
+}
+
+int PubSubClient::endPublish() {
+ return 1;
+}
+
+size_t PubSubClient::write(uint8_t data) {
+    lastOutActivity = millis();
+    return _client->write(data);
+}
+
+size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
+    lastOutActivity = millis();
+    return _client->write(buffer,size);
+}
+
+size_t PubSubClient::buildHeader(uint8_t header, uint8_t* buf, uint16_t length) {
+    uint8_t lenBuf[4];
+    uint8_t llen = 0;
+    uint8_t digit;
+    uint8_t pos = 0;
+    uint16_t len = length;
+    do {
+
+        digit = len  & 127; //digit = len %128
+        len >>= 7; //len = len / 128
+        if (len > 0) {
+            digit |= 0x80;
+        }
+        lenBuf[pos++] = digit;
+        llen++;
+    } while(len>0);
+
+    buf[4-llen] = header;
+    for (int i=0;i<llen;i++) {
+        buf[MQTT_MAX_HEADER_SIZE-llen+i] = lenBuf[i];
+    }
+    return llen+1; // Full header size is variable length bit plus the 1-byte fixed header
+}
+
+boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
+    uint16_t rc;
+    uint8_t hlen = buildHeader(header, buf, length);
+
+#ifdef MQTT_MAX_TRANSFER_SIZE
+    uint8_t* writeBuf = buf+(MQTT_MAX_HEADER_SIZE-hlen);
+    uint16_t bytesRemaining = length+hlen;  //Match the length type
+    uint8_t bytesToWrite;
+    boolean result = true;
+    while((bytesRemaining > 0) && result) {
+        bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
+        rc = _client->write(writeBuf,bytesToWrite);
+        result = (rc == bytesToWrite);
+        bytesRemaining -= rc;
+        writeBuf += rc;
+    }
+    return result;
+#else
+    rc = _client->write(buf+(MQTT_MAX_HEADER_SIZE-hlen),length+hlen);
+    lastOutActivity = millis();
+    return (rc == hlen+length);
+#endif
+}
+
+boolean PubSubClient::subscribe(const char* topic) {
+    return subscribe(topic, 0);
+}
+
+boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
+    size_t topicLength = strnlen(topic, this->bufferSize);
+    if (topic == 0) {
+        return false;
+    }
+    if (qos > 1) {
+        return false;
+    }
+    if (this->bufferSize < 9 + topicLength) {
+        // Too long
+        return false;
+    }
+    if (connected()) {
+        // Leave room in the buffer for header and variable length field
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
+        nextMsgId++;
+        if (nextMsgId == 0) {
+            nextMsgId = 1;
+        }
+        this->buffer[length++] = (nextMsgId >> 8);
+        this->buffer[length++] = (nextMsgId & 0xFF);
+        length = writeString((char*)topic, this->buffer,length);
+        this->buffer[length++] = qos;
+        return write(MQTTSUBSCRIBE|MQTTQOS1,this->buffer,length-MQTT_MAX_HEADER_SIZE);
+    }
+    return false;
+}
+
+boolean PubSubClient::unsubscribe(const char* topic) {
+	size_t topicLength = strnlen(topic, this->bufferSize);
+    if (topic == 0) {
+        return false;
+    }
+    if (this->bufferSize < 9 + topicLength) {
+        // Too long
+        return false;
+    }
+    if (connected()) {
+        uint16_t length = MQTT_MAX_HEADER_SIZE;
+        nextMsgId++;
+        if (nextMsgId == 0) {
+            nextMsgId = 1;
+        }
+        this->buffer[length++] = (nextMsgId >> 8);
+        this->buffer[length++] = (nextMsgId & 0xFF);
+        length = writeString(topic, this->buffer,length);
+        return write(MQTTUNSUBSCRIBE|MQTTQOS1,this->buffer,length-MQTT_MAX_HEADER_SIZE);
+    }
+    return false;
+}
+
+void PubSubClient::disconnect() {
+    this->buffer[0] = MQTTDISCONNECT;
+    this->buffer[1] = 0;
+    _client->write(this->buffer,2);
+    _state = MQTT_DISCONNECTED;
+    _client->flush();
+    _client->stop();
+    lastInActivity = lastOutActivity = millis();
+}
+
+uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t pos) {
+    const char* idp = string;
+    uint16_t i = 0;
+    pos += 2;
+    while (*idp) {
+        buf[pos++] = *idp++;
+        i++;
+    }
+    buf[pos-i-2] = (i >> 8);
+    buf[pos-i-1] = (i & 0xFF);
+    return pos;
+}
+
+
+boolean PubSubClient::connected() {
+    boolean rc;
+    if (_client == NULL ) {
+        rc = false;
+    } else {
+        rc = (int)_client->connected();
+        if (!rc) {
+            if (this->_state == MQTT_CONNECTED) {
+                this->_state = MQTT_CONNECTION_LOST;
+                _client->flush();
+                _client->stop();
+            }
+        } else {
+            return this->_state == MQTT_CONNECTED;
+        }
+    }
+    return rc;
+}
+
+PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
+    IPAddress addr(ip[0],ip[1],ip[2],ip[3]);
+    return setServer(addr,port);
+}
+
+PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) {
+    this->ip = ip;
+    this->port = port;
+    this->domain = NULL;
+    return *this;
+}
+
+PubSubClient& PubSubClient::setServer(const char * domain, uint16_t port) {
+    this->domain = domain;
+    this->port = port;
+    return *this;
+}
+
+PubSubClient& PubSubClient::setCallback(MQTT_CALLBACK_SIGNATURE) {
+    this->callback = callback;
+    return *this;
+}
+
+PubSubClient& PubSubClient::setClient(Client& client){
+    this->_client = &client;
+    return *this;
+}
+
+PubSubClient& PubSubClient::setStream(Stream& stream){
+    this->stream = &stream;
+    return *this;
+}
+
+int PubSubClient::state() {
+    return this->_state;
+}
+
+boolean PubSubClient::setBufferSize(uint16_t size) {
+    if (size == 0) {
+        // Cannot set it back to 0
+        return false;
+    }
+    if (this->bufferSize == 0) {
+        this->buffer = (uint8_t*)malloc(size);
+    } else {
+        uint8_t* newBuffer = (uint8_t*)realloc(this->buffer, size);
+        if (newBuffer != NULL) {
+            this->buffer = newBuffer;
+        } else {
+            return false;
+        }
+    }
+    this->bufferSize = size;
+    return (this->buffer != NULL);
+}
+
+uint16_t PubSubClient::getBufferSize() {
+    return this->bufferSize;
+}
+PubSubClient& PubSubClient::setKeepAlive(uint16_t keepAlive) {
+    this->keepAlive = keepAlive;
+    return *this;
+}
+PubSubClient& PubSubClient::setSocketTimeout(uint16_t timeout) {
+    this->socketTimeout = timeout;
+    return *this;
+}

Nem az összes módosított fájl került megjelenítésre, mert túl sok fájl változott