[{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eOverview\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/030/original/lora-thermometer-base-and-sensor.jpeg?1762582102","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThis project uses 900 MHz RFM95W LoRa FeatherWing modules to transmit temperature measurements from greenhouses and receive them at a base station about half a kilometer away. The base station hardware outputs sensor reports over USB serial, an optional 2x16 Character LCD, and an optional ESP-NOW gateway.\u003c/p\u003e\n\u003cp\u003eThe LoRa radio settings are tuned for extended battery life at a range of up to 500m in suburban or rural conditions (non line of sight with limited obstructions). With a fully charged 400 mAh LiPo battery and a 9 minute reporting interval, typical sensor runtime should be about 4 weeks (~22µA deep sleep current, ~2667ms of time per wake cycle, ~0.222 coulombs of charge per wake cycle).\u003c/p\u003e\n\u003cp\u003eTo optimize the transmitter for running on a small LiPo cell, I used a Nordic nRF-PPK2 power analyzer to tune the firmware. Some of the power saving tricks I used include reducing the cpu frequency, putting the RFM95W radio in sleep mode, putting the MAX17048 fuel gauge in hibernate mode, and using ESP32-S3 deep sleep. To compare the impact of different changes, I took extensive measurements using Nordic's Power Profiler app with the PPK2 connected to the Feather board's battery jack and GPIO outputs.\u003c/p\u003e\n\u003cp\u003e\u003cspan\u003eTransparency note: Adafruit provided some of the parts I used for this guide (Thanks Adafruit!).\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/p\u003e\n\u003ch2\u003e\u003cspan\u003eRelated Projects\u003c/span\u003e\u003c/h2\u003e\n\u003cp\u003e\u003cspan\u003eFor logging, charting, and IRC status notifications, check out my related projects:\u003c/span\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cspan\u003e\u003ca href=\"https://github.com/samblenny/serial-sensor-hub\" target=\"_blank\"\u003eserial-sensor-hub\u003c/a\u003e\u003c/span\u003e\u003c/li\u003e\n\u003cli\u003e\u003cspan\u003e\u003ca href=\"https://adafruit-playground.com/u/SamBlenny/pages/irc-display-bot\" target=\"_blank\"\u003eirc-display-bot\u003c/a\u003e.\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eParts\u003c/h2\u003e\n\u003cp\u003eThe firmware can be configured to run in several modes:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eLoRa temperature sensor (ESP32-S3 Feather + LoRa FeatherWing)\u003c/li\u003e\n\u003cli\u003eLoRa base station (ESP32-S3 Feather + LoRa FeatherWing + optional I2C LCD)\u003c/li\u003e\n\u003cli\u003eLoRa base station with ESP-NOW gateway (ESP32-S3 Feather + LoRa FeatherWing + optional I2C LCD)\u003c/li\u003e\n\u003cli\u003eESP-NOW base station (ESP32-S3 Feather, QT Py, or Metro + optional I2C LCD)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eAt minimum, you will need one LoRa sensor and one LoRa base station. If you want to operate your LoRa base station in ESP-NOW gateway mode, you can use other ESP-NOW boards to receive the sensor packets forwarded by the gateway.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eLoRa Sensor Parts:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eESP32-S3 Feather\u003c/li\u003e\n\u003cli\u003eRFM05W LoRa FeatherWing (+ hookup wire)\u003c/li\u003e\n\u003cli\u003e915MHz spring antenna\u003c/li\u003e\n\u003cli\u003eFeatherWing Doubler\u003c/li\u003e\n\u003cli\u003e400 mAh LiPo battery\u003c/li\u003e\n\u003cli\u003e100mm STEMMA QT / Qwiic I2C cable\u003c/li\u003e\n\u003cli\u003eMCP9808 I2C temperature sensor\u003c/li\u003e\n\u003cli\u003eIP67 rated waterproof enclosure (preferably with plastic screws)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eLoRa Base Station Parts:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eESP32-S3 Feather\u003c/li\u003e\n\u003cli\u003eRFM05W LoRa FeatherWing (+ hookup wire)\u003c/li\u003e\n\u003cli\u003e915MHz spring antenna\u003c/li\u003e\n\u003cli\u003eEdge launch SMA connector\u003c/li\u003e\n\u003cli\u003eSMA mount 915MHz half-wave dipole antenna\u003c/li\u003e\n\u003cli\u003eFeatherWing Doubler (or FeatherWing Tripler)\u003c/li\u003e\n\u003cli\u003e[optional] I2C character LCD backpack\u003c/li\u003e\n\u003cli\u003e[optional] RGB backlit 2x16 character LCD\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eESP-NOW Base Station Parts:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eESP-NOW capable board such as ESP32-S3 Feather, QT Py, or Metro\u003c/li\u003e\n\u003cli\u003e[optional] I2C character LCD backpack\u003c/li\u003e\n\u003cli\u003e[optional] RGB backlit 2x16 character LCD\u003c/li\u003e\n\u003c/ul\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5323","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3231","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4269","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/1865","metadata":{}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e1\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003ca href=\"https://www.digikey.com/en/products/detail/te-connectivity-linx/ANT-916-OC-LG-SMA/2651619\" class=\"parts-name\" target=\"_blank\"\u003eTE Connectivity ANT-916-OC-LG-SMA\u003c/a\u003e\n      \u003cdiv class=\"parts-description\"\u003e915 MHz 1/2-wave dipole antenna, SMA M\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n      \u003ca href=\"https://www.digikey.com/en/products/detail/te-connectivity-linx/ANT-916-OC-LG-SMA/2651619\" class=\"parts-url btn-primary\" target=\"_blank\"\u003eBuy Now\u003c/a\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"TE Connectivity ANT-916-OC-LG-SMA","url":"https://www.digikey.com/en/products/detail/te-connectivity-linx/ANT-916-OC-LG-SMA/2651619","description":"915 MHz 1/2-wave dipole antenna, SMA M","quantity":"1"}},{"element_type":"product","content":"https://www.adafruit.com/product/2890","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3417","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3898","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4210","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5027","metadata":{}},{"element_type":"parts","content":"\n  \u003cdiv class=\"parts-details\"\u003e\n    \u003cdiv\u003e\n      \u003cspan class=\"parts-quantity\"\u003e1\u003c/span\u003e\u003cspan\u003e x \u003c/span\u003e\n        \u003ca href=\"https://www.amazon.com/dp/B0D9BQ5PHF\" class=\"parts-name\" target=\"_blank\"\u003eIP67 Waterproof Box\u003c/a\u003e\n      \u003cdiv class=\"parts-description\"\u003e3.9\"x3.9\"x3\" IP67 junction box with plastic screws\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n  \u003cdiv class=\"parts-action\"\u003e\n  \u003cdiv\u003e\n      \u003ca href=\"https://www.amazon.com/dp/B0D9BQ5PHF\" class=\"parts-url btn-primary\" target=\"_blank\"\u003eBuy Now\u003c/a\u003e\n\n  \u003c/div\u003e\n\u003c/div\u003e\n\n  \u003cdiv class=\"clearfix\"\u003e\u003c/div\u003e\n","metadata":{"name":"IP67 Waterproof Box","url":"https://www.amazon.com/dp/B0D9BQ5PHF","description":"3.9\"x3.9\"x3\" IP67 junction box with plastic screws","quantity":"1"}},{"element_type":"product","content":"https://www.adafruit.com/product/292","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/398","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3174","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3468","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3057","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5048","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n        \u003ch2\u003eSoldering \u0026amp; Pinout\u003c/h2\u003e\n\u003cp\u003eThis project involves a lot of soldering. Most of it is easy, but the antenna connector is a little harder. You should definitely \u003cstrong\u003euse a flux pen\u003c/strong\u003e to apply flux to the \u003cstrong\u003eantenna connector\u003c/strong\u003e. Without extra flux, you're gonna have a hard time. It also helps to use Kapton tape to hold the spring antenna or SMA connector while you solder.\u003c/p\u003e\n\u003cp\u003eCheck out these Learn guides for soldering tips and pinout info:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://learn.adafruit.com/adafruit-guide-excellent-soldering\" target=\"_blank\"\u003eAdafruit Guide To Excellent Soldering\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003ca href=\"https://learn.adafruit.com/radio-featherwing/wiring\" target=\"_blank\"\u003eRadio FeatherWing Wiring\u003c/a\u003e (see pinout below)\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://learn.adafruit.com/radio-featherwing/assembly\" target=\"_blank\"\u003eRadio FeatherWing Assembly\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://learn.adafruit.com/i2c-spi-lcd-backpack/overview\" target=\"_blank\"\u003eI2C/SPI LCD Backpack\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003eLoRa Radio FeatherWing Pinout\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eRST goes to C (gray wire)\u003c/li\u003e\n\u003cli\u003eCS goes to B (yellow wire)\u003c/li\u003e\n\u003cli\u003eIRQ goes to A (orange wire)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      \n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/069/original/Radio-FeatherWing-Pinout.jpeg?1763975614","metadata":{}},{"element_type":"text","content":"\n        \u003ch3\u003eCut MCP9808 LED Jumper\u003c/h3\u003e\n\u003cp\u003eFor lower current draw, use a hobby knife to cut the PCB trace joining the two pads on the temperature sensor's LED jumper. The jumper is located next to the green LED at the top left of the board.\u003c/p\u003e\n      ","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n        \u003ch3\u003eI2C LCD Backpack\u003c/h3\u003e\n\u003cp\u003eTo assemble the I2C character LCD backpack, you should pay attention to:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cstrong\u003eDANGER\u003c/strong\u003e: Be very sure the \u003cstrong\u003escrew terminal pins\u003c/strong\u003e on the backpack \u003cstrong\u003edo not touch components\u003c/strong\u003e on your LCD module. You may need to trim the pins. Check clearance before soldering. (see photos below)\u003c/li\u003e\n\u003cli\u003eTo get the classic 90's green backlit LCD look using Adafruit's RGB backlit character LCD module, you can use a short piece of hookup wire to connect the green LED pin to the backpack's backlight pin. If you just wire the pins straight across (no angled hookup wire), you'll get a red backlight.\u003c/li\u003e\n\u003cli\u003eTo hold the backpack PCB parallel to the LCD module PCB while you solder, you can shim the far side with some scraps of pin header turned sideways (see photos below)\u003c/li\u003e\n\u003cli\u003eYou will probably need to adjust the contrast trim pot on the back of the I2C backpack. If the LCD looks blank when the code runs (backlight on but no text), it's probably because the contrast is set wrong.\u003c/li\u003e\n\u003c/ol\u003e\n      \n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/070/original/lcd-solder-1.jpeg?1763979508","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/071/original/lcd-solder-2.jpeg?1763979521","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/072/original/lcd-solder-3.jpeg?1763979536","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/073/original/lcd-solder-4.jpeg?1763979557","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/074/original/lcd-solder-5.jpeg?1763979820","metadata":{}},{"element_type":"alert","content":"\u003cp\u003eDANGER! Be sure the LCD backpack screw terminal pins do not touch the back of the LCD module. You may need to trim the pins with flush cutters.\u003c/p\u003e","metadata":{"markdown":"DANGER! Be sure the LCD backpack screw terminal pins do not touch the back of the LCD module. You may need to trim the pins with flush cutters.","alert_type":"danger","icon":"exclamation"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/075/original/lcd-solder-6-DANGER.jpeg?1763979839","metadata":{}},{"element_type":"alert","content":"\u003cp\u003eIMPORTANT! You will probably need to adjust the LCD contrast trim pot on the back of the I2C backpack. If the LCD looks blank when the code runs, check the contrast adjustment.\u003c/p\u003e","metadata":{"markdown":"IMPORTANT! You will probably need to adjust the LCD contrast trim pot on the back of the I2C backpack. If the LCD looks blank when the code runs, check the contrast adjustment.","alert_type":"warning","icon":"exclamation"}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/076/original/lcd-solder-7.jpeg?1763979855","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2 class=\"heading-element\"\u003eLoRa Node Addresses \u0026amp; HMAC Keys\u003c/h2\u003e\n\u003cp\u003e\u003ca id=\"user-content-lora-node-addresses--hmac-keys\" class=\"anchor\" href=\"https://github.com/samblenny/lora-greenhouse-monitor#lora-node-addresses--hmac-keys\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis project doesn't really care how many sensor nodes you use or how you assign the addresses. But, if you want to use my serial-sensor-hub and irc-display-bot code too, those work best with 1 to 3 sensors, using node addresses 1, 2, and 3. For base station node addresses, you can use whatever so long as it doesn't conflict with the sensor addresses (maybe start at 200).\u003c/p\u003e\n\u003cp\u003eSensors and base stations use\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://en.wikipedia.org/wiki/HMAC\" target=\"_blank\"\u003eHMAC\u003c/a\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003esignatures with a shared key for message integrity, sender authentication, and duplicate packet filtering. The sensors sign their temperature report packets, which include a sequence number (derived from RTC). The base station(s) verify the HMAC signature and check that the sequence numbers are monotonic. The signature implementation is based on\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://datatracker.ietf.org/doc/html/rfc6238\" target=\"_blank\"\u003eTOTP\u003c/a\u003e, but the message to be signed includes node address, battery voltage, temperature, etc. instead of only a UNIX timestamp.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eCAUTION: If you reset or power cycle a sensor, you need to reset or reboot the base station(s) to reset their sequence number checking.\u003c/strong\u003e\u003c/p\u003e\n\u003ch2 class=\"heading-element\"\u003eConfiguration\u003c/h2\u003e\n\u003cp\u003e\u003ca id=\"user-content-configuration\" class=\"anchor\" href=\"https://github.com/samblenny/lora-greenhouse-monitor#configuration\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThe project code can be configured to run in several modes:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eLoRa temperature sensor (ESP32-S3 Feather + LoRa FeatherWing)\u003c/li\u003e\n\u003cli\u003eLoRa base station (ESP32-S3 Feather + LoRa FeatherWing)\u003c/li\u003e\n\u003cli\u003eLoRa base station with ESP-NOW gateway (ESP32-S3 Feather + LoRa FeatherWing)\u003c/li\u003e\n\u003cli\u003eESP-NOW base station (ESP32-S3 Feather, QT Py, or Metro)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eEach sensor and base station needs to have some\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003eCIRCUITPY/settings.toml\u003c/code\u003e values set to configure which mode to operate in, what key to use for HMAC, what LoRa node address to use (except for the ESP-NOW base station), etc.\u003c/p\u003e\n\u003cp\u003eThe HMAC key should be the same for all the sensors and base stations you want to be able to communicate with each other. If you want more than one sensor network without cross-talk interference, you can assign each network its own key.\u003c/p\u003e\n\u003ch3 class=\"heading-element\"\u003eSettings.toml for Sensor Mode\u003c/h3\u003e\n\u003cp\u003e\u003ca id=\"user-content-settingstoml-for-sensor-mode\" class=\"anchor\" href=\"https://github.com/samblenny/lora-greenhouse-monitor#settingstoml-for-sensor-mode\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eTo run in sensor mode, put this stuff in your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003esettings.toml\u003c/code\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003efile, editing the HMAC key and node address values as needed:\u003c/p\u003e\n\u003cpre class=\"notranslate\"\u003e\u003ccode\u003eHMAC_KEY = \"YOUR HMAC PASSPHRASE GOES HERE\"\nBASE_MODE = 0\nLORA_NODE = 1\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch3 class=\"heading-element\"\u003eSettings.toml for Plain LoRa Base Station\u003c/h3\u003e\n\u003cp\u003e\u003ca id=\"user-content-settingstoml-for-plain-lora-base-station\" class=\"anchor\" href=\"https://github.com/samblenny/lora-greenhouse-monitor#settingstoml-for-plain-lora-base-station\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eTo run in base station mode, put this stuff in your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003esettings.toml\u003c/code\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003efile, editing the HMAC key and node address values as needed:\u003c/p\u003e\n\u003cpre class=\"notranslate\"\u003e\u003ccode\u003eHMAC_KEY = \"YOUR HMAC PASSPHRASE GOES HERE\"\nBASE_MODE = 1\nLORA_NODE = 200\nLCD_BACKLIGHT = 0\nESPNOW_GATEWAY = 0\nESPNOW_RX = 0\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf you've attached an I2C 2x16 character LCD and you want to turn the backlight on, do\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003eLCD_BACKLIGHT = 1\u003c/code\u003e.\u003c/p\u003e\n\u003ch3 class=\"heading-element\"\u003eSettings.toml for LoRa Base Station with ESP-NOW Gateway\u003c/h3\u003e\n\u003cp\u003e\u003ca id=\"user-content-settingstoml-for-lora-base-station-with-esp-now-gateway\" class=\"anchor\" href=\"https://github.com/samblenny/lora-greenhouse-monitor#settingstoml-for-lora-base-station-with-esp-now-gateway\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eTo run a base station in LoRa to ESP-NOW gateway mode, put this stuff in your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003esettings.toml\u003c/code\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003efile, editing the HMAC key and node address values as needed:\u003c/p\u003e\n\u003cpre class=\"notranslate\"\u003e\u003ccode\u003eHMAC_KEY = \"YOUR HMAC PASSPHRASE GOES HERE\"\nBASE_MODE = 1\nLORA_NODE = 201\nLCD_BACKLIGHT = 0\nESPNOW_GATEWAY = 1\nESPNOW_RX = 0\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf you've attached an I2C 2x16 character LCD and you want to turn the backlight on, do\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003eLCD_BACKLIGHT = 1\u003c/code\u003e.\u003c/p\u003e\n\u003ch3 class=\"heading-element\"\u003eSettings.toml for ESP-NOW Base Station\u003c/h3\u003e\n\u003cp\u003e\u003ca id=\"user-content-settingstoml-for-esp-now-base-station\" class=\"anchor\" href=\"https://github.com/samblenny/lora-greenhouse-monitor#settingstoml-for-esp-now-base-station\"\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eTo run a base station ESP-NOW receiver mode (receiving packets forwarded by a LoRa to ESP-NOW gateway), put this stuff in your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003esettings.toml\u003c/code\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003efile, editing the HMAC key value as needed:\u003c/p\u003e\n\u003cpre class=\"notranslate\"\u003e\u003ccode\u003eHMAC_KEY = \"YOUR HMAC PASSPHRASE GOES HERE\"\nBASE_MODE = 1\nLCD_BACKLIGHT = 0\nESPNOW_GATEWAY = 0\nESPNOW_RX = 1\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003eIf you've attached an I2C 2x16 character LCD and you want to turn the backlight on, do\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ccode\u003eLCD_BACKLIGHT = 1\u003c/code\u003e.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eUpdating CircuitPython\u003c/h2\u003e\n\u003cp\u003eAs I write this (November 14, 2025), CircuitPython 10.0.3 is the most recent release build. To keep your board up to date, you can use the \"DOWNLOAD .BIN NOW\" button on the download page of circuitpython.org:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003ca href=\"https://circuitpython.org/board/adafruit_feather_esp32s3_nopsram/\" target=\"_blank\"\u003eFeather ESP32-S3 8MB\u003c/a\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003epage\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eTo install the .BIN File:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eConnect your board to a computer with a USB data cable (\u003cem\u003echarge-only cables won't work!\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003c/em\u003e)\u003c/li\u003e\n\u003cli\u003ePress and hold the board's boot button\u003c/li\u003e\n\u003cli\u003ePress and release the reset button\u003c/li\u003e\n\u003cli\u003eRelease the boot button\u003c/li\u003e\n\u003cli\u003e\n\u003cspan\u003eFollow the instructions in the\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://learn.adafruit.com/circuitpython-with-esp32-quick-start/web-serial-esptool\" target=\"_blank\"\u003eWeb Serial ESPTool\u003c/a\u003e\u003cspan\u003e\u0026nbsp;section of the \"CircuitPython on ESP32 Quick Start\" learn guide to update your board with CircuitPython (I've had the best luck with using\u0026nbsp;\u003ca href=\"https://adafruit.github.io/Adafruit_WebSerial_ESPTool/\" target=\"_blank\"\u003eAdafruit WebSerial ESPTool\u003c/a\u003e\u0026nbsp;to erase the whole flash then program the .BIN file)\u003c/span\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2\u003e\n\u003cspan class=\"fa fa-link\"\u003e\u003c/span\u003e\u003cspan id=\"circuitpython-code-3211581\" class=\"anchor-link-target\"\u003e\u003c/span\u003eCircuitPython Code\u003c/h2\u003e\n\u003cp\u003eYou can view the code at the\u003cspan\u003e\u0026nbsp;\u003ca href=\"https://github.com/samblenny/lora-greenhouse-monitor\"\u003esamblenny/lora-greenhouse-monitor\u003c/a\u003e\u0026nbsp;\u003c/span\u003eGitHub repository. To download a zip archive project bundle with the code and all the necessary libraries, use the \"Download Project Bundle\" button:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"button","content":"https://github.com/samblenny/lora-greenhouse-monitor/releases/download/v0.4.1/lora-greenhouse-monitor-4900fb7.zip","metadata":{"class":"btn btn-large btn-block btn-primary","button_type":"primary","target":"_blank","zip_folder":"false"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eInstall Project Bundle\u003c/h3\u003e\n\u003cp class=\"p2\"\u003e\u003cspan class=\"s1\"\u003eTo copy the project bundle files to your CIRCUITPY drive:\u003c/span\u003e\u003c/p\u003e\n\u003col class=\"ol1\"\u003e\n\u003cli class=\"li3\"\u003e\u003cspan class=\"s1\"\u003eDownload the project bundle .zip file using the \"Download Project Bundle\" button above.\u003c/span\u003e\u003c/li\u003e\n\u003cli class=\"li3\"\u003e\u003cspan class=\"s1\"\u003eExpand the zip file by opening it, or use unzip in a Terminal. The zip archive should expand to a folder. When you open the folder, it should contain a README.txt file and a CircuitPython 10.x folder.\u003c/span\u003e\u003c/li\u003e\n\u003cli class=\"li3\"\u003e\u003cspan class=\"s1\"\u003eOpen the CircuitPython 10.x folder and copy all of its contents to your CIRCUITPY drive.\u003c/span\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp class=\"p2\"\u003e\u003cspan class=\"s1\"\u003eTo learn more about copying libraries to your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eCIRCUITPY\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003edrive, check out the\u0026nbsp;\u003ca href=\"https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries\" target=\"_blank\"\u003e\u003cspan class=\"s2\"\u003eCircuitPython Libraries\u003c/span\u003e\u003c/a\u003e\u0026nbsp;section of the\u0026nbsp;\u003ca href=\"https://learn.adafruit.com/welcome-to-circuitpython\" target=\"_blank\"\u003e\u003cspan class=\"s2\"\u003eWelcome to CircuitPython!\u003c/span\u003e\u003c/a\u003e\u0026nbsp;learn guide.\u003c/span\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCIRCUITPY/code.py\u003c/h3\u003e\n\u003cp\u003eYou can ignore the stuff about a Feather RP2350 mentioned in the code below. That's left over from some early experiments that I never got around to cleaning up. I suggest using a Feather ESP32-S3 with \u003ccode\u003eBASE_MODE = 1\u003c/code\u003e\u0026nbsp;in settings.toml so that you have the option to use the ESP-NOW gateway mode.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/lora-greenhouse-monitor/blob/v0.4.1/code.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCIRCUITPY/sensor_mode.py\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/lora-greenhouse-monitor/blob/v0.4.1/sensor_mode.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCIRCUITPY/base_mode.py\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/lora-greenhouse-monitor/blob/v0.4.1/base_mode.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCIRCUITPY/common.py\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/lora-greenhouse-monitor/blob/v0.4.1/common.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCIRCUITPY/sb_hmac.py\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/lora-greenhouse-monitor/blob/v0.4.1/sb_hmac.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCIRCUITPY/boot.py\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/lora-greenhouse-monitor/blob/v0.4.1/boot.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003ePPK2 Power Profiling\u003c/h2\u003e\n\u003cp\u003eI spent a long time iterating over small code changes, measuring their effects using Nordic Power Profiler and a PPK2 power analyzer. If you want all the step by step details, check out \u003ca href=\"https://github.com/samblenny/lora-greenhouse-monitor/blob/main/power_analysis/README.md\" target=\"_blank\"\u003esamblenny/lora-greenhouse-monitor/power_analysis/README.md\u003c/a\u003e in my GitHub repo for this project. For this writeup, I've included a small excerpt with Power Profiler screenshots showing power use for my second range test.\u003c/p\u003e\n\u003cp\u003eThe main things I learned are:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eFor IO bound code that spends a lot of time waiting on I2C and SPI perhipherals, reducing \u003ccode\u003emicrocontroller.cpu.frequency\u003c/code\u003e saves a lot of power. But, it's more efficient to let imports and the bytecode compiler run at full speed.\u003c/li\u003e\n\u003cli\u003eA significant portion of the total charge per wake cycle gets spent on booting the CircuitPython VM, so there's not really anything to do about that.\u003c/li\u003e\n\u003cli\u003eTo minimize deep sleep current, be sure to put I2C and SPI peripherals in their lowest power mode before starting deep sleep. For example, \u003ccode\u003eRFM9x.sleep()\u003c/code\u003e is much better than \u003ccode\u003eRFM9x.idle()\u003c/code\u003e.\u003c/li\u003e\n\u003cli\u003eSomething about switching \u003ccode\u003eboard.I2C_POWER\u003c/code\u003e on the Feather ESP32-S3 causes a large (500+ mA peak) transient. The CircuitPython VM does this before running boot.py, but you can also trigger the transient in your own code. You can verify this for yourself by running code with a loop to toggle\u0026nbsp;\u003ccode\u003eI2C_POWER\u003c/code\u003e then \u003ccode\u003esleep()\u003c/code\u003e for a while. The transient seems to cause a brownout on the I2C bus power when the board is running on a small LiPo cell (e.g. 400 mAh). For me this caused faulty MCP9808 temperature readings until I re-ordered my code. Waiting 300ms after the start of code.py before attempting to talk to anything on the I2C bus resolved the faulty temperature reading problem.\u003c/li\u003e\n\u003cli\u003eFor RFM95 LoRa transmitting, you have a variety of options to improve the received signal quality at your receiver. Some of those options increase the time spent transmitting each symbol, and some don't. For example, increasing spreading factor by 1 \u003ca href=\"https://www.thethingsnetwork.org/docs/lorawan/spreading-factors/#receiver-sensitivity\" target=\"_blank\"\u003eboosts receiver sensitivity by about 3 dB\u003c/a\u003e, but it also doubles the on-air time. So, boosting your signal quality by increasing spreading factor incurs the current penalty of from having the cpu running during the extra transmit time. On the other hand, getting more dB by boosting \u003ccode\u003eRFM95.tx_power\u003c/code\u003e doesn't increase your on-air time.\u003c/li\u003e\n\u003cli\u003eMinimizing the number of bytes in each RFM95 packet is an easy way to save power. But, if you take it too far, you will sacrifice important message integrity and security properties. I chose to spend 8 bytes of packet payload on a timestamp and a truncated HMAC hash (modeled on how TOTP tokens work). For those 8 bytes, I get message authentication, protection against replay attacks, and an easy way to filter out my own repeated packets that I use for reliability and range testing.\u003c/li\u003e\n\u003c/ol\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eSensor \u0026amp; Nordic PPK2 Wiring\u003c/h3\u003e\n\u003cp\u003eFor the power connection, I made an adapter cable from DuPont connectors to a JST PH 2-pin battery connector to fit the Feather's battery jack.\u003c/p\u003e\n\u003cp\u003eFor the logic port connections, I lifted the RFM95W FeatherWing slightly out of its socket so that I could clip probe hooks around the pins. After attaching the hooks, I pressed the FeatherWing back down snugly against the plastic of the probes for better mechanical stability. I used the probe hooks that came with a Saleae Logic 8. You could also use the hooks from a Bus Pirate probe cable set. Or, you could put the Feather and FeatherWing on a FeatherWing Tripler backplane and use regular DuPont wires.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eNOTE:\u003c/strong\u003e You need to hook up both the GND (to Feather GND) and VCC (to Feather 3V) or the logic port inputs won't work. I didn't see an explanation in the Nordic documentation, but it acts like there's an isolator or logic level converter powered by the device under test.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/034/original/lora-thermometer.jpeg?1762588789","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/035/original/lora-thermometer-logic-probes.jpeg?1762588827","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eWake Cycle 2.667 s, 221.55 mC\u003c/h3\u003e\n\u003cp\u003eThis shows how a full wake cycle lasts for about 2.667 seconds and uses about 221.55 millicoulombs (mC) of charge from the battery. The gray selected are to the right is the time spent on boot.py, code.py, and sensor_mode.py. Logic port input 0 gets turned on by boot.py. Logic port input 1 gets toggled by code.py and sensor_mode.py as the code progresses. As you can see, about half of the wake cycle time, and about 30% of the charge, gets spent on booting the CircuitPython VM.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/067/original/tune_for_range_wake_cycle_2.667s_221.55mC.png?1763973859","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eDeep Sleep 22µA\u003c/h3\u003e\n\u003cp\u003eThis shows the average deep sleep current is about 22µA. Note this would be much, much higher if I didn't call \u003ccode\u003eRFM9x.sleep()\u003c/code\u003e before starting deep sleep. Calling \u003ccode\u003eMAX17048.hibernate()\u003c/code\u003e also helps.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/002/068/original/tune_for_range_sleep_current_21.55uA.png?1763973907","metadata":{}}]