%% fig-alt: Mind map showing critical datasheet sections including features and overview, absolute maximum ratings, electrical characteristics, timing diagrams, application circuits, and package information.
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#FFFFFF', 'primaryBorderColor': '#16A085', 'lineColor': '#7F8C8D', 'secondaryColor': '#ECF0F1', 'tertiaryColor': '#FFFFFF'}}}%%
mindmap
root((Datasheet<br/>Sections))
Features
Key specifications
Application areas
Pin descriptions
Absolute Max
Supply voltage
Temperature range
ESD ratings
Electrical
Operating conditions
DC characteristics
AC characteristics
Timing
Setup/hold times
Clock requirements
Propagation delays
Applications
Reference designs
Component values
Layout guidelines
Package
Dimensions
Thermal properties
Pin assignments
1631 Datasheet Navigator
Interactive tool for understanding IoT component datasheets with parameter highlighting, comparison, and derating analysis
1631.1 Navigating IoT Component Datasheets
Datasheets are essential reference documents for IoT hardware design. This interactive navigator helps you understand key parameters, compare components, and apply derating rules for reliable system design.
This datasheet navigator provides structured access to critical specifications for common IoT components. It highlights key parameters, enables side-by-side comparison, checks absolute maximum ratings, and generates quick reference cards for your designs.
- Select a Component Type (MCU, Sensor, Radio Module, Power IC)
- Choose a specific Component from the library
- Review Key Parameters with highlighted important values
- Use the Comparison Builder to compare up to 3 components
- Check Absolute Maximum Ratings for safe operating limits
- Apply Derating Calculator for temperature-adjusted specifications
- Generate a Quick Reference Card for your selected component
- Use the Unit Converter for parameter conversions
Show code
{
// ===========================================================================
// DATASHEET NAVIGATOR
// ===========================================================================
// Features:
// - Component type selector (MCU, Sensor, Radio Module, Power IC)
// - Key parameter highlighter
// - Parameter comparison table builder
// - Absolute maximum ratings checker
// - Derating calculator (temperature vs power)
// - Quick reference card generator
// - Common datasheets library (ESP32, STM32L4, DHT22, SX1276)
// - Parameter unit converter
// - Design checklist generator
//
// IEEE Color Palette:
// Navy: #2C3E50 (primary)
// Teal: #16A085 (secondary)
// Orange: #E67E22 (highlights)
// Gray: #7F8C8D (neutral)
// LtGray: #ECF0F1 (backgrounds)
// Green: #27AE60 (good)
// Red: #E74C3C (warnings)
// ===========================================================================
// ---------------------------------------------------------------------------
// CONFIGURATION
// ---------------------------------------------------------------------------
const config = {
width: 950,
height: 2600,
colors: {
navy: "#2C3E50",
teal: "#16A085",
orange: "#E67E22",
gray: "#7F8C8D",
lightGray: "#ECF0F1",
white: "#FFFFFF",
green: "#27AE60",
red: "#E74C3C",
yellow: "#F1C40F",
purple: "#9B59B6",
blue: "#3498DB",
pink: "#E91E63"
},
componentTypes: [
{ id: "mcu", name: "MCU", icon: "CPU", description: "Microcontrollers and processors", color: "#3498DB" },
{ id: "sensor", name: "Sensor", icon: "SEN", description: "Environmental and motion sensors", color: "#27AE60" },
{ id: "radio", name: "Radio Module", icon: "RF", description: "Wireless communication modules", color: "#9B59B6" },
{ id: "power", name: "Power IC", icon: "PWR", description: "Voltage regulators and power management", color: "#E67E22" }
],
// Comprehensive component database
components: {
// MCUs
esp32: {
id: "esp32",
type: "mcu",
name: "ESP32-WROOM-32",
manufacturer: "Espressif Systems",
partNumber: "ESP32-WROOM-32E",
description: "Wi-Fi & Bluetooth MCU Module",
color: "#E74C3C",
keyParams: {
operatingVoltage: { value: "3.0 - 3.6V", typical: "3.3V", highlight: true },
currentActive: { value: "80mA", note: "RF active, modem sleep", highlight: true },
currentModemSleep: { value: "20mA", note: "CPU active" },
currentLightSleep: { value: "0.8mA", note: "RTC memory retention" },
currentDeepSleep: { value: "10µA", note: "RTC timer + RTC memory", highlight: true },
currentHibernation: { value: "2.5µA", note: "RTC timer only" },
operatingTemp: { value: "-40°C to +85°C", highlight: true },
clockSpeed: { value: "Up to 240MHz", note: "Dual-core Xtensa LX6" },
flash: { value: "4MB", note: "External SPI flash" },
ram: { value: "520KB", note: "SRAM" },
wifi: { value: "802.11 b/g/n", note: "2.4GHz, up to 150Mbps" },
bluetooth: { value: "BLE 4.2 + BR/EDR", note: "Classic and Low Energy" },
gpio: { value: "34 GPIO", note: "Multiplexed pins" },
adc: { value: "18 channels", note: "12-bit SAR ADC" },
interfaces: { value: "SPI, I2C, I2S, UART, CAN, PWM", highlight: true }
},
absoluteMax: {
supplyVoltage: { value: 3.6, unit: "V", warning: "Exceeding may cause permanent damage" },
inputVoltage: { value: 3.6, unit: "V", warning: "On any GPIO pin" },
outputCurrent: { value: 40, unit: "mA", warning: "Per GPIO pin" },
totalCurrent: { value: 1200, unit: "mA", warning: "Sum of all outputs" },
storageTemp: { value: [-40, 150], unit: "°C", warning: "Non-operating" },
junctionTemp: { value: 150, unit: "°C", warning: "Maximum junction temperature" }
},
derating: {
tempCoeff: 0.5, // % reduction per °C above 25°C
maxTemp: 85,
baseTemp: 25
},
designChecklist: [
"Add 100nF decoupling capacitor close to VDD pins",
"Ensure 3.3V supply can provide 500mA peak current",
"Use proper antenna matching for RF performance",
"Add pull-up resistor on EN pin for reliable startup",
"Keep GPIO0 high during normal boot",
"Consider brown-out detection threshold settings"
],
datasheetUrl: "https://www.espressif.com/en/products/hardware/esp32/resources"
},
stm32l4: {
id: "stm32l4",
type: "mcu",
name: "STM32L476RG",
manufacturer: "STMicroelectronics",
partNumber: "STM32L476RGT6",
description: "Ultra-low-power ARM Cortex-M4 MCU",
color: "#16A085",
keyParams: {
operatingVoltage: { value: "1.71 - 3.6V", typical: "3.3V", highlight: true },
currentActive: { value: "100µA/MHz", note: "Run mode from Flash", highlight: true },
currentLPRun: { value: "28µA", note: "Low-power run mode" },
currentStop0: { value: "1.3µA", note: "Stop 0 with RTC" },
currentStop1: { value: "0.84µA", note: "Stop 1 with RTC" },
currentStop2: { value: "0.29µA", note: "Stop 2 with RTC", highlight: true },
currentStandby: { value: "0.03µA", note: "Standby with RTC", highlight: true },
currentShutdown: { value: "8nA", note: "Shutdown mode" },
operatingTemp: { value: "-40°C to +85°C", highlight: true },
clockSpeed: { value: "Up to 80MHz", note: "ARM Cortex-M4 with FPU" },
flash: { value: "1MB", note: "Internal Flash" },
ram: { value: "128KB", note: "SRAM" },
gpio: { value: "51 GPIO", note: "With 5V tolerance on some pins" },
adc: { value: "3 ADCs", note: "12-bit, 5Msps" },
dac: { value: "2 DACs", note: "12-bit" },
interfaces: { value: "USB, SPI, I2C, UART, CAN, SAI, SDMMC", highlight: true }
},
absoluteMax: {
supplyVoltage: { value: 4.0, unit: "V", warning: "On VDD pins" },
inputVoltage: { value: 4.0, unit: "V", warning: "On 5V tolerant pins" },
outputCurrent: { value: 25, unit: "mA", warning: "Per GPIO pin" },
totalCurrent: { value: 120, unit: "mA", warning: "Total on all VDD" },
storageTemp: { value: [-65, 150], unit: "°C", warning: "Non-operating" },
junctionTemp: { value: 125, unit: "°C", warning: "Maximum junction temperature" }
},
derating: {
tempCoeff: 0.3,
maxTemp: 85,
baseTemp: 25
},
designChecklist: [
"Add 100nF + 4.7µF on each VDD pin",
"Connect VBAT to VDD if backup not needed",
"Use internal voltage reference for accurate ADC",
"Configure unused pins as analog to reduce leakage",
"Enable brown-out reset (BOR) for supply monitoring",
"Consider VDDUSB requirements for USB operation"
],
datasheetUrl: "https://www.st.com/en/microcontrollers-microprocessors/stm32l476rg.html"
},
// Sensors
dht22: {
id: "dht22",
type: "sensor",
name: "DHT22/AM2302",
manufacturer: "Aosong Electronics",
partNumber: "AM2302",
description: "Digital Temperature & Humidity Sensor",
color: "#27AE60",
keyParams: {
operatingVoltage: { value: "3.3 - 5.5V", typical: "5V", highlight: true },
currentMeasuring: { value: "1.5mA", note: "During measurement", highlight: true },
currentStandby: { value: "40µA", note: "Standby current" },
operatingTemp: { value: "-40°C to +80°C", highlight: true },
tempRange: { value: "-40 to +80°C", note: "Measurement range" },
tempAccuracy: { value: "±0.5°C", note: "Typical accuracy", highlight: true },
tempResolution: { value: "0.1°C", note: "Resolution" },
humidityRange: { value: "0 - 100%RH", note: "Measurement range" },
humidityAccuracy: { value: "±2%RH", note: "At 25°C", highlight: true },
humidityResolution: { value: "0.1%RH", note: "Resolution" },
samplingPeriod: { value: "2 seconds", note: "Minimum between readings", highlight: true },
responseTime: { value: "<5s", note: "1/e (63%) of step" },
interface: { value: "Single-wire digital", note: "Proprietary protocol", highlight: true }
},
absoluteMax: {
supplyVoltage: { value: 6.0, unit: "V", warning: "Exceeding damages sensor" },
storageTemp: { value: [-40, 80], unit: "°C", warning: "Non-condensing" },
storageHumidity: { value: [10, 90], unit: "%RH", warning: "Non-condensing" }
},
derating: {
tempCoeff: 0.1,
maxTemp: 80,
baseTemp: 25
},
designChecklist: [
"Add 4.7kΩ pull-up resistor on data line",
"Keep data wire short (<20m) or add buffer",
"Allow 2+ seconds between readings",
"Avoid placing near heat sources",
"Consider sensor self-heating effects",
"Use averaging for stable readings"
],
datasheetUrl: "https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf"
},
bme280: {
id: "bme280",
type: "sensor",
name: "BME280",
manufacturer: "Bosch Sensortec",
partNumber: "BME280",
description: "Environmental Sensor (T/H/P)",
color: "#3498DB",
keyParams: {
operatingVoltage: { value: "1.71 - 3.6V", typical: "3.3V", highlight: true },
currentMeasuring: { value: "350µA", note: "1Hz, all sensors", highlight: true },
currentSleep: { value: "0.1µA", note: "Sleep mode", highlight: true },
operatingTemp: { value: "-40°C to +85°C", highlight: true },
tempRange: { value: "-40 to +85°C", note: "Full accuracy range" },
tempAccuracy: { value: "±1°C", note: "0 to 65°C range" },
tempResolution: { value: "0.01°C", note: "Resolution" },
pressureRange: { value: "300 - 1100 hPa", note: "Measurement range" },
pressureAccuracy: { value: "±1 hPa", note: "Absolute accuracy", highlight: true },
humidityRange: { value: "0 - 100%RH", note: "Measurement range" },
humidityAccuracy: { value: "±3%RH", note: "At 25°C" },
responseTime: { value: "1s", note: "Humidity τ63%" },
interface: { value: "I2C / SPI", note: "Up to 3.4MHz I2C", highlight: true }
},
absoluteMax: {
supplyVoltage: { value: 4.25, unit: "V", warning: "On VDD" },
esd: { value: 2, unit: "kV", warning: "HBM ESD rating" },
storageTemp: { value: [-40, 85], unit: "°C", warning: "Non-operating" }
},
derating: {
tempCoeff: 0.2,
maxTemp: 85,
baseTemp: 25
},
designChecklist: [
"Add 100nF decoupling capacitor on VDD",
"Use IIR filter for stable readings",
"Configure oversampling based on application",
"Allow for sensor self-heating compensation",
"Use forced mode for lowest power",
"Consider altitude for pressure readings"
],
datasheetUrl: "https://www.bosch-sensortec.com/products/environmental-sensors/humidity-sensors-bme280/"
},
// Radio Modules
sx1276: {
id: "sx1276",
type: "radio",
name: "SX1276",
manufacturer: "Semtech",
partNumber: "SX1276",
description: "LoRa Long Range Transceiver",
color: "#9B59B6",
keyParams: {
operatingVoltage: { value: "1.8 - 3.7V", typical: "3.3V", highlight: true },
currentTx: { value: "120mA", note: "+20dBm output", highlight: true },
currentRxContinuous: { value: "10.8mA", note: "LnaBoost on" },
currentRxDutyCycled: { value: "1.5mA", note: "With CAD", highlight: true },
currentSleep: { value: "0.2µA", note: "Sleep mode", highlight: true },
currentStandby: { value: "1.6mA", note: "RC oscillator" },
operatingTemp: { value: "-40°C to +85°C", highlight: true },
frequency: { value: "137 - 1020 MHz", note: "Multiple bands", highlight: true },
txPower: { value: "+20dBm", note: "Max output power" },
sensitivity: { value: "-148dBm", note: "SF12, 125kHz BW", highlight: true },
spreadingFactor: { value: "SF6 - SF12", note: "Configurable" },
bandwidth: { value: "7.8 - 500 kHz", note: "Configurable" },
dataRate: { value: "0.018 - 37.5 kbps", note: "LoRa mode" },
interface: { value: "SPI", note: "Up to 10MHz", highlight: true }
},
absoluteMax: {
supplyVoltage: { value: 3.9, unit: "V", warning: "On VDD" },
rfInput: { value: 10, unit: "dBm", warning: "At RF pins" },
storageTemp: { value: [-55, 115], unit: "°C", warning: "Non-operating" },
junctionTemp: { value: 125, unit: "°C", warning: "Maximum junction" }
},
derating: {
tempCoeff: 0.8,
maxTemp: 85,
baseTemp: 25
},
designChecklist: [
"Use proper impedance matching network",
"Add ESD protection on antenna port",
"Decouple each VDD pin with 100nF",
"Keep SPI traces short and matched",
"Consider regulatory requirements for band",
"Implement proper duty cycle limits"
],
datasheetUrl: "https://www.semtech.com/products/wireless-rf/lora-connect/sx1276"
},
// Power ICs
mcp1700: {
id: "mcp1700",
type: "power",
name: "MCP1700",
manufacturer: "Microchip",
partNumber: "MCP1700-3302E/TO",
description: "Low Quiescent Current LDO",
color: "#E67E22",
keyParams: {
inputVoltage: { value: "2.3 - 6.0V", note: "Input range", highlight: true },
outputVoltage: { value: "3.3V", note: "Fixed output", highlight: true },
outputCurrent: { value: "250mA", note: "Maximum output", highlight: true },
quiescentCurrent: { value: "1.6µA", note: "Typical Iq", highlight: true },
dropoutVoltage: { value: "178mV", note: "At 250mA", highlight: true },
lineRegulation: { value: "0.1%/V", note: "Typical" },
loadRegulation: { value: "0.4%", note: "Typical" },
operatingTemp: { value: "-40°C to +125°C", highlight: true },
psrr: { value: "60dB", note: "At 100Hz" },
outputNoise: { value: "60µVrms", note: "10Hz - 100kHz" },
package: { value: "TO-92, SOT-23", note: "Through-hole and SMD" }
},
absoluteMax: {
inputVoltage: { value: 6.5, unit: "V", warning: "Maximum input voltage" },
outputCurrent: { value: 300, unit: "mA", warning: "Short circuit protected" },
powerDissipation: { value: 625, unit: "mW", warning: "TO-92 package" },
storageTemp: { value: [-65, 150], unit: "°C", warning: "Non-operating" },
junctionTemp: { value: 150, unit: "°C", warning: "Maximum junction" }
},
derating: {
tempCoeff: 1.0,
maxTemp: 125,
baseTemp: 25
},
designChecklist: [
"Add 1µF ceramic capacitor on input",
"Add 1µF ceramic capacitor on output",
"Ensure adequate thermal dissipation",
"Calculate power dissipation: (Vin-Vout) × Iout",
"Consider dropout at low battery voltage",
"ESR of output cap affects stability"
],
datasheetUrl: "https://www.microchip.com/en-us/product/MCP1700"
},
tps62200: {
id: "tps62200",
type: "power",
name: "TPS62200",
manufacturer: "Texas Instruments",
partNumber: "TPS62200DBVR",
description: "High-Efficiency Step-Down Converter",
color: "#E74C3C",
keyParams: {
inputVoltage: { value: "2.5 - 6.0V", note: "Input range", highlight: true },
outputVoltage: { value: "Adjustable", note: "0.6V - Vin", highlight: true },
outputCurrent: { value: "300mA", note: "Maximum output", highlight: true },
quiescentCurrent: { value: "20µA", note: "PWM mode", highlight: true },
efficiency: { value: "95%", note: "Peak efficiency", highlight: true },
switchingFreq: { value: "1MHz", note: "Fixed frequency" },
operatingTemp: { value: "-40°C to +85°C", highlight: true },
outputRipple: { value: "15mV", note: "Typical" },
softStart: { value: "200µs", note: "Built-in" },
package: { value: "SOT-23-5", note: "5-pin SMD" }
},
absoluteMax: {
inputVoltage: { value: 7.0, unit: "V", warning: "Maximum input voltage" },
switchCurrent: { value: 500, unit: "mA", warning: "Peak switch current" },
storageTemp: { value: [-65, 150], unit: "°C", warning: "Non-operating" },
junctionTemp: { value: 150, unit: "°C", warning: "Maximum junction" }
},
derating: {
tempCoeff: 0.6,
maxTemp: 85,
baseTemp: 25
},
designChecklist: [
"Use recommended inductor value (10µH)",
"Add 10µF input capacitor",
"Add 10µF output capacitor",
"Calculate output voltage: Vout = 0.6 × (1 + R1/R2)",
"Keep switch node traces short",
"Consider EMI from switching"
],
datasheetUrl: "https://www.ti.com/product/TPS62200"
}
}
};
// ---------------------------------------------------------------------------
// STATE MANAGEMENT
// ---------------------------------------------------------------------------
let state = {
selectedType: "mcu",
selectedComponent: "esp32",
comparisonList: ["esp32", "stm32l4"],
// Derating inputs
deratingTemp: 70,
deratingLoad: 80,
// Unit converter
convertValue: 1,
convertFrom: "mA",
convertTo: "µA"
};
// ---------------------------------------------------------------------------
// HELPER FUNCTIONS
// ---------------------------------------------------------------------------
function getComponentsByType(type) {
return Object.values(config.components).filter(c => c.type === type);
}
function getComponent(id) {
return config.components[id];
}
function calculateDerating(component, temperature) {
if (!component.derating) return 100;
const tempDiff = Math.max(0, temperature - component.derating.baseTemp);
const reduction = tempDiff * component.derating.tempCoeff;
return Math.max(0, 100 - reduction);
}
function convertUnit(value, from, to) {
const conversions = {
// Current
'A': { 'mA': 1000, 'µA': 1000000, 'nA': 1000000000, 'A': 1 },
'mA': { 'A': 0.001, 'µA': 1000, 'nA': 1000000, 'mA': 1 },
'µA': { 'A': 0.000001, 'mA': 0.001, 'nA': 1000, 'µA': 1 },
'nA': { 'A': 0.000000001, 'mA': 0.000001, 'µA': 0.001, 'nA': 1 },
// Frequency
'GHz': { 'MHz': 1000, 'kHz': 1000000, 'Hz': 1000000000, 'GHz': 1 },
'MHz': { 'GHz': 0.001, 'kHz': 1000, 'Hz': 1000000, 'MHz': 1 },
'kHz': { 'GHz': 0.000001, 'MHz': 0.001, 'Hz': 1000, 'kHz': 1 },
'Hz': { 'GHz': 0.000000001, 'MHz': 0.000001, 'kHz': 0.001, 'Hz': 1 },
// Voltage
'V': { 'mV': 1000, 'µV': 1000000, 'V': 1 },
'mV': { 'V': 0.001, 'µV': 1000, 'mV': 1 },
'µV': { 'V': 0.000001, 'mV': 0.001, 'µV': 1 }
};
if (conversions[from] && conversions[from][to]) {
return value * conversions[from][to];
}
return value;
}
// ---------------------------------------------------------------------------
// CREATE CONTAINER
// ---------------------------------------------------------------------------
const container = d3.create("div")
.style("font-family", "system-ui, -apple-system, sans-serif")
.style("max-width", `${config.width}px`)
.style("margin", "0 auto");
// ---------------------------------------------------------------------------
// COMPONENT TYPE SELECTOR
// ---------------------------------------------------------------------------
const typePanel = container.append("div")
.style("background", config.colors.lightGray)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.gray}`);
typePanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Select Component Type");
const typeGrid = typePanel.append("div")
.style("display", "grid")
.style("grid-template-columns", "repeat(auto-fit, minmax(180px, 1fr))")
.style("gap", "10px");
config.componentTypes.forEach(ct => {
const btn = typeGrid.append("button")
.attr("class", `type-btn type-${ct.id}`)
.style("padding", "15px")
.style("border-radius", "8px")
.style("border", `2px solid ${ct.color}`)
.style("background", state.selectedType === ct.id ? ct.color : config.colors.white)
.style("color", state.selectedType === ct.id ? config.colors.white : ct.color)
.style("cursor", "pointer")
.style("text-align", "left")
.style("transition", "all 0.2s");
const header = btn.append("div")
.style("display", "flex")
.style("align-items", "center")
.style("gap", "10px")
.style("margin-bottom", "5px");
header.append("span")
.style("font-size", "14px")
.style("font-weight", "bold")
.style("padding", "4px 8px")
.style("background", state.selectedType === ct.id ? "rgba(255,255,255,0.3)" : ct.color + "22")
.style("border-radius", "4px")
.text(ct.icon);
header.append("span")
.style("font-weight", "600")
.style("font-size", "14px")
.text(ct.name);
btn.append("div")
.style("font-size", "11px")
.style("opacity", "0.8")
.text(ct.description);
btn.on("click", function() {
state.selectedType = ct.id;
// Select first component of this type
const comps = getComponentsByType(ct.id);
if (comps.length > 0) {
state.selectedComponent = comps[0].id;
}
updateDisplay();
});
btn.on("mouseenter", function() {
if (state.selectedType !== ct.id) {
d3.select(this)
.style("background", ct.color + "22")
.style("transform", "translateY(-2px)");
}
});
btn.on("mouseleave", function() {
if (state.selectedType !== ct.id) {
d3.select(this)
.style("background", config.colors.white)
.style("transform", "translateY(0)");
}
});
});
// ---------------------------------------------------------------------------
// COMPONENT SELECTOR
// ---------------------------------------------------------------------------
const componentPanel = container.append("div")
.style("background", config.colors.white)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.teal}`);
componentPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Component Library");
const componentGrid = componentPanel.append("div")
.attr("class", "component-grid")
.style("display", "grid")
.style("grid-template-columns", "repeat(auto-fit, minmax(200px, 1fr))")
.style("gap", "10px");
function updateComponentGrid() {
componentGrid.selectAll("*").remove();
const components = getComponentsByType(state.selectedType);
components.forEach(comp => {
const card = componentGrid.append("div")
.attr("class", `component-card component-${comp.id}`)
.style("padding", "15px")
.style("border-radius", "8px")
.style("border", `2px solid ${comp.color}`)
.style("background", state.selectedComponent === comp.id ? comp.color + "22" : config.colors.lightGray)
.style("cursor", "pointer")
.style("transition", "all 0.2s");
card.append("div")
.style("font-weight", "bold")
.style("color", config.colors.navy)
.style("font-size", "14px")
.style("margin-bottom", "5px")
.text(comp.name);
card.append("div")
.style("font-size", "11px")
.style("color", config.colors.gray)
.style("margin-bottom", "5px")
.text(comp.manufacturer);
card.append("div")
.style("font-size", "12px")
.style("color", comp.color)
.text(comp.description);
card.on("click", function() {
state.selectedComponent = comp.id;
updateDisplay();
});
card.on("mouseenter", function() {
d3.select(this)
.style("transform", "translateY(-2px)")
.style("box-shadow", "0 4px 8px rgba(0,0,0,0.1)");
});
card.on("mouseleave", function() {
d3.select(this)
.style("transform", "translateY(0)")
.style("box-shadow", "none");
});
});
}
// ---------------------------------------------------------------------------
// KEY PARAMETERS DISPLAY
// ---------------------------------------------------------------------------
const paramsPanel = container.append("div")
.style("background", config.colors.lightGray)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.navy}`);
paramsPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Key Parameters");
const paramsHeader = paramsPanel.append("div")
.attr("class", "params-header")
.style("margin-bottom", "15px");
const paramsTable = paramsPanel.append("div")
.attr("class", "params-table");
function updateParamsDisplay() {
paramsHeader.selectAll("*").remove();
paramsTable.selectAll("*").remove();
const comp = getComponent(state.selectedComponent);
if (!comp) return;
// Header with component info
const headerRow = paramsHeader.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("align-items", "center")
.style("padding", "15px")
.style("background", comp.color)
.style("color", config.colors.white)
.style("border-radius", "8px");
const titleSection = headerRow.append("div");
titleSection.append("div")
.style("font-size", "18px")
.style("font-weight", "bold")
.text(comp.name);
titleSection.append("div")
.style("font-size", "12px")
.style("opacity", "0.8")
.text(`${comp.manufacturer} • ${comp.partNumber}`);
headerRow.append("a")
.attr("href", comp.datasheetUrl)
.attr("target", "_blank")
.style("padding", "8px 16px")
.style("background", "rgba(255,255,255,0.2)")
.style("border-radius", "6px")
.style("color", config.colors.white)
.style("text-decoration", "none")
.style("font-size", "12px")
.text("View Datasheet");
// Parameters table
const table = paramsTable.append("table")
.style("width", "100%")
.style("border-collapse", "collapse")
.style("font-size", "13px");
Object.entries(comp.keyParams).forEach(([key, param]) => {
const row = table.append("tr")
.style("background", param.highlight ? config.colors.orange + "22" : config.colors.white)
.style("border-bottom", `1px solid ${config.colors.lightGray}`);
// Parameter name
const nameCell = row.append("td")
.style("padding", "12px")
.style("font-weight", "600")
.style("color", config.colors.navy)
.style("width", "35%");
// Format parameter name from camelCase
const formattedName = key.replace(/([A-Z])/g, ' $1')
.replace(/^./, str => str.toUpperCase());
nameCell.text(formattedName);
if (param.highlight) {
nameCell.append("span")
.style("margin-left", "8px")
.style("padding", "2px 6px")
.style("background", config.colors.orange)
.style("color", config.colors.white)
.style("border-radius", "4px")
.style("font-size", "10px")
.text("KEY");
}
// Value
row.append("td")
.style("padding", "12px")
.style("font-weight", "bold")
.style("color", param.highlight ? config.colors.orange : config.colors.navy)
.style("width", "30%")
.text(param.value);
// Note/typical
const noteCell = row.append("td")
.style("padding", "12px")
.style("color", config.colors.gray)
.style("font-size", "12px");
if (param.typical) {
noteCell.append("span")
.style("color", config.colors.teal)
.style("margin-right", "10px")
.text(`Typical: ${param.typical}`);
}
if (param.note) {
noteCell.append("span").text(param.note);
}
});
}
// ---------------------------------------------------------------------------
// ABSOLUTE MAXIMUM RATINGS
// ---------------------------------------------------------------------------
const maxRatingsPanel = container.append("div")
.style("background", config.colors.white)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.red}`);
maxRatingsPanel.append("h3")
.style("margin", "0 0 5px 0")
.style("color", config.colors.red)
.style("font-size", "16px")
.text("Absolute Maximum Ratings");
maxRatingsPanel.append("div")
.style("font-size", "12px")
.style("color", config.colors.gray)
.style("margin-bottom", "15px")
.text("Exceeding these values may cause permanent damage to the device");
const maxRatingsContent = maxRatingsPanel.append("div")
.attr("class", "max-ratings-content");
function updateMaxRatings() {
maxRatingsContent.selectAll("*").remove();
const comp = getComponent(state.selectedComponent);
if (!comp || !comp.absoluteMax) return;
const grid = maxRatingsContent.append("div")
.style("display", "grid")
.style("grid-template-columns", "repeat(auto-fit, minmax(200px, 1fr))")
.style("gap", "10px");
Object.entries(comp.absoluteMax).forEach(([key, spec]) => {
const card = grid.append("div")
.style("padding", "15px")
.style("background", config.colors.red + "11")
.style("border-radius", "8px")
.style("border-left", `4px solid ${config.colors.red}`);
// Format name
const formattedName = key.replace(/([A-Z])/g, ' $1')
.replace(/^./, str => str.toUpperCase());
card.append("div")
.style("font-weight", "600")
.style("color", config.colors.navy)
.style("font-size", "12px")
.style("margin-bottom", "5px")
.text(formattedName);
// Value display
let valueText;
if (Array.isArray(spec.value)) {
valueText = `${spec.value[0]} to ${spec.value[1]} ${spec.unit}`;
} else {
valueText = `${spec.value} ${spec.unit}`;
}
card.append("div")
.style("font-size", "20px")
.style("font-weight", "bold")
.style("color", config.colors.red)
.style("margin-bottom", "5px")
.text(valueText);
card.append("div")
.style("font-size", "11px")
.style("color", config.colors.gray)
.text(spec.warning);
});
}
// ---------------------------------------------------------------------------
// DERATING CALCULATOR
// ---------------------------------------------------------------------------
const deratingPanel = container.append("div")
.style("background", config.colors.lightGray)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.orange}`);
deratingPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Temperature Derating Calculator");
const deratingRow = deratingPanel.append("div")
.style("display", "grid")
.style("grid-template-columns", "1fr 1fr")
.style("gap", "20px");
// Temperature slider
const tempGroup = deratingRow.append("div");
const tempHeader = tempGroup.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("margin-bottom", "10px");
tempHeader.append("label")
.style("font-weight", "600")
.style("color", config.colors.navy)
.style("font-size", "13px")
.text("Operating Temperature");
const tempValue = tempHeader.append("span")
.style("font-weight", "bold")
.style("color", config.colors.orange)
.text(`${state.deratingTemp}°C`);
const tempSlider = tempGroup.append("input")
.attr("type", "range")
.attr("min", -40)
.attr("max", 125)
.attr("value", state.deratingTemp)
.style("width", "100%")
.style("accent-color", config.colors.orange);
tempSlider.on("input", function() {
state.deratingTemp = +this.value;
tempValue.text(`${state.deratingTemp}°C`);
updateDeratingResult();
});
// Result display
const resultGroup = deratingRow.append("div")
.style("text-align", "center")
.style("padding", "15px")
.style("background", config.colors.white)
.style("border-radius", "8px");
resultGroup.append("div")
.style("font-size", "12px")
.style("color", config.colors.gray)
.style("margin-bottom", "5px")
.text("Capability at Temperature");
const deratingResult = resultGroup.append("div")
.attr("class", "derating-result")
.style("font-size", "36px")
.style("font-weight", "bold")
.style("color", config.colors.green)
.text("100%");
resultGroup.append("div")
.attr("class", "derating-note")
.style("font-size", "11px")
.style("color", config.colors.gray)
.style("margin-top", "5px");
// Derating chart
const chartContainer = deratingPanel.append("div")
.style("margin-top", "15px");
const deratingSvg = chartContainer.append("svg")
.attr("viewBox", "0 0 700 200")
.attr("width", "100%");
function updateDeratingResult() {
const comp = getComponent(state.selectedComponent);
const capability = calculateDerating(comp, state.deratingTemp);
let color = config.colors.green;
if (capability < 50) color = config.colors.red;
else if (capability < 80) color = config.colors.orange;
deratingResult.text(`${capability.toFixed(0)}%`).style("color", color);
container.select(".derating-note")
.text(capability < 100 ?
`Derate specifications by ${(100 - capability).toFixed(1)}%` :
"Full rated operation");
updateDeratingChart();
}
function updateDeratingChart() {
deratingSvg.selectAll("*").remove();
const comp = getComponent(state.selectedComponent);
if (!comp || !comp.derating) return;
const margin = { top: 20, right: 30, bottom: 40, left: 50 };
const width = 700 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;
const g = deratingSvg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// Generate derating curve data
const data = [];
for (let t = -40; t <= comp.derating.maxTemp; t += 5) {
data.push({ temp: t, capability: calculateDerating(comp, t) });
}
// Scales
const x = d3.scaleLinear()
.domain([-40, comp.derating.maxTemp])
.range([0, width]);
const y = d3.scaleLinear()
.domain([0, 110])
.range([height, 0]);
// Area
const area = d3.area()
.x(d => x(d.temp))
.y0(height)
.y1(d => y(d.capability))
.curve(d3.curveMonotoneX);
g.append("path")
.datum(data)
.attr("fill", config.colors.teal + "33")
.attr("d", area);
// Line
const line = d3.line()
.x(d => x(d.temp))
.y(d => y(d.capability))
.curve(d3.curveMonotoneX);
g.append("path")
.datum(data)
.attr("fill", "none")
.attr("stroke", config.colors.teal)
.attr("stroke-width", 2)
.attr("d", line);
// Current temperature marker
const currentCap = calculateDerating(comp, state.deratingTemp);
g.append("circle")
.attr("cx", x(state.deratingTemp))
.attr("cy", y(currentCap))
.attr("r", 8)
.attr("fill", config.colors.orange);
g.append("text")
.attr("x", x(state.deratingTemp))
.attr("y", y(currentCap) - 15)
.attr("text-anchor", "middle")
.attr("font-size", "11px")
.attr("fill", config.colors.orange)
.attr("font-weight", "bold")
.text(`${currentCap.toFixed(0)}%`);
// Axes
g.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x).ticks(10))
.selectAll("text")
.attr("font-size", "10px")
.attr("fill", config.colors.gray);
g.append("g")
.call(d3.axisLeft(y).ticks(5))
.selectAll("text")
.attr("font-size", "10px")
.attr("fill", config.colors.gray);
// Labels
g.append("text")
.attr("x", width / 2)
.attr("y", height + 35)
.attr("text-anchor", "middle")
.attr("font-size", "11px")
.attr("fill", config.colors.navy)
.text("Temperature (°C)");
g.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height / 2)
.attr("y", -35)
.attr("text-anchor", "middle")
.attr("font-size", "11px")
.attr("fill", config.colors.navy)
.text("Capability (%)");
}
// ---------------------------------------------------------------------------
// COMPARISON TABLE
// ---------------------------------------------------------------------------
const comparisonPanel = container.append("div")
.style("background", config.colors.white)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.purple}`);
comparisonPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Component Comparison");
// Component selector for comparison
const compSelector = comparisonPanel.append("div")
.style("display", "flex")
.style("gap", "10px")
.style("flex-wrap", "wrap")
.style("margin-bottom", "15px");
Object.values(config.components).forEach(comp => {
const checkLabel = compSelector.append("label")
.style("display", "flex")
.style("align-items", "center")
.style("gap", "5px")
.style("padding", "5px 10px")
.style("background", state.comparisonList.includes(comp.id) ? comp.color + "22" : config.colors.lightGray)
.style("border-radius", "6px")
.style("cursor", "pointer")
.style("font-size", "12px");
checkLabel.append("input")
.attr("type", "checkbox")
.attr("checked", state.comparisonList.includes(comp.id) ? true : null)
.style("accent-color", comp.color)
.on("change", function() {
if (this.checked) {
if (state.comparisonList.length < 3) {
state.comparisonList.push(comp.id);
} else {
this.checked = false;
alert("Maximum 3 components for comparison");
}
} else {
state.comparisonList = state.comparisonList.filter(id => id !== comp.id);
}
updateComparisonTable();
});
checkLabel.append("span")
.style("color", comp.color)
.style("font-weight", "600")
.text(comp.name);
});
const comparisonTable = comparisonPanel.append("div")
.attr("class", "comparison-table")
.style("overflow-x", "auto");
function updateComparisonTable() {
comparisonTable.selectAll("*").remove();
if (state.comparisonList.length === 0) {
comparisonTable.append("div")
.style("padding", "20px")
.style("text-align", "center")
.style("color", config.colors.gray)
.text("Select components above to compare");
return;
}
const comps = state.comparisonList.map(id => getComponent(id)).filter(Boolean);
const table = comparisonTable.append("table")
.style("width", "100%")
.style("border-collapse", "collapse")
.style("font-size", "12px");
// Header row
const headerRow = table.append("tr")
.style("background", config.colors.navy);
headerRow.append("th")
.style("padding", "12px")
.style("text-align", "left")
.style("color", config.colors.white)
.text("Parameter");
comps.forEach(comp => {
headerRow.append("th")
.style("padding", "12px")
.style("text-align", "center")
.style("color", config.colors.white)
.style("background", comp.color)
.text(comp.name);
});
// Comparison rows for key params
const keyParamNames = ["operatingVoltage", "currentActive", "currentSleep",
"currentDeepSleep", "operatingTemp", "interfaces"];
keyParamNames.forEach(paramName => {
const row = table.append("tr")
.style("border-bottom", `1px solid ${config.colors.lightGray}`);
// Format parameter name
const formattedName = paramName.replace(/([A-Z])/g, ' $1')
.replace(/^./, str => str.toUpperCase());
row.append("td")
.style("padding", "10px")
.style("font-weight", "600")
.style("color", config.colors.navy)
.style("background", config.colors.lightGray)
.text(formattedName);
comps.forEach(comp => {
const param = comp.keyParams[paramName];
row.append("td")
.style("padding", "10px")
.style("text-align", "center")
.style("color", param && param.highlight ? config.colors.orange : config.colors.navy)
.style("font-weight", param && param.highlight ? "bold" : "normal")
.text(param ? param.value : "N/A");
});
});
}
// ---------------------------------------------------------------------------
// UNIT CONVERTER
// ---------------------------------------------------------------------------
const converterPanel = container.append("div")
.style("background", config.colors.lightGray)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.gray}`);
converterPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Parameter Unit Converter");
const converterRow = converterPanel.append("div")
.style("display", "grid")
.style("grid-template-columns", "1fr auto 1fr auto 1fr")
.style("gap", "15px")
.style("align-items", "end");
// Input value
const inputGroup = converterRow.append("div");
inputGroup.append("label")
.style("display", "block")
.style("font-size", "12px")
.style("color", config.colors.gray)
.style("margin-bottom", "5px")
.text("Value");
const valueInput = inputGroup.append("input")
.attr("type", "number")
.attr("value", state.convertValue)
.style("width", "100%")
.style("padding", "10px")
.style("border-radius", "6px")
.style("border", `1px solid ${config.colors.gray}`)
.style("font-size", "14px")
.style("box-sizing", "border-box");
// From unit
const fromGroup = converterRow.append("div");
fromGroup.append("label")
.style("display", "block")
.style("font-size", "12px")
.style("color", config.colors.gray)
.style("margin-bottom", "5px")
.text("From");
const fromSelect = fromGroup.append("select")
.style("padding", "10px")
.style("border-radius", "6px")
.style("border", `1px solid ${config.colors.gray}`)
.style("font-size", "13px")
.style("cursor", "pointer");
const units = [
{ group: "Current", units: ["A", "mA", "µA", "nA"] },
{ group: "Frequency", units: ["GHz", "MHz", "kHz", "Hz"] },
{ group: "Voltage", units: ["V", "mV", "µV"] }
];
units.forEach(group => {
const optgroup = fromSelect.append("optgroup").attr("label", group.group);
group.units.forEach(u => {
optgroup.append("option")
.attr("value", u)
.attr("selected", u === state.convertFrom ? true : null)
.text(u);
});
});
// Arrow
converterRow.append("div")
.style("font-size", "24px")
.style("color", config.colors.teal)
.style("text-align", "center")
.style("padding-bottom", "10px")
.text("→");
// To unit
const toGroup = converterRow.append("div");
toGroup.append("label")
.style("display", "block")
.style("font-size", "12px")
.style("color", config.colors.gray)
.style("margin-bottom", "5px")
.text("To");
const toSelect = toGroup.append("select")
.style("padding", "10px")
.style("border-radius", "6px")
.style("border", `1px solid ${config.colors.gray}`)
.style("font-size", "13px")
.style("cursor", "pointer");
units.forEach(group => {
const optgroup = toSelect.append("optgroup").attr("label", group.group);
group.units.forEach(u => {
optgroup.append("option")
.attr("value", u)
.attr("selected", u === state.convertTo ? true : null)
.text(u);
});
});
// Result
const resultDisplay = converterRow.append("div")
.style("text-align", "center")
.style("padding", "10px")
.style("background", config.colors.white)
.style("border-radius", "6px");
const convertResult = resultDisplay.append("div")
.attr("class", "convert-result")
.style("font-size", "18px")
.style("font-weight", "bold")
.style("color", config.colors.teal);
function updateConversion() {
const result = convertUnit(state.convertValue, state.convertFrom, state.convertTo);
let displayValue;
if (result >= 1000000) {
displayValue = result.toExponential(3);
} else if (result < 0.001) {
displayValue = result.toExponential(3);
} else {
displayValue = result.toLocaleString(undefined, { maximumFractionDigits: 6 });
}
convertResult.text(`${displayValue} ${state.convertTo}`);
}
valueInput.on("input", function() {
state.convertValue = +this.value || 0;
updateConversion();
});
fromSelect.on("change", function() {
state.convertFrom = this.value;
updateConversion();
});
toSelect.on("change", function() {
state.convertTo = this.value;
updateConversion();
});
// ---------------------------------------------------------------------------
// DESIGN CHECKLIST
// ---------------------------------------------------------------------------
const checklistPanel = container.append("div")
.style("background", config.colors.white)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("border", `2px solid ${config.colors.green}`);
checklistPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("color", config.colors.navy)
.style("font-size", "16px")
.text("Design Checklist");
const checklistContent = checklistPanel.append("div")
.attr("class", "checklist-content");
function updateChecklist() {
checklistContent.selectAll("*").remove();
const comp = getComponent(state.selectedComponent);
if (!comp || !comp.designChecklist) return;
const list = checklistContent.append("div")
.style("display", "grid")
.style("gap", "8px");
comp.designChecklist.forEach((item, idx) => {
const checkItem = list.append("label")
.style("display", "flex")
.style("align-items", "flex-start")
.style("gap", "10px")
.style("padding", "10px")
.style("background", config.colors.lightGray)
.style("border-radius", "6px")
.style("cursor", "pointer")
.style("transition", "background 0.2s");
checkItem.append("input")
.attr("type", "checkbox")
.style("margin-top", "2px")
.style("accent-color", config.colors.green);
checkItem.append("span")
.style("font-size", "13px")
.style("color", config.colors.navy)
.text(item);
checkItem.on("mouseenter", function() {
d3.select(this).style("background", config.colors.green + "22");
});
checkItem.on("mouseleave", function() {
d3.select(this).style("background", config.colors.lightGray);
});
});
}
// ---------------------------------------------------------------------------
// QUICK REFERENCE CARD
// ---------------------------------------------------------------------------
const refCardPanel = container.append("div")
.style("background", config.colors.navy)
.style("border-radius", "12px")
.style("padding", "20px")
.style("margin-bottom", "15px")
.style("color", config.colors.white);
refCardPanel.append("h3")
.style("margin", "0 0 15px 0")
.style("font-size", "16px")
.text("Quick Reference Card");
const refCardContent = refCardPanel.append("div")
.attr("class", "ref-card-content");
function updateRefCard() {
refCardContent.selectAll("*").remove();
const comp = getComponent(state.selectedComponent);
if (!comp) return;
const card = refCardContent.append("div")
.style("background", "rgba(255,255,255,0.1)")
.style("border-radius", "8px")
.style("padding", "20px");
// Header
const header = card.append("div")
.style("display", "flex")
.style("justify-content", "space-between")
.style("align-items", "center")
.style("padding-bottom", "15px")
.style("border-bottom", "1px solid rgba(255,255,255,0.2)")
.style("margin-bottom", "15px");
const titleSection = header.append("div");
titleSection.append("div")
.style("font-size", "20px")
.style("font-weight", "bold")
.text(comp.name);
titleSection.append("div")
.style("font-size", "12px")
.style("opacity", "0.7")
.text(`${comp.manufacturer} • ${comp.partNumber}`);
header.append("div")
.style("padding", "8px 16px")
.style("background", comp.color)
.style("border-radius", "6px")
.style("font-size", "12px")
.text(comp.type.toUpperCase());
// Key specs grid
const specsGrid = card.append("div")
.style("display", "grid")
.style("grid-template-columns", "repeat(auto-fit, minmax(150px, 1fr))")
.style("gap", "15px");
// Extract highlighted parameters
const keySpecs = Object.entries(comp.keyParams)
.filter(([_, param]) => param.highlight)
.slice(0, 6);
keySpecs.forEach(([key, param]) => {
const spec = specsGrid.append("div")
.style("background", "rgba(255,255,255,0.1)")
.style("padding", "10px")
.style("border-radius", "6px");
const formattedName = key.replace(/([A-Z])/g, ' $1')
.replace(/^./, str => str.toUpperCase());
spec.append("div")
.style("font-size", "10px")
.style("opacity", "0.7")
.style("margin-bottom", "5px")
.text(formattedName);
spec.append("div")
.style("font-size", "14px")
.style("font-weight", "bold")
.style("color", config.colors.orange)
.text(param.value);
});
// Copy button
const copyBtn = card.append("button")
.style("margin-top", "15px")
.style("padding", "10px 20px")
.style("background", config.colors.teal)
.style("color", config.colors.white)
.style("border", "none")
.style("border-radius", "6px")
.style("cursor", "pointer")
.style("font-size", "13px")
.text("Copy Reference Card");
copyBtn.on("click", function() {
let text = `${comp.name} (${comp.partNumber})\n`;
text += `Manufacturer: ${comp.manufacturer}\n`;
text += `\nKey Specifications:\n`;
keySpecs.forEach(([key, param]) => {
const formattedName = key.replace(/([A-Z])/g, ' $1')
.replace(/^./, str => str.toUpperCase());
text += ` ${formattedName}: ${param.value}\n`;
});
text += `\nDatasheet: ${comp.datasheetUrl}`;
navigator.clipboard.writeText(text).then(() => {
d3.select(this).text("Copied!").style("background", config.colors.green);
setTimeout(() => {
d3.select(this).text("Copy Reference Card").style("background", config.colors.teal);
}, 2000);
});
});
}
// ---------------------------------------------------------------------------
// UPDATE DISPLAY FUNCTION
// ---------------------------------------------------------------------------
function updateDisplay() {
// Update type buttons
config.componentTypes.forEach(ct => {
container.select(`.type-${ct.id}`)
.style("background", state.selectedType === ct.id ? ct.color : config.colors.white)
.style("color", state.selectedType === ct.id ? config.colors.white : ct.color);
});
// Update component grid
updateComponentGrid();
// Highlight selected component
const comp = getComponent(state.selectedComponent);
container.selectAll(".component-card")
.style("background", function() {
const id = d3.select(this).attr("class").split("component-")[1];
const c = getComponent(id);
return id === state.selectedComponent ? c.color + "22" : config.colors.lightGray;
});
// Update all sections
updateParamsDisplay();
updateMaxRatings();
updateDeratingResult();
updateComparisonTable();
updateConversion();
updateChecklist();
updateRefCard();
}
// ---------------------------------------------------------------------------
// INITIALIZE
// ---------------------------------------------------------------------------
updateDisplay();
return container.node();
}1631.2 Understanding Datasheets
1631.2.1 Critical Datasheet Sections
When reviewing IoT component datasheets, focus on these key sections:
%% fig-alt: Flowchart showing the recommended sequence for reading IoT component datasheets, starting with features overview, then checking absolute maximum ratings, verifying electrical characteristics meet requirements, reviewing application circuits, and finally checking package compatibility.
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#FFFFFF', 'primaryBorderColor': '#16A085', 'lineColor': '#7F8C8D', 'secondaryColor': '#ECF0F1', 'tertiaryColor': '#FFFFFF'}}}%%
flowchart TD
START[Start Reading<br/>Datasheet] --> FEAT[Features Overview<br/>Verify it meets needs]
FEAT --> ABS[Absolute Maximum<br/>Ratings]
ABS --> Q1{Within system<br/>constraints?}
Q1 -->|No| REJECT[Select Different<br/>Component]
Q1 -->|Yes| ELEC[Electrical<br/>Characteristics]
ELEC --> Q2{Power budget<br/>acceptable?}
Q2 -->|No| REJECT
Q2 -->|Yes| APP[Application<br/>Circuits]
APP --> BOM[Create BOM from<br/>Reference Design]
BOM --> PKG[Package<br/>Selection]
PKG --> LAYOUT[PCB Layout<br/>Guidelines]
LAYOUT --> DONE[Ready for<br/>Design]
style START fill:#2C3E50,stroke:#16A085,stroke-width:2px,color:#fff
style DONE fill:#27AE60,stroke:#2C3E50,stroke-width:2px,color:#fff
style REJECT fill:#E74C3C,stroke:#2C3E50,stroke-width:2px,color:#fff
Follow this workflow to systematically evaluate component datasheets. Each step builds on the previous, ensuring you catch compatibility issues early in the design process.
1631.2.2 Temperature Derating
Temperature affects component performance significantly. The derating formula helps estimate capability at elevated temperatures:
\[Capability(\%) = 100 - (T_{operating} - T_{base}) \times K\]
Where: - \(T_{operating}\) = Actual operating temperature - \(T_{base}\) = Reference temperature (typically 25°C) - \(K\) = Temperature coefficient (%/°C)
| Component Type | Typical K Value | Notes |
|---|---|---|
| MCU | 0.3 - 0.5 | Affects clock stability |
| Power IC | 0.8 - 1.2 | Current capability |
| Radio | 0.5 - 1.0 | Output power |
| Sensor | 0.1 - 0.3 | Accuracy specification |
1631.2.3 Common Datasheet Pitfalls
- Typical vs. Maximum values - Design for worst case, not typical
- Test conditions - Specifications valid only under stated conditions
- Absolute vs. Recommended - Stay within recommended operating conditions
- Temperature ranges - Industrial (-40 to +85°C) vs Commercial (0 to +70°C)
- Package thermal resistance - Affects actual operating temperature
- Supply current - Active, sleep, and deep sleep values vary significantly
1631.2.4 Reading Power Specifications
Power parameters in datasheets require careful interpretation:
%% fig-alt: Diagram showing different power consumption states in IoT components from highest to lowest, including active transmission mode, active processing mode, idle or light sleep mode, deep sleep with RTC, and shutdown or hibernation mode, with typical current ranges for each state.
%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#2C3E50', 'primaryTextColor': '#FFFFFF', 'primaryBorderColor': '#16A085', 'lineColor': '#7F8C8D', 'secondaryColor': '#ECF0F1', 'tertiaryColor': '#FFFFFF'}}}%%
flowchart LR
subgraph Power["Power Consumption States"]
direction TB
TX["Active TX<br/>10-250 mA"]
ACTIVE["Active CPU<br/>5-100 mA"]
IDLE["Light Sleep<br/>0.1-2 mA"]
DEEP["Deep Sleep<br/>1-100 µA"]
OFF["Shutdown<br/>0.01-10 µA"]
end
TX --> ACTIVE --> IDLE --> DEEP --> OFF
style TX fill:#E74C3C,stroke:#2C3E50,stroke-width:2px,color:#fff
style ACTIVE fill:#E67E22,stroke:#2C3E50,stroke-width:2px,color:#fff
style IDLE fill:#F1C40F,stroke:#2C3E50,stroke-width:2px,color:#000
style DEEP fill:#27AE60,stroke:#2C3E50,stroke-width:2px,color:#fff
style OFF fill:#16A085,stroke:#2C3E50,stroke-width:2px,color:#fff
1631.3 What’s Next
Explore related hardware design topics:
- Hardware Selection Optimizer - Component selection tool
- Power Budget Calculator - Battery life estimation
- Test Design Generator - Create comprehensive test cases
- Design Thinking and Planning - Development workflow guide
Interactive datasheet navigator created for the IoT Class Textbook - DATA-001