<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://blog.meshcore.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://blog.meshcore.io/" rel="alternate" type="text/html" /><updated>2026-09-14T02:33:34+00:00</updated><id>https://blog.meshcore.io/feed.xml</id><title type="html">MeshCore Blog</title><subtitle>Posts from the MeshCore Developers</subtitle><entry><title type="html">Sensor Node Intro</title><link href="https://blog.meshcore.io/2026/09/14/sensor-intro" rel="alternate" type="text/html" title="Sensor Node Intro" /><published>2026-09-14T00:00:00+00:00</published><updated>2026-09-14T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/09/14/sensor-intro</id><content type="html" xml:base="https://blog.meshcore.io/2026/09/14/sensor-intro">&lt;p&gt;The MeshCore sensor node type is much harder to get going with as we don’t
pre-build variants with each release, like we do with repeater, companion and room server,
so it requires some developer knowledge.&lt;/p&gt;

&lt;p&gt;The reason behind this is because there simply are too many customisations
that typically would be required to accommodate, and there would have to be
thousands of variants. So, sensor nodes need to be designed for whatever purpose
they’re intended for (eg. monitoring water level in a water tank)&lt;/p&gt;

&lt;h2 id=&quot;setup&quot;&gt;Setup&lt;/h2&gt;

&lt;p&gt;You will need to install &lt;a href=&quot;https://code.visualstudio.com/download&quot;&gt;VSCode&lt;/a&gt; and once that is installed, within VSCode install the
&lt;a href=&quot;https://platformio.org/&quot;&gt;PlatformIO&lt;/a&gt; extension.&lt;/p&gt;

&lt;p&gt;Then use Git to clone the MeshCore firmware repo:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git clone https://github.com/meshcore-dev/MeshCore.git&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;starting-with-the-example&quot;&gt;Starting with the example&lt;/h2&gt;

&lt;p&gt;The sensor firmware is essentially a starter or ‘template’ firmware, which has
most of the components you’re going to need. In the project tree, it is in:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/examples/simple_sensor
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Typical customisations should only need to touch the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.cpp&lt;/code&gt; module. This
has a section which defines a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyMesh&lt;/code&gt; class, and this inherits from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SensorMesh&lt;/code&gt; 
which provides all the &lt;em&gt;plumbing&lt;/em&gt; and hooks which you can utilise.&lt;/p&gt;

&lt;h2 id=&quot;choose-a-board-variant&quot;&gt;Choose a board variant&lt;/h2&gt;

&lt;p&gt;A lot of the boards supported should already have a PlatformIO target &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt; defined
for the simple_sensor example firmware, like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[env:Heltec_v3_sensor]&lt;/code&gt;. But, you
may need to add your own &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;env&lt;/code&gt; definition in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;platformio.ini&lt;/code&gt; file in one of
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/variant&lt;/code&gt; folders.&lt;/p&gt;

&lt;p&gt;This sets up the build rules/dependencies, etc for that board+firmware role. You may
need to modify the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target.h/cpp&lt;/code&gt; files of the variant. These target modules 
assemble various global objects, like this:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;EnvironmentSensorManager&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sensors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This one is a kind of &lt;em&gt;Swiss Army knife&lt;/em&gt; helper class which the other firmwares also
use (eg. repeater) for doing the low-level work of managing physical sensors, like
BME180’s, etc. So, most of that is done for you, but you typically have to ENABLE which modules
your node is expecting to use. These can be enabled in your /variant &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;platformio.ini&lt;/code&gt; file like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;build_flags =
  -D ENV_INCLUDE_GPS=1
  -D ENV_INCLUDE_AHTX0=1
  -D ENV_INCLUDE_BME280=1
  -D ENV_INCLUDE_BMP280=1
  -D ENV_INCLUDE_SHTC3=1
  -D ENV_INCLUDE_SHT4X=1
  -D ENV_INCLUDE_LPS22HB=1
  -D ENV_INCLUDE_INA3221=1
  -D ENV_INCLUDE_INA219=1
  -D ENV_INCLUDE_INA226=1
  -D ENV_INCLUDE_INA260=1
  -D ENV_INCLUDE_MLX90614=1
  -D ENV_INCLUDE_VL53L0X=1
  -D ENV_INCLUDE_BME680=1
  -D ENV_INCLUDE_BMP085=1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;basic-concepts&quot;&gt;Basic concepts&lt;/h2&gt;

&lt;p&gt;The sensor node can utilise these features:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Alerts (with High or Low priority)&lt;/li&gt;
  &lt;li&gt;Telemetry queries (ie. other nodes can &lt;em&gt;pull&lt;/em&gt; telemetry from this node)&lt;/li&gt;
  &lt;li&gt;Time series data&lt;/li&gt;
  &lt;li&gt;Custom CLI command logic (eg. ‘turn switch A on’)&lt;/li&gt;
  &lt;li&gt;Telemetry &lt;em&gt;push&lt;/em&gt; subscriptions (NEW: will be supported soon)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;alerts&quot;&gt;Alerts&lt;/h2&gt;

&lt;p&gt;In the example this is demonstrated with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Trigger&lt;/code&gt; class and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;alertIf()&lt;/code&gt; calls:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;n&quot;&gt;Trigger&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low_batt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;critical_batt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onSensorDataRead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batt_voltage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getVoltage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TELEM_CHANNEL_SELF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;alertIf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batt_voltage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.4&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;critical_batt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HIGH_PRI_ALERT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Battery is critical!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;alertIf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;batt_voltage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;low_batt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LOW_PRI_ALERT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Battery is low&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;High priority alerts will re-try sending to nodes in the ACL which have
the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PERM_RECV_ALERTS_HI&lt;/code&gt; bit set. The sensor nodes will wait for an ACK, like 
any other text message.&lt;/p&gt;

&lt;p&gt;Low priority alerts only fire off the message &lt;em&gt;once&lt;/em&gt; and don’t wait for an ACK. These are
sent to nodes in ACL with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PERM_RECV_ALERTS_LO&lt;/code&gt; bit set.&lt;/p&gt;

&lt;h2 id=&quot;telemetry&quot;&gt;Telemetry&lt;/h2&gt;

&lt;p&gt;This is basically &lt;em&gt;automatic&lt;/em&gt; as it’s a core mechanism in MeshCore. The target/variant
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sensor&lt;/code&gt; object will handle LPP encoding all the collected telemetry
readings.&lt;/p&gt;

&lt;p&gt;Normally, other nodes to need to request telemetry from your sensor node, and a 
telemetry response is then sent, but very soon you will also be able to &lt;em&gt;subscribe&lt;/em&gt;
to Telemetry &lt;em&gt;push&lt;/em&gt;, where the sensor node sends telemetry packets to subscriber(s)
but only when certain values &lt;em&gt;change&lt;/em&gt; by some minimum amount. eg. a subscriber can
send SUBSCRIBE request, and specify that temperature must change by 2 Celcius.&lt;/p&gt;

&lt;p&gt;Telemetry push will have some guard rails to hopefully minimise abuse:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;subscription has a timeout (returned in the subscribe response), so subscribers will need to re-subscribe.&lt;/li&gt;
  &lt;li&gt;must use a region scope (as fallback, if direct path is not established)&lt;/li&gt;
  &lt;li&gt;subscriber must specify which LPP channels/types and &lt;em&gt;min deltas&lt;/em&gt; that these must change by to trigger push&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;time-series-data&quot;&gt;Time series data&lt;/h2&gt;

&lt;p&gt;The sensor can collect periodic readings, and stores these (in volatile memory, in a circular buffer)
using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TimeSeriesData&lt;/code&gt; helper class. Example:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;n&quot;&gt;TimeSeriesData&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;battery_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;MyMesh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MainBoard&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;board&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Radio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MillisecondClock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RNG&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RTCClock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rtc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mesh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;MeshTables&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SensorMesh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;board&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;radio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rtc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tables&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; 
       &lt;span class=&quot;n&quot;&gt;battery_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// 24 hours worth of battery data, every 5 minutes&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;onSensorDataRead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batt_voltage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getVoltage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TELEM_CHANNEL_SELF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;battery_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recordData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getRTCClock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;batt_voltage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// record battery&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;querySeriesData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_secs_ago&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_secs_ago&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MinMaxAvg&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;battery_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;calcMinMaxAvg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getRTCClock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start_secs_ago&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end_secs_ago&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TELEM_CHANNEL_SELF&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LPP_VOLTAGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Remote nodes can then send ‘min/max/average’ queries to the sensor node, specifying
a time range. To achieve this, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;querySeriesData()&lt;/code&gt; method must be overridden
as above. The return value is the number of data series supported by this node.&lt;/p&gt;

&lt;h2 id=&quot;custom-cli-commands&quot;&gt;Custom CLI Commands&lt;/h2&gt;

&lt;p&gt;Remote nodes can also enable actuators of different types, like turning an
LED on/off, moving a servo, etc. by adding custom CLI command logic. This is
done in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handleCustomCommand()&lt;/code&gt; method:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;handleCustomCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sender_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strcmp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;magic&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;// example 'custom' command handling&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;strcpy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;**Magic now done**&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;// handled&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// not handled&lt;/span&gt;
  &lt;span class=&quot;err&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This should be fairly straight-forward to adapt to whatever your sensor node
wants to do. Just return &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;true&lt;/code&gt; to indicate the command was intercepted and
handled, and place the CLI response  in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reply&lt;/code&gt; buffer (which is sent to command sender node).&lt;/p&gt;</content><author><name>scottpowell</name></author><summary type="html">The MeshCore sensor node type is much harder to get going with as we don’t pre-build variants with each release, like we do with repeater, companion and room server, so it requires some developer knowledge.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/2026/09/14/sensor_mesh.jpg" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/2026/09/14/sensor_mesh.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The KISS Modem</title><link href="https://blog.meshcore.io/2026/08/27/kiss-modem-intro" rel="alternate" type="text/html" title="The KISS Modem" /><published>2026-08-27T00:00:00+00:00</published><updated>2026-08-27T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/08/27/kiss-modem-intro</id><content type="html" xml:base="https://blog.meshcore.io/2026/08/27/kiss-modem-intro">&lt;p&gt;What the KISS Modem firmware role is, what it isn’t, and who it’s for.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2026/08/27/kiss-modem-hero.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Since v1.16.0 the flasher has had a KISS Modem role for most boards (the role picker calls it “KISS Radio Modem”), and going by the questions on Discord the name confuses people. So, a quick rundown.&lt;/p&gt;

&lt;p&gt;It’s the same MeshCore firmware and the same radio underneath. What changes is how you talk to the board: instead of the app, you open a serial port and speak KISS, an old and very simple protocol that amateur radio packet modems (TNCs) have used for decades. The radio stays on the board. Everything that decides what to send, and what to do with whatever comes back, runs on the computer at the other end of the cable. What you end up with is closer to a LoRa dongle for MeshCore than a node in its own right.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2026/08/27/kiss-modem-brains.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;who-its-for&quot;&gt;Who it’s for&lt;/h2&gt;

&lt;p&gt;Most people don’t need it. If you want to message from your phone, companion firmware plus the app is where to start.&lt;/p&gt;

&lt;p&gt;The KISS Modem is for people building gateways or services on a proper computer. OpenHop (formerly pyMC) is the obvious example and can use a KISS Modem as its radio.&lt;/p&gt;

&lt;p&gt;It doesn’t have to be a proper computer though. I have a Commodore 64 chatting on the mesh through one, over the user port at 600 baud, which is about all the stock KERNAL serial routines can keep up with. The C64 builds the packets and draws the screen, the modem does the LoRa and the AES.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2026/08/27/mc64-waiting-for-modem.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It’s also handy if you want to poke at MeshCore packets from a laptop in whatever language you like, without flashing custom firmware for every idea. (The companion firmware can hand you raw packets too, and since 1.16 send them, but here you get the whole radio with nothing in the way.)&lt;/p&gt;

&lt;h2 id=&quot;what-is-kiss&quot;&gt;What is KISS?&lt;/h2&gt;

&lt;p&gt;Keep It Simple, Stupid. It’s the framing amateur packet radio has used between a computer and a TNC since the 80s. MeshCore didn’t invent it, it borrowed it because it’s simple and there are libraries for it in every language.&lt;/p&gt;

&lt;p&gt;The way I think of it: KISS is the envelope, the MeshCore packet is the letter inside.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2026/08/27/kiss-envelope.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;A C0 byte on each end, a type byte, and the packet in between. That’s why the protocol doc says any KISS client (Direwolf, APRSdroid and so on) can drive the modem: they’ll happily push raw frames out through the radio. It doesn’t get them onto the mesh though. They can open the envelope, but what’s inside means nothing to them, and the mesh won’t make anything of what they send either.&lt;/p&gt;

&lt;p&gt;On top of plain KISS the firmware adds the MeshCore extras (radio settings, signal reports, battery, crypto) through a standard KISS command that plain clients ignore.&lt;/p&gt;

&lt;h2 id=&quot;what-the-board-does&quot;&gt;What the board does&lt;/h2&gt;

&lt;p&gt;Quite a lot, it just doesn’t do any of the mesh logic. It sends and receives raw MeshCore packets over LoRa. Received packets come up the serial link exactly as they came off the air, each with a signal report (RSSI and SNR) attached, and your software decides what to do with them.&lt;/p&gt;

&lt;p&gt;The host sets the radio up: frequency, bandwidth, spreading factor, coding rate and transmit power. You can also ask the board for its battery voltage, the noise floor, packet counters and whatever sensors it has, and it can estimate how long a packet would take on air at the current settings. The protocol doc has the full list.&lt;/p&gt;

&lt;p&gt;None of the radio settings survive a reboot. Apart from the board’s key pair nothing is saved, so your software sets the radio up each time it connects.&lt;/p&gt;

&lt;p&gt;It listens before it transmits so it won’t talk over other traffic, and it takes one packet at a time: it tells you when a packet has gone out and refuses a second one until then.&lt;/p&gt;

&lt;p&gt;The board has its own key pair, generated on first boot and stored in flash. The private key can’t be read out, so if you want the board’s identity on the mesh you ask the board to sign and do key exchanges for you. It can also encrypt, decrypt and verify with keys you hand it. Or you skip all of that. The board sends whatever bytes you give it and doesn’t check them, so a host that keeps its own key pair builds valid packets without ever touching the board’s crypto. OpenHop does it that way. The C64 goes the other way entirely, it hasn’t got the horsepower for AES so it hands every message to the modem to encrypt or decrypt.&lt;/p&gt;

&lt;p&gt;What it leaves out: routing, repeating, chat, room server. All of that lives on the host side.&lt;/p&gt;

&lt;h2 id=&quot;flashing-it&quot;&gt;Flashing it&lt;/h2&gt;

&lt;p&gt;Flashing is the same as any other role.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Head to &lt;a href=&quot;https://flasher.meshcore.io&quot;&gt;flasher.meshcore.io&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Pick your board&lt;/li&gt;
  &lt;li&gt;Choose the KISS Radio Modem role&lt;/li&gt;
  &lt;li&gt;Flash it&lt;/li&gt;
  &lt;li&gt;Open the board’s serial port at 115200 baud, 8N1, from software that speaks MeshCore&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2026/08/27/flasher-kiss-role.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Step 5 is where the real work lives. On nearly every board that serial port is the USB one. There is a compile-time option (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KISS_UART_RX&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KISS_UART_TX&lt;/code&gt;) to move that onto bare UART pins if you want to wire the board straight to a Pi header, but you’ll need to build the firmware yourself for that.&lt;/p&gt;

&lt;p&gt;If you’d rather not write the serial side yourself, OpenHop already has it. If you do want to roll your own, the &lt;a href=&quot;https://docs.meshcore.io/kiss_modem_protocol&quot;&gt;KISS Modem protocol&lt;/a&gt; doc covers the serial side and the &lt;a href=&quot;https://docs.meshcore.io/packet_format&quot;&gt;packet format&lt;/a&gt; page covers what goes inside the frames.&lt;/p&gt;

&lt;h2 id=&quot;where-to-start&quot;&gt;Where to start&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Flasher: &lt;a href=&quot;https://flasher.meshcore.io&quot;&gt;https://flasher.meshcore.io&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Protocol doc: &lt;a href=&quot;https://docs.meshcore.io/kiss_modem_protocol&quot;&gt;https://docs.meshcore.io/kiss_modem_protocol&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Packet format: &lt;a href=&quot;https://docs.meshcore.io/packet_format&quot;&gt;https://docs.meshcore.io/packet_format&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;OpenHop: &lt;a href=&quot;https://github.com/openhop-dev/openhop_repeater&quot;&gt;https://github.com/openhop-dev/openhop_repeater&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you get something running on it, post it on the &lt;a href=&quot;https://meshcore.gg&quot;&gt;Discord&lt;/a&gt;, I’d like to see what people wire it into.&lt;/p&gt;</content><author><name>viezevingertjes</name></author><category term="Firmware" /><category term="KISS" /><summary type="html">What the KISS Modem firmware role is, what it isn’t, and who it’s for.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/2026/08/27/kiss-modem-hero.png" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/2026/08/27/kiss-modem-hero.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Release v1.17.1</title><link href="https://blog.meshcore.io/2026/08/14/release-1-17-1" rel="alternate" type="text/html" title="Release v1.17.1" /><published>2026-08-14T00:00:00+00:00</published><updated>2026-08-14T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/08/14/release-1-17-1</id><content type="html" xml:base="https://blog.meshcore.io/2026/08/14/release-1-17-1">&lt;p&gt;&lt;img src=&quot;/assets/images/firmware_release.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;download&quot;&gt;Download&lt;/h2&gt;

&lt;p&gt;Latest firmwares are in the &lt;a href=&quot;https://flasher.meshcore.io/&quot;&gt;flasher.meshcore.io&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;change-log&quot;&gt;Change Log&lt;/h2&gt;

&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3137&quot;&gt;#3137&lt;/a&gt; new ‘get/set radio.fem.rxgain/txgain’ CLI commands (txgain is Station G3 only), fixed pref mapping for radio.fem.rxgain&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3148&quot;&gt;#3148&lt;/a&gt; added missing kiss radio roles, kiss radio build added to build.sh&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enhancements&quot;&gt;Enhancements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3106&quot;&gt;#3106&lt;/a&gt; login response no longer sent as flood on direct login, fix for unscoped flood login&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3146&quot;&gt;#3146&lt;/a&gt; LR2021: PREAMBLE_DETECTED bit and IRQ rx timeout logic&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3154&quot;&gt;#3154&lt;/a&gt; NRF52 CC310: nRFCrypto.begin()/end() now called only once&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3166&quot;&gt;#3166&lt;/a&gt; RadioLibWrapper noise floor debug print moved behind new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MESH_DEBUG_NOISE_FLOOR&lt;/code&gt; flag&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3206&quot;&gt;#3206&lt;/a&gt; nRF RadioNoiseListener RNG now combines entropy from radio and CC310&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bug-fixes-and-other&quot;&gt;Bug fixes and Other&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3140&quot;&gt;#3140&lt;/a&gt; T-Echo Lite pins aligned to updated Lilygo schematic, TCXO voltage set to 3.0V&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3142&quot;&gt;#3142&lt;/a&gt; build fix for R1 Neo and Minewsemi repeater&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3158&quot;&gt;#3158&lt;/a&gt; Rx boosted gain no longer reset to compiled value after AGC reset&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3164&quot;&gt;#3164&lt;/a&gt; T-Beam Supreme S3 display fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3170&quot;&gt;#3170&lt;/a&gt; ProMicro pinmap tidy up, LoRa pins moved to variant.h&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3185&quot;&gt;#3185&lt;/a&gt; T-Echo Card TCXO voltage set to 3.0V as per &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3140&quot;&gt;#3140&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3188&quot;&gt;#3188&lt;/a&gt; Heltec T096 Tx failure fixed (out of bounds PIN_SPI1_MISO)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3189&quot;&gt;#3189&lt;/a&gt; Heltec T1 / MeshPocket / T-Echo Lite: unused pin fix (&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/issues/3151#issuecomment-5268905160&quot;&gt;root cause&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3203&quot;&gt;#3203&lt;/a&gt; Companion: fem_radio_rx/txgain pref disabled until settable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;fixes-and-enhancements-for-devices-with-fem&quot;&gt;Fixes and enhancements for devices with FEM&lt;/h2&gt;
&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radio.fem.rxgain&lt;/code&gt; setting was not being persisted properly in v1.17.0, this is now fixed. Repeater admins will want to check that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radio.fem.rxgain&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;radio.rxgain&lt;/code&gt; are configured to their liking after updating.
Companion firmware currently has no way to configure these settings, so they they will use the default values only for now.&lt;/p&gt;

&lt;h2 id=&quot;heltec-t096-transmit-issue-fix&quot;&gt;Heltec T096 Transmit issue fix&lt;/h2&gt;
&lt;p&gt;The Heltec T096 transmit issue was found to be an out of bounds read of the pin map due to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PIN_SPI1_MISO&lt;/code&gt; being set to -1. It was causing the FEM’s Tx enable pin to stop working. This has been fixed and other NRF52 boards have had their unused pins corrected.&lt;/p&gt;</content><author><name>admin</name></author><category term="Announcements" /><category term="Firmware" /><category term="Release" /><summary type="html">Download Latest firmwares are in the flasher.meshcore.io Change Log New Features #3137 new ‘get/set radio.fem.rxgain/txgain’ CLI commands (txgain is Station G3 only), fixed pref mapping for radio.fem.rxgain #3148 added missing kiss radio roles, kiss radio build added to build.sh Enhancements #3106 login response no longer sent as flood on direct login, fix for unscoped flood login #3146 LR2021: PREAMBLE_DETECTED bit and IRQ rx timeout logic #3154 NRF52 CC310: nRFCrypto.begin()/end() now called only once #3166 RadioLibWrapper noise floor debug print moved behind new MESH_DEBUG_NOISE_FLOOR flag #3206 nRF RadioNoiseListener RNG now combines entropy from radio and CC310 Bug fixes and Other #3140 T-Echo Lite pins aligned to updated Lilygo schematic, TCXO voltage set to 3.0V #3142 build fix for R1 Neo and Minewsemi repeater #3158 Rx boosted gain no longer reset to compiled value after AGC reset #3164 T-Beam Supreme S3 display fix #3170 ProMicro pinmap tidy up, LoRa pins moved to variant.h #3185 T-Echo Card TCXO voltage set to 3.0V as per #3140 #3188 Heltec T096 Tx failure fixed (out of bounds PIN_SPI1_MISO) #3189 Heltec T1 / MeshPocket / T-Echo Lite: unused pin fix (root cause) #3203 Companion: fem_radio_rx/txgain pref disabled until settable. Fixes and enhancements for devices with FEM The radio.fem.rxgain setting was not being persisted properly in v1.17.0, this is now fixed. Repeater admins will want to check that radio.fem.rxgain and radio.rxgain are configured to their liking after updating. Companion firmware currently has no way to configure these settings, so they they will use the default values only for now. Heltec T096 Transmit issue fix The Heltec T096 transmit issue was found to be an out of bounds read of the pin map due to PIN_SPI1_MISO being set to -1. It was causing the FEM’s Tx enable pin to stop working. This has been fixed and other NRF52 boards have had their unused pins corrected.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/firmware_release.jpg" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/firmware_release.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Release v1.17.0</title><link href="https://blog.meshcore.io/2026/08/09/release-1-17-0" rel="alternate" type="text/html" title="Release v1.17.0" /><published>2026-08-09T00:00:00+00:00</published><updated>2026-08-09T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/08/09/release-1-17-0</id><content type="html" xml:base="https://blog.meshcore.io/2026/08/09/release-1-17-0">&lt;p&gt;&lt;img src=&quot;/assets/images/firmware_release.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;download&quot;&gt;Download&lt;/h2&gt;

&lt;p&gt;Latest firmwares are in the &lt;a href=&quot;https://flasher.meshcore.io/&quot;&gt;flasher.meshcore.io&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;change-log&quot;&gt;Change Log&lt;/h2&gt;

&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2987&quot;&gt;#2987&lt;/a&gt; companion, MCU temperature added to sensor telemetry&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3115&quot;&gt;#3115&lt;/a&gt; LR2021 radio support added. (Also Meshnology W12 added)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2688&quot;&gt;#2688&lt;/a&gt; new room server ‘room.post’ CLI command (for server orig posts)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2883&quot;&gt;#2883&lt;/a&gt; repeater power off on long button press&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/1727&quot;&gt;#1727&lt;/a&gt; new ‘set cad on/off’ CLI command&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2765&quot;&gt;#2765&lt;/a&gt; ESP targets now support the ‘get pwrmgt.bootreason’ CLI command&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2140&quot;&gt;#2140&lt;/a&gt; new ‘get/set radio.fem.rxgain’ CLI command (some Heltec boards)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enhancements&quot;&gt;Enhancements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3036&quot;&gt;#3036&lt;/a&gt; fix for missing preamble detect IRQ bit&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2977&quot;&gt;#2977&lt;/a&gt; preamble and header IRQ rx timeout logic&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2824&quot;&gt;#2824&lt;/a&gt; nrf52 targets now use CC310 hardware crypto functions&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2982&quot;&gt;#2982&lt;/a&gt; config now stored in JSON format (all firmwares)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3034&quot;&gt;#3034&lt;/a&gt; new color scheme on companion UI&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3023&quot;&gt;#3023&lt;/a&gt; room server now supports rx boosted gain&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2951&quot;&gt;#2951&lt;/a&gt; Fast ST7735 disply driver (Heltec T096, Wireless Tracker, etc)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2895&quot;&gt;#2895&lt;/a&gt; hibernate/poweroff power draw savings&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;new-device-support&quot;&gt;New device support&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3139&quot;&gt;#3139&lt;/a&gt; Sensecap X1, QSPI Flash support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3122&quot;&gt;#3122&lt;/a&gt; Sensecap X1, LED and haptic feedback&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3112&quot;&gt;#3112&lt;/a&gt; added Sensecap MeshTracker X1 support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3049&quot;&gt;#3049&lt;/a&gt; Thinknode M7 support, plus architecture for universal companion&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2966&quot;&gt;#2966&lt;/a&gt; added Heltec RC32 board support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2560&quot;&gt;#2560&lt;/a&gt; added Heltec V4 R8 board support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/1983&quot;&gt;#1983&lt;/a&gt; support for RAK ethernet modules&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2942&quot;&gt;#2942&lt;/a&gt; added Elecrow Thinknode M9 support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2839&quot;&gt;#2839&lt;/a&gt; added Elecrow Thinknode M7 support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/1194&quot;&gt;#1194&lt;/a&gt; added Nibble Zero Connect support&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2752&quot;&gt;#2752&lt;/a&gt; added Heltec tower V2 support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bug-fixes-and-other&quot;&gt;Bug fixes and Other&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3121&quot;&gt;#3121&lt;/a&gt; companion, hardware CAD disabled&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3107&quot;&gt;#3107&lt;/a&gt; ANON_REQ reply path_len check&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2863&quot;&gt;#2863&lt;/a&gt; Thinknode M6 GPS re-init fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3048&quot;&gt;#3048&lt;/a&gt; ‘start ota’ failure now reported on nRF devices&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2819&quot;&gt;#2819&lt;/a&gt; kiss modem fixes for stalls under USB backpressure&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3005&quot;&gt;#3005&lt;/a&gt; ESP32, BLE bonded reconnects fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3007&quot;&gt;#3007&lt;/a&gt; ESP32, BLE receive queue synchronization&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3006&quot;&gt;#3006&lt;/a&gt; Heltec V4 hardware USB serial&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2815&quot;&gt;#2815&lt;/a&gt; T-Beam Supreme OLED fixes&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2887&quot;&gt;#2887&lt;/a&gt; Thinknode M3, GPS LED fixes&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2990&quot;&gt;#2990&lt;/a&gt; Xiao nrf52 repeater build fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2899&quot;&gt;#2899&lt;/a&gt; T-Echo Lite DC-DC regulator fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2905&quot;&gt;#2905&lt;/a&gt; Heltec T114 DC-DC regulator fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2937&quot;&gt;#2937&lt;/a&gt; fix for GPS time sync stall on long uptime nodes&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2936&quot;&gt;#2936&lt;/a&gt; external watchdog timer for Heltec Tower V2&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2867&quot;&gt;#2867&lt;/a&gt; sx1262 LDO support fix&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2844&quot;&gt;#2844&lt;/a&gt; fixed rx boosted gain on LR1110&lt;/li&gt;
  &lt;li&gt;GPS time sync fix for Heltec T114&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2763&quot;&gt;#2763&lt;/a&gt; companion fix when anon contacts full&lt;/li&gt;
  &lt;li&gt;bad path_len now rejected, in PAYLOAD_TYPE_PATH and ANON_REQ&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;packet-collision-improvements&quot;&gt;Packet Collision Improvements&lt;/h2&gt;

&lt;p&gt;The ‘listen-before-talk’ code has had some pretty big changes, thanks to Taco.
He has spent weeks doing diagnostics, and even simulations, testing an improved
scheme which involves handling cases where the LoRa radio’s IRQ flags get
‘stuck’, and also the big one being proper preamble detection. This one
could be the most significant performance improvement for all meshes.&lt;/p&gt;

&lt;p&gt;Also, he found that the new scheme performs on par with hardware CAD, but without the
4 second lock-up glitches that CAD still suffers from. So, we are still leaving
hardware CAD off by default.&lt;/p&gt;

&lt;h2 id=&quot;companion-ui&quot;&gt;Companion UI&lt;/h2&gt;

&lt;p&gt;Various color displays will now sport a new look, and be much more responsive.&lt;/p&gt;

&lt;h2 id=&quot;json-config&quot;&gt;JSON Config&lt;/h2&gt;

&lt;p&gt;The node config should be automatically migrated to a new JSON format
upon upgrading to v1.17.0.  The old binary-blob config is left intact, however,
in case some people need to revert to old firmware.&lt;/p&gt;

&lt;h2 id=&quot;steps-toward-universal-companion&quot;&gt;Steps Toward Universal Companion&lt;/h2&gt;

&lt;p&gt;With &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/3049&quot;&gt;#3049&lt;/a&gt; Liam has paved
the way for companions to support multiple serial interfaces, eg. BLE + USB. Up to 4
can now be supported. There are no official multi-interface companion builds &lt;em&gt;yet&lt;/em&gt;, 
but all the ‘plumbing’ for this is now there.&lt;/p&gt;</content><author><name>admin</name></author><category term="Announcements" /><category term="Firmware" /><category term="Release" /><summary type="html"></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/firmware_release.jpg" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/firmware_release.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Thank You</title><link href="https://blog.meshcore.io/2026/07/28/thankyou" rel="alternate" type="text/html" title="Thank You" /><published>2026-07-28T00:00:00+00:00</published><updated>2026-07-28T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/07/28/thankyou</id><content type="html" xml:base="https://blog.meshcore.io/2026/07/28/thankyou">&lt;p&gt;The &lt;a href=&quot;https://givealittle.co.nz/cause/help-us-save-meshcore&quot;&gt;GiveALittle fundraiser&lt;/a&gt; is now closed, and the results, even after the first 12 hours, were
overwhelming!&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/28/goal-reached.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We were all blown away by the response, and it has been great to know that the community has our back.
There we some remarkable donations by individuals, in the thousands of dollars, but even more modest ones
that were clearly by &lt;em&gt;battlers&lt;/em&gt; not exactly well off. We also had some of the manufacturers get in touch
and insisted on being anonymous donors. All of it much appreciated.&lt;/p&gt;

&lt;p&gt;Your comments and wishes were very encouraging. Here’s a sample:&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/28/c1.png&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/28/c2.png&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/28/c3.png&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/28/c4.png&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/28/c5.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;There have also been many new &lt;a href=&quot;https://github.com/sponsors/meshcore-dev/&quot;&gt;Github sponsor&lt;/a&gt; supporters, and this is equally appreciated.&lt;/p&gt;

&lt;h2 id=&quot;current-status&quot;&gt;Current Status&lt;/h2&gt;

&lt;p&gt;So, the UK lawyer has now officially submitted the opposition, and the trademark
is now in &lt;em&gt;opposed&lt;/em&gt; status. We don’t have any definite dates yet, but essentially
it’s a waiting game now.&lt;/p&gt;

&lt;p&gt;Hopefully there is more than enough evidence presented to determine a ruling, but
the law is difficult to understand, and nothing is really guaranteed.&lt;/p&gt;

&lt;h2 id=&quot;onwards&quot;&gt;Onwards&lt;/h2&gt;

&lt;p&gt;The uncertainty is still difficult to deal with at times, but overall we’re positive
about the future, and there are many options still available. There are solid improvements
coming in the v1.17.0 release, and many more long-term improvements we are busy with. So, the tech
goes on regardless.&lt;/p&gt;

&lt;p&gt;Once again, thank you all for your generosity and your ongoing commitment to
the project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The MeshCore Team&lt;/em&gt;&lt;/p&gt;</content><author><name>admin</name></author><summary type="html">The GiveALittle fundraiser is now closed, and the results, even after the first 12 hours, were overwhelming!</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/2026/07/28/thankyou-icon.png" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/2026/07/28/thankyou-icon.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Help Us Save MeshCore</title><link href="https://blog.meshcore.io/2026/07/04/help-us-save-meshcore" rel="alternate" type="text/html" title="Help Us Save MeshCore" /><published>2026-07-04T00:00:00+00:00</published><updated>2026-07-04T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/07/04/help-us-save-meshcore</id><content type="html" xml:base="https://blog.meshcore.io/2026/07/04/help-us-save-meshcore">&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/07/04/meshcore-banner-short.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;foreword-by-scott-powell&quot;&gt;Foreword, by Scott Powell&lt;/h2&gt;

&lt;p&gt;Many of you got into MeshCore because it answered an as-yet unknown call. 
The project had its beginnings &lt;a href=&quot;https://buymeacoffee.com/ripplebiz/the-future-3211940&quot;&gt;here&lt;/a&gt; in late 2024, when I was
frustrated that there was no sufficiently open and permissive mesh protocol which could
form the centre of a vibrant ecosystem. From the start, I made my intentions clear, that I wanted
an open protocol, an open source core engine, but also permissive of 3rd party products that could build on top of it.
I then spent the next two months designing and writing what became the &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore&quot;&gt;C++ MeshCore engine&lt;/a&gt;, and the 3 main firmware roles.&lt;/p&gt;

&lt;p&gt;What I also made clear were the &lt;a href=&quot;https://buymeacoffee.com/ripplebiz/meshcore-philosophy&quot;&gt;principles&lt;/a&gt; that project was founded on.
What has been great to see is how MeshCore has attracted the &lt;em&gt;right&lt;/em&gt; people, as many have
noted and found the general &lt;em&gt;spirit&lt;/em&gt; of conversations to be very positive and cooperative.&lt;/p&gt;

&lt;p&gt;I believe its success has rested on two main pillars:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;technical pragmatism (eg. keep it simple)&lt;/li&gt;
  &lt;li&gt;a positive and appropriate ethic for the times we’re in (eg. heavy gov/corp tracking and censorship)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As many of you know, a &lt;a href=&quot;/2026/04/23/the-split&quot;&gt;team split&lt;/a&gt; occurred earlier this year due to a steady erosion of trust, which culminated
in a trademark filing that completely went behind the core team’s back. We are now on a &lt;em&gt;war footing&lt;/em&gt; as
&lt;strong&gt;every&lt;/strong&gt; attempt from us to come to an understanding has been met with contempt by the former member.&lt;/p&gt;

&lt;p&gt;All of this could have been avoided with one simple email from him: to state his intentions upon winning
the legal mark. That’s it. I’ve made my intentions for MeshCore widely known, but the former
member prefers to hide his intentions (and his methods). Part of the huge backlash against him and his derived
products is precisely because of his lack of openness. He has plenty of time
to rebrand even the latest MeshCore releases, modify them, promote them as his own, but he doesn’t
even have time to send us, the core team, a single email?&lt;/p&gt;

&lt;p&gt;And the irony is he primarily wants to steer people &lt;em&gt;from&lt;/em&gt; the MeshCore brand &lt;em&gt;to&lt;/em&gt; his own brand! MeshCore
is simply a stepping stone, yet he still has shown no intention of dropping the trademark filing. It begs the question, why?&lt;/p&gt;

&lt;p&gt;As a result, we have burned countless days and dollars mounting a legal challenge. This has
been very draining, and has been &lt;em&gt;hurting&lt;/em&gt; the project. PR’s pile up, and features we’d hoped to have done 
by now still haven’t been touched. So, we &lt;em&gt;need&lt;/em&gt; to get this behind us and get the project back on track.&lt;/p&gt;

&lt;p&gt;But, for the next phase, we need your help.&lt;/p&gt;

&lt;p&gt;We are approaching the &lt;em&gt;pointy&lt;/em&gt; end of the legals, with a deadline looming, and
crossing the next threshold is going to cost a lot, so we’re asking for help.
The details will be explained further in this post, by Liam and the rest of the team.&lt;/p&gt;

&lt;p&gt;I just want to get back to where we keep pushing where MeshCore is going, innovating and seeing
just what is &lt;em&gt;possible&lt;/em&gt; with a community-run mesh. We have SO much still to do! And hopefully we’ll
be back on track again soon.&lt;/p&gt;

&lt;p&gt;warm regards,&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Scott&lt;/em&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;timeline-summary&quot;&gt;Timeline Summary&lt;/h2&gt;

&lt;p&gt;We’ve included some key information from the timeline of events relating to this dispute below.
For the purposes of the timeline, we refer to the former team member as &lt;em&gt;AK&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;16/Nov/2024&lt;/strong&gt; Scott shares &lt;a href=&quot;https://buymeacoffee.com/ripplebiz/the-future-3211940&quot;&gt;blog post&lt;/a&gt; announcing his plans to work on MeshCore.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;20/Jan/2025&lt;/strong&gt; Scott publishes his open source MeshCore project on GitHub.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;(things are going well for more than 1 year, with a thriving community)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;(trust with AK was starting to erode)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;(some internal disagreements came up)&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;29/Mar/2026&lt;/strong&gt; AK secretly files for UK trademark.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;03/Apr/2026&lt;/strong&gt; We confronted AK on the filings. Conversation broke down with no resolution.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;10/Apr/2026&lt;/strong&gt; Liam and Scott start New Zealand company “MeshCore Technologies Limited”.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;11/Apr/2026&lt;/strong&gt; We file for MeshCore logo trademark in New Zealand.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;20/Apr/2026&lt;/strong&gt; AK secretly files for EU trademark.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;23/Apr/2026&lt;/strong&gt; We announce &lt;a href=&quot;/2026/04/23/the-split&quot;&gt;team split&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;25/Apr/2026&lt;/strong&gt; We start engagements with legal counsel.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;06/May/2026&lt;/strong&gt; We file for logo trademark in Australia.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;06/May/2026&lt;/strong&gt; We file for word trademark in Australia, New Zealand, United States and China.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;07/May/2026&lt;/strong&gt; We ask AK (again) to withdraw the UK/EU trademarks.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;07/May/2026&lt;/strong&gt; AK responds saying he won’t withdraw the UK/EU trademark applications.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;08/May/2026&lt;/strong&gt; AK says we will need to form some sort of commercial agreement with him.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;09/May/2026&lt;/strong&gt; We ask AK for a proposal around trademark rights. He says he’ll have a think about it and get back to us.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;19/May/2026&lt;/strong&gt; We follow up via email and discord asking again, about a proposal around the trademarks.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;04/Jun/2026&lt;/strong&gt; We file for subsequent international designations for word trademark in Canada, Switzerland, European Union and United Kingdom.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;12/Jun/2026&lt;/strong&gt; Our lawyers send notice of threatened opposition and extend UK trademark opposition period from 17/June/2026 to 17/July/2026.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;18/Jun/2026&lt;/strong&gt; Our lawyers send demand letter to AK. (alleges copyright infringement, stolen assets, and tool cloning, which can be seen in file names and api responses of .uk site)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;24/Jun/2026&lt;/strong&gt; AK responds to our demand letter. (denies any wrong doing or bad faith, refusing &lt;em&gt;all&lt;/em&gt; desist orders)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;25/Jun/2026&lt;/strong&gt; We reach out to AK one more time via email and discord, giving him another opportunity to provide us with a proposal around the trademarks, however received no reply.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-not-just-rename&quot;&gt;Why Not Just Rename?&lt;/h2&gt;

&lt;p&gt;We know some of you might be thinking, &lt;em&gt;“Why not just rename the project and move on?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The short answer is, we shouldn’t have to. We came up with the name, hand crafted the firmware and are still the original core maintainers of the project.&lt;/p&gt;

&lt;p&gt;It also sets a dangerous precedent, that if an open source project simply folds and rebrands every time a bad faith actor tries to claim a trademark, it signals that open source developers can always be bullied out of their own hard work.&lt;/p&gt;

&lt;p&gt;So instead, we are choosing to stand our ground and fight for the name we earned, and for the future of the project and our community.&lt;/p&gt;

&lt;p&gt;If AK becomes successful in registering the trademark, all it will do is fracture an already well established, global ecosystem.
It doesn’t make sense why he’s still pursuing this, especially after the massive backlash from the community.&lt;/p&gt;

&lt;h2 id=&quot;keeping-the-core-human--open-source&quot;&gt;Keeping the Core &lt;em&gt;Human&lt;/em&gt; &amp;amp; Open Source&lt;/h2&gt;

&lt;p&gt;This fight also highlights exactly where things are headed if AK gets control of the name.&lt;/p&gt;

&lt;p&gt;While some of the apps/clients in our ecosystem may be closed source, our core firmware and libraries have &lt;em&gt;always&lt;/em&gt; been strictly open source, and written by humans.&lt;/p&gt;

&lt;p&gt;AK’s version proves his trajectory, taking open source community code, feeding it to an AI, locking it down, and making it closed source, for profit.&lt;/p&gt;

&lt;p&gt;Supporting us in this fight is a vote to keep the core firmware free, open, and community driven.&lt;/p&gt;

&lt;h2 id=&quot;the-next-step&quot;&gt;The Next Step&lt;/h2&gt;

&lt;p&gt;So, now we’re facing the expensive part of all this…&lt;/p&gt;

&lt;p&gt;Unfortunately, AK is forcing this with his refusal to provide any workable resolution to this conflict.&lt;/p&gt;

&lt;p&gt;As we are getting closer to the deadline, we now need to push ahead with legal opposition of the trademarks.
At this stage, we’ve only extended the deadline for submitting our opposition arguments.
Should AK try to defend the opposition, we plan to proceed with prosecution through the courts.&lt;/p&gt;

&lt;p&gt;We have been given some estimated costs by our lawyers, totalling around $18,000 USD.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;~$3,000 USD - Legal fees to oppose the UK trademark application.&lt;/li&gt;
  &lt;li&gt;~$9,000 USD - Legal fees to proceed to prosecution if the UK trademark opposition is defended.&lt;/li&gt;
  &lt;li&gt;~$6,000 USD - Legal fees to file an invalidation action for the EU trademark.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition to this, we have already personally covered more than $15,000 towards counter-trademark filings (in other jurisdictions), legal fees and extension of opposition deadlines.&lt;/p&gt;

&lt;p&gt;Nearly all five of the core team members do MeshCore work part time.
And up until recently, the project has had no central revenue earning capability (unlike similar projects like Meshtastic).&lt;/p&gt;

&lt;p&gt;Because of this, the project is very underfunded. However, none of us have really minded. We do the work because we want to see it succeed.&lt;/p&gt;

&lt;p&gt;Very recently, we started a &lt;a href=&quot;https://github.com/sponsors/meshcore-dev/&quot;&gt;GitHub Sponsors page&lt;/a&gt;, and it’s been great to see so many of you donate to us.&lt;/p&gt;

&lt;p&gt;As this hasn’t been running for very long, unfortunately we haven’t accrued anywhere near enough to cover the legal costs.
So we’ve now started a &lt;a href=&quot;https://givealittle.co.nz/cause/help-us-save-meshcore&quot;&gt;crowd funding campaign&lt;/a&gt;, in an attempt to raise the required funds to continue the legal challenge.&lt;/p&gt;

&lt;p&gt;We are now asking the MeshCore community for any support you may be able to provide us in our fight to protect the MeshCore project’s name and future.
Any contribution you are able to provide will be greatly appreciated.&lt;/p&gt;

&lt;h2 id=&quot;what-happens-if-we-win&quot;&gt;What Happens If We Win&lt;/h2&gt;

&lt;p&gt;If we win the legal opposition, we will need to start a process to get consensus on what the trademark (and logo) ‘fair use’ policy should be.
We would be looking for suggestions from the community, and would reach out for comments when we get to that stage.&lt;/p&gt;

&lt;p&gt;We’ve always had a pretty &lt;em&gt;liberal&lt;/em&gt; attitude to the use of the name and logo, but we will have to have some formal rules
around it, and a means to prohibit any ‘bad faith’ or abusive uses.&lt;/p&gt;

&lt;p&gt;Other than that, the project would continue as normal. Instead of dealing with this legal dispute, we’d have more time to put toward working through our growing pile of feature requests!&lt;/p&gt;

&lt;h2 id=&quot;what-happens-if-challenge-is-not-viable&quot;&gt;What Happens If Challenge Is Not Viable&lt;/h2&gt;

&lt;p&gt;In the event that the trademark opposition is unsuccessful and a prosecution through the courts is not viable, say due to insufficient
funding, we would pool any raised funds into the GitHub Sponsors fund, with plans for it to benefit the MeshCore community directly.&lt;/p&gt;

&lt;p&gt;We’ve wanted to establish things like bug bounties, and some way of rewarding the top contributors after each release.
These funds could end up at least helping the future of the project in more practical ways, by helping the
efforts be more sustainable.&lt;/p&gt;

&lt;p&gt;So far, from our generous sponsors, we have accrued around ~$1,800.&lt;/p&gt;

&lt;h2 id=&quot;our-final-request-to-andy&quot;&gt;Our Final Request to Andy&lt;/h2&gt;

&lt;p&gt;Andy, if you’re reading this, we urge you to withdraw your trademark applications.
Please consider the long term health and future of the MeshCore project, and bring this dispute to a close.&lt;/p&gt;

&lt;p&gt;All it takes is a quick email to the trademark offices requesting the withdrawal of your filings.
If you do that, we will drop our legal challenges, and we can all move on, allowing us more time and energy for the project.&lt;/p&gt;

&lt;p&gt;Otherwise, we have compiled all necessary evidence, and are fully prepared to push forward with defending our open source project.&lt;/p&gt;

&lt;h2 id=&quot;help-support-the-meshcore-team&quot;&gt;Help Support the MeshCore Team&lt;/h2&gt;

&lt;p&gt;If you’d like to help support the MeshCore project, please consider donating through our links below.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Crowd Funding Campaign: &lt;a href=&quot;https://givealittle.co.nz/cause/help-us-save-meshcore&quot;&gt;https://givealittle.co.nz/cause/help-us-save-meshcore&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;GitHub Sponsors: &lt;a href=&quot;https://github.com/sponsors/meshcore-dev/&quot;&gt;https://github.com/sponsors/meshcore-dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if you’re unable to contribute financially, sharing this post will help us tremendously.&lt;/p&gt;

&lt;p&gt;We appreciate all the support we can get.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The MeshCore Team&lt;/em&gt;&lt;/p&gt;</content><author><name>admin</name></author><summary type="html"></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/icon.png" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/icon.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">OTA Updates by Drone</title><link href="https://blog.meshcore.io/2026/06/22/drone-ota" rel="alternate" type="text/html" title="OTA Updates by Drone" /><published>2026-06-22T00:00:00+00:00</published><updated>2026-06-22T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/06/22/drone-ota</id><content type="html" xml:base="https://blog.meshcore.io/2026/06/22/drone-ota">&lt;p&gt;&lt;em&gt;OTA Updating hard to reach nRF52 based repeaters with a drone&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;As we added more and more repeaters to our local mesh in Slovakia, we found out it’s not always possible to physically reach some repeater sites often enough. We incrementally got better in addressing this issue by experimenting with different approaches.
I built a &lt;a href=&quot;https://github.com/recrof/nrf_dfu_py&quot;&gt;custom nrf dfu app that works on desktop OSes&lt;/a&gt;, so you can use &lt;a href=&quot;https://github.com/recrof/nrf_dfu_py/tree/main/adapter-antenna-buying-tips&quot;&gt;external bluetooth adapters with rp-sma ports and directional antennas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/06/22/nrf_dfu_py.jpg&quot; /&gt;
&lt;sup class=&quot;mx-auto&quot;&gt;Updating local repeater with uConsole, high-power BLE adapter and directional antenna&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;My buddy lucidnx started to experiment with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nrf_dfu_py&lt;/code&gt; and created a &lt;a href=&quot;https://github.com/lucidnx/meshcore-drone-updater&quot;&gt;whole framework for drone updating&lt;/a&gt;. This solution works well, but the rpi zero approach is not trivial to setup, requires additional DIY and it’s hard to use and debug. That’s why I decided to build more user-friendly version, so the drone doesn’t need to carry whole linux board on its back.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/06/22/rpi_drone.jpg&quot; /&gt;
&lt;sup class=&quot;mx-auto&quot;&gt;Older version of Drone updater - with Raspberry Pi Zero 2W and hefty battery pack. 70g total payload&lt;/sup&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-star-of-the-show&quot;&gt;The Star of the Show&lt;/h2&gt;

&lt;p&gt;Xiao nRF52840 packs a perfect combination of things you want for very small low-power repeater updater: nRF MCU is power efficient, it has 2MB of onboard flash and it has full blown USB controller. Inspired with Arduino bootloader that has UF2 mode, I decided to use the external 2MB flash as Mass Storage with real FAT12 filesystem, so you can even use a phone to copy over the firmware file, configure the updater and review the update log - very handy in the field.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/06/22/xiao_drone.jpg&quot; /&gt;
&lt;sup class=&quot;mx-auto&quot;&gt;DJI Neo2 with Xiao nRF52840 updater and 250mAh Li-Ion battery. 7.5g total payload&lt;/sup&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-setup-and-use-the-updater&quot;&gt;How to setup and use the updater&lt;/h2&gt;

&lt;p&gt;Be sure the repeater you want to update uses &lt;a href=&quot;https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX/releases/&quot;&gt;oltaco’s OTAFIX bootloader&lt;/a&gt; with version at least 2.1 or higher&lt;/p&gt;

&lt;p&gt;Get the firmware on &lt;a href=&quot;https://github.com/recrof/xiao_nrf52_updater/releases&quot;&gt;Project releases page&lt;/a&gt;. There are 2 boards supported: Xiao nRF52840 and RAK3401/RAK4631 with RAK15001 external flash module. We’ll focus on Xiao, as that’s easier to pick up for most of the readers.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Download &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;updater-xiao_nrf52840-vX.X.uf2&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Connect Xiao to your computer over USB&lt;/li&gt;
  &lt;li&gt;Double click the small reset button near the USB port - you might need to use your fingernail to do it&lt;/li&gt;
  &lt;li&gt;Copy the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;updater-xiao_nrf52840-vX.X.uf2&lt;/code&gt; to newly opened usb drive&lt;/li&gt;
  &lt;li&gt;Xiao will restart(you might get error about unsuccessful transfer, disregard)&lt;/li&gt;
  &lt;li&gt;You will be presented with new empty USB drive labeled &lt;strong&gt;“XIAO DFU”&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Copy &lt;a href=&quot;https://raw.githubusercontent.com/recrof/xiao_nrf52_updater/refs/heads/main/config.txt&quot;&gt;config.txt&lt;/a&gt; over to the USB disk&lt;/li&gt;
  &lt;li&gt;Open the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;config.txt&lt;/code&gt; with text editor&lt;/li&gt;
  &lt;li&gt;Set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ble_name&lt;/code&gt; to OTA name your repeater uses, here are few examples:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4631 | 3401&lt;/code&gt; for RAK based boars - covers both RAK4631 and RAK3401 1W&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SENSECAP | SCAP&lt;/code&gt; for Seeed SenseCap Solar P1&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;XIAO&lt;/code&gt; for XIAO NRF52 based repeater(yeah, you can update Xiao with your Xiao!)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T114&lt;/code&gt; for Heltec T114&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProMicro | PROM&lt;/code&gt; for FakeTec / Promicro based boards&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;(optional) Set any config parameters you like, but the defaults are well balanced already&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://flasher.meshcore.io/&quot;&gt;Download&lt;/a&gt; and copy firmware &lt;strong&gt;zip&lt;/strong&gt; that you want to flash to your repeater&lt;/li&gt;
  &lt;li&gt;Decide how you want to power your Xiao board.. I would recommend to solder battery leads to &lt;a href=&quot;https://files.seeedstudio.com/wiki/XIAO-BLE/XIAO_nRF52840_back_pinout.png&quot;&gt;battery pads&lt;/a&gt;, but you can wing it with USB power if want.&lt;/li&gt;
  &lt;li&gt;Attach the Xiao to your drone, send &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start ota&lt;/code&gt; to your repeater and make sure Xiao is blinking blue - that means it’s ready to flash your repeater&lt;/li&gt;
  &lt;li&gt;Fly near the target as close as you can - transfer will start as soon as Updater detects ble_name with min_rssi or better.&lt;/li&gt;
  &lt;li&gt;Keep Pinging your repeater via LoRa - it will tell you if the process started and later after few minutes, starts to be reachable again.&lt;/li&gt;
  &lt;li&gt;Get your drone back and look at the Xiao LED color - if it’s GREEN, the update was successful, if it’s RED, it failed. if it still blinks blue, that means the update did not even start - ble_name was not set right, the rssi was too weak or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;start ota&lt;/code&gt; failed&lt;/li&gt;
  &lt;li&gt;(optional) you can look into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log.txt&lt;/code&gt; in Xiao’s USB drive - it should hold update process with timestamps relative to boot. You can look at how &lt;a href=&quot;/assets/images/2026/06/22/success.log&quot;&gt;successful update log&lt;/a&gt; looks like&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let us know if this guide helped you flash your distant repeaters! Don’t hesitate to ask any questions either in the comments or on our &lt;a href=&quot;https://discord.com/channels/1495203904898728149/1509594396482601121&quot;&gt;Discord&lt;/a&gt;.&lt;/p&gt;</content><author><name>recrof</name></author><category term="Firmware" /><category term="Guide, Drone" /><summary type="html">OTA Updating hard to reach nRF52 based repeaters with a drone</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/2026/06/22/xiao_drone.jpg" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/2026/06/22/xiao_drone.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Release v1.16.0</title><link href="https://blog.meshcore.io/2026/06/06/release-1-16-0" rel="alternate" type="text/html" title="Release v1.16.0" /><published>2026-06-06T00:00:00+00:00</published><updated>2026-06-06T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/06/06/release-1-16-0</id><content type="html" xml:base="https://blog.meshcore.io/2026/06/06/release-1-16-0">&lt;p&gt;&lt;img src=&quot;/assets/images/firmware_release.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;download&quot;&gt;Download&lt;/h2&gt;

&lt;p&gt;Latest firmwares are in the &lt;a href=&quot;https://flasher.meshcore.io/&quot;&gt;flasher.meshcore.io&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;change-log&quot;&gt;Change Log&lt;/h2&gt;

&lt;h3 id=&quot;new-features&quot;&gt;New Features&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;New CLI config var ‘flood.max.unscoped’ &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2661&quot;&gt;#2661&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;New CLI config var ‘flood.max.advert’ &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2702&quot;&gt;#2702&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;longer preamble now for lower SF. (32 for SF&amp;lt;=8, 16 for SF&amp;gt;8) &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/1954&quot;&gt;#1954&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;app/companion can now do anon_req/response with non-contact nodes &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2672&quot;&gt;#2672&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;companion auto-shutdown, disabled when on external power, new UI warning on display &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2663&quot;&gt;#2663&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;new ‘region def …’ CLI command &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2540&quot;&gt;#2540&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;extended ACK support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2594&quot;&gt;#2594&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;app/companion can now compose and send raw packets &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2543&quot;&gt;#2543&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;companion can now override default scope to explicit unscoped &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2492&quot;&gt;#2492&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enhancements&quot;&gt;Enhancements&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;All ESP repeaters, power saving improvements  &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/1687&quot;&gt;#1687&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;nRF companions, power saving &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2286&quot;&gt;#2286&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;new-device-support&quot;&gt;New device support&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;NEW: LilyGo T-Echo Card support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2517&quot;&gt;#2517&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NEW: LilyGo T-Impulse Plus support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2522&quot;&gt;#2522&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NEW: Station G3 support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2515&quot;&gt;#2515&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NEW: Heltec Mesh Node T1 support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2520&quot;&gt;#2520&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;new Xiao S3 variants (repeater, companion, etc) &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2383&quot;&gt;#2383&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;bug-fixes-and-other&quot;&gt;Bug fixes and Other&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;RP2040 target build fixes. &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2684&quot;&gt;#2684&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;companion protocol max frame size increase (now 176) &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2022&quot;&gt;#2022&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;RAK Wismesh Tag fixes &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2664&quot;&gt;#2664&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Bug fix: repeater neighbor discovery fail when path.hash.mode != 0&lt;/li&gt;
  &lt;li&gt;RAK4631, now using Bosch driver for BME680 sensor &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2634&quot;&gt;#2634&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;enable radio.rxgain CLI command for LR1110 (T1000e) &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2235&quot;&gt;#2235&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;default flood advert interval now 47 hours (was 12) &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2608&quot;&gt;#2608&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Client repeat (off-grid) EU freq change (from 869.0 to 869.495) &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2604&quot;&gt;#2604&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;CLI validation on rxdelay, txdelay and direct.txdelay &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2443&quot;&gt;#2443&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Heltec T096, sensor node support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2576&quot;&gt;#2576&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Heltec E290 USB companion fix &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2562&quot;&gt;#2562&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;WiFi companion, reconnect logic redesigned for non-blocking &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2493&quot;&gt;#2493&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;RAM usage reduced for older boards &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2497&quot;&gt;#2497&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;nRF variants, CustomLFS lib upgrade to v2.2 &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2519&quot;&gt;#2519&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;T-Echo Lite, fixes to RXEN, TXEN and TCXO &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2511&quot;&gt;#2511&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;KISS modem frame timeout fixes &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2490&quot;&gt;#2490&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;sensor manager redesign &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2327&quot;&gt;#2327&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;startup tune suppressed if sound pref off &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2460&quot;&gt;#2460&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;added KISS Modem variants for most boards &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2620&quot;&gt;#2620&lt;/a&gt; &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2432&quot;&gt;#2432&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Adafruit nRF BLE fork, to prevent lockup during rapid connect/disconnect &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2430&quot;&gt;#2430&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;RAK3401 companion, analog button support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2436&quot;&gt;#2436&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Heltec boards, LNA disabled by default &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2439&quot;&gt;#2439&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;new splash screens &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2424&quot;&gt;#2424&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Sensecap Solar Tx LED fix &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2157&quot;&gt;#2157&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;new repeater variant: Heltec V4 expansion kit &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2326&quot;&gt;#2326&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;new T-Echo Lite non-shell companion variants &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2503&quot;&gt;#2503&lt;/a&gt; &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2353&quot;&gt;#2353&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;T-Echo Lite, battery measure fix &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2287&quot;&gt;#2287&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;RAK4631, sx1262 reset pin fix &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2008&quot;&gt;#2008&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Heltec T096, Wireless Tracker: FEM/LNA enable by default &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2340&quot;&gt;#2340&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;R1 Neo, shutdown fix &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2371&quot;&gt;#2371&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Heltec V4, set adc.multiplier support &lt;a href=&quot;https://github.com/meshcore-dev/MeshCore/pull/2335&quot;&gt;#2335&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;limiting-unscoped-traffic&quot;&gt;Limiting Unscoped Traffic&lt;/h2&gt;

&lt;p&gt;The new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flood.max.unscoped&lt;/code&gt; CLI config variable is specifically for limiting unscoped
flood traffic. Like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flood.max&lt;/code&gt;, it drops unscoped flood packets which have already had a given number of
hops. By default it is 64, which is essentially &lt;em&gt;off&lt;/em&gt;.&lt;/p&gt;

&lt;h2 id=&quot;limiting-advert-traffic&quot;&gt;Limiting Advert Traffic&lt;/h2&gt;

&lt;p&gt;The new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flood.max.advert&lt;/code&gt; CLI config variable is specifically for limiting adverts.
Like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flood.max&lt;/code&gt;, it drops advert packets which have already had a given number of
hops. By default it is &lt;strong&gt;8&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;new-preamble&quot;&gt;New Preamble&lt;/h2&gt;

&lt;p&gt;When using the lower Spreading Factors, the radio has less time to &lt;em&gt;lock onto&lt;/em&gt; an incoming
packet, so this change gives the faster SF’s a longer preamble, and thus decreasing the
chance of the preamble being missed. For SF &amp;lt;= 8, the preamble is now 32 symbols.&lt;/p&gt;

&lt;h2 id=&quot;improved-region-discovery-in-mobile-app&quot;&gt;Improved Region Discovery in Mobile App&lt;/h2&gt;

&lt;p&gt;The new companion firmware, and latest app, will be able to do ad-hoc requests to
near by repeaters &lt;em&gt;without&lt;/em&gt; having to add them to contacts first. This will streamline
both repeater discovery, and region discovery.&lt;/p&gt;

&lt;h2 id=&quot;new-region-def-command&quot;&gt;New &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;region def&lt;/code&gt; Command&lt;/h2&gt;

&lt;p&gt;Defining regions via the CLI is currently quite verbose, and the latest CLI handling
introduces a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;region def...&lt;/code&gt; command which has a short-hand notation for defining
regions, especially ones which have deep nesting.&lt;/p&gt;

&lt;p&gt;See the &lt;a href=&quot;https://docs.meshcore.io/cli_commands/&quot;&gt;CLI Command Reference&lt;/a&gt; for more details.&lt;/p&gt;

&lt;h2 id=&quot;extended-ack-support&quot;&gt;Extended ACK Support&lt;/h2&gt;

&lt;p&gt;The latest firmwares introduce support for ‘extended ACKs’, which are 6 bytes instead of 4.
The extra bytes contain an extended attempt number, and additional random byte. This is in
preparation for a later app feature which will enable much more than 4 attempts for
direct messages. For now, repeaters will have to be updated first.&lt;/p&gt;

&lt;h2 id=&quot;companion-raw-packets&quot;&gt;Companion Raw Packets&lt;/h2&gt;

&lt;p&gt;The latest companion firmwares now enable apps to compose the &lt;em&gt;full&lt;/em&gt; packet, ie.
headers, path and payload. This can correspond with the existing RxLog ability, so app
can do its own raw send and receive of packets.&lt;/p&gt;</content><author><name>admin</name></author><category term="Announcements" /><category term="Firmware" /><category term="Release" /><summary type="html"></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/firmware_release.jpg" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/firmware_release.jpg" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">pyMC Introduction</title><link href="https://blog.meshcore.io/2026/05/12/pymc-intro" rel="alternate" type="text/html" title="pyMC Introduction" /><published>2026-05-12T00:00:00+00:00</published><updated>2026-05-12T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/05/12/pymc-intro</id><content type="html" xml:base="https://blog.meshcore.io/2026/05/12/pymc-intro">&lt;p&gt;&lt;img src=&quot;/assets/images/2026/05/12/control-room.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What is pyMC? At its core, pyMC is a Python implementation of a MeshCore-compatible stack. It is designed to run on Linux-based systems and connect embedded LoRa radios to higher-level software services. It started as a way to better understand the MeshCore protocol. But pretty quickly, it became something more useful: a reusable core library for building flexible, Linux-powered mesh infrastructure. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pymc core&lt;/code&gt; handles the protocol-level work:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Parsing and generating MeshCore packets&lt;/li&gt;
  &lt;li&gt;Managing identities and addressing&lt;/li&gt;
  &lt;li&gt;Maintaining compatibility as the protocol evolves&lt;/li&gt;
  &lt;li&gt;Handling radio interfaces (SPI, KISS, USB-CH341)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;with over 15 boards currently supported and many new ones in development, the system has grown from a simple experiment into a practical toolkit for building and running distributed mesh infrastructure.&lt;/p&gt;

&lt;p&gt;On top of pyMC core sits &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pymc repeater&lt;/code&gt;, which handles the operational side:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Processing packets&lt;/li&gt;
  &lt;li&gt;Applying routing and filtering logic&lt;/li&gt;
  &lt;li&gt;Forwarding traffic&lt;/li&gt;
  &lt;li&gt;Supporting services like roomservers, companions and observer data output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Embedded firmware is efficient and well suited to dedicated devices, but it operates under tight resource constraints. Running pyMC on Linux expands the design space: more compute, better tooling, easier debugging, and deeper real-time visibility into mesh behaviour.&lt;/p&gt;

&lt;p&gt;A key design choice is how identities are handled. Instead of assuming one physical node equals one logical presence, pyMC lets multiple identities exist on the same radio.&lt;/p&gt;

&lt;p&gt;In practice, a single device can take on multiple roles. It might act as a repeater, represent different logical endpoints, or host additional services–each with its own context.&lt;/p&gt;

&lt;p&gt;This flexibility allows a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pymc repeater&lt;/code&gt; to evolve into a multi-companion base station. At that point, it behaves less like a simple packet repeater and more like a lightweight message hub for the mesh.&lt;/p&gt;

&lt;p&gt;Put another way: pyMC gives MeshCore a Linux-native surface area. It can run repeaters, host services, power analytics, or support entirely new mesh applications–without losing compatibility with the underlying radio layer.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/image.pymc-map.webp&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/image.pymc-stats.webp&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/image.pymc-system-stats.webp&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;where-pymc_console-fits&quot;&gt;Where pymc_console fits&lt;/h2&gt;

&lt;p&gt;One example of that larger design space is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pymc_console&lt;/code&gt;: a browser-based dashboard built on top of pyMC repeater.&lt;/p&gt;

&lt;p&gt;Where pyMC handles the protocol and repeater layer, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pymc_console&lt;/code&gt; turns that activity into something you can actually see and reason about. Packet flow, radio status, connected identities, observer output, airtime utilization, and network behavior can all be surfaced in a more approachable interface.&lt;/p&gt;

&lt;p&gt;That matters because a mesh network is difficult to improve if it is invisible. Once packets, routes, signal quality, and utilization patterns become observable, the repeater becomes more than a forwarding node. It becomes a local window into the health and behavior of the mesh.&lt;/p&gt;

&lt;p&gt;In that sense, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pymc_console&lt;/code&gt; is less a separate idea than a natural extension of the pyMC architecture. The same Linux-native foundation that lets pyMC talk to radios also makes it possible to build analytics, dashboards, companion experiences, and new tools around the mesh.&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/image-console.webp&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/image-console-map.webp&quot; /&gt;
&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/image-console-compan.webp&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The interesting part isn’t just what pyMC does today, but what it enables in practice.&lt;/p&gt;

&lt;p&gt;If you’d like to explore it, run it yourself, or follow along as it evolves, everything you need to get started is available.&lt;/p&gt;

&lt;h2 id=&quot;where-to-start&quot;&gt;Where to start&lt;/h2&gt;

&lt;p&gt;Source and setup instructions are on &lt;a href=&quot;https://github.com/pyMC-dev/pyMC_Repeater#pymc_repeater&quot;&gt;https://github.com/pyMC-dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or join us in the pyMC Discord &lt;a href=&quot;https://discord.gg/hRjW9ha6m&quot;&gt;https://discord.gg/hRjW9ha6m&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;recommended-gear&quot;&gt;Recommended Gear&lt;/h2&gt;

&lt;p&gt;For a no-fuss pyMC setup, I recommend the following tested and compatible hardware platforms. The MeshToad and MeshTadpole are ideal for lightweight installs, home labs, and desktop usage, while PiMesh provides an excellent Raspberry Pi-based solution for infrastructure and gateway deployments. For repeater-focused installations, the UltraPeater Luckfox Pico Ultra HAT offers a compact and efficient dedicated repeater platform.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;MeshToad V3 — &lt;a href=&quot;https://muzi.works/products/nullhop-meshtoad-v3&quot;&gt;https://muzi.works/products/nullhop-meshtoad-v3&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;MeshTadpole SX1262 USB Stick — &lt;a href=&quot;https://www.elecrow.com/meshtadpole-sx1262-usb-stick.html&quot;&gt;https://www.elecrow.com/meshtadpole-sx1262-usb-stick.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;PiMesh — &lt;a href=&quot;https://meshsmith.net/&quot;&gt;https://meshsmith.net/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;UltraPeater — &lt;a href=&quot;https://zindello.com.au/ultrapeater/&quot;&gt;https://zindello.com.au/ultrapeater/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/05/12/pymc-gear.jpeg&quot; /&gt;&lt;/p&gt;</content><author><name>rightup</name></author><summary type="html"></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/2026/05/12/control-room.png" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/2026/05/12/control-room.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Ripple UI v9.7</title><link href="https://blog.meshcore.io/2026/04/30/ripple-9.7" rel="alternate" type="text/html" title="Ripple UI v9.7" /><published>2026-04-30T00:00:00+00:00</published><updated>2026-04-30T00:00:00+00:00</updated><id>https://blog.meshcore.io/2026/04/30/ripple-9.7</id><content type="html" xml:base="https://blog.meshcore.io/2026/04/30/ripple-9.7">&lt;p&gt;The latest release of the Ripple UI firmwares has had quite a big overhaul (under the hood) and the UI now sports a Light and Dark mode theming, plus you can now customise the accent colour used throughout the firmware.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/2026/04/30/t-pager-9.7.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;display-preferences&quot;&gt;Display Preferences&lt;/h2&gt;

&lt;p&gt;The Display menu now shows these preferences:&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/04/30/display-prefs-9.7.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;UI Theme&lt;/strong&gt; preferences is one of: Light, Dark or Auto. The Auto option automatically switches the UI theme depending on the &lt;strong&gt;Brightness&lt;/strong&gt; setting (day or night).&lt;/p&gt;

&lt;p&gt;PAID FEATURE: The &lt;strong&gt;Accent color&lt;/strong&gt; lets you customise the accent colour used throughout the firmware. There are 10 fun colour swatches to select from:&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/04/30/color-select.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;map-theme&quot;&gt;Map Theme&lt;/h2&gt;

&lt;p&gt;Note that the &lt;strong&gt;UI Theme&lt;/strong&gt; preference also determines the light/dark theming for the maps:&lt;/p&gt;

&lt;p&gt;&lt;img alt=&quot;&quot; class=&quot;mx-auto&quot; src=&quot;/assets/images/2026/04/30/map-dark-light.png&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;download&quot;&gt;Download&lt;/h2&gt;

&lt;p&gt;The v9.7 is now available for &lt;a href=&quot;https://www.lilygo.cc/products/t-deck-plus-1?variant=51618501951669&amp;amp;bg_ref=cq3pUU7cD3&quot;&gt;LilyGo T-Deck&lt;/a&gt;, &lt;a href=&quot;https://www.lilygo.cc/products/t-lora-pager?bg_ref=cq3pUU7cD3&quot;&gt;T-Pager&lt;/a&gt; and the &lt;a href=&quot;https://www.lilygo.cc/products/t-watch-s3-plus?variant=52457652224181&amp;amp;bg_ref=cq3pUU7cD3&quot;&gt;T-Watch S3 Plus&lt;/a&gt;. It will be rolling out soon for the other colour devices, like Heltec V4 Expansion kit, etc.&lt;/p&gt;

&lt;p&gt;These are now available in the &lt;a href=&quot;https://flasher.meshcore.io&quot;&gt;MeshCore.io Flasher&lt;/a&gt;, for easy installation.&lt;/p&gt;</content><author><name>scottpowell</name></author><summary type="html">The latest release of the Ripple UI firmwares has had quite a big overhaul (under the hood) and the UI now sports a Light and Dark mode theming, plus you can now customise the accent colour used throughout the firmware.</summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blog.meshcore.io/assets/images/2026/04/30/t-pager-9.7.png" /><media:content medium="image" url="https://blog.meshcore.io/assets/images/2026/04/30/t-pager-9.7.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>