diff --git a/config/sitemap.json b/config/sitemap.json
index 0b5800180f..2cbc4a3354 100644
--- a/config/sitemap.json
+++ b/config/sitemap.json
@@ -8223,7 +8223,7 @@
"date": "2023-11-08"
},
"getting-started/new.md": {
- "hash": "aefc497912a9ddec48834ece2811d83bdc27dd40b94c401e4e9459388fe8987b",
+ "hash": "da4fb336553bde479b238c0a00abbba9730f99d501fb45e34825f41bd0c3b122",
"date": "2025-05-12"
},
"getting-started/cloud/logic.md": {
@@ -9721,6 +9721,14 @@
"reference/device-os/libraries/n/NFC_UICR_RK.md": {
"hash": "36a001fb0db71f23921ab242277114b287234eb8d1f7a0387fd91f6a8890e6c8",
"date": "2025-05-01"
+ },
+ "hardware/community/input-protection.md": {
+ "hash": "49db577fc0db8736f15794a804af667f63bdf94934d8a2b6af843795a8585520",
+ "date": "2025-05-09"
+ },
+ "tools/developer-tools/resistor-calculator.md": {
+ "hash": "35bb4e830b64f265674ad1499923905054b7fd8ef7d1a87d231779638024c5bb",
+ "date": "2025-05-09"
}
}
}
\ No newline at end of file
diff --git a/src/assets/files/hardware-community/input-protection/InputBlock.dbl b/src/assets/files/hardware-community/input-protection/InputBlock.dbl
new file mode 100644
index 0000000000..9e0d52ca7c
--- /dev/null
+++ b/src/assets/files/hardware-community/input-protection/InputBlock.dbl
@@ -0,0 +1,994 @@
+
+
+
+
+Analog or digital input protection
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+>VALUE
+
+
+
+
+>VALUE
+
+
+
+
+
+RES SMD 0 OHM JUMPER 1/10W 0603 <br>
+Panasonic Electronic Components ERJ-3GEY0R00V<br>
+0 Ohms Jumper 0.1W, 1/10W Chip Resistor 0603 (1608 Metric) Automotive AEC-Q200 Thick Film<br>
+https://www.digikey.com/product-detail/en/panasonic-electronic-components/ERJ-3GEY0R00V/P0-0GCT-ND/134711<br>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+RES SMD 10K OHM 5% 1/4W 0603 $ 0.10<br>
+https://www.digikey.com/product-detail/en/panasonic-electronic-components/ERJ-PA3J103V/P10KBZCT-ND/5036237
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Do Not Populate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dataline protecvtion 3.3V - Zener + Rail-to-rail<br>
+Diodes Incorporated D1213A-02SOL-7 $0.40<br>
+TVS DIODE 3.3V 10V SOT23<br>
+10V (Typ) Clamp 1A (8/20µs) Ipp Tvs Diode Surface Mount SOT-23<br>
+https://www.digikey.com/product-detail/en/diodes-incorporated/D1213A-02SOL-7/D1213A-02SOL-7DICT-ND/3340437<br>
+Ordered 10 2019-04-10<br>
+Left = Signal, Top = VCC, Bottom=GND<br>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.3V supply symbol
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>EAGLE Design Rules</b>
+<p>
+Die Standard-Design-Rules sind so gewählt, dass sie für
+die meisten Anwendungen passen. Sollte ihre Platine
+besondere Anforderungen haben, treffen Sie die erforderlichen
+Einstellungen hier und speichern die Design Rules unter
+einem neuen Namen ab.
+<b>EAGLE Design Rules</b>
+<p>
+The default Design Rules have been set to cover
+a wide range of applications. Your particular design
+may have different requirements, so please make the
+necessary adjustments and save your customized
+design rules under a new name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/files/hardware-community/input-protection/InputBlock/InputBlock.brd b/src/assets/files/hardware-community/input-protection/InputBlock/InputBlock.brd
new file mode 100644
index 0000000000..4fda838951
--- /dev/null
+++ b/src/assets/files/hardware-community/input-protection/InputBlock/InputBlock.brd
@@ -0,0 +1,479 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>EAGLE Design Rules</b>
+<p>
+Die Standard-Design-Rules sind so gewählt, dass sie für
+die meisten Anwendungen passen. Sollte ihre Platine
+besondere Anforderungen haben, treffen Sie die erforderlichen
+Einstellungen hier und speichern die Design Rules unter
+einem neuen Namen ab.
+<b>EAGLE Design Rules</b>
+<p>
+The default Design Rules have been set to cover
+a wide range of applications. Your particular design
+may have different requirements, so please make the
+necessary adjustments and save your customized
+design rules under a new name.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/files/hardware-community/input-protection/InputBlock/InputBlock.sch b/src/assets/files/hardware-community/input-protection/InputBlock/InputBlock.sch
new file mode 100644
index 0000000000..1715e562ee
--- /dev/null
+++ b/src/assets/files/hardware-community/input-protection/InputBlock/InputBlock.sch
@@ -0,0 +1,510 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+>VALUE
+
+
+
+
+>VALUE
+
+
+
+
+
+RES SMD 0 OHM JUMPER 1/10W 0603 <br>
+Panasonic Electronic Components ERJ-3GEY0R00V<br>
+0 Ohms Jumper 0.1W, 1/10W Chip Resistor 0603 (1608 Metric) Automotive AEC-Q200 Thick Film<br>
+https://www.digikey.com/product-detail/en/panasonic-electronic-components/ERJ-3GEY0R00V/P0-0GCT-ND/134711<br>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+RES SMD 10K OHM 5% 1/4W 0603 $ 0.10<br>
+https://www.digikey.com/product-detail/en/panasonic-electronic-components/ERJ-PA3J103V/P10KBZCT-ND/5036237
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Do Not Populate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Dataline protecvtion 3.3V - Zener + Rail-to-rail<br>
+Diodes Incorporated D1213A-02SOL-7 $0.40<br>
+TVS DIODE 3.3V 10V SOT23<br>
+10V (Typ) Clamp 1A (8/20µs) Ipp Tvs Diode Surface Mount SOT-23<br>
+https://www.digikey.com/product-detail/en/diodes-incorporated/D1213A-02SOL-7/D1213A-02SOL-7DICT-ND/3340437<br>
+Ordered 10 2019-04-10<br>
+Left = Signal, Top = VCC, Bottom=GND<br>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+3.3V supply symbol
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/images/hardware-community/input-protection/block-brd.png b/src/assets/images/hardware-community/input-protection/block-brd.png
new file mode 100644
index 0000000000..58a45cf036
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/block-brd.png differ
diff --git a/src/assets/images/hardware-community/input-protection/block-sch.png b/src/assets/images/hardware-community/input-protection/block-sch.png
new file mode 100644
index 0000000000..26370673d1
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/block-sch.png differ
diff --git a/src/assets/images/hardware-community/input-protection/div12.png b/src/assets/images/hardware-community/input-protection/div12.png
new file mode 100644
index 0000000000..a8c9008549
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/div12.png differ
diff --git a/src/assets/images/hardware-community/input-protection/div5.png b/src/assets/images/hardware-community/input-protection/div5.png
new file mode 100644
index 0000000000..200b8b4836
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/div5.png differ
diff --git a/src/assets/images/hardware-community/input-protection/div5b.png b/src/assets/images/hardware-community/input-protection/div5b.png
new file mode 100644
index 0000000000..0b6ed800ad
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/div5b.png differ
diff --git a/src/assets/images/hardware-community/input-protection/div5tvs.png b/src/assets/images/hardware-community/input-protection/div5tvs.png
new file mode 100644
index 0000000000..aa5f7e999e
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/div5tvs.png differ
diff --git a/src/assets/images/hardware-community/input-protection/float-sensor.png b/src/assets/images/hardware-community/input-protection/float-sensor.png
new file mode 100644
index 0000000000..8d03aa2fad
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/float-sensor.png differ
diff --git a/src/assets/images/hardware-community/input-protection/in0.png b/src/assets/images/hardware-community/input-protection/in0.png
new file mode 100644
index 0000000000..643d86944f
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/in0.png differ
diff --git a/src/assets/images/hardware-community/input-protection/in1-board.png b/src/assets/images/hardware-community/input-protection/in1-board.png
new file mode 100644
index 0000000000..61b888b283
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/in1-board.png differ
diff --git a/src/assets/images/hardware-community/input-protection/in1.png b/src/assets/images/hardware-community/input-protection/in1.png
new file mode 100644
index 0000000000..88ac52f5cf
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/in1.png differ
diff --git a/src/assets/images/hardware-community/input-protection/in2.png b/src/assets/images/hardware-community/input-protection/in2.png
new file mode 100644
index 0000000000..75cf7c41a7
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/in2.png differ
diff --git a/src/assets/images/hardware-community/input-protection/in3.png b/src/assets/images/hardware-community/input-protection/in3.png
new file mode 100644
index 0000000000..fbafb0616e
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/in3.png differ
diff --git a/src/assets/images/hardware-community/input-protection/in4.png b/src/assets/images/hardware-community/input-protection/in4.png
new file mode 100644
index 0000000000..17a0b7fd99
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/in4.png differ
diff --git a/src/assets/images/hardware-community/input-protection/resistor-divider.png b/src/assets/images/hardware-community/input-protection/resistor-divider.png
new file mode 100644
index 0000000000..c800727f5c
Binary files /dev/null and b/src/assets/images/hardware-community/input-protection/resistor-divider.png differ
diff --git a/src/assets/js/resistor-calculator.js b/src/assets/js/resistor-calculator.js
new file mode 100644
index 0000000000..6e231710d9
--- /dev/null
+++ b/src/assets/js/resistor-calculator.js
@@ -0,0 +1,420 @@
+let calculator = {};
+
+$(document).ready(function () {
+ // auth not required
+ $('.resistorCalculator').each(function() {
+ const thisPartial = $(this);
+
+ calculator.partial = thisPartial;
+
+ calculator.decimalStringTruncate = function(value, decimalPlaces) {
+ let s = value.toString();
+
+ let dotIndex = s.indexOf('.');
+ if (dotIndex > 0) {
+ if (decimalPlaces > 0) {
+ s = s.substring(0, dotIndex + decimalPlaces + 1);
+ }
+ else {
+ s = s.substring(0, dotIndex);
+ }
+ }
+
+ return s;
+ }
+
+ calculator.resistorWithUnits = function(value, options = {}) {
+ let unit = '';
+
+ if (value < 1000) {
+ }
+ else
+ if (value < 1000000) {
+ value /= 1000;
+ unit = 'K';
+ }
+ else {
+ value /= 1000000;
+ unit = 'M';
+ }
+
+ let valueStr = '';
+
+ if (typeof options.truncate != 'undefined') {
+ valueStr = calculator.decimalStringTruncate(value, options.truncate);
+ }
+ else {
+ valueStr = value.toString();
+ }
+
+ return valueStr + unit + 'Ω';
+ }
+
+ // Common resistor values for 10% and 5%
+ calculator.tenPct = [];
+ {
+ const values = [10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82];
+ let done = false;
+ for(let multiplier = 1; !done; multiplier *= 10) {
+ for(const value of values) {
+ const r = value * multiplier;
+ if (r > 1000000) {
+ // 1M
+ done = true;
+ break;
+ }
+ calculator.tenPct.push(r);
+ }
+ }
+ // 61 10% resistor values
+ }
+ calculator.fivePct = [];
+ {
+ const values = [10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91];
+ let done = false;
+ for(let multiplier = 1; !done; multiplier *= 10) {
+ for(const value of values) {
+ const r = value * multiplier;
+ if (r > 22000000) {
+ // 22M
+ done = true;
+ break;
+ }
+ calculator.fivePct.push(r);
+ }
+ }
+ // 153 5% resistor values
+ }
+ calculator.twoPct = [];
+ {
+ const values = [
+ 10.0, 10.5, 11.0, 11.5, 12.1, 12.7, 13.3, 14.0, 14.7, 15.4, 16.2, 16.9, 17.8, 18.7, 19.6,
+ 20.5, 21.5, 22.6, 23.7, 24.9, 26.1, 27.4, 28.7, 30.1, 31.6, 33.2, 34.8, 36.5, 38.3,
+ 40.2, 42.2, 44.2, 46.4, 48.7, 51.1, 53.6, 56.2, 59.0, 61.9, 64.9, 68.1, 71.5, 75.0, 78.7, 82.5, 86.6, 90.9, 95.3
+ ];
+ let done = false;
+ for(let multiplier = 1; !done; multiplier *= 10) {
+ for(const value of values) {
+ const r = value * multiplier;
+ if (r > 1000000) {
+ // 1M
+ done = true;
+ break;
+ }
+ calculator.twoPct.push(r);
+ }
+ }
+ // 240 2% resistor values
+ }
+
+ calculator.onePct = [];
+ {
+ const values = [
+ 10.0, 10.2, 10.5, 10.7, 11.0, 11.3, 11.5, 11.8, 12.1, 12.4, 12.7, 13.0, 13.3, 13.7, 14.0, 14.3, 14.7,
+ 15.0, 15.4, 15.8, 16.2, 16.5, 16.9, 17.4, 17.8, 18.2, 18.7, 19.1, 19.6, 20.0, 20.5,
+ 21.0, 21.5, 22.1, 22.6, 23.2, 23.7, 24.3, 24.9, 25.5, 26.1, 26.7, 27.4, 28.0, 28.7, 29.4,
+ 30.1, 30.9, 31.6, 32.4, 33.2, 34.0, 34.8, 35.7, 36.5, 37.4, 38.3, 39.2,
+ 40.2, 41.2, 42.2, 43.2, 44.2, 45.3, 46.4, 47.5, 48.7, 49.9, 51.1, 52.3, 53.6, 54.9, 56.2, 57.6, 59.0,
+ 60.4, 61.9, 63.4, 64.9, 66.5, 68.1, 69.8, 71.5, 73.2, 75.0, 76.8, 78.7, 80.6, 82.5, 84.5, 86.6, 88.7, 90.9, 93.1, 95.3, 97.6
+ ];
+ let done = false;
+ for(let multiplier = 1; !done; multiplier *= 10) {
+ for(const value of values) {
+ const r = value * multiplier;
+ if (r > 1000000) {
+ // 1M
+ done = true;
+ break;
+ }
+ calculator.onePct.push(r);
+ }
+ }
+ // Additional M ohm 1% resistors above 1M.
+ for(const r of [1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2]) {
+ calculator.onePct.push(r * 1000000);
+ }
+ // 489 1% resistor values!
+ }
+ calculator.parameters = {};
+
+
+ $(thisPartial).find('[data-group]').each(function() {
+ const groupName = $(this).data('group');
+
+ calculator.parameters[groupName] = {
+ inputElem: $(this).find('input[type="text"]'),
+ unitElem: $(this).find('.resistorUnit'),
+ groupName,
+ };
+ });
+
+ calculator.solve = function() {
+ const p = {};
+
+ // Hide rows
+ p.solveFor = $(thisPartial).find('input[type="radio"][name="solveFor"]:checked').val();
+ p.style = $(thisPartial).find('input[name="style"]:checked').val();
+ if (p.style == 'auto') {
+ $(thisPartial).find('.autoRow').show();
+ $(thisPartial).find('.manualRow').hide();
+
+ if (p.solveFor == 'r1' || p.solveFor == 'r2') {
+ $(thisPartial).find('input[type="radio"][name="solveFor"][value="vout"]').prop('checked', true);
+ }
+ }
+ else {
+ $(thisPartial).find('.autoRow').hide();
+ $(thisPartial).find('.manualRow').show();
+ }
+ p.solveFor = $(thisPartial).find('input[type="radio"][name="solveFor"]:checked').val();
+ p.solveForElem = calculator.parameters[p.solveFor].inputElem;
+
+ for(const groupName in calculator.parameters) {
+ p[groupName] = parseFloat($(calculator.parameters[groupName].inputElem).val());
+ if (calculator.parameters[groupName].unitElem.length) {
+ const multiplier = parseFloat($(calculator.parameters[groupName].unitElem).val());
+ p[groupName] *= multiplier;
+ }
+ }
+
+ if (p.style == 'auto') {
+ // Auto
+ p.useKey = $(thisPartial).find('input[name="use"]:checked').val();
+ p.rmin *= 1000;
+ p.rmax *= 1000;
+
+ // nearest, above, below
+ p.show = $(thisPartial).find('input[name="show"]:checked').val();
+
+ p.resToTry = [];
+ for(const r of calculator[p.useKey]) {
+ if (r >= p.rmin && r <= p.rmax) {
+ p.resToTry.push(r);
+ }
+ }
+
+ $(thisPartial).find('.autoResults > tbody').empty();
+
+
+ p.results = [];
+
+ for(const r1 of p.resToTry) {
+ const resultR1 = {
+ r1,
+ };
+
+ for(const r2 of p.resToTry) {
+ let result;
+ let delta;
+
+ switch(p.solveFor) {
+ case 'vin':
+ result = (p.vout * (r1 + r2)) / r2;
+ delta = result - p.vin;
+ break;
+
+ case 'vout':
+ result = (p.vin * r2) / (r1 + r2);
+ delta = result - p.vout;
+ break;
+ }
+
+ switch(p.show) {
+ case 'above':
+ if (delta >= 0) {
+ if (typeof resultR1.delta == 'undefined' || delta < resultR1.delta) {
+ resultR1.r2 = r2;
+ resultR1.result = result;
+ resultR1.delta = delta;
+ }
+ }
+ break;
+
+ case 'below':
+ if (delta <= 0) {
+ if (typeof resultR1.delta == 'undefined' || -delta < -resultR1.delta) {
+ resultR1.r2 = r2;
+ resultR1.result = result;
+ resultR1.delta = delta;
+ }
+ }
+ break;
+
+ case 'nearest':
+ if (typeof resultR1.delta == 'undefined' || Math.abs(delta) < Math.abs(resultR1.delta)) {
+ resultR1.r2 = r2;
+ resultR1.result = result;
+ resultR1.delta = delta;
+ }
+ break;
+ }
+ }
+ if (typeof resultR1.delta != 'undefined') {
+ switch(p.solveFor) {
+ case 'vin':
+ resultR1.deltaPct = resultR1.delta * 100 / p.vin;
+ break;
+
+ case 'vout':
+ resultR1.deltaPct = resultR1.delta * 100 / p.vout;
+ break;
+ }
+ // V = IR
+ // I = V/R
+ resultR1.ir1 = (p.vin - p.vout) / p.r1;
+ resultR1.wr1 = (p.vin - p.vout) * resultR1.ir1;
+
+ resultR1.ir2 = p.vout / p.r2;
+ resultR1.wr2 = p.vout * resultR1.ir2;
+
+ if (Math.abs(resultR1.deltaPct) < 10) {
+ p.results.push(resultR1);
+ }
+ }
+ }
+ p.results.sort(function(a, b) {
+ // Sort by ascending abs(delta)
+ let cmp = Math.abs(a.delta) - Math.abs(b.delta);
+ if (cmp != 0) {
+ return cmp;
+ }
+ // Then ascending R1
+ cmp = a.r1 - b.r1;
+
+ return cmp;
+ });
+
+
+ switch(p.solveFor) {
+ case 'vin':
+ $(thisPartial).find('th.autoV').html('Vin ');
+ break;
+
+ case 'vout':
+ $(thisPartial).find('th.autoV').html('Vout ');
+ break;
+ }
+
+ for(const result of p.results) {
+ const trElem = document.createElement('tr');
+
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).html(calculator.resistorWithUnits(result.r1, {truncate:1}));
+ $(trElem).append(tdElem);
+ }
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).html(calculator.resistorWithUnits(result.r2, {truncate:1}));
+ $(trElem).append(tdElem);
+ }
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).text(calculator.decimalStringTruncate(result.result, 3) + 'V');
+ $(trElem).append(tdElem);
+ }
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).text(calculator.decimalStringTruncate(result.delta, 3) + 'V');
+ $(trElem).append(tdElem);
+ }
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).text(calculator.decimalStringTruncate(result.deltaPct, 2) + ' %');
+ $(trElem).append(tdElem);
+ }
+ /*
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).text(calculator.decimalStringTruncate(result.ir1, 3) + 'A (' + calculator.decimalStringTruncate(result.wr1, 3) + 'W)');
+ $(trElem).append(tdElem);
+ }
+ {
+ const tdElem = document.createElement('td');
+ $(tdElem).text(calculator.decimalStringTruncate(result.ir2, 3) + 'A (' + calculator.decimalStringTruncate(result.wr2, 3) + 'W)');
+ $(trElem).append(tdElem);
+ }
+ */
+
+ $(thisPartial).find('.autoResults > tbody').append(trElem);
+ }
+
+
+ $(thisPartial).find('.autoResults').show();
+ }
+ else {
+ // Manual
+ let result;
+ let decimalPlaces = 0;
+
+ switch(p.solveFor) {
+ case 'vin':
+ result = (p.vout * (p.r1 + p.r2)) / p.r2;
+ decimalPlaces = 3;
+ break;
+
+ case 'r1':
+ result = p.r2 * ((p.vin / p.vout) - 1);
+ decimalPlaces = 1;
+ break;
+
+ case 'r2':
+ result = p.r1 * 1 / ((p.vin / p.vout) - 1);
+ decimalPlaces = 1;
+ break;
+
+ case 'vout':
+ result = (p.vin * p.r2) / (p.r1 + p.r2);
+ decimalPlaces = 3;
+ break;
+ }
+ result = calculator.decimalStringTruncate(result, decimalPlaces);
+
+ $(p.solveForElem).val(result);
+
+ $(thisPartial).find('.autoResults').hide();
+ }
+
+ // console.log('solve', p);
+ };
+
+ $(thisPartial).find('input[name="style"]').on('click', calculator.solve);
+ $(thisPartial).find('input[name="use"]').on('click', calculator.solve);
+ $(thisPartial).find('input[name="show"]').on('click', calculator.solve);
+
+
+ $(thisPartial).find('.inputText').on('input blur', calculator.solve);
+
+ $(thisPartial).find('input[name="solveFor"]').on('click', calculator.solve);
+
+ $(thisPartial).find('.resistorUnit').each(function() {
+ const units = [
+ {
+ title: 'ohm',
+ value: "1",
+ },
+ {
+ title: 'K ohm',
+ value: "1000",
+ },
+ {
+ title: 'M ohm',
+ value: "1000000",
+ },
+ ];
+ for(const unitObj of units) {
+ const optionElem = document.createElement('option');
+
+ $(optionElem).text(unitObj.title);
+ $(optionElem).attr('value', unitObj.value);
+
+ $(this).append(optionElem);
+ }
+ $(this).val("1");
+ $(this).on('change', calculator.solve);
+ });
+ calculator.solve();
+
+ // console.log('calculator', calculator);
+ });
+});
\ No newline at end of file
diff --git a/src/content/getting-started/new.md b/src/content/getting-started/new.md
index 0706849ad8..7d170069f2 100644
--- a/src/content/getting-started/new.md
+++ b/src/content/getting-started/new.md
@@ -21,6 +21,14 @@ When adding new items to this page:
The header format must be exactly that because the search feature uses that to delimit entries, and determine the date of entries
--}}
+### Input protection page 2025-05-12
+
+New community hardware page for [input protection](/hardware/community/input-protection/) for digital and analog inputs using rail-to-rail TVS diodes.
+
+### Resistor divider calculator 2025-05-12
+
+New [resistor divider calculator](/tools/developer-tools/resistor-calculator/) which has the typical calculation features and also can choose the resistors from standard 10% or 5% resistors and shows a sorted list.
+
### acquireWireBuffer example 2025-05-12
The example code for acquireWireBuffer used a deprecated type, should use hal_i2c_config_t.
diff --git a/src/content/hardware/community/input-protection.md b/src/content/hardware/community/input-protection.md
new file mode 100644
index 0000000000..480c46b76f
--- /dev/null
+++ b/src/content/hardware/community/input-protection.md
@@ -0,0 +1,142 @@
+---
+title: Input protection
+columns: two
+layout: commonTwo.hbs
+description: Input protection
+---
+
+# {{title}}
+
+Most Particle devices have a 3.3V limit on digital and analog inputs. When connecting to external sensors, it's important to make sure:
+
+- The voltage is in the required range
+- The Particle device is protected against transient voltages
+
+
+### Resistor voltage divider
+
+If you have a need to slightly decrease voltage, such as from 5V to 3.3V, especially for analog signals, a resistor voltage divider is an effective
+and inexpensive option.
+
+
+
+
Credit: [Wikipedia](https://commons.wikimedia.org/wiki/File:Resistive_divider2.svg)
+
+You can use the [resistor divider calculator](/tools/developer-tools/resistor-calculator/) to find the appropriate values for other voltages.
+
+You should not use a voltage divider for high voltage differences as the current through the resistor can be excessive. You should also never connect
+the output of a voltage divider to yet another voltage divider.
+
+### Level shifter
+
+A level shifter can be used to:
+
+- Decrease voltage, such as 5V logic to 3.3V logic
+- Increase voltage, such as 3.3V logic on the Particle device to a 5V sensor
+- Bidirectional voltage translation, such as 3.3V I2C to 5V I2C
+- Automatic direction sensing level sensing
+
+Additional information will be provided in the future on options for level shifters.
+
+### TVS input protection
+
+One common solution is to use a rail-to-rail TVS (transient voltage suppressor) with Zener diode to protect the input.
+
+The examples here use a Diodes Inc. [D1213A-02SOL-7](https://www.digikey.com/en/products/detail/diodes-incorporated/D1213A-02SOL-7/3340437)
+(TVS DIODE 3.3VWM 10VC SOT233). They're US$ 0.20 in single quantities and significantly less expensive in larger quantities. This version is in the SOT-23-3 package
+but there are variations in several common surface mount packages.
+
+This chip isn't available in PTH packages for breadboards, but if you want to prototype a design in a breadboard, you can
+easily search for "SOT-23-3 breakout" and find items such as this one [from Amazon](https://www.amazon.com/Chironal-Double-Side-SOT23-3-Adapter-Converter/dp/B07MQBF2DD/ref=sr_1_3) which is 50 pieces for US$ 9.49. The SOT-23-3 is intended to be reflow soldered, but the pins are far enough apart that you can
+solder it by hand with a soldering iron fairly easily.
+
+
+## Example circuits
+
+### Voltage divider (5V)
+
+One common situation is interfacing a 5V signal to 3.3V GPIO. A common solution, especially for analog signals, is a voltage divider:
+
+
+
+These resistors values do not exactly match 5 VDC to 3.3V (4095 on the ADC), but are close and use common off-the-shelf resistor values.
+
+Because resistors in series add together, you could make this will three common 10K resistors, as well.
+
+
+
+
+### Voltage divider (12V)
+
+This is a voltage divider for a 12 VDC signal, 27K on the high side, and 10K on the low side.
+
+
+
+These resistors values do not exactly match 12 VDC to 3.3V (4095 on the ADC), but are close and use common off-the-shelf resistor values.
+
+### 3.3V TVS
+
+In the simplest case, a 3.3V analog or digital signal, you can use it like this:
+
+
+
+- The input signal is `IN4` in this example.
+- It connects to `A0` though any analog or digital input can be used.
+- The 100Ω resistor protects against excessive current through the diode.
+- If the input voltage is negative, the diode shunts it to ground, protecting the MCU.
+- If the input signal is slightly more than 3.3V, the diode shunts it to 3V3, protecting the MCU.
+- If the input signal is very large, including ESD, the Zener diode stops the highest voltages, leaving the small differential to the rail-to-rail diodes.
+
+### 5V TVS
+
+You can also attach a voltage divider to the input of the TVS:
+
+
+
+- The voltage divider works the same as [Voltage divider (5V)](#voltage-divider-5v-), above.
+- Instead of the 100Ω R20 in [3.3V TVS](#3-3v-tvs), above, the high side of the voltage divider (R19) limits the input current.
+
+### Input design block
+
+One technique that I like is to use this universal input block on my circuits. If I might want to change the voltage or other characteristics
+of the input in the future, I can just rework the board to change the resistors and not have to spin a new board.
+
+#### 3.3V input block
+
+This circuit is electrically the same as [3.3V TVS](#3-3v-tvs). The DNP, Do Not Populate, resistors are left off when assembling the board.
+
+
+
+The layout on a circuit board looks like this:
+
+
+
+#### 3.3V with pull-up input block
+
+By adding R5, a 10KΩ resistor, the input now has a pull-up. If you are using an open-collector input (only pulls to ground), or you
+want the value to not float when disconnected, you can use a circuit like this.
+
+
+
+Of course you could make a pull-down by populating R6 instead of R5.
+
+#### 5V input block
+
+This is the same design as [Voltage divider (5V)](#voltage-divider-15-) with a 10K high-side and 20K low-side resistor.
+
+
+
+I used this input circuit with a tank level sensor, and it successfully protected my device. This magneto-resistive sensor is powered at 12V but supplies
+an analog output 0-5 VDC depending on level. While a voltage divider alone would be sufficient for this voltage, it also has the odd characteristics that if
+you have a loose ground wire, the output is around 8V! That would have been sufficient to damage the device if not for the protection diodes.
+
+
+
+
+
+#### 12V input block
+
+This is the same design as [Voltage divider (12V)](#voltage-divider-12v-) with a 27K high-side and 10K low-side resistor.
+
+
+
diff --git a/src/content/hardware/newMenu.json b/src/content/hardware/newMenu.json
index aa2101385a..f4eeeced18 100644
--- a/src/content/hardware/newMenu.json
+++ b/src/content/hardware/newMenu.json
@@ -414,6 +414,10 @@
{
"dir": "monitor-one-modbus",
"title": "Monitor One getting started with Modbus"
+ },
+ {
+ "dir": "input-protection",
+ "title": "Input protection"
}
]
}
diff --git a/src/content/tools/developer-tools/resistor-calculator.md b/src/content/tools/developer-tools/resistor-calculator.md
new file mode 100644
index 0000000000..709a3c3e51
--- /dev/null
+++ b/src/content/tools/developer-tools/resistor-calculator.md
@@ -0,0 +1,12 @@
+---
+title: Resistor divider calculator
+columns: two
+layout: commonTwo.hbs
+description: Resistor calculator
+includeDefinitions: [api-helper, api-helper-extras, resistor-calculator]
+---
+
+# {{title}}
+
+{{> resistor-calculator}}
+
diff --git a/src/content/tools/newMenu.json b/src/content/tools/newMenu.json
index 3f1630cc25..d0565a8445 100644
--- a/src/content/tools/newMenu.json
+++ b/src/content/tools/newMenu.json
@@ -72,6 +72,10 @@
"dir": "battery-calculator",
"title": "Battery calculator"
},
+ {
+ "dir": "resistor-calculator",
+ "title": "Resistor divider calculator"
+ },
{
"dir": "configure-wi-fi",
"title": "Configure Wi-Fi"
diff --git a/templates/partials/resistor-calculator.hbs b/templates/partials/resistor-calculator.hbs
new file mode 100644
index 0000000000..5fa72c33a3
--- /dev/null
+++ b/templates/partials/resistor-calculator.hbs
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+ R1
+ R2
+ V
+ ΔV
+ ΔV%
+
+
+
+
+
+
+
+
diff --git a/templates/partials/scripts.hbs b/templates/partials/scripts.hbs
index 9cc1a0d7dd..c56fac616e 100644
--- a/templates/partials/scripts.hbs
+++ b/templates/partials/scripts.hbs
@@ -193,6 +193,9 @@
{{#contains includeDefinitions 'release-notes'}}
{{/contains}}
+{{#contains includeDefinitions 'resistor-calculator'}}
+
+{{/contains}}
{{#contains includeDefinitions 'showdown'}}
{{/contains}}