{"id":4309,"date":"2025-10-29T01:49:07","date_gmt":"2025-10-29T01:49:07","guid":{"rendered":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/?p=4309"},"modified":"2025-10-29T01:49:08","modified_gmt":"2025-10-29T01:49:08","slug":"spectrum-sensing-techniques-from-energy-detectors-to-hybrid-fftml-triage","status":"publish","type":"post","link":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/?p=4309","title":{"rendered":"Spectrum Sensing Techniques: From Energy Detectors to Hybrid FFT+ML Triage"},"content":{"rendered":"\n<h3 class=\"wp-block-heading\"><em>A Practical Guide for RF Engineers in 2025<\/em><\/h3>\n\n\n\n<p><strong>By Benjamin J. Gilbert<\/strong><br><em>Spectrcyde RF Quantum SCYTHE<\/em><br><a href=\"mailto:bgilbert2@com.edu\">bgilbert2@com.edu<\/a><br><a href=\"https:\/\/gilbert1984.com\/papers\/rf-triage-rev2.pdf\">Full Paper PDF<\/a> \u00b7 <a href=\"https:\/\/github.com\/bgilbert1984\/rf-triage-benchmark\">Reproducible Code<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What Is <strong>Spectrum Sensing<\/strong>?<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Detecting, classifying, or localizing active RF transmissions in a frequency band \u2014 in real time, under noise, with minimal compute.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<p>Used in:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Cognitive Radio<\/strong><\/li>\n\n\n\n<li><strong>Dynamic Spectrum Access (DSA)<\/strong><\/li>\n\n\n\n<li><strong>Electronic Warfare (EW)<\/strong><\/li>\n\n\n\n<li><strong>5G\/6G Shared Spectrum<\/strong><\/li>\n\n\n\n<li><strong>SIGINT Triage<\/strong><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Core Challenges<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Challenge<\/th><th>Why It Matters<\/th><\/tr><\/thead><tbody><tr><td><strong>Low SNR<\/strong><\/td><td>Signals buried in noise (&lt; 0 dB)<\/td><\/tr><tr><td><strong>Latency<\/strong><\/td><td>Must decide in <strong>&lt;10 ms<\/strong> for real-time ops<\/td><\/tr><tr><td><strong>Compute<\/strong><\/td><td>Edge devices: &lt;100 mW, &lt;1 GFLOPs<\/td><\/tr><tr><td><strong>Unknown Modulations<\/strong><\/td><td>BPSK? FM? OFDM? Jamming?<\/td><\/tr><tr><td><strong>Regulatory Compliance<\/strong><\/td><td>False alarms = spectrum waste<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Evolution of Spectrum Sensing Techniques<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Era<\/th><th>Technique<\/th><th>Pros<\/th><th>Cons<\/th><th>Compute<\/th><\/tr><\/thead><tbody><tr><td><strong>1970s\u201390s<\/strong><\/td><td><strong>Energy Detection<\/strong><\/td><td>Simple, blind<\/td><td>No modulation info, poor at low SNR<\/td><td><strong>&lt;10k FLOPs<\/strong><\/td><\/tr><tr><td><strong>2000s<\/strong><\/td><td><strong>Cyclostationary Features<\/strong><\/td><td>Robust to noise<\/td><td>High latency, needs long integration<\/td><td><strong>100k\u20131M FLOPs<\/strong><\/td><\/tr><tr><td><strong>2010s<\/strong><\/td><td><strong>Matched Filters \/ Correlators<\/strong><\/td><td>Optimal for known signals<\/td><td>Useless for unknown modulations<\/td><td><strong>N log N<\/strong><\/td><\/tr><tr><td><strong>2016\u20132020<\/strong><\/td><td><strong>Deep Learning (CNNs on Spectrograms)<\/strong><\/td><td>High accuracy, learns features<\/td><td>High latency, power-hungry<\/td><td><strong>10M\u2013100M FLOPs<\/strong><\/td><\/tr><tr><td><strong>2025 \u2192<\/strong><\/td><td><strong>Hybrid FFT + Light ML Gate<\/strong><\/td><td><strong>Best of all<\/strong>: fast, accurate, low-power<\/td><td>Needs gating policy<\/td><td><strong>0.25M \u2013 2.6M FLOPs<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Deep Dive: <strong>Energy Detection<\/strong> (Still Relevant!)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>power = np.mean(np.abs(iq)**2)\nif power &gt; threshold:\n    occupied = True<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Blind<\/strong> \u2014 no prior needed<\/li>\n\n\n\n<li><strong>Fast<\/strong> \u2014 O(N)<\/li>\n\n\n\n<li><strong>Fails below 0 dB SNR<\/strong><\/li>\n\n\n\n<li><strong>No classification<\/strong><\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Use for <strong>coarse occupancy<\/strong> only.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Cyclostationary Detection<\/strong> (Academic Favorite)<\/h2>\n\n\n\n<p>Exploits <strong>periodic statistics<\/strong> in modulated signals (e.g., symbol rate).<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Good at \u201310 dB SNR<\/strong><\/li>\n\n\n\n<li>Needs <strong>10\u2074\u201310\u2076 samples<\/strong><\/li>\n\n\n\n<li><strong>High compute<\/strong> (FFT + correlation)<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Great for <strong>research<\/strong>, bad for <strong>edge SDRs<\/strong>.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>FFT-Based Spectral Features<\/strong> (The Hero of 2025)<\/h2>\n\n\n\n<p>Your SDR already computes the FFT. <strong>Why throw it away?<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lightweight Post-Filters (from our paper):<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Feature<\/th><th>Formula<\/th><th>Intuition<\/th><\/tr><\/thead><tbody><tr><td><strong>Band Energy<\/strong><\/td><td>$ \\sum<\/td><td>S(f)<\/td><\/tr><tr><td><strong>Peak Spacing<\/strong><\/td><td>$ \\Delta f = \\arg\\max_2<\/td><td>S(f)<\/td><\/tr><tr><td><strong>Spectral Flatness<\/strong><\/td><td>$ \\exp(\\frac{1}{N}\\sum \\log<\/td><td>S<\/td><\/tr><tr><td><strong>Bandmask Priors<\/strong><\/td><td>Pre-defined AM\/FM bands<\/td><td>Domain knowledge<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Total cost<\/strong>: ~250k FLOPs<br><strong>p99 latency<\/strong>: <strong>1.5 ms<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Tiny CNNs on Spectra<\/strong> (The Overhyped Baseline)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>model = Conv1D(16, kernel=8) \u2192 ReLU \u2192 Conv1D(32, kernel=4) \u2192 FC(1)<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>12M FLOPs<\/strong><\/li>\n\n\n\n<li><strong>6.0 ms p99 @ 0 dB<\/strong><\/li>\n\n\n\n<li><strong>Worse AUROC than FFT<\/strong> (0.671 vs 0.754)<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Deep learning lost this round.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">The Winner: <strong>Hybrid Gating<\/strong><\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>graph TD\n    A&#91;IQ Samples] --&gt; B&#91;1024-pt FFT]\n    B --&gt; C&#91;Light Filters \u2192 Confidence Score]\n    C --&gt; D{Confidence &gt; 0.9?}\n    D --&gt;|Yes| E&#91;Return FFT Result&lt;br&gt;1.5 ms, 0.25M FLOPs]\n    D --&gt;|No| F&#91;Tiny CNN&lt;br&gt;6.0 ms, 12M FLOPs]<\/code><\/pre>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-opt-id=883448075  fetchpriority=\"high\" decoding=\"async\" width=\"622\" height=\"873\" src=\"https:\/\/ml6vmqguit1n.i.optimole.com\/w:auto\/h:auto\/q:mauto\/f:best\/https:\/\/172-234-197-23.ip.linodeusercontent.com\/wp-content\/uploads\/2025\/10\/image-40.png\" alt=\"\" class=\"wp-image-4310\" srcset=\"https:\/\/ml6vmqguit1n.i.optimole.com\/w:622\/h:873\/q:mauto\/f:best\/https:\/\/172-234-197-23.ip.linodeusercontent.com\/wp-content\/uploads\/2025\/10\/image-40.png 622w, https:\/\/ml6vmqguit1n.i.optimole.com\/w:214\/h:300\/q:mauto\/f:best\/https:\/\/172-234-197-23.ip.linodeusercontent.com\/wp-content\/uploads\/2025\/10\/image-40.png 214w\" sizes=\"(max-width: 622px) 100vw, 622px\" \/><\/figure>\n<\/div>\n\n\n<h3 class=\"wp-block-heading\">Math:<\/h3>\n\n\n\n<p>$$<br>\\boxed{<br>C_{\\text{hybrid}} = (1-f) \\cdot 0.25M + f \\cdot 12M<br>}<br>$$<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Gate Rate $ f $<\/th><th>Avg Compute<\/th><th>Savings<\/th><th>p99 Latency<\/th><\/tr><\/thead><tbody><tr><td>0%<\/td><td>0.25M<\/td><td><strong>48\u00d7<\/strong><\/td><td>1.5 ms<\/td><\/tr><tr><td><strong>20%<\/strong><\/td><td><strong>2.6M<\/strong><\/td><td><strong>4.6\u00d7<\/strong><\/td><td><strong>1.5 ms<\/strong><\/td><\/tr><tr><td>100%<\/td><td>12M<\/td><td>1\u00d7<\/td><td>6.0 ms<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Real-World Deployment Tips<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Scenario<\/th><th>Recommended Technique<\/th><\/tr><\/thead><tbody><tr><td><strong>Battery-powered sensor<\/strong><\/td><td><strong>FFT + Energy + Peak Spacing<\/strong><\/td><\/tr><tr><td><strong>Edge gateway (1W)<\/strong><\/td><td><strong>Hybrid Gate (f \u2264 0.2)<\/strong><\/td><\/tr><tr><td><strong>Lab \/ Cloud<\/strong><\/td><td><strong>Full CNN or Transformer<\/strong><\/td><\/tr><tr><td><strong>Jamming detection<\/strong><\/td><td><strong>Cyclostationary + FFT<\/strong><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Open-Source Benchmark (Run It Now!)<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>git clone https:\/\/github.com\/bgilbert1984\/rf-triage-benchmark\ncd rf-triage-benchmark\nmake all<\/code><\/pre>\n\n\n\n<p>Outputs:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>AUROC vs SNR<\/li>\n\n\n\n<li>Latency curves<\/li>\n\n\n\n<li>Confusion matrices<\/li>\n\n\n\n<li><code>paper.pdf<\/code><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Future Directions<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Hardware-measured latency<\/strong> on USRP X410<\/li>\n\n\n\n<li><strong>Adaptive gating<\/strong> using entropy of FFT<\/li>\n\n\n\n<li><strong>Multi-class triage<\/strong> (BPSK vs OFDM vs FM)<\/li>\n\n\n\n<li><strong>Federated learning<\/strong> across edge nodes<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">TL;DR: <strong>2025 Spectrum Sensing Stack<\/strong><\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Layer<\/th><th>Tool<\/th><th>When to Use<\/th><\/tr><\/thead><tbody><tr><td><strong>L0<\/strong><\/td><td>Energy Detection<\/td><td>Coarse occupancy<\/td><\/tr><tr><td><strong>L1<\/strong><\/td><td><strong>FFT + Handcrafted Filters<\/strong><\/td><td><strong>Default path<\/strong><\/td><\/tr><tr><td><strong>L2<\/strong><\/td><td>Tiny CNN<\/td><td>Only if L1 confidence &lt; 0.9<\/td><\/tr><tr><td><strong>L3<\/strong><\/td><td>Full DL<\/td><td>Offline analysis<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>FFT is not dead. It\u2019s the new baseline.<\/strong><\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><strong>Read the paper<\/strong>: <a href=\"https:\/\/gilbert1984.com\/papers\/rf-triage-rev2.pdf\">FFT-Only vs Learned Spectral Proxies (PDF)<\/a><br><strong>Run the code<\/strong>: <a href=\"https:\/\/github.com\/bgilbert1984\/rf-triage-benchmark\">github.com\/bgilbert1984\/rf-triage-benchmark<\/a> (coming soon)<br><strong>Follow<\/strong>: @bgilbert1984 on X for RF+ML updates<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><em>Published October 29, 2025<\/em><br><em><a href=\"https:\/\/grok.com\/share\/bGVnYWN5LWNvcHk%3D_93cadb0f-45eb-457f-957e-7f082bf34165\">Share this if you believe in efficient RF AI.<\/a><\/em><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Practical Guide for RF Engineers in 2025 By Benjamin J. GilbertSpectrcyde RF Quantum SCYTHEbgilbert2@com.eduFull Paper PDF \u00b7 Reproducible Code What Is Spectrum Sensing? Detecting, classifying, or localizing active RF transmissions in a frequency band \u2014 in real time, under noise, with minimal compute. Used in: Core Challenges Challenge Why It Matters Low SNR Signals&hellip;&nbsp;<a href=\"https:\/\/172-234-197-23.ip.linodeusercontent.com\/?p=4309\" rel=\"bookmark\"><span class=\"screen-reader-text\">Spectrum Sensing Techniques: From Energy Detectors to Hybrid FFT+ML Triage<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":4311,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","footnotes":""},"categories":[6,7],"tags":[],"class_list":["post-4309","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-signal-science","category-the-truben-show"],"_links":{"self":[{"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/posts\/4309","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4309"}],"version-history":[{"count":1,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/posts\/4309\/revisions"}],"predecessor-version":[{"id":4312,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/posts\/4309\/revisions\/4312"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=\/wp\/v2\/media\/4311"}],"wp:attachment":[{"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4309"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4309"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/172-234-197-23.ip.linodeusercontent.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4309"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}