<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>KiCad on Dhiru's Notebook</title><link>https://rfcorner.in/tags/kicad/</link><description>Recent content in KiCad on Dhiru's Notebook</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sat, 07 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://rfcorner.in/tags/kicad/index.xml" rel="self" type="application/rss+xml"/><item><title>Simplest APRS Digipeater and iGate on MCU!</title><link>https://rfcorner.in/posts/simplest-aprs-digipeater-igate-on-mcu/</link><pubDate>Sat, 07 Feb 2026 00:00:00 +0000</pubDate><guid>https://rfcorner.in/posts/simplest-aprs-digipeater-igate-on-mcu/</guid><description>&lt;h2 id="description"&gt;Description&lt;/h2&gt;
&lt;p&gt;We have built the simplest, power-efficient and 'ready-for-solar' APRS
Digipeater and iGate on an MCU (RPi Pico 2 W)!&lt;/p&gt;
&lt;p&gt;&lt;img alt="KISSLink v1 Render" loading="lazy" src="https://rfcorner.in/images/KISSLink-v1-7.png"&gt;&lt;/p&gt;
&lt;p&gt;Our existing &lt;code&gt;KISSLink v1 BLE KISS TNC&lt;/code&gt; device is capable of running in
standalone mode with an alternate firmware!&lt;/p&gt;
&lt;p&gt;Goal(s): Our design prioritizes low power, reliability, and unattended
deployment over flexibility.&lt;/p&gt;
&lt;p&gt;And yes, we want to do this with cheap, widely available BaoFeng radios. This
means a couple of things:&lt;/p&gt;</description></item><item><title>Wireless APRS interface for BaoFeng and other radios!</title><link>https://rfcorner.in/posts/aprs-interface-v2/</link><pubDate>Thu, 29 Jan 2026 00:00:00 +0000</pubDate><guid>https://rfcorner.in/posts/aprs-interface-v2/</guid><description>&lt;h2 id="description"&gt;Description&lt;/h2&gt;
&lt;p&gt;We have built a Bluetooth-enabled and APRSdroid-compatible digital interface (KISS TNC) for less than 15 USD (for the fully-loaded make including cables). We call it the KISSLink v1.&lt;/p&gt;
&lt;p&gt;&lt;img alt="KISSLink v1" loading="lazy" src="https://rfcorner.in/images/aprsdroid-3.jpg"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="KISSLink v1 Render" loading="lazy" src="https://rfcorner.in/images/KISSLink-v1-7.png"&gt;&lt;/p&gt;
&lt;p&gt;This digital interface can be powered from the USB 5V or the inbuilt battery.&lt;/p&gt;
&lt;h2 id="schematic"&gt;Schematic&lt;/h2&gt;
&lt;div class="embed-pdf-container" id="embed-pdf-container-f1c39fe8"&gt;
&lt;div class="pdf-loadingWrapper" id="pdf-loadingWrapper-f1c39fe8"&gt;
&lt;div class="pdf-loading" id="pdf-loading-f1c39fe8"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id="overlayText"&gt;
&lt;a href="https://rfcorner.in/pdfs/KISSLink-v1.pdf" aria-label="Download" download&gt;
&lt;svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"&gt;
&lt;path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /&gt;
&lt;/svg&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;canvas class="pdf-canvas" id="pdf-canvas-f1c39fe8"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;div class="pdf-paginator" id="pdf-paginator-f1c39fe8"&gt;
&lt;button id="pdf-prev-f1c39fe8"&gt;Previous&lt;/button&gt;
&lt;button id="pdf-next-f1c39fe8"&gt;Next&lt;/button&gt; &amp;nbsp; &amp;nbsp;
&lt;span&gt;
&lt;span class="pdf-pagenum" id="pdf-pagenum-f1c39fe8"&gt;&lt;/span&gt; / &lt;span class="pdf-pagecount" id="pdf-pagecount-f1c39fe8"&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;a class="pdf-source" id="pdf-source-f1c39fe8" href="https://rfcorner.in/pdfs/KISSLink-v1.pdf"&gt;[pdf]&lt;/a&gt;
&lt;/div&gt;
&lt;noscript&gt;
View the PDF file &lt;a class="pdf-source" id="pdf-source-noscript-f1c39fe8" href="https://rfcorner.in/pdfs/KISSLink-v1.pdf"&gt;here&lt;/a&gt;.
&lt;/noscript&gt;
&lt;script type="text/javascript"&gt;
(function(){
var url = '\/pdfs\/KISSLink-v1.pdf';
var hidePaginator = "" === "true";
var hideLoader = "true" === "true";
var selectedPageNum = parseInt("") || 1;
var pdfjsLib = window['pdfjs-dist/build/pdf'];
if (pdfjsLib.GlobalWorkerOptions.workerSrc == '')
pdfjsLib.GlobalWorkerOptions.workerSrc = "https:\/\/rfcorner.in\/" + 'js/pdf-js/build/pdf.worker.js';
var pdfDoc = null,
pageNum = selectedPageNum,
pageRendering = false,
pageNumPending = null,
scale = 3,
canvas = document.getElementById('pdf-canvas-f1c39fe8'),
ctx = canvas.getContext('2d'),
paginator = document.getElementById("pdf-paginator-f1c39fe8"),
loadingWrapper = document.getElementById('pdf-loadingWrapper-f1c39fe8');
showPaginator();
showLoader();
function renderPage(num) {
pageRendering = true;
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function() {
pageRendering = false;
showContent();
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
document.getElementById('pdf-pagenum-f1c39fe8').textContent = num;
}
function showContent() {
loadingWrapper.style.display = 'none';
canvas.style.display = 'block';
}
function showLoader() {
if(hideLoader) return
loadingWrapper.style.display = 'flex';
canvas.style.display = 'none';
}
function showPaginator() {
if(hidePaginator) return
paginator.style.display = 'block';
}
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
function onPrevPage() {
if (pageNum &lt;= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById('pdf-prev-f1c39fe8').addEventListener('click', onPrevPage);
function onNextPage() {
if (pageNum &gt;= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
}
document.getElementById('pdf-next-f1c39fe8').addEventListener('click', onNextPage);
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
var numPages = pdfDoc.numPages;
document.getElementById('pdf-pagecount-f1c39fe8').textContent = numPages;
if(pageNum &gt; numPages) {
pageNum = numPages
}
renderPage(pageNum);
});
})();
&lt;/script&gt;
&lt;h2 id="rx-path-simulation-af-front-end"&gt;RX path simulation (AF front-end)&lt;/h2&gt;
&lt;p&gt;&lt;img alt="KISSLink v1 Simulation TX" loading="lazy" src="https://rfcorner.in/images/KISSLink-Sim-TX-1.png"&gt;&lt;/p&gt;</description></item><item><title>APRS Interface for BaoFeng and Other Radios</title><link>https://rfcorner.in/posts/aprs-interface/</link><pubDate>Sat, 17 Jan 2026 00:00:00 +0000</pubDate><guid>https://rfcorner.in/posts/aprs-interface/</guid><description>&lt;h2 id="design"&gt;Design&lt;/h2&gt;
&lt;p&gt;Here is a "safe" APRS interface for BaoFeng and other radios.&lt;/p&gt;
&lt;p&gt;Sample schematic:&lt;/p&gt;
&lt;div class="embed-pdf-container" id="embed-pdf-container-7475f967"&gt;
&lt;div class="pdf-loadingWrapper" id="pdf-loadingWrapper-7475f967"&gt;
&lt;div class="pdf-loading" id="pdf-loading-7475f967"&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div id="overlayText"&gt;
&lt;a href="https://rfcorner.in/pdfs/TheDigitalInterface-2026.pdf" aria-label="Download" download&gt;
&lt;svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18"&gt;
&lt;path d="M9 13c.3 0 .5-.1.7-.3L15.4 7 14 5.6l-4 4V1H8v8.6l-4-4L2.6 7l5.7 5.7c.2.2.4.3.7.3zm-7 2h14v2H2z" /&gt;
&lt;/svg&gt;
&lt;/a&gt;
&lt;/div&gt;
&lt;canvas class="pdf-canvas" id="pdf-canvas-7475f967"&gt;&lt;/canvas&gt;
&lt;/div&gt;
&lt;div class="pdf-paginator" id="pdf-paginator-7475f967"&gt;
&lt;button id="pdf-prev-7475f967"&gt;Previous&lt;/button&gt;
&lt;button id="pdf-next-7475f967"&gt;Next&lt;/button&gt; &amp;nbsp; &amp;nbsp;
&lt;span&gt;
&lt;span class="pdf-pagenum" id="pdf-pagenum-7475f967"&gt;&lt;/span&gt; / &lt;span class="pdf-pagecount" id="pdf-pagecount-7475f967"&gt;&lt;/span&gt;
&lt;/span&gt;
&lt;a class="pdf-source" id="pdf-source-7475f967" href="https://rfcorner.in/pdfs/TheDigitalInterface-2026.pdf"&gt;[pdf]&lt;/a&gt;
&lt;/div&gt;
&lt;noscript&gt;
View the PDF file &lt;a class="pdf-source" id="pdf-source-noscript-7475f967" href="https://rfcorner.in/pdfs/TheDigitalInterface-2026.pdf"&gt;here&lt;/a&gt;.
&lt;/noscript&gt;
&lt;script type="text/javascript"&gt;
(function(){
var url = '\/pdfs\/TheDigitalInterface-2026.pdf';
var hidePaginator = "" === "true";
var hideLoader = "true" === "true";
var selectedPageNum = parseInt("") || 1;
var pdfjsLib = window['pdfjs-dist/build/pdf'];
if (pdfjsLib.GlobalWorkerOptions.workerSrc == '')
pdfjsLib.GlobalWorkerOptions.workerSrc = "https:\/\/rfcorner.in\/" + 'js/pdf-js/build/pdf.worker.js';
var pdfDoc = null,
pageNum = selectedPageNum,
pageRendering = false,
pageNumPending = null,
scale = 3,
canvas = document.getElementById('pdf-canvas-7475f967'),
ctx = canvas.getContext('2d'),
paginator = document.getElementById("pdf-paginator-7475f967"),
loadingWrapper = document.getElementById('pdf-loadingWrapper-7475f967');
showPaginator();
showLoader();
function renderPage(num) {
pageRendering = true;
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport({scale: scale});
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: ctx,
viewport: viewport
};
var renderTask = page.render(renderContext);
renderTask.promise.then(function() {
pageRendering = false;
showContent();
if (pageNumPending !== null) {
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
document.getElementById('pdf-pagenum-7475f967').textContent = num;
}
function showContent() {
loadingWrapper.style.display = 'none';
canvas.style.display = 'block';
}
function showLoader() {
if(hideLoader) return
loadingWrapper.style.display = 'flex';
canvas.style.display = 'none';
}
function showPaginator() {
if(hidePaginator) return
paginator.style.display = 'block';
}
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
function onPrevPage() {
if (pageNum &lt;= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById('pdf-prev-7475f967').addEventListener('click', onPrevPage);
function onNextPage() {
if (pageNum &gt;= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
}
document.getElementById('pdf-next-7475f967').addEventListener('click', onNextPage);
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
var numPages = pdfDoc.numPages;
document.getElementById('pdf-pagecount-7475f967').textContent = numPages;
if(pageNum &gt; numPages) {
pageNum = numPages
}
renderPage(pageNum);
});
})();
&lt;/script&gt;
&lt;h2 id="render"&gt;Render&lt;/h2&gt;
&lt;p&gt;&lt;img alt="TheDigitalInterface-2026" loading="lazy" src="https://rfcorner.in/images/TheDigitalInterface-2026.png"&gt;&lt;/p&gt;</description></item><item><title>Writing test cases for PCBs</title><link>https://rfcorner.in/posts/writing-test-cases-for-pcbs/</link><pubDate>Fri, 07 Nov 2025 00:00:00 +0000</pubDate><guid>https://rfcorner.in/posts/writing-test-cases-for-pcbs/</guid><description>&lt;p&gt;This note demonstrates a small &lt;code&gt;connectivity tester&lt;/code&gt; / &lt;code&gt;check nets&lt;/code&gt; program for
KiCad. This program allows doing checks like: Is the &lt;code&gt;U1:8&lt;/code&gt; pin connected to
&lt;code&gt;GND&lt;/code&gt;?&lt;/p&gt;
&lt;h2 id="motivation"&gt;Motivation&lt;/h2&gt;
&lt;p&gt;Sometimes visual errors can creep in the schematic (and the PCB subsequently).
This &lt;code&gt;connectivity tester&lt;/code&gt; allows expressing the same connections in a
non-visual way (with a different probability of making errors).&lt;/p&gt;
&lt;p&gt;The ERC and DRC checks in KiCad work great but this non-visual test assertions
provide another level of sanity checking.&lt;/p&gt;</description></item></channel></rss>