Skip to main content

MeshCore Sensor Nodes

MeshCore Sensor FirmwareSupport

MeshCore providesdoes not ship a dedicatedseparate Sensor"Sensor" firmware variant,variant. separateMeshCore fromdevice firmware is built around three roles - Companion, Repeater, and Room Server. Environmental-sensor support is a compile-time feature: it is enabled when the Repeaterfirmware is built with the relevant ENV_INCLUDE_* flags (the environment-sensor manager, demonstrated by example builds such as simple_sensor / SensorMesh). It is an evolving, limited capability, not a polished deployable role you "flash and Clientgo." variants.

Flash

Because sensor support is selected at build time, there is no stock "RAK4631 SENSOR" release asset to download. To use it ontoyou compile a supportedsensor-capable boardbuild for your board. nRF52 boards (e.g. RAK4631, T-Echo) theare same way you would any MeshCore firmware -flashed via UF2 drag-and-drop or the MeshCore web flasher orflasher; esptool. applies only to ESP32 boards.

Supported Sensors

When a sensor-capable build is compiled in, the environment-sensor manager probes the I2C bus to detect supported sensors. Commonly referenced hardware includes:

  • BME280 - temperature, humidity, barometric pressure (I2C). The mostA common choice for weather monitoring.
  • BME680 - adds a gas/VOC sensor to the BME280 feature set.set, Usefuluseful for airindoor air-quality monitoring.indication. (IAQ requires the Bosch BSEC library and a calibration period to be meaningful.)
  • INA219 - bus voltage and current measurement over I2C. IdealUseful for monitoring battery banks, solar panels, or loadload/charge current.
  • Custom GPIO sensors - Sensor firmware exposes hooks for custom analog or digitaladditional inputs (seerequire modifying and recompiling the MeshCorefirmware firmware(e.g. source)the onSensorDataRead hook plus the appropriate ENV_INCLUDE_* flags in EnvironmentSensorManager). This is a build-time change, not a runtime configuration option.

How Sensor AdvertisementsTelemetry WorkIs Delivered

A common misconception is that MeshCore "broadcasts" sensor readings in its adverts. It does not. A MeshCore advert announces a node's presence and routing information only - its name, optional position, and signed public key. Adverts do not carry temperature, humidity, or any other sensor value.

Sensor firmwaredata transmitstravels readingsinstead asover MeshCore's MeshCorebinary advertisementsrequest/response protocol. atA client explicitly requests telemetry from a user-configurednode interval. These broadcasts propagate through(REQ_TYPE_GET_TELEMETRY_DATA); the meshnode thereplies samewith waya anyCayenneLPP-encoded otherpayload. MeshCoreThis advertisementexchange doesis addressed and permission-gated - anyit repeateris a pull (request/response), not a broadcast that every node receives and forwards. (Adverts themselves are either zero-hop or clientflooded withinfor rangerouting (directpurposes, orbut viain relay)neither willcase receivedo andthey forward them. No special gateway or bridge is required to seecontain sensor data in the MeshCore app's node list.readings.)

Power Profile

SensorA nodestelemetry-reporting MeshCore node can run at verya low duty cycles,cycle, makingwhich themmakes suitable for solar-poweredsolar or long-term battery deployments:deployment feasible. Concrete figures depend heavily on TX power, reporting frequency, whether Bluetooth is disabled, and the board's sleep current, so the numbers below are rough estimates, not specifications:

  • An nRF52840 node (e.g. RAK4631) +with BME280a BME280, reporting infrequently with BLE off and low TX power, can draw on the order of a few mAh/day. Measure your own node's consumption before sizing a battery - do not treat any single figure as a firm spec.
Battery runtime estimates must also account for self-discharge and capacity derating over time, so a nominal pack capacity does not translate directly into a guaranteed number of days. A small (~1 W) solar panel can offset consumption at a 10-minute broadcast interval: approximately < 5 mAh/day. A 3 000 mAh LiPo atsite that ratereliably lastsgets 4+ peak-sun-hours, but this varies by season and location and will not keep a node running "indefinitely" - lithium cells still age out over 600calendar days without any charging. A single 1 W (6 V, ~170 mA peak) solar panel in a location with 4+ hours of useful sun per day comfortably offsets consumption and keeps the battery topped up indefinitely.years. For the mostlowest aggressive power savings,power, disable Bluetooth and set the LoRa TX power to the minimum needed to reach the nearest repeater.

Outdoor lithium safety: never charge a lithium cell (including LiFePO4) below 0 C / 32 F. For any outdoor node deployed where winter temperatures drop below freezing, use a charger/controller with a low-temperature charge cutoff, and add an in-line fuse on the battery positive lead.

Configuration

Configure sensor nodes via the MeshCore CLIis configured over USB/serial or throughover BLE (via the companion app or the MeshCore mobileCLI). appThe over BLE:

    Setactual sensor type:CLI is a small generic key/value store - there is no set sensor type bme280 Set I2C address:, set sensor addr 0x76 Set broadcast interval:, set sensor interval 600 (seconds) Enable, or disable: set sensor enabled truecommand. The real commands are:
      sensor list [start] - list the sensor custom variables (printed as key=value lines). sensor get <key> - read a sensor custom variable. sensor set <key> <value> - set a sensor custom variable.

      FullWhich CLIsensors syntaxare present is documenteddetermined inat compile time (the ENV_INCLUDE_* build flags) and by I2C auto-detection at startup - not by a runtime enable/disable or type-selection command. I2C addresses are detected during the environment MeshCoresensor Sensormanager's CLIbus Referenceprobe; page.they are not set from the CLI. Advert cadence is governed by the real interval prefs (e.g. set flood.advert.interval <hours> / set advert.interval <minutes>), which control advert timing - they do not broadcast sensor readings.

      Use Cases

      • Remote weather station: BME280 on a ridge or mountain peak, reporting temperature, humidity, and pressure everyon 10 minutes.request.
      • Water level monitoring: an ultrasonic or pressure sensor at a stream crossing or water tank. Treat this as best-effort situational awareness only - mesh packets can drop, and a hobbyist sensor must not replace official NWS/USGS flood warnings for any safety decision (see the Water Quality and Flood Monitoring page).
      • Air quality monitoring:indication: BME680 in an urban or wildfire smoke corridor.corridor (low-cost sensors are indicative, not reference-grade).
      • Soil temperature for agriculture: BME280 buried at root depth in a remote field.
      • Power system monitoring: INA219 across the shunt resistor of a solar-charged battery bank, reporting bus voltage and load/charge current. Note: state of charge is not measured directly - it must be derived (e.g. coulomb counting) from voltage and load current.

      Integration with Data Pipelines

      SensorCapturing advertisementsMeshCore aresensor visibledata is not automatic - readings do not appear by themselves in the MeshCore app's node listlist. alongsideYou normalneed nodes.a Fornode automatedconnected datato capture,a usehost (a room server, or a serial/USB/BLE bridge) running code that requests telemetry and logs it. Use the real async MeshCore Python librarymeshcore_py tolibrary: create a client, subscribe to thetelemetry meshevents, and logissue readingstelemetry torequests athrough database:commands.* - do not parse adverts for sensor values.

      import asyncio, sqlite3, datetime
      from meshcore import MeshCoreMeshCore, importEventType
      
      sqlite3,async datetimedef main():
          # create_serial(port), create_tcp(host, port), or create_ble(address)
          mc = MeshCore(await MeshCore.create_serial("/dev/ttyUSB0")
      
          db = sqlite3.connect("sensors.db")
          db.execute("CREATE TABLE IF NOT EXISTS readings "
                     "(ts TEXT, node TEXT, temppayload REAL, hum REAL, pres REAL)TEXT)")
      
          def on_advert(advert)on_telemetry(event):
              if# advert.get("type")event.payload ==is "sensor":the decoded CayenneLPP telemetry response
              db.execute("INSERT INTO readings VALUES (?,?,?,?,?)", (
                  datetime.datetime.utcnow().isoformat(),
                  advert[str(event.payload.get("node_name"]from", advert.get("temperature"")),
                  advert.get("humidity"),
       advert.get("pressure")str(event.payload),
              ))
              db.commit()
      
          mc.subscribe(EventType.TELEMETRY_RESPONSE, on_telemetry)
      
          # Pull telemetry from a known contact (request/response, not broadcast):
          contacts = await mc.commands.get_contacts()
          for contact in contacts.values():
              await mc.commands.req_telemetry(contact)
      
          # keep the asyncio loop running to receive responses
          await asyncio.Event().wait()
      
      asyncio.run(main())

      There is no MeshCore("/dev/ttyUSB0") constructor, no mc.on_advertisement = on_advert... callback, no mc.run(), and no advert.get("temperature") - adverts do not carry sensor values. MeshCore has no built-in MQTT module; MQTT export is done through an external bridge (meshcore_py-based, or a third-party tool such as MeshMonitor), not by the room server.

      A MeshCore Home Assistant integration does exist (github.com/meshcore-dev/meshcore-ha, domain meshcore), built on meshcore_py.

      Comparison with Meshtastic Telemetry

      Feature Meshtastic Telemetry module MeshCore Sensorsensor firmwaresupport
      BME280 / BME680 support Yes (auto-detected on I2C) YesYes, via built-in environmental telemetry (compiled in)
      INA219 support Yes (via power metrics) Yes
      Data propagation Mesh packet (NodeInfo / Telemetry protobuf) MeshCoreCayenneLPP advertisementtelemetry broadcastover the binary request/response protocol (pull, not broadcast)
      MQTT output Yes (via Meshtastic MQTT module)module, ESP32 gateways) RequiresNo MeshCorebuilt-in roomMQTT; serverrequires /an Pythonexternal bridge (e.g. meshcore_py or MeshMonitor)
      Dedicated sensor firmware No (runs on standard node firmware) YesNo separate variant - separatesensor Sensorsupport is compiled into the node firmware variantvia ENV_INCLUDE_* flags
      Power profile Low - configurabledominated by TX intervalduty cycle and sleep config Very lowLow - nRF52840likewise dominated by TX duty cycle and sleep between broadcastsconfig