<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ble - Hard Wired</title>
	<atom:link href="https://www.hardwired.dev/tag/ble/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.hardwired.dev</link>
	<description></description>
	<lastBuildDate>Tue, 05 May 2026 12:05:36 +0000</lastBuildDate>
	<language>cs</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.hardwired.dev/wp-content/uploads/2022/10/android-chrome-256x256-1-150x150.png</url>
	<title>ble - Hard Wired</title>
	<link>https://www.hardwired.dev</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Váš Bluetooth čip křičí šifrovací klíče. Slyšet ho jde z parkoviště.</title>
		<link>https://www.hardwired.dev/2026/05/05/vas-bluetooth-cip-krici-sifrovaci-klice-slyset-ho-z-parkoviste/</link>
		
		<dc:creator><![CDATA[Valentino Hesse OK2HSS]]></dc:creator>
		<pubDate>Tue, 05 May 2026 12:02:35 +0000</pubDate>
				<category><![CDATA[Cyber Security]]></category>
		<category><![CDATA[AES-128]]></category>
		<category><![CDATA[automotive bezpečnost]]></category>
		<category><![CDATA[ble]]></category>
		<category><![CDATA[Bluetooth bezpečnost]]></category>
		<category><![CDATA[embedded security]]></category>
		<category><![CDATA[EURECOM]]></category>
		<category><![CDATA[Gnuradio]]></category>
		<category><![CDATA[HackRF]]></category>
		<category><![CDATA[hardware security]]></category>
		<category><![CDATA[IoT bezpečnost]]></category>
		<category><![CDATA[kryptografie]]></category>
		<category><![CDATA[mixed-signal čip]]></category>
		<category><![CDATA[Nordic Semiconductor]]></category>
		<category><![CDATA[nRF52832]]></category>
		<category><![CDATA[penetrační testování]]></category>
		<category><![CDATA[RF side channel]]></category>
		<category><![CDATA[Screaming Channels]]></category>
		<category><![CDATA[SDR]]></category>
		<category><![CDATA[side-channel útok]]></category>
		<category><![CDATA[šifrování]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=3043</guid>

					<description><![CDATA[<p>Jak mixed-signal SoC nechtěně vysílá kryptografická tajemství a jak to reprodukovat s HackRF za odpoledne Sedíte v autě, zaparkovaní u &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2026/05/05/vas-bluetooth-cip-krici-sifrovaci-klice-slyset-ho-z-parkoviste/">Váš Bluetooth čip křičí šifrovací klíče. Slyšet ho jde z parkoviště.</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p><em>Jak mixed-signal SoC nechtěně vysílá kryptografická tajemství a jak to reprodukovat s HackRF za odpoledne</em></p>
<hr />
<p>Sedíte v autě, zaparkovaní u továrny. Výrobní hala je dvacet metrů za zdí. Spustíte skript na laptopu, nasměrujete anténu a čekáte. Za pár hodin máte AES-128 klíč z komunikace zámkového modulu uvnitř.</p>
<p>Žádné hackování sítě. Žádný fyzický kontakt. Žádné stopy.</p>
<p>Tohle není filmový scénář - je to zdokumentovaný útok, publikovaný akademicky v roce 2018, rozšiřovaný výzkumy až do roku 2024, spustitelný na fakt běžném SDR hardware. Jmenuje se <strong>Screaming Channels</strong> a má přímou relevanci pro každý automotive modul, který na sobě nese BLE čip od Nordic Semiconductor.</p>
<hr />
<h2>Čip, který si sám zesílí vlastní únik</h2>
<p>Mixed-signal SoC je čip, kde digitální logika a rádiový transceiver sdílejí jeden křemíkový die. Zní to jako detail z datasheetu. Ve skutečnosti je to bezpečnostní časovaná bomba.</p>
<p>Digitální logika při výpočtech generuje elektromagnetický šum. Na izolovaném mikrokontroléru to není velký problém - šum je slabý, slyšitelný jen z milimetrů. Ale na mixed-signal čipu se ten šum šíří do analogové části: přes sdílené napájení, substrátové vazby, kapacitní přeslech mezi bloky na die. A v analogové části je PA - výkonnostní zesilovač rádiového vysílače.</p>
<p>Čip si vlastní kryptografický únik zesílí a vyšle anténou do prostoru.</p>
<p>Giovanni Camurati a jeho kolegové z EURECOM tohle v roce 2018 pojmenovali &quot;screaming channels&quot; - v kontrastu ke klasickým EM side-channels, které &quot;šeptají&quot; z centimetrů. Tady čip doslova křičí.</p>
<p>Konkrétní cíl výzkumu: <strong>nRF52832</strong> od Nordic Semiconductor. ARM Cortex-M4 na 64 MHz, integrovaný BLE/ANT transceiver na 2,4 GHz. Používaný v milionech zařízení - wearables, průmyslový IoT, smart home. A automotive.</p>
<hr />
<h2>Proč 2,464 GHz a ne 2,400 GHz</h2>
<p>Tady je fyzika, která útok umožňuje.</p>
<p>CPU nRF52832 taktuje na <strong>64 MHz</strong>. Při AES výpočtu generuje harmonické tohoto taktu - šum s komponentami na 64 MHz, 128 MHz, 192 MHz atd. Ten šum vstoupí do IQ mixeru v rádiovém řetězci, kde se amplitudově namoduluje na nosnou BT kanálu.</p>
<p>Výsledek: útočník neladí na 2,400 GHz (BT kanál 0), ale na <strong>2,464 GHz</strong>:</p>
<pre><code>f(screaming channel) = f(BT kanál) + f(CPU clock)
                     = 2,400 GHz  + 0,064 GHz
                     = 2,464 GHz</code></pre>
<p>V spektrogramu to vypadá jako tenký proužek vedle hlavního BT signálu - vizuálně nenápadný, statisticky informativní. Každé jedno AES šifrování zanechá v zachyceném signálu &quot;otisk&quot; - trace. Jedna trace toho moc neřekne. Ale po 90 000 tracích jde z korelace vytáhnout celý 128bitový klíč.</p>
<p>Zpátky k tomu autu na parkovišti: útočník nepotřebuje dekódovat Bluetooth provoz. Jen passivně naslouchá vedlejšímu šumu. Zařízení ani netuší, že je sledováno.</p>
<hr />
<h2>Sedm let výzkumu v pěti minutách</h2>
<p>Projekt Screaming Channels není jednorázová akademická kuriozita. Vyvíjí se.</p>
<p><strong>CCS 2018</strong> (Camurati et al., EURECOM): Původní demonstrace. Útok na tinyAES implementaci na nRF52832, vzdálenost 10 metrů v anechoické komoře, vzdálenost 1 metr v kancelářském prostředí. Korelační analýza, 180 000 traces. Tři místo na CSAW Europe 2018.</p>
<p><strong>CHES 2020</strong>: Podrobnější analýza kanálu, útok na Google Eddystone beacony (reálný produkt, ne lab firmware), vzdálenost 15 metrů v kancelářské chodbě, spatial diversity s dvěma přijímači, reuse profilu postaveného na jiném zařízení měsíce předem.</p>
<p><strong>ACSAC 2024</strong> (BlueScream, Ayoub et al., EURECOM + Univ. Lille + CNRS + Inria): Útok na reálný BLE stack bez modifikace firmware. Útočník manipuluje BLE protokol tak, aby zařízení leaked Long Term Key při standardní komunikaci. Tohle je z mého pohledu nejzásadnější posun - předchozí práce vyžadovaly speciální firmware na target zařízení. BlueScream funguje na produkčním zařízení s factory firmware.</p>
<p>Musím ale říct, že &quot;funguje na produkčním zařízení&quot; je trochu zjednodušení. BlueScream stále potřebuje, aby útočník mohl ovlivnit BLE session - tedy aby byl v dosahu a mohl komunikovat. Vzdálený pasivní útok bez jakékoliv interakce to zatím není. Ale hranice se posouvají každý rok.</p>
<p>Mimochodem: vedle toho v roce 2025 publikovali Ji et al. ze Stockholm University útok na <em>hardwarový</em> AES akcelerátor (ne softwarovou implementaci) na stejném čipu, s ML-assisted analýzou a 90 000 traces z 1 metru. Hardwarový akcelerátor se dřív považoval za odolnější. Ukázalo se, že ne.</p>
<hr />
<h2>Jak to reprodukovat: hardware</h2>
<p>Celý projekt je open-source. EURECOM zveřejnil firmware, kód, GNURadio bloky a naměřené datasety. Není potřeba nic vymýšlet od nuly.</p>
<p><strong>Minimální setup</strong> pro laboratorní validaci:</p>
<table>
<thead>
<tr>
<th>Komponenta</th>
<th>Model</th>
<th>Cena</th>
</tr>
</thead>
<tbody>
<tr>
<td>Target čip</td>
<td>Nordic nRF52832 PCA10040 DK</td>
<td>~1 000 Kč</td>
</tr>
<tr>
<td>SDR přijímač</td>
<td>HackRF One</td>
<td>máte</td>
</tr>
<tr>
<td>Anténa</td>
<td>WiFi directional 2,4 GHz (TP-Link nebo podobná)</td>
<td>~500 Kč</td>
</tr>
<tr>
<td>Počítač</td>
<td>Linux, GNURadio 3.7+</td>
<td>máte</td>
</tr>
</tbody>
</table>
<p>PCA10040 má onboard J-Link debugger - žádný extra programátor nepotřebujete, stačí USB kabel.</p>
<p>HackRF zvládne útok z 1 až 3 metrů v tichém RF prostředí. Pro 10+ metrů (publikované výsledky) potřebujete USRP N210 s SBX daughterboard a paraboliku s 24 dBi - to je jiný cenový segment (~150 000 Kč za USRP). Pro automotive bezpečnostní testování v laboratoři ale 1 metr odpovídá realistickému scénáři technická diagnostiky u vozidla.</p>
<hr />
<h2>Jak to reprodukovat: software a postup</h2>
<h3>1. Instalace</h3>
<pre><code class="language-bash">sudo apt install gnuradio gr-osmosdr hackrf minicom gcc-arm-none-eabi

git clone https://github.com/eurecom-s3/screaming_channels
cd screaming_channels
git checkout ches20

cd experiments/src
python2 setup.py develop
pip3 install gatt==0.2.7 pyzmq==17.1.2</code></pre>
<p>Repo obsahuje i Dockerfile pro izolované prostředí - doporučuji, závislosti jsou trochu starší:</p>
<pre><code class="language-bash">docker build -t screaming docker/
docker run -it --privileged screaming</code></pre>
<h3>2. Flash firmware</h3>
<pre><code class="language-bash">cd screaming_channels/firmware

# mbedTLS varianta (doporučená pro první pokus)
make GNU_INSTALL_ROOT=$GCC_PATH/gcc-arm-none-eabi-7-2017-q4-major/bin/ \
  -C blenano2_mbedtls/blank/armgcc/

# Flashnout přes J-Link (automaticky při připojení PCA10040 přes USB)
cp blenano2_mbedtls/blank/armgcc/_build/nrf52832_xxaa.hex /media/$USER/DAPLINK/</code></pre>
<p>Po flashnutí se připojte přes UART (<code>minicom -b 115200 -D /dev/ttyACM0</code>) a stiskněte <code>h</code> - uvidíte menu s dostupnými módy.</p>
<h3>3. Vizualizace úniku - první krok</h3>
<p>Než začnete sbírat traces, ověřte, že leak vůbec vidíte.</p>
<p>Naladíte HackRF na offset frekvenci:</p>
<pre><code class="language-bash"># Přímý přístup přes hackrf_transfer (jen pro rychlý test)
hackrf_transfer -r /dev/null -f 2464000000 -s 8000000 -l 40 -g 40</code></pre>
<p>Lépe otevřete GQRX nebo GNURadio Companion, nastavte:</p>
<ul>
<li>Frekvence: <strong>2 464 MHz</strong></li>
<li>Sample rate: 8 MSPS</li>
<li>FFT size: 4096</li>
<li>Gain: začněte na 30 dB, dolaďte</li>
</ul>
<p>Ve firmware spusťte AES smyčku: <code>n</code> (TinyAES mód), <code>n2000</code> (2000 opakování), <code>r</code> (spustit). Ve spektrogramu by se měl objevit periodický proužek kolem +64 MHz offsetu od BT nosné. Když ho vidíte, jste na správné stopě.</p>
<h3>4. Sběr traces</h3>
<pre><code class="language-bash">sc-experiment \
  --radio=HackRF \
  --device=/dev/ttyACM0 \
  collect \
  config/example_collection_plot.json \
  ../traces/ \
  --plot</code></pre>
<p><code>--plot</code> zobrazí live vizualizaci každé trace. Hledáte konzistentní tvar signálu korelovaný se šifrováním - pokud každá trace vypadá jinak a chaoticky, SNR je příliš nízké (zkuste zkrátit vzdálenost nebo zvýšit gain).</p>
<h3>5. Analýza - bez vlastního hardware</h3>
<p>Pokud chcete nejdřív ověřit celý analytický pipeline, EURECOM poskytl veřejné datasety:</p>
<ul>
<li><a href="https://drive.google.com/drive/folders/1bJniDXOroLrWUvazbE5jFU0ETFYVx0Av">Small sample set (56 MB)</a> - útok na 20 cm</li>
<li><a href="https://drive.google.com/drive/folders/1W17IOGQb7uok8H0WvLJOEchrAusZvCW5">CCS18 traces (2,6 GB)</a> - útok na 10 m v anechoické komoře, útok na 1 m v kanceláři</li>
<li>CHES20 traces (15 GB) - vše od 55 cm doma přes 15 m v chodbě po T-test na 34 m</li>
</ul>
<pre><code class="language-bash">export TRACES_SAMPLE=&quot;/cesta/k/datum&quot;

sc-attack \
  --norm \
  --plot \
  attack config/example_attack.json \
  $TRACES_SAMPLE/sample/</code></pre>
<h3>6. Dvě metody key recovery</h3>
<p><strong>Korelační analýza (CPA)</strong> - bez profilování, ~180 000 traces, deterministická. Dobrá pro první pokus, nevyžaduje referenční zařízení se známým klíčem.</p>
<p><strong>Template attack s ML</strong> - vyžaduje profilování (traces se známým klíčem na tom samém modelu čipu), útok pak z ~90 000 traces. Přibližně dvakrát efektivnější.</p>
<pre><code class="language-bash"># Profilování (coaxiální připojení, plný SNR, známý klíč)
sc-attack --norm \
  --data-path ./traces/profile \
  --num-traces 5000 \
  profile \
  --variable p_xor_k \
  --pois-algo r \
  --num-pois 1 \
  /tmp/profile_output/

# Útok (vzdálené traces, neznámý klíč)
sc-attack --norm \
  --data-path ./traces/attack \
  --num-traces 90000 \
  attack \
  --attack-algo pcc \
  --profile /tmp/profile_output/ \
  /tmp/attack_output/</code></pre>
<hr />
<h2>Co s tím dělat: mitigace, která nestačí, a ta, která pomáhá</h2>
<p>Softwarová oprava neexistuje. Problém je fyzický.</p>
<p>Maskovací schémata v AES implementaci (Rivain-Prouff a podobné) zvýší počet potřebných traces, ale útok neumožní - Ji et al. (2025) demonstrovali průlom i přes masking. Jitter v časování šifrování komplikuje synchronizaci traces. Žádná sláva.</p>
<p>Fakticky fungující opatření jsou hardwarová:</p>
<p><strong>RF stínění modulu</strong> - faradayova klec kolem čipu ořízne leak na přijatelnou úroveň. Přidá ale hmotnost, rozměry a cenu.</p>
<p><strong>Čipy s integrovanou ochranou</strong> - Nordic nRF54 série (nástupce nRF52) obsahuje dedikovanou side-channel leakage protection v kryptoakcelerátoru. Pokud navrhujete nový modul, tohle je relevantní volba.</p>
<p><strong>Oddělit napájení</strong> - digitální a RF napájení na PCB oddělené ferritovými korálky a LC filtry sníží substrátovou vazbu, ale neodstraní ji úplně. Pomáhá SNR útoku poškodit, ale nestačí jako jediné opatření.</p>
<p>Pro firemní kontext: výsledky testování vlastních modulů zdokumentujte jako součást threat modelu a bezpečnostní dokumentace. Pokud modul projde CPA testem bez key recovery do 200 000 traces v laboratorních podmínkách, máte datový podklad pro rozhodování.</p>
<hr />
<h2>Zdroje</h2>
<p><strong>Akademické práce (primární zdroje):</strong></p>
<ul>
<li>Camurati et al. (CCS 2018): <a href="http://s3.eurecom.fr/docs/ccs18_camurati.pdf">Screaming Channels: When EM Side Channels Meet Radio Transceivers</a></li>
<li>Camurati et al. (CHES 2020): <a href="https://tches.iacr.org/index.php/TCHES/article/view/8594/8161">Understanding Screaming Channels</a></li>
<li>Ayoub et al. (ACSAC 2024): <a href="https://s3.eurecom.fr/docs/acsac24_ayoub.pdf">BlueScream: Screaming Channels on Bluetooth Low Energy</a></li>
<li>Ji, Dubrova, Wang (IACR ePrint 2025): <a href="https://eprint.iacr.org/2025/559">Is Your Bluetooth Chip Leaking Secrets via RF Signals?</a></li>
</ul>
<p><strong>Kód a datasety:</strong></p>
<ul>
<li><a href="https://github.com/eurecom-s3/screaming_channels">github.com/eurecom-s3/screaming_channels</a> - firmware, experimenty, datasety, Docker</li>
<li><a href="https://github.com/pierreay/bluescream">github.com/pierreay/bluescream</a> - BlueScream (reálný BLE stack, ACSAC 2024)</li>
<li><a href="https://eurecom-s3.github.io/screaming_channels/">eurecom-s3.github.io/screaming_channels</a> - dokumentace, download datasety</li>
</ul>
<p><strong>Prezentace:</strong></p>
<ul>
<li><a href="https://youtu.be/K7wqwOzD1Yw">Black Hat USA 2018 - video</a></li>
<li><a href="https://youtu.be/Xb9xGwiOYkY">CHES 2020 - video</a></li>
</ul>
<hr />
<p><em>Testování technik popsaných v tomto článku proveďte výhradně na vlastním hardware nebo s písemným souhlasem vlastníka zařízení. Útoky na cizí zařízení jsou trestné.</em></p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2026%2F05%2F05%2Fvas-bluetooth-cip-krici-sifrovaci-klice-slyset-ho-z-parkoviste%2F&#038;via=hessevalentino&#038;related=hessevalentino%3AValentino%20Hesse%20OK2HSS" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2026/05/05/vas-bluetooth-cip-krici-sifrovaci-klice-slyset-ho-z-parkoviste/">Váš Bluetooth čip křičí šifrovací klíče. Slyšet ho jde z parkoviště.</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>MeshCore: Off-grid komunikaci prostřednictvím LoRa mesh sítí</title>
		<link>https://www.hardwired.dev/2025/07/20/meshcore-off-grid-komunikaci-prostrednictvim-lora-mesh-siti/</link>
		
		<dc:creator><![CDATA[Valentino Hesse OK2HSS]]></dc:creator>
		<pubDate>Sun, 20 Jul 2025 12:55:55 +0000</pubDate>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[HAM]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[IOT]]></category>
		<category><![CDATA[Různé]]></category>
		<category><![CDATA[SDR]]></category>
		<category><![CDATA[868 MHz]]></category>
		<category><![CDATA[Andy Kirby]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[backup communication]]></category>
		<category><![CDATA[bateriové napájení]]></category>
		<category><![CDATA[battery powered]]></category>
		<category><![CDATA[BBS server]]></category>
		<category><![CDATA[bezdrátová komunikace]]></category>
		<category><![CDATA[ble]]></category>
		<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[C++ library]]></category>
		<category><![CDATA[Česká republika]]></category>
		<category><![CDATA[chat aplikace]]></category>
		<category><![CDATA[chat application]]></category>
		<category><![CDATA[companion radio]]></category>
		<category><![CDATA[crisis communication]]></category>
		<category><![CDATA[Czech Republic]]></category>
		<category><![CDATA[decentralized network]]></category>
		<category><![CDATA[decentralizovaná síť]]></category>
		<category><![CDATA[digital signatures]]></category>
		<category><![CDATA[digitální podpisy]]></category>
		<category><![CDATA[disaster recovery]]></category>
		<category><![CDATA[Discord komunita]]></category>
		<category><![CDATA[dlouhý dosah]]></category>
		<category><![CDATA[embedded systems]]></category>
		<category><![CDATA[emergency communication]]></category>
		<category><![CDATA[encryption]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[firmware]]></category>
		<category><![CDATA[fixed routing]]></category>
		<category><![CDATA[flasher]]></category>
		<category><![CDATA[flood routing]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[ham radio]]></category>
		<category><![CDATA[Heltec]]></category>
		<category><![CDATA[hybrid routing]]></category>
		<category><![CDATA[infrastructure independent]]></category>
		<category><![CDATA[IoT network]]></category>
		<category><![CDATA[IoT síť]]></category>
		<category><![CDATA[Ještěd]]></category>
		<category><![CDATA[katastrofické scénáře]]></category>
		<category><![CDATA[Klínovec]]></category>
		<category><![CDATA[krizová komunikace]]></category>
		<category><![CDATA[long range]]></category>
		<category><![CDATA[LoRa mesh]]></category>
		<category><![CDATA[LoRa radio]]></category>
		<category><![CDATA[low power]]></category>
		<category><![CDATA[mesh networking]]></category>
		<category><![CDATA[mesh topology]]></category>
		<category><![CDATA[MeshCore]]></category>
		<category><![CDATA[meshcore.cz]]></category>
		<category><![CDATA[Meshtastic alternativa]]></category>
		<category><![CDATA[Meshtastic alternative]]></category>
		<category><![CDATA[MIT licence]]></category>
		<category><![CDATA[MIT license]]></category>
		<category><![CDATA[mobile app]]></category>
		<category><![CDATA[mobilní aplikace]]></category>
		<category><![CDATA[multi-hop routing]]></category>
		<category><![CDATA[network technologies]]></category>
		<category><![CDATA[nezávislý na infrastruktuře]]></category>
		<category><![CDATA[nízká spotřeba]]></category>
		<category><![CDATA[nouzová komunikace]]></category>
		<category><![CDATA[off-grid communication]]></category>
		<category><![CDATA[off-grid komunikace]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[outdoor communication]]></category>
		<category><![CDATA[outdoor komunikace]]></category>
		<category><![CDATA[P2P komunikace]]></category>
		<category><![CDATA[packet radio]]></category>
		<category><![CDATA[paketové rádio]]></category>
		<category><![CDATA[path memory]]></category>
		<category><![CDATA[peer to peer]]></category>
		<category><![CDATA[platformio]]></category>
		<category><![CDATA[radioamatéři]]></category>
		<category><![CDATA[RAK Wireless]]></category>
		<category><![CDATA[repeater]]></category>
		<category><![CDATA[Říp]]></category>
		<category><![CDATA[room server]]></category>
		<category><![CDATA[samoléčící síť]]></category>
		<category><![CDATA[self-healing network]]></category>
		<category><![CDATA[šifrování]]></category>
		<category><![CDATA[síťová topologie]]></category>
		<category><![CDATA[síťové technologie]]></category>
		<category><![CDATA[solar powered]]></category>
		<category><![CDATA[solární napájení]]></category>
		<category><![CDATA[store and forward]]></category>
		<category><![CDATA[tactical radio]]></category>
		<category><![CDATA[taktické rádio]]></category>
		<category><![CDATA[tech blog]]></category>
		<category><![CDATA[technologický blog]]></category>
		<category><![CDATA[Telegram skupina]]></category>
		<category><![CDATA[telemetrie]]></category>
		<category><![CDATA[telemetry]]></category>
		<category><![CDATA[terminal chat]]></category>
		<category><![CDATA[USB komunikace]]></category>
		<category><![CDATA[vestavné systémy]]></category>
		<category><![CDATA[web aplikace]]></category>
		<category><![CDATA[web application]]></category>
		<category><![CDATA[wireless communication]]></category>
		<category><![CDATA[záložní komunikace]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=2788</guid>

					<description><![CDATA[<p>MeshCore: Revoluce v off-grid komunikaci prostřednictvím LoRa mesh sítí Představte si situaci: bouře vyřadí mobilní věže, internet je nedostupný, klasické &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2025/07/20/meshcore-off-grid-komunikaci-prostrednictvim-lora-mesh-siti/">MeshCore: Off-grid komunikaci prostřednictvím LoRa mesh sítí</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><h1>MeshCore: Revoluce v off-grid komunikaci prostřednictvím LoRa mesh sítí</h1>
<p>Představte si situaci: bouře vyřadí mobilní věže, internet je nedostupný, klasické komunikační kanály selhávají. Právě v takových chvílích oceníte technologie, které fungují nezávisle na centralizované infrastruktuře. A přesně to je oblast, kde se MeshCore etabluje jako game-changer.</p>
<p>V posledních letech jsme svědky dramatického růstu zájmu o decentralizované komunikační systémy. Ať už jde o přírodní katastrofy, výpadky infrastruktury, nebo jednoduše potřebu komunikace v odlehlých oblastech, tradiční řešení často selhávají právě tehdy, kdy je potřebujeme nejvíce. Zde vstupuje do hry mesh networking - technologie, která umožňuje zařízením komunikovat přímo mezi sebou, vytvářet samoléčící se sítě a poskytovat komunikační kanály tam, kde žádné neexistují.</p>
<p>MeshCore reprezentuje novou generaci této technologie. Zatímco jeho starší bratr Meshtastic si získal obrovskou popularitu a přinesl mesh networking do povědomí širší veřejnosti, zároveň odkryl některé fundamentální problémy škálovatelnosti. Právě tyto výzvy se MeshCore rozhodl řešit od základů - s čistším designem, efektivnějším routingem a architekturou pripravenou na budoucnost.</p>
<p><strong>Problém s přetížením sítí:</strong> Zatímco populární Meshtastic trpí problémy se zahlcováním sítě kvůli své architektuře, MeshCore přináší elegantní řešení těchto problémů od samého počátku.</p>
<h2>Co je MeshCore?</h2>
<p>MeshCore je multiplatformní systém umožňující bezpečnou textovou komunikaci využívající LoRa rádiový hardware. Jde o lightweight, open-source C++ knihovnu vytvořenou pro umožnění mesh networkingu přes LoRa a další packet-based rádia.</p>
<p>Hlavní charakteristiky MeshCore zahrnují:</p>
<p><strong>Multi-hop packet routing</strong> - zařízení mohou předávat zprávy přes více uzlů, rozšiřuje dosah nad rámec jednoho rádia. Systém podporuje konfigurovatelný počet hopů pro vyvážení efektivity sítě.</p>
<p><strong>Decentralizovaná architektura</strong> - nevyžaduje centrální server ani internet; síť je self-healing, což znamená, že pokud jeden uzel selže nebo se dostane mimo dosah, MeshCore najde alternativní cestu.</p>
<p><strong>Nízká spotřeba energie</strong> - ideální pro zařízení napájená z baterií nebo solárních panelů, což umožňuje dlouhodobé nasazení v odlehlých oblastech.</p>
<h2>Proč vznikl MeshCore?</h2>
<h3>Problémy Meshtastic</h3>
<p>Ačkoliv se Meshtastic stal velmi populárním (v České republice bylo registrováno přes 1110 zařízení), přinesl to i problémy:</p>
<p><strong>Zahlcení sítě:</strong> Radiokomunikační pásmo 868 MHz se rychle zahltilo kvůli architektuře, kdy se každá zpráva šíří z každého bodu na všechny dostupné body. Meshtastic ve skupině 10 zařízení funguje dobře, ale ve skupině stovek zařízení už zprávy často nedorazí nebo nedorazí potvrzení.</p>
<p><strong>Neefektivní provoz:</strong> Každá krabička se spojí s každou, což vytváří zbytečný síťový provoz a degraduje celkový výkon sítě.</p>
<p><strong>Problém s aktualizacemi:</strong> I když Meshtastic verze 2.6 slibuje vylepšení, musela by se nainstalovat na všechna existující zařízení - což u tisíců zařízení na stožárech a těžko přístupných místech představuje obrovský problém.</p>
<h2>Použití a aplikace</h2>
<p>MeshCore nachází uplatnění v široké škále scénářů:<br />
Může být použit pro off-grid komunikaci, emergency response &amp; disaster recovery, outdoor aktivity. Systém umožňuje zůstat v kontaktu i v odlehlých oblastech bez pokrytí mobilní sítě.</p>
<h3>Taktické a bezpečnostní aplikace</h3>
<p>Taktická bezpečnost včetně práva a pořádku a soukromé bezpečnosti - MeshCore poskytuje šifrovanou komunikaci pro profesionální použití.</p>
<h3>IoT a senzorové sítě</h3>
<p>Také IoT senzorové sítě - systém dokáže efektivně přenášet data ze vzdálených senzorů zpět do centrálního místa.</p>
<h2>Technické specifikace</h2>
<h3>Architektura a vývojové prostředí</h3>
<p>MeshCore je lightweight, portable C++ knihovna určená pro vývojáře, kteří chtějí vytvářet resilientní, decentralizované komunikační sítě bez internetu. Na rozdíl od Meshtastic, který je přizpůsoben pro casual LoRa komunikaci, nebo Reticulum s pokročilým networkingem, MeshCore balancuje jednoduchost se škálovatelností.</p>
<p><strong>Vývojové možnosti:</strong></p>
<ul>
<li><strong>Pro koncové uživatele</strong> - předkompilované firmware k přímému flashování</li>
<li><strong>Pro vývojáře</strong> - otevřená C++ knihovna pro custom embedded řešení</li>
<li><strong>MIT licence</strong> - volné použití pro osobní i komerční projekty</li>
</ul>
<h3>Podporovaná zařízení</h3>
<p>MeshCore podporuje širokou škálu LoRa hardware:</p>
<ul>
<li><strong>Heltec</strong> - V3 LoRa Boards, T114, V2</li>
<li><strong>RAK Wireless</strong> - RAK4631 (nejúspornější varianta)</li>
<li><strong>LilyGo</strong> - T3S3, TLora32 v1.6</li>
<li><strong>Xiaomi</strong> - XiaoS3 WIO (sx1262 combo), XiaoC3 (plus externí sx126x modul)</li>
<li><strong>Sensecap</strong> - T1000e</li>
<li><strong>Station G2</strong></li>
</ul>
<p>V České republice můžete zařízení zakoupit u specializovaných distributorů elektronických komponent jako je Pájeníčko.</p>
<h3>Protokol a routing</h3>
<p>MeshCore funguje jako mesh knihovna v jazyce C++ i jako hotový firmware, který stačí nahrát do podporovaného zařízení. Systém vytváří self-organizing mesh síť, kde každý uzel udržuje routing tabulku a může předávat pakety jménem ostatních uzlů.</p>
<p><strong>Klíčové funkce routingu:</strong></p>
<ul>
<li><strong>Flood a path memory</strong> - první soukromou zprávu posílá jako Flood, jakmile je zpráva doručena, zapamatuje si její cestu a pak ji posílá jen přes zapamatované uzly</li>
<li><strong>Fixed path routing</strong> - možnost ručně nastavit cesty pro zprávy, což vede ke spolehlivějšímu doručení ve složitějších topologiích</li>
<li><strong>Automatické routing</strong> - pokud doručení selže, posílá se znovu Flood</li>
<li><strong>Multi-hop routování</strong> - zprávy mohou cestovat přes více uzlů</li>
<li><strong>Rozlišení rolí</strong> - klient nebo router jsou oddělené role, routery jen přeposílají packety bez zbytečných funkcí</li>
</ul>
<h2>MeshCore vs. konkurence</h2>
<h3>Porovnání s Meshtastic</h3>
<p>Zatímco Meshtastic je nejpopulárnějším off-grid messaging řešením, MeshCore nabízí několik klíčových výhod a nevýhod:</p>
<p><strong>Výhody MeshCore:</strong></p>
<ul>
<li><strong>Vyšší flexibilita</strong> - díky otevřené knihovně mohou vývojáři tvořit specifická síťová řešení</li>
<li><strong>Vylepšené routování</strong> - možnost ručně nastavit cesty nebo využít efektivnější fixed path routing</li>
<li><strong>Méně zahlcení sítě</strong> - menší objem status provozu, výhodné v rozsáhlých sítích</li>
<li><strong>MIT licence</strong> - umožňuje použití i v komerčních projektech</li>
<li><strong>Strukturovanější přístup</strong> s pokročilými síťovými funkcemi jako static path optimalizace</li>
<li><strong>Oddělené role</strong> - routery jsou jen routery, klienti jen klienti</li>
<li><strong>Store-and-forward messaging</strong> - ukládání zpráv pro offline příjemce (mailbox funkce)</li>
<li><strong>Čistě mesh komunikace</strong> - žádné internetové propojení, funguje i bez elektriky jen se solárním napájením</li>
</ul>
<p><strong>Nevýhody MeshCore:</strong></p>
<ul>
<li><strong>Menší komunita</strong> - méně uživatelské podpory a návodů (ale rychle rostoucí)</li>
<li><strong>Statické role</strong> - nelze dynamicky měnit role uzlů bez reflashe firmware</li>
<li><strong>Menší podpora hardware</strong> - zatím podporuje méně zařízení než Meshtastic</li>
<li><strong>Chybí MQTT integrace</strong> - zaměřuje se čistě na mesh komunikaci bez internetového rozhraní</li>
<li><strong>Nekompatibilita</strong> - sdílí stejné frekvenční pásmo s Meshtastic, ale nejsou navzájem kompatibilní</li>
</ul>
<h3>Referenční aplikace</h3>
<p>MeshCore nabízí několik předkompilovaných firmware typů:</p>
<p><strong>Companion Radio</strong> - pro použití s externí chat aplikací přes BLE, USB nebo WiFi s podporou pro:</p>
<ul>
<li><strong>Web aplikace</strong> - app.meshcore.nz</li>
<li><strong>Android aplikace</strong> - dostupná v Google Play Store</li>
<li><strong>iOS aplikace</strong> - dostupná v App Store</li>
<li><strong>NodeJS a Python</strong> - pro vývojáře a automatizaci</li>
</ul>
<p><strong>Simple Repeater</strong> - rozšiřuje pokrytí sítě předáváním zpráv, konfigurovatelný přes web config tool nebo mobilní aplikaci</p>
<p><strong>Simple Room Server</strong> - jednoduchý BBS server pro sdílené příspěvky a store-and-forward messaging</p>
<p><strong>Simple Secure Chat</strong> - bezpečná terminálová textová komunikace přímo mezi zařízeními</p>
<h2>Boom MeshCore v České republice</h2>
<p>Červenec 2025 se stal přelomovým měsícem pro MeshCore v České republice. <strong>20. července 2025 se Ještěd přepnul na MeshCore</strong>, což spustilo lavinu dalších nasazení.</p>
<h3>Rychlý růst sítě</h3>
<p>Následovalo nasazení MeshCore na klíčových místech:</p>
<ul>
<li><strong>Říp</strong> - strategické místo pro severní Čechy</li>
<li><strong>Klínovec</strong> - nejvyšší hora Krušných hor</li>
<li><strong>Další menší vysílače</strong> po celé republice</li>
</ul>
<p>Za pouhý týden se pokrytí dramaticky zlepšilo a aktivita ukazuje, že trend pokračuje.</p>
<h3>Česká komunita</h3>
<p>Vznikl specializovaný komunitní web <strong>meshcore.cz</strong> s návody, tipy a triky. Telegram skupina <strong>meshcore_cz</strong> rychle roste a sdružuje nadšence po celé republice.</p>
<p><strong>Klíčové výhody oproti Meshtastic v ČR:</strong></p>
<ul>
<li><strong>Funkčnost</strong> - na rozdíl od přetížené Meshtastic sítě MeshCore skutečně funguje</li>
<li><strong>Méně telemetrie</strong> - síť není zahlcená zbytečnými daty</li>
<li><strong>Čistě offline</strong> - žádné internetové propojení, skutečná nezávislost</li>
<li><strong>Solární napájení</strong> - funguje i bez elektrické sítě, jen se slunečním svitem</li>
</ul>
<h3>Doporučené nastavení pro ČR</h3>
<p>Česká komunita se domluvila na těchto parametrech:</p>
<ul>
<li><strong>Frekvence:</strong> 869.525 MHz</li>
<li><strong>Bandwidth:</strong> 62.5 kHz  </li>
<li><strong>Spreading Factor:</strong> 7</li>
<li><strong>Coding Rate:</strong> 5</li>
<li><strong>Transmit Power:</strong> 22</li>
</ul>
<h3>Praktické nasazení v ČR</h3>
<ol>
<li><strong>Získání hardware</strong> - doporučujeme Heltec LoRa v3.1, dostupný u specializovaných distributorů jako je Pájeníčko</li>
<li><strong>Flashování firmware</strong> - využijte webový flasher na <a href="https://flasher.meshcore.co.uk/">https://flasher.meshcore.co.uk/</a>
<ul>
<li>Vyberte podporované zařízení</li>
<li>Zvolte typ firmware (Companion, Repeater, Room Server)</li>
<li>Klikněte FLASH</li>
</ul>
</li>
<li><strong>Připojení klientů:</strong>
<ul>
<li><strong>Web aplikace</strong> - app.meshcore.nz (funguje offline)</li>
<li><strong>Mobilní aplikace</strong> - Android/iOS z oficiálních obchodů</li>
<li><strong>Bluetooth pairing</strong> - PIN zobrazený na OLED displeji zařízení</li>
</ul>
</li>
<li><strong>Kontrola pokrytí</strong> - mapa uzlů dostupná na <a href="https://map.meshcore.dev/">https://map.meshcore.dev/</a></li>
</ol>
<p><strong>Důležité upozornění:</strong> Žádné zařízení s konektorem pro externí anténu nesmí být spuštěno bez připojené antény - hrozí zničení vysílací části čipu.</p>
<h3>Zdroje pro českou komunitu</h3>
<ul>
<li><strong>Oficiální web:</strong> <a href="https://meshcore.co.uk/">https://meshcore.co.uk/</a></li>
<li><strong>Česká stránka:</strong> <a href="https://meshcore.cz/">https://meshcore.cz/</a></li>
<li><strong>GitHub repository:</strong> <a href="https://github.com/ripplebiz/MeshCore">https://github.com/ripplebiz/MeshCore</a></li>
<li><strong>Webový flasher:</strong> <a href="https://flasher.meshcore.co.uk/">https://flasher.meshcore.co.uk/</a></li>
<li><strong>Web aplikace:</strong> <a href="https://app.meshcore.nz">https://app.meshcore.nz</a></li>
<li><strong>Telegram skupina:</strong> @meshcore_cz</li>
<li><strong>Discord komunita:</strong> Andy Kirby's Discord pro podporu vývojářů</li>
<li><strong>Mapa uzlů:</strong> <a href="https://map.meshcore.dev/">https://map.meshcore.dev/</a></li>
<li><strong>FAQ a dokumentace:</strong> GitHub wiki s detailními návody</li>
</ul>
<h3>Vzdělávací videa a tutoriály</h3>
<p><strong>Andy Kirby YouTube kanál</strong> - klíčový zdroj pro pochopení MeshCore:</p>
<ul>
<li><strong>MeshCore Intro Video</strong> - základní úvod do systému pro začátečníky</li>
<li><strong>Messaging System Tutorial</strong> - návod na používání komunikačního systému</li>
<li><strong>MeshCore Update série</strong> - pravidelné aktualizace o vývoji projektu</li>
<li><strong>Praktické testování</strong> - reálné testy dosahu a funkčnosti v terénu</li>
</ul>
<p>Andy Kirby byl instrumental v getting projects known out there a pro helping educate people s jeho videi. Jeho videa poskytují praktické návody od základního nastavení až po pokročilé konfigurace repeaterů.</p>
<p><strong>Doporučené sledování:</strong> Začněte s Intro Video, poté pokračujte tutoriály pro messaging systém a sledujte nejnovější update videa pro informace o vývoji.</p>
<h3>Vývojářské možnosti</h3>
<p>Pro pokročilé uživatele a vývojáře:</p>
<ul>
<li><strong>PlatformIO a Visual Studio Code</strong> - kompletní vývojové prostředí</li>
<li><strong>Open-source</strong> - MIT licence umožňuje modifikace a komerční použití</li>
<li><strong>Příspěvky do projektu</strong> - PR požadavky přes 'dev' branch na GitHubu</li>
<li><strong>Bug reporting</strong> - GitHub Issues pro hlášení chyb a feature požadavky</li>
</ul>
<h2>Závěr</h2>
<p>MeshCore představuje významný krok vpřed v oblasti decentralizované komunikace a v České republice už není jen teoretickou možností - <strong>je tu a funguje</strong>. Červencový boom ukázal, že česká komunita je připravena na alternativu k přetíženému Meshtastic.</p>
<p>Zatímco Meshtastic bojuje s problémy škálovatelnosti a čeká na nasazení verze 2.6 na tisíce existujících zařízení, MeshCore nabízí řešení těchto problémů od počátku. Jeho open-source povaha, nízké požadavky na energii, pokročilé mesh routing schopnosti a především <strong>funkčnost v reálném provozu</strong> z něj činí atraktivní volbu pro každého, kdo hledá spolehlivé off-grid komunikační řešení.</p>
<p>S rostoucím pokrytím a aktivní komunitou je MeshCore v České republice připraven stát se dominantní platformou pro decentralizovanou komunikaci. Jak říkají nadšenci: <strong>&quot;Meshtastic je mrtev, ať žije MeshCore!&quot;</strong></p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2025%2F07%2F20%2Fmeshcore-off-grid-komunikaci-prostrednictvim-lora-mesh-siti%2F&#038;via=hessevalentino&#038;related=hessevalentino%3AValentino%20Hesse%20OK2HSS" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2025/07/20/meshcore-off-grid-komunikaci-prostrednictvim-lora-mesh-siti/">MeshCore: Off-grid komunikaci prostřednictvím LoRa mesh sítí</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32 Bluetooth Server &#8211; Rozšíření</title>
		<link>https://www.hardwired.dev/2023/02/05/esp32-bluetooth-server-2/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Sun, 05 Feb 2023 14:02:16 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[IOT]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[ble]]></category>
		<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[platformio]]></category>
		<category><![CDATA[server]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=975</guid>

					<description><![CDATA[<p>Rozšíření článku ESP32 Bluetooth Server. Kód vytváří UART BLE server na ESP32 vývojové desce. Bluetooth server se jde připojit pomocí &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2023/02/05/esp32-bluetooth-server-2/">ESP32 Bluetooth Server – Rozšíření</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Rozšíření článku <a href="https://www.hardwired.dev/esp32-bluetooth-server/">ESP32 Bluetooth Server</a>. Kód vytváří <a href="https://cs.wikipedia.org/wiki/UART">UART</a> <a href="https://cs.wikipedia.org/wiki/Bluetooth">BLE</a> server na <a href="https://www.espressif.com/en/products/socs/esp32">ESP32</a> vývojové desce. Bluetooth server se jde připojit pomocí programu <a href="https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal">Serial Bluetooth Terminal</a> na telefonu se systémem Android, nebo ekvivalentním na iOS.</p>
<p>Bluetooth server reaguje na dva příkazy.</p>
<ul>
<li><code>get</code></li>
<li><code>set &lt;payload&gt;</code></li>
</ul>
<p>Příkazem <code>set</code> se do dočasné paměti ukládá textová hodnota <code>payload</code>. Pokud vše proběhne v pořádku, server vrátí do konzole uloženou zprávu.</p>
<p>Příkazem <code>get</code> získáme ze serveru uloženou zprávu. Po poslání uložené zprávy klientovi se zpráva ze serveru smaže.</p>
<pre><code class="language-cpp">/**
 * @file main.cpp
 * @author Hard Wired
 * @brief Bluetooth server reagující na příkazy.
 * @version 0.1
 * @date 2023-02-01
 * @details Umožňuje připojení telefonu přes Bluetooth terminal aplikaci a
 *          pomocí příkazu &quot;set &lt;text&gt;&quot; uložit textový řetězec do paměti
 *          Bluetooth serveru. Při úspěšném uložení pošle server zprávu
 *          zpět do konzole na telefonu jako potvrzení. Zpráva v takovém
 *          případě zůstává uložena v paměti serveru.
 *
 *          Při opětovném připojení a zadání příkazu &quot;get&quot; server pošle zpět do
 *          Bluetooth konzole na telefonu uloženou zprávu. Tuto zprávu
 *          následně smaže.
 */

#include &lt;Arduino.h&gt;

// Bluetooth knihovny
#include &lt;BLE2902.h&gt;
#include &lt;BLEDevice.h&gt;
#include &lt;BLEServer.h&gt;
#include &lt;BLEUtils.h&gt;

// inicializace modulu z knihovny
BLECharacteristic *pCharacteristic;

const String COMMAND_GET = &quot;get&quot;;
const String COMMAND_SET = &quot;set&quot;;

/**
 * @brief Definuje zda li je klient aktualne pripojeny
 *
 */
bool deviceConnected = false;

/**
 * @brief Flag definující akci odeslat
 *
 */
bool send = false;

/**
 * @brief Flag definující ponechat zprávu uloženou i po odeslání
 *
 */
bool keepMessage = false;

/**
 * @brief Obsahuje zprávu kterou klient pošle serveru
 *
 */
std::string receivedMessage;

/**
 * @brief Zpráva, která se bude odesílat klientovi
 *
 */
String out = &quot;Lorem ipsum&quot;;

#define SERVICE_UUID &quot;6E400001-B5A3-F393-E0A9-E50E24DCCA9E&quot;
#define CHARACTERISTIC_UUID_RX &quot;6E400002-B5A3-F393-E0A9-E50E24DCCA9E&quot;
#define CHARACTERISTIC_UUID_TX &quot;6E400003-B5A3-F393-E0A9-E50E24DCCA9E&quot;

/**
 * @brief Převede std::string na String objekt.
 *
 * @param message
 * @return String
 */
String convertMessageToString(std::string message)
{
    return String(message.c_str());
}

String normalizeMessage(String message)
{
    message.trim();
    message.toLowerCase();

    return message;
}

/**
 * @brief Zpracovává a ukládá zprávu pro odeslání.
 *
 * @param message
 */
void setOutputMessage(String message)
{
    message.trim();

    out = message;
}

/**
 * @brief Maže zprávu pro odeslání
 *
 */
void clearOutputMessage() { out = &quot;&quot;; }

/**
 * @brief Vrací `payload` příkazu typu `[command] &lt;payload&gt;`.
 *
 * @param str
 * @return String
 */
String getCommandPayload(String str, int spacePosition)
{
    return str.substring(spacePosition + 1, str.length());
}

/**
 * @brief Hledá první mezeru v řetězci. Když nenajde, vraci délku řetězce + 1.
 *
 * @param str
 * @return int
 */
int findCommandPositionIndex(String str)
{
    int spacePosition = 0;
    int length = str.length();

    for (int i = 0; i &lt; length; i++)
    {
        spacePosition = i;

        if (str[i] == &#039; &#039;)
        {
            return spacePosition;
        }
    }

    return spacePosition + 1;
}

/**
 * @brief Nastaví odchozí zprávu na základě přijatého příkazu SET.
 *
 * @param message
 */
void commandSet(String payload)
{
    keepMessage = true;
    send = true;

    setOutputMessage(payload);
}

/**
 * @brief Nastavi odeslání zprávy klientovi a její následné smazání.
 *
 */
void commandGet()
{
    keepMessage = false;
    send = true;
}

/**
 * @brief Zpracování příkazu zaslaného klientem.
 *
 * @param message
 */
void processCommand(std::string message)
{
    /*
     * Převedení std::string zprávy na String.
     */
    String stringMessage = convertMessageToString(message);

    /*
     * Odstranění mezer na začátku a konci řetězce. Převedení na malá písmena.
     */
    String normalizedMessage = normalizeMessage(stringMessage);

    /*
     * Vyhledá kde v řetězci končí příkaz. Hledá první mezeru :).
     */
    int commandPositionIndex = findCommandPositionIndex(normalizedMessage);

    String command = normalizedMessage.substring(0, commandPositionIndex);

    if (command == COMMAND_GET)
    {
        commandGet();
    }
    else if (command == COMMAND_SET)
    {
        String payload = getCommandPayload(stringMessage, commandPositionIndex);
        commandSet(payload);
    }
}

/**
 * @brief Odešle zprávu přes Bluetooth.
 *
 */
void sendMessage()
{
    /*
     * Úprava pro výstup do terminálové aplikace.
     */
    String txMessage = out + &quot;\n&quot;;
    int txMessageLength = txMessage.length() + 1;

    char message[txMessageLength];

    txMessage.toCharArray(message, txMessageLength);

    pCharacteristic-&gt;setValue(message);

    pCharacteristic-&gt;notify();
}

/**
 * @brief Vytiskne přijatou zprávu do sériové konzole.
 *
 * @param receivedMessage
 */
void printReceivedMessage(std::string receivedMessage)
{
    Serial.print(&quot;Prijata zprava: &quot;);

    for (int i = 0; i &lt; receivedMessage.length(); i++)
    {
        Serial.print(receivedMessage[i]);
    }

    Serial.println();
}

/**
 * @brief Connect, disconnect callbacks
 *
 */
class MyServerCallbacks : public BLEServerCallbacks
{
    void onConnect(BLEServer *pServer) { deviceConnected = true; };

    void onDisconnect(BLEServer *pServer)
    {
        deviceConnected = false;
        pServer-&gt;getAdvertising()-&gt;start();
    }
};

/**
 * @brief Callback zpracovávající příchozí zprávy
 *
 */
class MyCallbacks : public BLECharacteristicCallbacks
{
    void onWrite(BLECharacteristic *pCharacteristic)
    {
        receivedMessage = pCharacteristic-&gt;getValue();

        if (receivedMessage.length() &gt; 0)
        {
            printReceivedMessage(receivedMessage);
            processCommand(receivedMessage);
        }
    }
};

void setup()
{
    Serial.begin(115200);

    BLEDevice::init(&quot;ESP32 BLE SERVER&quot;);

    BLEServer *pServer = BLEDevice::createServer();
    pServer-&gt;setCallbacks(new MyServerCallbacks());

    BLEService *pService = pServer-&gt;createService(SERVICE_UUID);

    pCharacteristic = pService-&gt;createCharacteristic(CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY);
    pCharacteristic-&gt;addDescriptor(new BLE2902());

    BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE);
    pCharacteristic-&gt;setCallbacks(new MyCallbacks());

    pService-&gt;start();

    pServer-&gt;getAdvertising()-&gt;start();

    Serial.println(&quot;BLE nastaveno, ceka na pripojeni..&quot;);
}

void loop()
{
    if (deviceConnected == true &amp;&amp; out.length() &gt; 0 &amp;&amp; send == true)
    {
        sendMessage();
        delay(100);

        if (keepMessage == false)
        {
            clearOutputMessage();
        }

        send = false;
        keepMessage = false;
    }

    delay(1000);
}</code></pre>
<pre><code class="language-ini">; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200</code></pre>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2023%2F02%2F05%2Fesp32-bluetooth-server-2%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2023/02/05/esp32-bluetooth-server-2/">ESP32 Bluetooth Server – Rozšíření</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>ESP32 Bluetooth Server</title>
		<link>https://www.hardwired.dev/2023/02/01/esp32-bluetooth-server/</link>
		
		<dc:creator><![CDATA[John Doe]]></dc:creator>
		<pubDate>Wed, 01 Feb 2023 03:28:54 +0000</pubDate>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[IOT]]></category>
		<category><![CDATA[Různé]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[ble]]></category>
		<category><![CDATA[bluetooth]]></category>
		<category><![CDATA[cpp]]></category>
		<category><![CDATA[esp32]]></category>
		<category><![CDATA[platformio]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[vscode]]></category>
		<guid isPermaLink="false">https://www.hardwired.dev/?p=938</guid>

					<description><![CDATA[<p>Dneska se podíváme jak zprovoznit Bluetooth na ESP32. Cílem je umožnit telefonu připojit se na naše Bluetooth zařízení a odpovídat &#62;&#62;&#62;</p>
<p>The post <a href="https://www.hardwired.dev/2023/02/01/esp32-bluetooth-server/">ESP32 Bluetooth Server</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></description>
										<content:encoded><![CDATA[<div id="bsf_rt_marker"></div><p>Dneska se podíváme jak zprovoznit Bluetooth na ESP32. Cílem je umožnit telefonu připojit se na naše Bluetooth zařízení a odpovídat na specifické zprávy. Jako vývojové prostředí použijeme <a href="https://platformio.org/">PlatformIO</a>.</p>
<h1>ESP32</h1>
<p>Pro projekt použijeme <a href="https://www.aliexpress.com/item/32996458212.html">ESP32 Development Board</a> z Aliexpressu. V době psaní článku stojí zhruba 120CZK.</p>
<p><img decoding="async" src="https://www.hardwired.dev/wp-content/uploads/2023/02/esp32-aliexpress.jpg" alt="" /></p>
<h1>platformio.ini</h1>
<p>Konfigurační soubor pro projekt.</p>
<pre><code class="language-ini">[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200</code></pre>
<h1>main.cpp</h1>
<p>Jako základ kódu jsem použil výborný článek <a href="https://navody.dratek.cz/navody-k-produktum/esp32-a-bluetooth-low-energy-ble.html">ESP32 a Bluetooth Low Energy (BLE)</a> z <a href="https://navody.dratek.cz/">Drátek Návody</a> a provedl úpravy pro potřeby projektu. Pro zjednodušení nejprve celý kód projektu. Rozbor bude pokračovat.</p>
<pre><code class="language-c++">#include &lt;Arduino.h&gt;

// Bluetooth knihovny
#include &lt;BLEDevice.h&gt;
#include &lt;BLEServer.h&gt;
#include &lt;BLEUtils.h&gt;
#include &lt;BLE2902.h&gt;

// inicializace modulu z knihovny
BLECharacteristic *pCharacteristic;

// proměnná pro kontrolu připojených zařízení
bool deviceConnected = false;

// proměnná pro ukládání přijaté zprávy
std::string receivedMessage;

// proměnná pro zprávu pro odeslání
String out = &quot;&quot;;

// definice unikátních ID pro různé služby,
// pro vlastní UUID využijte generátor
// https://www.uuidgenerator.net/
#define SERVICE_UUID &quot;6E400001-B5A3-F393-E0A9-E50E24DCCA9E&quot;
#define CHARACTERISTIC_UUID_RX &quot;6E400002-B5A3-F393-E0A9-E50E24DCCA9E&quot;
#define CHARACTERISTIC_UUID_TX &quot;6E400003-B5A3-F393-E0A9-E50E24DCCA9E&quot;

int compareCommand(std::string message, String command)
{
    String converted = String(message.c_str());
    converted.trim();
    converted.toLowerCase();

    return converted == command;
}

void setOutputMessage(String message)
{
    out = message;
    out += &quot;\n&quot;;
}

void clearOutputMessage()
{
    out = &quot;&quot;;
}

void sendMessage()
{
    char message[out.length() + 1];
    out.toCharArray(message, out.length() + 1);

    // přepsání zprávy do BLE služby
    pCharacteristic-&gt;setValue(message);

    // odeslání zprávy skrze BLE do připojeného zařízení
    pCharacteristic-&gt;notify();
}

// třída pro kontrolu připojení
class MyServerCallbacks : public BLEServerCallbacks
{
    // při spojení zařízení nastav proměnnou na log1
    void onConnect(BLEServer *pServer)
    {
        deviceConnected = true;
    };
    // při odpojení zařízení nastav proměnnou na log0
    void onDisconnect(BLEServer *pServer)
    {
        deviceConnected = false;
        pServer-&gt;getAdvertising()-&gt;start();
    }
};

// třída pro příjem zprávy
class MyCallbacks : public BLECharacteristicCallbacks
{
    // při příjmu zprávy proveď následující
    void onWrite(BLECharacteristic *pCharacteristic)
    {
        // načti přijatou zprávu do proměnné
        receivedMessage = pCharacteristic-&gt;getValue();

        // pokud není zpráva prázdná, vypiš její obsah
        // po znacích po sériové lince
        // a pokud přijde očekávaný příkaz pošli odpověď
        if (receivedMessage.length() &gt; 0)
        {
            Serial.print(&quot;Prijata zprava: &quot;);
            for (int i = 0; i &lt; receivedMessage.length(); i++)
            {
                Serial.print(receivedMessage[i]);
            }
            Serial.println();

            if (compareCommand(receivedMessage, &quot;ahoj&quot;))
            {
                setOutputMessage(&quot;No nazdar&quot;);
            }
        }
    }
};

void setup()
{
    // zahájení komunikace po sériové lince
    // rychlostí 115200 baud
    Serial.begin(115200);

    // inicializace Bluetooth s nastavením jména zařízení
    BLEDevice::init(&quot;ESP32 BLE&quot;);

    // vytvoření BLE serveru
    BLEServer *pServer = BLEDevice::createServer();
    pServer-&gt;setCallbacks(new MyServerCallbacks());

    // vytvoření BLE služby
    BLEService *pService = pServer-&gt;createService(SERVICE_UUID);

    // vytvoření BLE komunikačního kanálu pro odesílání (TX)
    pCharacteristic = pService-&gt;createCharacteristic(
        CHARACTERISTIC_UUID_TX,
        BLECharacteristic::PROPERTY_NOTIFY);
    pCharacteristic-&gt;addDescriptor(new BLE2902());

    // vytvoření BLE komunikačního kanálu pro příjem (RX)
    BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(
        CHARACTERISTIC_UUID_RX,
        BLECharacteristic::PROPERTY_WRITE);
    pCharacteristic-&gt;setCallbacks(new MyCallbacks());

    // zahájení BLE služby
    pService-&gt;start();

    // zapnutí viditelnosti BLE
    pServer-&gt;getAdvertising()-&gt;start();
    Serial.println(&quot;BLE nastaveno, ceka na pripojeni..&quot;);
}

void loop()
{
    if (deviceConnected == true &amp;&amp; out.length() &gt; 0)
    {
        sendMessage();
        delay(100);
        clearOutputMessage();
    }

    // pauza před novým během smyčky
    delay(1000);
}</code></pre>
<h1>Rozbor kódu</h1>
<pre><code class="language-cpp">#include &lt;Arduino.h&gt;

// Bluetooth knihovny
#include &lt;BLEDevice.h&gt;
#include &lt;BLEServer.h&gt;
#include &lt;BLEUtils.h&gt;
#include &lt;BLE2902.h&gt;</code></pre>
<p>Knihovny potřebné pro obsluhu Bluetooth.</p>
<pre><code class="language-cpp">BLECharacteristic *pCharacteristic;</code></pre>
<p>Inicializace modulu knihovny pro práci s Bluetooth.</p>
<pre><code class="language-cpp">bool deviceConnected = false;</code></pre>
<p>Indikace, že je zařízení připojeno k našemu Bluetooth zařízení.</p>
<pre><code class="language-cpp">std::string receivedMessage;</code></pre>
<p>Proměnná pro uložení zprávy, kterou pošleme našemu Bluetooth zařízení.</p>
<pre><code class="language-cpp">String out = &quot;&quot;;</code></pre>
<p>Proměnná pro uložení odchozí zprávy.</p>
<pre><code class="language-cpp">#define SERVICE_UUID &quot;6E400001-B5A3-F393-E0A9-E50E24DCCA9E&quot;
#define CHARACTERISTIC_UUID_RX &quot;6E400002-B5A3-F393-E0A9-E50E24DCCA9E&quot;
#define CHARACTERISTIC_UUID_TX &quot;6E400003-B5A3-F393-E0A9-E50E24DCCA9E&quot;</code></pre>
<p>Bluetooth se skládá z jednotlivých služeb pro které je mít potřeba vygenerované unikátní identifikátory.</p>
<pre><code class="language-cpp">int compareCommand(std::string message, String command)
{
    String converted = String(message.c_str());
    converted.trim();
    converted.toLowerCase();

    return converted == command;
}</code></pre>
<p>Naše Bluetooth zařízení se chová jako server. Pokud mu pošlete zprávu/příkaz, který rozpozná, tak odpoví zpět. Příchozí zpráva se ukládá do proměnné typu <code>std::string</code>. Zprávu je potřeba očistit od bílých znaků, normalizovat (převést na malá písmena <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> ) a porovnat s příkazem, který chceme provést. Tady byl lehce zádrhel, protože vhodné metody obsahuje zase <code>String</code> objekt. Céčko/C++ jsem provozoval naposledy na vysoké pro školní projekty a už tam jsem většinu věcí řešil v Pythonu. Jsem už prostě zmlsaný moderními programovacími jazyky. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Mé řešení asi nebude nejefektivnější, ale je lehce čitelné a funguje.</p>
<p>TLDR: <code>compareCommand</code> vezme příchozí zprávu, očistí od bordelu, porovná s námi zadaným příkazem a vrátí hodnotu porovnání.</p>
<pre><code class="language-cpp">void setOutputMessage(String message)
{
    out = message;
    out += &quot;\n&quot;;
}</code></pre>
<p>Pomocná funkce pro nastavení odchozí zprávy.</p>
<pre><code class="language-cpp">void clearOutputMessage()
{
    out = &quot;&quot;;
}</code></pre>
<p>Pomocná funkce pro vyčistění proměnné po odeslání zprávy.</p>
<pre><code class="language-cpp">void sendMessage()
{
    char message[out.length() + 1];
    out.toCharArray(message, out.length() + 1);

    pCharacteristic-&gt;setValue(message);

    pCharacteristic-&gt;notify();
}</code></pre>
<p>Funkce zapouzdřující odeslání zprávy. Převede zprávu na pole znaků, předá Bluetooth knihovně a pomocí metody <code>notify</code> odešle na připojené zařízení.</p>
<pre><code class="language-cpp">class MyServerCallbacks : public BLEServerCallbacks
{
    void onConnect(BLEServer *pServer)
    {
        zarizeniPripojeno = true;
    };

    void onDisconnect(BLEServer *pServer)
    {
        zarizeniPripojeno = false;
        pServer-&gt;getAdvertising()-&gt;start();
    }
};</code></pre>
<blockquote>
<p>Během testů se objevil problém s opětovným připojením. Když se telefon odpojil od Bluetooth serveru, nešlo se znovu připojit. Pomohl jen restart ESPčka. Dle různých zdrojů za to můžou různé verze knihoven. Pokud přidáme při odpojení zařízení <code>pServer-&gt;getAdvertising()-&gt;start();</code>, který začne propagovat náš Bluetooth server do prostoru, opětovné připojení funguje.</p>
</blockquote>
<p>Třída zapouzdřující <code>callbacky</code> pro náš Bluetooth server. Pokud se zařízení připojí/odpojí nastaví proměnnou <code>deviceConnected</code>.</p>
<pre><code class="language-cpp">class MyCallbacks : public BLECharacteristicCallbacks
{
    void onWrite(BLECharacteristic *pCharacteristic)
    {
        receivedMessage = pCharacteristic-&gt;getValue();

        if (receivedMessage.length() &gt; 0)
        {
            Serial.print(&quot;Prijata zprava: &quot;);
            for (int i = 0; i &lt; receivedMessage.length(); i++)
            {
                Serial.print(receivedMessage[i]);
            }
            Serial.println();

            if (compareCommand(receivedMessage, &quot;ahoj&quot;))
            {
                setOutputMessage(&quot;No nazdar&quot;);
            }
        }
    }
};</code></pre>
<p>Třída zapouzdřující <code>callback</code> pro příjem zprávy. Při příchozí zprávě nenulové délky se jako první vypíše do sériové konzole. Následně proběhne porovnání jestli obsahuje, pro nás známý, příkaz. V našem případě <code>ahoj</code>. Pokud ano, tak odpoví <code>No nazdar</code>.</p>
<h2>setup()</h2>
<pre><code class="language-cpp">Serial.begin(115200);</code></pre>
<p>Nastavení rychlostí komunikace přes sériovou linku. Musí být stejné jako v <code>platformio.ini</code>.</p>
<pre><code class="language-cpp">BLEDevice::init(&quot;ESP32 BLE&quot;);</code></pre>
<p>Inicializace Bluetooth s nastavením jména, na které se bude dát z telefonu připojit.</p>
<pre><code class="language-cpp">BLEServer *pServer = BLEDevice::createServer();
pServer-&gt;setCallbacks(new MyServerCallbacks());</code></pre>
<p>Vytvoření Bluetooth serveru. Nastavíme <code>callbacky</code> pro detekci připojení/odpojení zařízení pomocí třídy nadefinované výše.</p>
<pre><code class="language-cpp">BLEService *pService = pServer-&gt;createService(SERVICE_UUID);</code></pre>
<p>Vytvoření Bluetooth služby.</p>
<pre><code class="language-cpp">pCharacteristic = pService-&gt;createCharacteristic(
        CHARACTERISTIC_UUID_TX,
        BLECharacteristic::PROPERTY_NOTIFY);
pCharacteristic-&gt;addDescriptor(new BLE2902());</code></pre>
<p>Vytvoření komunikačního kanálu pro odesílání zpráv.</p>
<pre><code class="language-cpp">BLECharacteristic *pCharacteristic = pService-&gt;createCharacteristic(
        CHARACTERISTIC_UUID_RX,
        BLECharacteristic::PROPERTY_WRITE);
pCharacteristic-&gt;setCallbacks(new MyCallbacks());</code></pre>
<p>Vytvoření kanálu pro příjem zpráv. Nastavujeme <code>callback</code> pro příjem nadefinovaný výše.</p>
<pre><code class="language-cpp">pService-&gt;start();</code></pre>
<p>Nastartování Bluetooth služby.</p>
<pre><code class="language-cpp">pServer-&gt;getAdvertising()-&gt;start();
Serial.println(&quot;BLE nastaveno, ceka na pripojeni..&quot;);</code></pre>
<p>Zviditelnění pro ostatní zařízení.</p>
<h2>loop()</h2>
<pre><code class="language-cpp">if (deviceConnected == true &amp;&amp; out.length() &gt; 0)
{
    sendMessage();
    delay(100);
    clearOutputMessage();
}

delay(1000);</code></pre>
<p><code>Loop</code> smyčka každou sekundu zkontroluje jestli je zařízení připojené k našemu Bluetooth serveru a jestli existuje zpráva co by šla odeslat. Pokud jsou obě podmínky splněny odešleme zprávu a vyčistíme data.</p>
<h2>TLDR</h2>
<p>Bluetooth server čeká na zp rávy. Pokud přijde zpráva, která obsahuje známy příkaz, nastaví se příslušné proměnné. Smyčka <code>loop</code> každou sekundu zkontroluje jestli jsou příslušné proměnné pro odchozí zprávu a pokud ano odešle zprávu na připojené zařízení. No raketová věda to teda není. <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f600.png" alt="😀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h1>Serial Bluetooth Terminal</h1>
<p>Kód je zkompilovaný, nahraný na ESP32 a běží. Teď je potřeba začít s naším Bluetooth zařízením komunikovat. Pro Android jde použít výbornou aplikaci <a href="https://play.google.com/store/apps/details?id=de.kai_morich.serial_bluetooth_terminal&amp;hl=cs&amp;gl=US">Serial Bluetooth Terminal</a>. Umí to co potřebujeme. Připojit se k zařízení, posílat a obdržet zprávy.</p>
<p>Po instalaci se v obrazovce <code>Devices</code> přepněte do tabu <code>Bluetooth LE</code> a naskenujte zařízení. Objeví se naše ESPčko. Kliknutím na něj se připojíte.</p>
<p><img decoding="async" src="https://www.hardwired.dev/wp-content/uploads/2023/02/ble-terminal-01.jpg" alt="" /></p>
<p>Pokud připojení proběhne v pořádku zobrazí se následující.</p>
<p><img decoding="async" src="https://www.hardwired.dev/wp-content/uploads/2023/02/ble-terminal-02.jpg" alt="" /></p>
<p>Po odeslání zprávy <code>ahoj</code> dostaneme odpověď.</p>
<p><img decoding="async" src="https://www.hardwired.dev/wp-content/uploads/2023/02/ble-terminal-03.jpg" alt="" /></p>
<h1>Závěr</h1>
<p>Prezentovaný kód je takové minimum, bez hlubší znalosti Bluetooth a jeho vnitřního fungování, které ověřuje koncept ESP32 jako Bluetooth serveru odpovídajícího na příkazy.</p>
<p>Happy coding.</p>

<div class="twitter-share"><a href="https://twitter.com/intent/tweet?url=https%3A%2F%2Fwww.hardwired.dev%2F2023%2F02%2F01%2Fesp32-bluetooth-server%2F&#038;via=hessevalentino" class="twitter-share-button">Tweet</a></div><p>The post <a href="https://www.hardwired.dev/2023/02/01/esp32-bluetooth-server/">ESP32 Bluetooth Server</a> first appeared on <a href="https://www.hardwired.dev">Hard Wired</a>.</p>]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
