CookbookLabs and workshopsNo. 26
An electronics lab manualfrom Ohm’s law to a blinking 555
See it in know.sh
Resistor colour codes and LED resistors
Read a four- or five-band resistor by picking its bands, or type a value to get its bands; then work out the current-limiting resistor for an LED, the next standard value up and the power it turns into heat. The page is printed in one ink, so each band is named rather than coloured. Colours follow IEC 60062; only the E12 and E24 series are checked, and the LED sum takes the forward voltage as fixed, which a real LED’s is not quite.
<div class="res">
<div class="tabs" role="tablist" aria-label="Tools">
<button type="button" role="tab" id="tabCode" aria-selected="true" aria-controls="panelCode">Colour code</button>
<button type="button" role="tab" id="tabLed" aria-selected="false" aria-controls="panelLed" tabindex="-1">LED resistor</button>
</div>
<section id="panelCode" role="tabpanel" aria-labelledby="tabCode">
<div class="count" role="group" aria-label="Number of bands">
<button type="button" data-bands="4" aria-pressed="true">4 bands</button>
<button type="button" data-bands="5" aria-pressed="false">5 bands</button>
</div>
<svg id="draw" role="img" aria-label="Resistor"></svg>
<div class="picks" id="picks"></div>
<dl class="figures">
<div><dt>Value</dt><dd id="valOut">–</dd></div>
<div><dt>Tolerance</dt><dd id="tolOut">–</dd></div>
<div><dt>Could measure</dt><dd id="rangeOut">–</dd></div>
</dl>
<p class="say" id="codeSay" aria-live="polite"></p>
<div class="typein">
<label for="typed">Or type a value</label>
<div class="row"><input id="typed" type="text" inputmode="decimal" autocomplete="off" spellcheck="false" placeholder="4.7k, 4k7, 220, 1M"><button type="button" id="showBands">Show bands</button></div>
</div>
<p class="say small" id="typeSay" aria-live="polite"></p>
</section>
<section id="panelLed" role="tabpanel" aria-labelledby="tabLed" hidden>
<div class="inputs">
<label>Supply voltage, V<input id="vs" type="number" min="0" max="24" step="0.1" value="9"></label>
<label>LED forward voltage, V<input id="vf" type="number" min="1" max="4" step="0.1" value="2.0"></label>
<label>LED current, mA<input id="ma" type="number" min="1" max="50" step="1" value="15"></label>
<label>Standard series<select id="series"><option value="E12" selected>E12</option><option value="E24">E24</option></select></label>
</div>
<div class="presets" role="group" aria-label="Typical forward voltages">
<span>Typical LEDs:</span>
<button type="button" data-vf="2.0">Red, 2.0 V</button>
<button type="button" data-vf="2.1">Yellow, 2.1 V</button>
<button type="button" data-vf="3.2">White or blue, 3.2 V</button>
</div>
<dl class="figures">
<div><dt>Resistor, worked out</dt><dd id="rOut">–</dd></div>
<div><dt>Next standard up</dt><dd id="stdOut">–</dd></div>
<div><dt>Current with it</dt><dd id="iOut">–</dd></div>
<div><dt>Power in the resistor</dt><dd id="pOut">–</dd></div>
</dl>
<p class="say" id="ledSay" aria-live="polite"></p>
<p><button type="button" id="toBands">Read its bands</button></p>
</section>
</div>.res { font-family: var(--sans); }
.tabs { display: flex; border-bottom: 1px solid var(--ink); margin-bottom: 12px; }
.tabs button { flex: 0 0 auto; font: 500 14px/1 var(--sans); background: var(--paper); color: var(--ink-2); border: 0; border-bottom: 3px solid transparent; padding: 10px 14px 8px; min-height: 40px; }
.tabs button[aria-selected='true'] { color: var(--ink); border-bottom-color: var(--ink); }
.count { display: flex; gap: 6px; }
.count button, .presets button, #toBands, .typein button { font: 500 13.5px/1 var(--sans); color: var(--ink); background: var(--paper); border: 1px solid var(--ink); padding: 9px 12px; min-height: 38px; }
.count button[aria-pressed='true'] { background: var(--ink); color: var(--paper); }
#draw { display: block; width: 100%; margin: 10px 0 4px; }
.lead { stroke: var(--ink-2); stroke-width: 2.5; }
.body { fill: var(--wash); stroke: var(--ink); stroke-width: 1.5; }
.band { fill: var(--ink); }
.bname { font: 500 11.5px var(--sans); fill: var(--ink); }
.bno { font: 400 10.5px var(--sans); fill: var(--ink-3); }
.tick { stroke: var(--ink-3); stroke-width: 1; }
.picks { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 8px 12px; }
.picks select { font-size: 13px; padding: 6px 4px; }
.picks label { display: grid; gap: 3px; }
.picks select, .inputs input, .inputs select { width: 100%; min-height: 36px; }
.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 0 18px; margin: 12px 0 0; border-top: 1px solid var(--ink); }
.figures div { padding: 6px 0; border-bottom: 1px solid var(--rule); }
.figures dt { font: 400 12.5px/1.3 var(--sans); color: var(--ink-3); }
.figures dd { margin: 2px 0 0; font: 400 18px/1.25 var(--serif); color: var(--ink); font-variant-numeric: tabular-nums; }
.say { margin: 8px 0 0; font: 400 15px/1.45 var(--serif); color: var(--ink); }
.say.small { color: var(--ink-2); min-height: 1.45em; }
.typein { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--rule); }
.typein label { display: block; margin-bottom: 3px; }
.row { display: flex; gap: 6px; }
.row input { flex: 1; min-width: 0; font: 400 15px var(--mono); }
.inputs { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px 12px; align-items: end; }
.inputs label { display: grid; gap: 3px; }
.inputs input { font-variant-numeric: tabular-nums; }
.presets { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; font: 400 13px var(--sans); color: var(--ink-2); }
#toBands { margin-top: 4px; }
button:focus-visible, input:focus-visible, select:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }(function () {
var $ = function (id) { return document.getElementById(id); };
// IEC 60062: digit, multiplier and tolerance for each colour.
var C = {
black: { name: 'Black', d: 0, m: 0 },
brown: { name: 'Brown', d: 1, m: 1, t: 1 },
red: { name: 'Red', d: 2, m: 2, t: 2 },
orange: { name: 'Orange', d: 3, m: 3 },
yellow: { name: 'Yellow', d: 4, m: 4 },
green: { name: 'Green', d: 5, m: 5, t: 0.5 },
blue: { name: 'Blue', d: 6, m: 6, t: 0.25 },
violet: { name: 'Violet', d: 7, m: 7, t: 0.1 },
grey: { name: 'Grey', d: 8, m: 8 },
white: { name: 'White', d: 9, m: 9 },
gold: { name: 'Gold', m: -1, t: 5 },
silver: { name: 'Silver', m: -2, t: 10 }
};
var DIGITS = ['black', 'brown', 'red', 'orange', 'yellow', 'green', 'blue', 'violet', 'grey', 'white'];
var MULTS = DIGITS.concat(['gold', 'silver']);
var TOLS = ['brown', 'red', 'green', 'blue', 'violet', 'gold', 'silver'];
var E12 = [10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82];
var E24 = [10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91];
var RATINGS = [[0.125, '1/8 W'], [0.25, '1/4 W'], [0.5, '1/2 W'], [1, '1 W'], [2, '2 W']];
var s = { n: 4, bands: ['yellow', 'violet', 'red', 'gold'] };
var multNames = { '-2': '× 0.01', '-1': '× 0.1', '0': '× 1', '1': '× 10', '2': '× 100', '3': '× 1k', '4': '× 10k', '5': '× 100k', '6': '× 1M', '7': '× 10M', '8': '× 100M', '9': '× 1G' };
function fmt(v) {
var u = [[1e9, ' GΩ'], [1e6, ' MΩ'], [1e3, ' kΩ'], [1, ' Ω']], i;
for (i = 0; i < u.length; i++) if (v >= u[i][0] * (1 - 1e-9) || i === u.length - 1) return String(parseFloat((v / u[i][0]).toPrecision(4))) + u[i][1];
}
function roles(n) { return n === 4 ? ['digit', 'digit', 'mult', 'tol'] : ['digit', 'digit', 'digit', 'mult', 'tol']; }
function roleLabel(r, i) { return r === 'digit' ? ['1st', '2nd', '3rd'][i] + ' digit' : r === 'mult' ? 'Multiplier' : 'Tolerance'; }
function listFor(r, i) { return r === 'digit' ? (i === 0 ? DIGITS.slice(1) : DIGITS) : r === 'mult' ? MULTS : TOLS; }
function optText(key, r) { var c = C[key]; return c.name + ' ' + (r === 'digit' ? c.d : r === 'mult' ? multNames[c.m].replace(' ', '') : '±' + c.t + '%'); }
function read() {
var r = roles(s.n), digits = 0, exp = 0, tol = 0;
s.bands.forEach(function (b, i) {
if (r[i] === 'digit') digits = digits * 10 + C[b].d;
else if (r[i] === 'mult') exp = C[b].m;
else tol = C[b].t;
});
return { v: parseFloat((digits * Math.pow(10, exp)).toPrecision(6)), tol: tol, digits: digits, exp: exp };
}
function mantissa(v) { var d = Math.pow(10, Math.floor(Math.log10(v) + 1e-9) - 1); return { m: Math.round(v / d * 1000) / 1000, d: d }; }
function inSeries(v, list) { var m = mantissa(v).m; return list.some(function (e) { return Math.abs(e - m) < 1e-6; }); }
function neighbours(v, list) {
var d = Math.pow(10, Math.floor(Math.log10(v) + 1e-9) - 1), c = [];
[d / 10, d, d * 10].forEach(function (k) { list.forEach(function (e) { c.push(parseFloat((e * k).toPrecision(6))); }); });
var below = c.filter(function (x) { return x <= v; }).pop(), above = c.filter(function (x) { return x >= v; })[0];
return [below, above];
}
function nextUp(v, list) {
var d = Math.pow(10, Math.floor(Math.log10(v) + 1e-9) - 1), c = [];
[d, d * 10, d * 100].forEach(function (k) { list.forEach(function (e) { c.push(parseFloat((e * k).toPrecision(6))); }); });
return c.filter(function (x) { return x >= v * (1 - 1e-9); })[0];
}
// The fewest significant figures that carry the value: 2 on four bands, 3 on five.
function bandsFor(v, n) {
var sig = n - 2, lo = Math.pow(10, sig - 1), hi = Math.pow(10, sig) - 1;
for (var e = -2; e <= 9; e++) {
var x = v / Math.pow(10, e), r = Math.round(x);
if (r >= lo && r <= hi && Math.abs(x - r) < 1e-6 * x) {
var ds = String(r).split('').map(function (ch) { return DIGITS[Number(ch)]; });
return ds.concat([MULTS.filter(function (k) { return C[k].m === e; })[0]]);
}
}
return null;
}
function parse(text) {
var t = String(text).replace(/\s+/g, '').replace(/(Ω|ohms?)$/i, '');
var m = /^(\d*)([rRkKmMgG])(\d+)$/.exec(t), k = { r: 1, k: 1e3, m: 1e6, g: 1e9 };
if (m && (m[1] || m[3])) return parseFloat((m[1] || '0') + '.' + m[3]) * k[m[2].toLowerCase()];
m = /^(\d+(?:\.\d+)?|\.\d+)([rRkKmMgG]?)$/.exec(t);
if (m) return parseFloat(m[1]) * (m[2] ? k[m[2].toLowerCase()] : 1);
return null;
}
function buildPicks() {
var r = roles(s.n), box = $('picks');
box.innerHTML = r.map(function (role, i) {
return '<label>Band ' + (i + 1) + ', ' + roleLabel(role, i).toLowerCase() + '<select data-i="' + i + '">' + listFor(role, i).map(function (k) {
return '<option value="' + k + '"' + (s.bands[i] === k ? ' selected' : '') + '>' + optText(k, role) + '</option>';
}).join('') + '</select></label>';
}).join('');
box.querySelectorAll('select').forEach(function (sel) {
sel.addEventListener('change', function () { s.bands[Number(sel.getAttribute('data-i'))] = sel.value; $('typeSay').textContent = ''; render(); });
});
document.querySelectorAll('[data-bands]').forEach(function (b) { b.setAttribute('aria-pressed', String(Number(b.getAttribute('data-bands')) === s.n)); });
}
function drawResistor() {
var svg = $('draw'), W = Math.max(260, Math.round(svg.getBoundingClientRect().width) || 588), narrow = W < 440;
var H = narrow ? 118 : 96, cy = narrow ? 58 : 40, bx = W * 0.14, bw = W * 0.72, bh = 42;
var pos = s.n === 4 ? [0.16, 0.3, 0.44, 0.84] : [0.14, 0.26, 0.38, 0.5, 0.86], w = Math.max(9, bw * 0.055), out = [];
svg.setAttribute('viewBox', '0 0 ' + W + ' ' + H); svg.setAttribute('height', H);
out.push('<line class="lead" x1="0" x2="' + bx + '" y1="' + cy + '" y2="' + cy + '"/><line class="lead" x1="' + (bx + bw) + '" x2="' + W + '" y1="' + cy + '" y2="' + cy + '"/>');
var y0 = cy - bh / 2, sh = bw * 0.09;
out.push('<path class="body" d="M' + bx + ' ' + (y0 + 6) + 'Q' + bx + ' ' + y0 + ' ' + (bx + 8) + ' ' + y0 + 'H' + (bx + sh) + 'L' + (bx + sh + 6) + ' ' + (y0 + 5) + 'H' + (bx + bw - sh - 6) + 'L' + (bx + bw - sh) + ' ' + y0 + 'H' + (bx + bw - 8) + 'Q' + (bx + bw) + ' ' + y0 + ' ' + (bx + bw) + ' ' + (y0 + 6) + 'V' + (y0 + bh - 6) + 'Q' + (bx + bw) + ' ' + (y0 + bh) + ' ' + (bx + bw - 8) + ' ' + (y0 + bh) + 'H' + (bx + bw - sh) + 'L' + (bx + bw - sh - 6) + ' ' + (y0 + bh - 5) + 'H' + (bx + sh + 6) + 'L' + (bx + sh) + ' ' + (y0 + bh) + 'H' + (bx + 8) + 'Q' + bx + ' ' + (y0 + bh) + ' ' + bx + ' ' + (y0 + bh - 6) + 'Z"/>');
s.bands.forEach(function (b, i) {
var x = bx + bw * pos[i], inner = x > bx + sh && x < bx + bw - sh, top = inner ? y0 + 5 : y0, bot = inner ? y0 + bh - 5 : y0 + bh;
out.push('<rect class="band" x="' + (x - w / 2) + '" y="' + top + '" width="' + w + '" height="' + (bot - top) + '"/>');
var up = narrow && i % 2 === 1, ty = up ? y0 - 10 : y0 + bh + 16;
out.push('<line class="tick" x1="' + x + '" x2="' + x + '" y1="' + (up ? y0 - 6 : y0 + bh + 2) + '" y2="' + (up ? y0 - 1 : y0 + bh + 5) + '"/>');
out.push('<text class="bname" x="' + x + '" y="' + ty + '" text-anchor="middle">' + C[b].name + '</text>');
if (!narrow) out.push('<text class="bno" x="' + x + '" y="' + (ty + 14) + '" text-anchor="middle">' + (i + 1) + '</text>');
});
svg.innerHTML = out.join('');
var r = read();
svg.setAttribute('aria-label', s.n + '-band resistor, read from the left: ' + s.bands.map(function (b) { return C[b].name.toLowerCase(); }).join(', ') + '. ' + fmt(r.v) + ', plus or minus ' + r.tol + ' per cent.');
}
function render() {
drawResistor();
var r = read(), names = s.bands.map(function (b) { return C[b].name.toLowerCase(); });
$('valOut').textContent = fmt(r.v);
$('tolOut').textContent = '±' + r.tol + '%';
var lo = fmt(r.v * (1 - r.tol / 100)), hi = fmt(r.v * (1 + r.tol / 100)), ul = lo.split(' ')[1], uh = hi.split(' ')[1];
$('rangeOut').textContent = ul === uh ? lo.split(' ')[0] + ' to ' + hi : lo + ' to ' + hi;
var series = inSeries(r.v, E12) ? 'It is an E12 value, so also in E24.' : inSeries(r.v, E24) ? 'It is an E24 value, not in E12.' : (function () { var nb = neighbours(r.v, E24); return 'Not an E12 or E24 value (five-band parts often come from E96); the nearest E24 values are ' + fmt(nb[0]) + ' and ' + fmt(nb[1]) + '.'; })();
var sentence = names.slice(0, s.n - 2).map(function (n, i) { return C[s.bands[i]].d; }).join('');
$('codeSay').textContent = names.join(', ') + ': ' + sentence + ' ' + multNames[r.exp] + ' = ' + fmt(r.v) + ', ±' + r.tol + '%. ' + series;
}
function setBands(v, keepSay) {
var four = bandsFor(v, 4), five = bandsFor(v, 5), say = $('typeSay');
if (!four && !five) { say.textContent = fmt(v) + ' needs more significant figures than colour bands carry (two on four bands, three on five), or lies outside 0.1 Ω to 999 GΩ.'; return false; }
var tol = s.bands[s.bands.length - 1], keep = TOLS.indexOf(tol) >= 0 && s.n === (four ? 4 : 5);
if (four) { s.n = 4; s.bands = four.concat([keep ? tol : 'gold']); }
else { s.n = 5; s.bands = five.concat([keep ? tol : 'brown']); }
buildPicks(); render();
if (!keepSay) say.textContent = four && five ? 'On a 1% five-band part the same value reads ' + five.map(function (k) { return C[k].name.toLowerCase(); }).join(', ') + ', brown.' : four ? '' : 'Three significant figures: this value needs five bands.';
return true;
}
function typed() {
var v = parse($('typed').value);
if (v === null || !(v > 0)) { $('typeSay').textContent = 'Type a value such as 4.7k, 4k7, 220, 0.47 or 1M.'; return; }
setBands(v);
}
$('showBands').addEventListener('click', typed);
$('typed').addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); typed(); } });
document.querySelectorAll('[data-bands]').forEach(function (b) {
b.addEventListener('click', function () {
var n = Number(b.getAttribute('data-bands')); if (n === s.n) return;
var v = read().v, next = bandsFor(v, n);
s.n = n;
s.bands = next ? next.concat([n === 4 ? 'gold' : 'brown']) : (n === 4 ? ['brown', 'black', 'red', 'gold'] : ['brown', 'black', 'black', 'brown', 'brown']);
$('typeSay').textContent = next ? '' : fmt(v) + ' cannot be written on ' + n + ' bands, so they start again at 1 kΩ.';
buildPicks(); render();
});
});
// Tabs, with arrow keys between them.
var tabs = [$('tabCode'), $('tabLed')];
function show(i) {
tabs.forEach(function (t, j) { t.setAttribute('aria-selected', String(i === j)); t.tabIndex = i === j ? 0 : -1; $(t.getAttribute('aria-controls')).hidden = i !== j; });
if (i === 0) render(); else led();
}
tabs.forEach(function (t, i) {
t.addEventListener('click', function () { show(i); });
t.addEventListener('keydown', function (e) { if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { var j = (i + 1) % 2; show(j); tabs[j].focus(); e.preventDefault(); } });
});
// LED: R = (Vs − Vf) ÷ I, then the next standard value up, and what it dissipates.
var ledStd = null;
function led() {
var vs = parseFloat($('vs').value), vf = parseFloat($('vf').value), ma = parseFloat($('ma').value), list = $('series').value === 'E24' ? E24 : E12, say = [];
ledStd = null;
['rOut', 'stdOut', 'iOut', 'pOut'].forEach(function (id) { $(id).textContent = '–'; });
$('toBands').disabled = true;
if (!(vs > 0) || !(vf > 0) || !(ma > 0)) { $('ledSay').textContent = 'Enter the supply voltage, the forward voltage and the current.'; return; }
if (vs > 24) { $('ledSay').textContent = 'This calculator stops at 24 V. Keep to low voltage, from batteries or a bench supply, and never work on mains.'; return; }
if (vs <= vf) { $('ledSay').textContent = 'The supply has to be above the LED’s forward voltage, or the LED barely lights, if at all. Use a higher supply or fewer LEDs in series.'; return; }
var i = ma / 1000, r = (vs - vf) / i, std = nextUp(r, list), ia = (vs - vf) / std, p = ia * ia * std, need = 2 * p;
var rating = RATINGS.filter(function (x) { return x[0] >= need; })[0];
ledStd = std;
$('rOut').textContent = fmt(r);
$('stdOut').textContent = fmt(std);
$('iOut').textContent = (ia * 1000).toFixed(1) + ' mA';
$('pOut').textContent = p < 0.01 ? (p * 1000).toFixed(1) + ' mW' : p.toFixed(3) + ' W';
$('toBands').disabled = false;
say.push('(' + vs + ' − ' + vf + ') V ÷ ' + ma + ' mA = ' + fmt(r) + '. The next ' + $('series').value + ' value up is ' + fmt(std) + ', which lets ' + (ia * 1000).toFixed(1) + ' mA through: a little under what you asked, never over.');
say.push('It turns ' + (p * 1000).toFixed(0) + ' mW into heat (I²R); ' + (rating ? 'with the usual margin of twice that, use a ' + rating[1] + ' resistor or larger.' : 'that is more than a small resistor can take: lower the supply or the current.'));
say.push('The LED itself takes ' + (vf * ia * 1000).toFixed(0) + ' mW.');
if (vs - vf < 1) say.push('Under a volt across the resistor leaves little headroom: the current will swing with the supply and with each LED.');
if (ma > 20) say.push('Above 20 mA: check the LED’s datasheet, as many 5 mm indicator LEDs are rated 20 mA continuous.');
$('ledSay').textContent = say.join(' ');
}
['vs', 'vf', 'ma', 'series'].forEach(function (id) { $(id).addEventListener('input', led); $(id).addEventListener('change', led); });
document.querySelectorAll('[data-vf]').forEach(function (b) { b.addEventListener('click', function () { $('vf').value = b.getAttribute('data-vf'); led(); }); });
$('toBands').addEventListener('click', function () {
if (!ledStd) return;
s.n = 4; s.bands = ['black', 'black', 'black', 'gold'];
setBands(ledStd, true);
show(0);
$('typeSay').textContent = 'The ' + fmt(ledStd) + ' resistor from the LED calculator, with a gold ±5% band, the commonest in a kit.';
tabs[0].focus();
});
document.addEventListener('know-tokens', function () { if (!$('panelCode').hidden) render(); });
var lastW = 0;
if (window.ResizeObserver) new ResizeObserver(function (en) { var w = Math.round(en[0].contentRect.width); if (w !== lastW) { lastW = w; requestAnimationFrame(function () { if (!$('panelCode').hidden) drawResistor(); }); } }).observe($('draw').parentNode);
buildPicks(); render(); led();
})();```element widget
{
"title": "Resistor colour codes and LED resistors",
"caption": "Read a four- or five-band resistor by picking its bands, or type a value to get its bands; then work out the current-limiting resistor for an LED, the next standard value up and the power it turns into heat. The page is printed in one ink, so each band is named rather than coloured. Colours follow IEC 60062; only the E12 and E24 series are checked, and the LED sum takes the forward voltage as fixed, which a real LED’s is not quite.",
"height": 560,
"html": "<div class=\"res\">\n <div class=\"tabs\" role=\"tablist\" aria-label=\"Tools\">\n <button type=\"button\" role=\"tab\" id=\"tabCode\" aria-selected=\"true\" aria-controls=\"panelCode\">Colour code</button>\n <button type=\"button\" role=\"tab\" id=\"tabLed\" aria-selected=\"false\" aria-controls=\"panelLed\" tabindex=\"-1\">LED resistor</button>\n </div>\n\n <section id=\"panelCode\" role=\"tabpanel\" aria-labelledby=\"tabCode\">\n <div class=\"count\" role=\"group\" aria-label=\"Number of bands\">\n <button type=\"button\" data-bands=\"4\" aria-pressed=\"true\">4 bands</button>\n <button type=\"button\" data-bands=\"5\" aria-pressed=\"false\">5 bands</button>\n </div>\n <svg id=\"draw\" role=\"img\" aria-label=\"Resistor\"></svg>\n <div class=\"picks\" id=\"picks\"></div>\n <dl class=\"figures\">\n <div><dt>Value</dt><dd id=\"valOut\">–</dd></div>\n <div><dt>Tolerance</dt><dd id=\"tolOut\">–</dd></div>\n <div><dt>Could measure</dt><dd id=\"rangeOut\">–</dd></div>\n </dl>\n <p class=\"say\" id=\"codeSay\" aria-live=\"polite\"></p>\n <div class=\"typein\">\n <label for=\"typed\">Or type a value</label>\n <div class=\"row\"><input id=\"typed\" type=\"text\" inputmode=\"decimal\" autocomplete=\"off\" spellcheck=\"false\" placeholder=\"4.7k, 4k7, 220, 1M\"><button type=\"button\" id=\"showBands\">Show bands</button></div>\n </div>\n <p class=\"say small\" id=\"typeSay\" aria-live=\"polite\"></p>\n </section>\n\n <section id=\"panelLed\" role=\"tabpanel\" aria-labelledby=\"tabLed\" hidden>\n <div class=\"inputs\">\n <label>Supply voltage, V<input id=\"vs\" type=\"number\" min=\"0\" max=\"24\" step=\"0.1\" value=\"9\"></label>\n <label>LED forward voltage, V<input id=\"vf\" type=\"number\" min=\"1\" max=\"4\" step=\"0.1\" value=\"2.0\"></label>\n <label>LED current, mA<input id=\"ma\" type=\"number\" min=\"1\" max=\"50\" step=\"1\" value=\"15\"></label>\n <label>Standard series<select id=\"series\"><option value=\"E12\" selected>E12</option><option value=\"E24\">E24</option></select></label>\n </div>\n <div class=\"presets\" role=\"group\" aria-label=\"Typical forward voltages\">\n <span>Typical LEDs:</span>\n <button type=\"button\" data-vf=\"2.0\">Red, 2.0 V</button>\n <button type=\"button\" data-vf=\"2.1\">Yellow, 2.1 V</button>\n <button type=\"button\" data-vf=\"3.2\">White or blue, 3.2 V</button>\n </div>\n <dl class=\"figures\">\n <div><dt>Resistor, worked out</dt><dd id=\"rOut\">–</dd></div>\n <div><dt>Next standard up</dt><dd id=\"stdOut\">–</dd></div>\n <div><dt>Current with it</dt><dd id=\"iOut\">–</dd></div>\n <div><dt>Power in the resistor</dt><dd id=\"pOut\">–</dd></div>\n </dl>\n <p class=\"say\" id=\"ledSay\" aria-live=\"polite\"></p>\n <p><button type=\"button\" id=\"toBands\">Read its bands</button></p>\n </section>\n</div>",
"css": ".res { font-family: var(--sans); }\n.tabs { display: flex; border-bottom: 1px solid var(--ink); margin-bottom: 12px; }\n.tabs button { flex: 0 0 auto; font: 500 14px/1 var(--sans); background: var(--paper); color: var(--ink-2); border: 0; border-bottom: 3px solid transparent; padding: 10px 14px 8px; min-height: 40px; }\n.tabs button[aria-selected='true'] { color: var(--ink); border-bottom-color: var(--ink); }\n.count { display: flex; gap: 6px; }\n.count button, .presets button, #toBands, .typein button { font: 500 13.5px/1 var(--sans); color: var(--ink); background: var(--paper); border: 1px solid var(--ink); padding: 9px 12px; min-height: 38px; }\n.count button[aria-pressed='true'] { background: var(--ink); color: var(--paper); }\n#draw { display: block; width: 100%; margin: 10px 0 4px; }\n.lead { stroke: var(--ink-2); stroke-width: 2.5; }\n.body { fill: var(--wash); stroke: var(--ink); stroke-width: 1.5; }\n.band { fill: var(--ink); }\n.bname { font: 500 11.5px var(--sans); fill: var(--ink); }\n.bno { font: 400 10.5px var(--sans); fill: var(--ink-3); }\n.tick { stroke: var(--ink-3); stroke-width: 1; }\n.picks { display: grid; grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); gap: 8px 12px; }\n.picks select { font-size: 13px; padding: 6px 4px; }\n.picks label { display: grid; gap: 3px; }\n.picks select, .inputs input, .inputs select { width: 100%; min-height: 36px; }\n.figures { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 0 18px; margin: 12px 0 0; border-top: 1px solid var(--ink); }\n.figures div { padding: 6px 0; border-bottom: 1px solid var(--rule); }\n.figures dt { font: 400 12.5px/1.3 var(--sans); color: var(--ink-3); }\n.figures dd { margin: 2px 0 0; font: 400 18px/1.25 var(--serif); color: var(--ink); font-variant-numeric: tabular-nums; }\n.say { margin: 8px 0 0; font: 400 15px/1.45 var(--serif); color: var(--ink); }\n.say.small { color: var(--ink-2); min-height: 1.45em; }\n.typein { margin: 12px 0 0; padding-top: 10px; border-top: 1px solid var(--rule); }\n.typein label { display: block; margin-bottom: 3px; }\n.row { display: flex; gap: 6px; }\n.row input { flex: 1; min-width: 0; font: 400 15px var(--mono); }\n.inputs { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 8px 12px; align-items: end; }\n.inputs label { display: grid; gap: 3px; }\n.inputs input { font-variant-numeric: tabular-nums; }\n.presets { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 10px; font: 400 13px var(--sans); color: var(--ink-2); }\n#toBands { margin-top: 4px; }\nbutton:focus-visible, input:focus-visible, select:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }",
"js": "(function () {\n var $ = function (id) { return document.getElementById(id); };\n // IEC 60062: digit, multiplier and tolerance for each colour.\n var C = {\n black: { name: 'Black', d: 0, m: 0 },\n brown: { name: 'Brown', d: 1, m: 1, t: 1 },\n red: { name: 'Red', d: 2, m: 2, t: 2 },\n orange: { name: 'Orange', d: 3, m: 3 },\n yellow: { name: 'Yellow', d: 4, m: 4 },\n green: { name: 'Green', d: 5, m: 5, t: 0.5 },\n blue: { name: 'Blue', d: 6, m: 6, t: 0.25 },\n violet: { name: 'Violet', d: 7, m: 7, t: 0.1 },\n grey: { name: 'Grey', d: 8, m: 8 },\n white: { name: 'White', d: 9, m: 9 },\n gold: { name: 'Gold', m: -1, t: 5 },\n silver: { name: 'Silver', m: -2, t: 10 }\n };\n var DIGITS = ['black', 'brown', 'red', 'orange', 'yellow', 'green', 'blue', 'violet', 'grey', 'white'];\n var MULTS = DIGITS.concat(['gold', 'silver']);\n var TOLS = ['brown', 'red', 'green', 'blue', 'violet', 'gold', 'silver'];\n var E12 = [10, 12, 15, 18, 22, 27, 33, 39, 47, 56, 68, 82];\n var E24 = [10, 11, 12, 13, 15, 16, 18, 20, 22, 24, 27, 30, 33, 36, 39, 43, 47, 51, 56, 62, 68, 75, 82, 91];\n var RATINGS = [[0.125, '1/8 W'], [0.25, '1/4 W'], [0.5, '1/2 W'], [1, '1 W'], [2, '2 W']];\n var s = { n: 4, bands: ['yellow', 'violet', 'red', 'gold'] };\n var multNames = { '-2': '× 0.01', '-1': '× 0.1', '0': '× 1', '1': '× 10', '2': '× 100', '3': '× 1k', '4': '× 10k', '5': '× 100k', '6': '× 1M', '7': '× 10M', '8': '× 100M', '9': '× 1G' };\n\n function fmt(v) {\n var u = [[1e9, ' GΩ'], [1e6, ' MΩ'], [1e3, ' kΩ'], [1, ' Ω']], i;\n for (i = 0; i < u.length; i++) if (v >= u[i][0] * (1 - 1e-9) || i === u.length - 1) return String(parseFloat((v / u[i][0]).toPrecision(4))) + u[i][1];\n }\n function roles(n) { return n === 4 ? ['digit', 'digit', 'mult', 'tol'] : ['digit', 'digit', 'digit', 'mult', 'tol']; }\n function roleLabel(r, i) { return r === 'digit' ? ['1st', '2nd', '3rd'][i] + ' digit' : r === 'mult' ? 'Multiplier' : 'Tolerance'; }\n function listFor(r, i) { return r === 'digit' ? (i === 0 ? DIGITS.slice(1) : DIGITS) : r === 'mult' ? MULTS : TOLS; }\n function optText(key, r) { var c = C[key]; return c.name + ' ' + (r === 'digit' ? c.d : r === 'mult' ? multNames[c.m].replace(' ', '') : '±' + c.t + '%'); }\n\n function read() {\n var r = roles(s.n), digits = 0, exp = 0, tol = 0;\n s.bands.forEach(function (b, i) {\n if (r[i] === 'digit') digits = digits * 10 + C[b].d;\n else if (r[i] === 'mult') exp = C[b].m;\n else tol = C[b].t;\n });\n return { v: parseFloat((digits * Math.pow(10, exp)).toPrecision(6)), tol: tol, digits: digits, exp: exp };\n }\n\n function mantissa(v) { var d = Math.pow(10, Math.floor(Math.log10(v) + 1e-9) - 1); return { m: Math.round(v / d * 1000) / 1000, d: d }; }\n function inSeries(v, list) { var m = mantissa(v).m; return list.some(function (e) { return Math.abs(e - m) < 1e-6; }); }\n function neighbours(v, list) {\n var d = Math.pow(10, Math.floor(Math.log10(v) + 1e-9) - 1), c = [];\n [d / 10, d, d * 10].forEach(function (k) { list.forEach(function (e) { c.push(parseFloat((e * k).toPrecision(6))); }); });\n var below = c.filter(function (x) { return x <= v; }).pop(), above = c.filter(function (x) { return x >= v; })[0];\n return [below, above];\n }\n function nextUp(v, list) {\n var d = Math.pow(10, Math.floor(Math.log10(v) + 1e-9) - 1), c = [];\n [d, d * 10, d * 100].forEach(function (k) { list.forEach(function (e) { c.push(parseFloat((e * k).toPrecision(6))); }); });\n return c.filter(function (x) { return x >= v * (1 - 1e-9); })[0];\n }\n\n // The fewest significant figures that carry the value: 2 on four bands, 3 on five.\n function bandsFor(v, n) {\n var sig = n - 2, lo = Math.pow(10, sig - 1), hi = Math.pow(10, sig) - 1;\n for (var e = -2; e <= 9; e++) {\n var x = v / Math.pow(10, e), r = Math.round(x);\n if (r >= lo && r <= hi && Math.abs(x - r) < 1e-6 * x) {\n var ds = String(r).split('').map(function (ch) { return DIGITS[Number(ch)]; });\n return ds.concat([MULTS.filter(function (k) { return C[k].m === e; })[0]]);\n }\n }\n return null;\n }\n\n function parse(text) {\n var t = String(text).replace(/\\s+/g, '').replace(/(Ω|ohms?)$/i, '');\n var m = /^(\\d*)([rRkKmMgG])(\\d+)$/.exec(t), k = { r: 1, k: 1e3, m: 1e6, g: 1e9 };\n if (m && (m[1] || m[3])) return parseFloat((m[1] || '0') + '.' + m[3]) * k[m[2].toLowerCase()];\n m = /^(\\d+(?:\\.\\d+)?|\\.\\d+)([rRkKmMgG]?)$/.exec(t);\n if (m) return parseFloat(m[1]) * (m[2] ? k[m[2].toLowerCase()] : 1);\n return null;\n }\n\n function buildPicks() {\n var r = roles(s.n), box = $('picks');\n box.innerHTML = r.map(function (role, i) {\n return '<label>Band ' + (i + 1) + ', ' + roleLabel(role, i).toLowerCase() + '<select data-i=\"' + i + '\">' + listFor(role, i).map(function (k) {\n return '<option value=\"' + k + '\"' + (s.bands[i] === k ? ' selected' : '') + '>' + optText(k, role) + '</option>';\n }).join('') + '</select></label>';\n }).join('');\n box.querySelectorAll('select').forEach(function (sel) {\n sel.addEventListener('change', function () { s.bands[Number(sel.getAttribute('data-i'))] = sel.value; $('typeSay').textContent = ''; render(); });\n });\n document.querySelectorAll('[data-bands]').forEach(function (b) { b.setAttribute('aria-pressed', String(Number(b.getAttribute('data-bands')) === s.n)); });\n }\n\n function drawResistor() {\n var svg = $('draw'), W = Math.max(260, Math.round(svg.getBoundingClientRect().width) || 588), narrow = W < 440;\n var H = narrow ? 118 : 96, cy = narrow ? 58 : 40, bx = W * 0.14, bw = W * 0.72, bh = 42;\n var pos = s.n === 4 ? [0.16, 0.3, 0.44, 0.84] : [0.14, 0.26, 0.38, 0.5, 0.86], w = Math.max(9, bw * 0.055), out = [];\n svg.setAttribute('viewBox', '0 0 ' + W + ' ' + H); svg.setAttribute('height', H);\n out.push('<line class=\"lead\" x1=\"0\" x2=\"' + bx + '\" y1=\"' + cy + '\" y2=\"' + cy + '\"/><line class=\"lead\" x1=\"' + (bx + bw) + '\" x2=\"' + W + '\" y1=\"' + cy + '\" y2=\"' + cy + '\"/>');\n var y0 = cy - bh / 2, sh = bw * 0.09;\n out.push('<path class=\"body\" d=\"M' + bx + ' ' + (y0 + 6) + 'Q' + bx + ' ' + y0 + ' ' + (bx + 8) + ' ' + y0 + 'H' + (bx + sh) + 'L' + (bx + sh + 6) + ' ' + (y0 + 5) + 'H' + (bx + bw - sh - 6) + 'L' + (bx + bw - sh) + ' ' + y0 + 'H' + (bx + bw - 8) + 'Q' + (bx + bw) + ' ' + y0 + ' ' + (bx + bw) + ' ' + (y0 + 6) + 'V' + (y0 + bh - 6) + 'Q' + (bx + bw) + ' ' + (y0 + bh) + ' ' + (bx + bw - 8) + ' ' + (y0 + bh) + 'H' + (bx + bw - sh) + 'L' + (bx + bw - sh - 6) + ' ' + (y0 + bh - 5) + 'H' + (bx + sh + 6) + 'L' + (bx + sh) + ' ' + (y0 + bh) + 'H' + (bx + 8) + 'Q' + bx + ' ' + (y0 + bh) + ' ' + bx + ' ' + (y0 + bh - 6) + 'Z\"/>');\n s.bands.forEach(function (b, i) {\n var x = bx + bw * pos[i], inner = x > bx + sh && x < bx + bw - sh, top = inner ? y0 + 5 : y0, bot = inner ? y0 + bh - 5 : y0 + bh;\n out.push('<rect class=\"band\" x=\"' + (x - w / 2) + '\" y=\"' + top + '\" width=\"' + w + '\" height=\"' + (bot - top) + '\"/>');\n var up = narrow && i % 2 === 1, ty = up ? y0 - 10 : y0 + bh + 16;\n out.push('<line class=\"tick\" x1=\"' + x + '\" x2=\"' + x + '\" y1=\"' + (up ? y0 - 6 : y0 + bh + 2) + '\" y2=\"' + (up ? y0 - 1 : y0 + bh + 5) + '\"/>');\n out.push('<text class=\"bname\" x=\"' + x + '\" y=\"' + ty + '\" text-anchor=\"middle\">' + C[b].name + '</text>');\n if (!narrow) out.push('<text class=\"bno\" x=\"' + x + '\" y=\"' + (ty + 14) + '\" text-anchor=\"middle\">' + (i + 1) + '</text>');\n });\n svg.innerHTML = out.join('');\n var r = read();\n svg.setAttribute('aria-label', s.n + '-band resistor, read from the left: ' + s.bands.map(function (b) { return C[b].name.toLowerCase(); }).join(', ') + '. ' + fmt(r.v) + ', plus or minus ' + r.tol + ' per cent.');\n }\n\n function render() {\n drawResistor();\n var r = read(), names = s.bands.map(function (b) { return C[b].name.toLowerCase(); });\n $('valOut').textContent = fmt(r.v);\n $('tolOut').textContent = '±' + r.tol + '%';\n var lo = fmt(r.v * (1 - r.tol / 100)), hi = fmt(r.v * (1 + r.tol / 100)), ul = lo.split(' ')[1], uh = hi.split(' ')[1];\n $('rangeOut').textContent = ul === uh ? lo.split(' ')[0] + ' to ' + hi : lo + ' to ' + hi;\n var series = inSeries(r.v, E12) ? 'It is an E12 value, so also in E24.' : inSeries(r.v, E24) ? 'It is an E24 value, not in E12.' : (function () { var nb = neighbours(r.v, E24); return 'Not an E12 or E24 value (five-band parts often come from E96); the nearest E24 values are ' + fmt(nb[0]) + ' and ' + fmt(nb[1]) + '.'; })();\n var sentence = names.slice(0, s.n - 2).map(function (n, i) { return C[s.bands[i]].d; }).join('');\n $('codeSay').textContent = names.join(', ') + ': ' + sentence + ' ' + multNames[r.exp] + ' = ' + fmt(r.v) + ', ±' + r.tol + '%. ' + series;\n }\n\n function setBands(v, keepSay) {\n var four = bandsFor(v, 4), five = bandsFor(v, 5), say = $('typeSay');\n if (!four && !five) { say.textContent = fmt(v) + ' needs more significant figures than colour bands carry (two on four bands, three on five), or lies outside 0.1 Ω to 999 GΩ.'; return false; }\n var tol = s.bands[s.bands.length - 1], keep = TOLS.indexOf(tol) >= 0 && s.n === (four ? 4 : 5);\n if (four) { s.n = 4; s.bands = four.concat([keep ? tol : 'gold']); }\n else { s.n = 5; s.bands = five.concat([keep ? tol : 'brown']); }\n buildPicks(); render();\n if (!keepSay) say.textContent = four && five ? 'On a 1% five-band part the same value reads ' + five.map(function (k) { return C[k].name.toLowerCase(); }).join(', ') + ', brown.' : four ? '' : 'Three significant figures: this value needs five bands.';\n return true;\n }\n\n function typed() {\n var v = parse($('typed').value);\n if (v === null || !(v > 0)) { $('typeSay').textContent = 'Type a value such as 4.7k, 4k7, 220, 0.47 or 1M.'; return; }\n setBands(v);\n }\n $('showBands').addEventListener('click', typed);\n $('typed').addEventListener('keydown', function (e) { if (e.key === 'Enter') { e.preventDefault(); typed(); } });\n document.querySelectorAll('[data-bands]').forEach(function (b) {\n b.addEventListener('click', function () {\n var n = Number(b.getAttribute('data-bands')); if (n === s.n) return;\n var v = read().v, next = bandsFor(v, n);\n s.n = n;\n s.bands = next ? next.concat([n === 4 ? 'gold' : 'brown']) : (n === 4 ? ['brown', 'black', 'red', 'gold'] : ['brown', 'black', 'black', 'brown', 'brown']);\n $('typeSay').textContent = next ? '' : fmt(v) + ' cannot be written on ' + n + ' bands, so they start again at 1 kΩ.';\n buildPicks(); render();\n });\n });\n\n // Tabs, with arrow keys between them.\n var tabs = [$('tabCode'), $('tabLed')];\n function show(i) {\n tabs.forEach(function (t, j) { t.setAttribute('aria-selected', String(i === j)); t.tabIndex = i === j ? 0 : -1; $(t.getAttribute('aria-controls')).hidden = i !== j; });\n if (i === 0) render(); else led();\n }\n tabs.forEach(function (t, i) {\n t.addEventListener('click', function () { show(i); });\n t.addEventListener('keydown', function (e) { if (e.key === 'ArrowRight' || e.key === 'ArrowLeft') { var j = (i + 1) % 2; show(j); tabs[j].focus(); e.preventDefault(); } });\n });\n\n // LED: R = (Vs − Vf) ÷ I, then the next standard value up, and what it dissipates.\n var ledStd = null;\n function led() {\n var vs = parseFloat($('vs').value), vf = parseFloat($('vf').value), ma = parseFloat($('ma').value), list = $('series').value === 'E24' ? E24 : E12, say = [];\n ledStd = null;\n ['rOut', 'stdOut', 'iOut', 'pOut'].forEach(function (id) { $(id).textContent = '–'; });\n $('toBands').disabled = true;\n if (!(vs > 0) || !(vf > 0) || !(ma > 0)) { $('ledSay').textContent = 'Enter the supply voltage, the forward voltage and the current.'; return; }\n if (vs > 24) { $('ledSay').textContent = 'This calculator stops at 24 V. Keep to low voltage, from batteries or a bench supply, and never work on mains.'; return; }\n if (vs <= vf) { $('ledSay').textContent = 'The supply has to be above the LED’s forward voltage, or the LED barely lights, if at all. Use a higher supply or fewer LEDs in series.'; return; }\n var i = ma / 1000, r = (vs - vf) / i, std = nextUp(r, list), ia = (vs - vf) / std, p = ia * ia * std, need = 2 * p;\n var rating = RATINGS.filter(function (x) { return x[0] >= need; })[0];\n ledStd = std;\n $('rOut').textContent = fmt(r);\n $('stdOut').textContent = fmt(std);\n $('iOut').textContent = (ia * 1000).toFixed(1) + ' mA';\n $('pOut').textContent = p < 0.01 ? (p * 1000).toFixed(1) + ' mW' : p.toFixed(3) + ' W';\n $('toBands').disabled = false;\n say.push('(' + vs + ' − ' + vf + ') V ÷ ' + ma + ' mA = ' + fmt(r) + '. The next ' + $('series').value + ' value up is ' + fmt(std) + ', which lets ' + (ia * 1000).toFixed(1) + ' mA through: a little under what you asked, never over.');\n say.push('It turns ' + (p * 1000).toFixed(0) + ' mW into heat (I²R); ' + (rating ? 'with the usual margin of twice that, use a ' + rating[1] + ' resistor or larger.' : 'that is more than a small resistor can take: lower the supply or the current.'));\n say.push('The LED itself takes ' + (vf * ia * 1000).toFixed(0) + ' mW.');\n if (vs - vf < 1) say.push('Under a volt across the resistor leaves little headroom: the current will swing with the supply and with each LED.');\n if (ma > 20) say.push('Above 20 mA: check the LED’s datasheet, as many 5 mm indicator LEDs are rated 20 mA continuous.');\n $('ledSay').textContent = say.join(' ');\n }\n ['vs', 'vf', 'ma', 'series'].forEach(function (id) { $(id).addEventListener('input', led); $(id).addEventListener('change', led); });\n document.querySelectorAll('[data-vf]').forEach(function (b) { b.addEventListener('click', function () { $('vf').value = b.getAttribute('data-vf'); led(); }); });\n $('toBands').addEventListener('click', function () {\n if (!ledStd) return;\n s.n = 4; s.bands = ['black', 'black', 'black', 'gold'];\n setBands(ledStd, true);\n show(0);\n $('typeSay').textContent = 'The ' + fmt(ledStd) + ' resistor from the LED calculator, with a gold ±5% band, the commonest in a kit.';\n tabs[0].focus();\n });\n\n document.addEventListener('know-tokens', function () { if (!$('panelCode').hidden) render(); });\n var lastW = 0;\n if (window.ResizeObserver) new ResizeObserver(function (en) { var w = Math.round(en[0].contentRect.width); if (w !== lastW) { lastW = w; requestAnimationFrame(function () { if (!$('panelCode').hidden) drawResistor(); }); } }).observe($('draw').parentNode);\n\n buildPicks(); render(); led();\n})();"
}
```Electronics 101No. 5
Lab 5 — The 555 timermaking an LED blink
9 sections, 1,820 words, about 8 minutes, filed 30 August, revised 24 September, 3 highlights.
An NE555 wired as an astable oscillator flashes a red LED from a 9 V battery, about once every one and a half seconds. Students build it from the words in The circuit in words, time ten flashes with a stopwatch, and compare the result with the formula.
Parts for the 555 blinker, one kit per pair
| P | M | W |
|---|---|---|
| U1, NE555 timer | Notch or dot at pin 1 | Notch to the left |
| R1, 1 kΩ | Brown, black, red, gold | Either |
| R2, 10 kΩ | Brown, black, orange, gold | Either |
| R3, 470 Ω, for the LED | Yellow, violet, brown, gold | Either |
| C1, 100 µF, 16 V or more | Stripe marks negative | Negative to the rail |
| C2, 10 nF | 103 | Either |
| LED1, red, 5 mm | Flat edge, short leg | Cathode to the rail |
| Supply, 9 V battery | Red lead positive | Connect last |
With R1 = 1 kΩ, R2 = 10 kΩ and C1 = 100 µF, the LED is on for about 0.76 s and off for about 0.69 s.
Parts for the 555 blinker, one kit per pair
| P | M | W |
|---|---|---|
| U1, NE555 timer | Notch or dot at pin 1 | Notch to the left |
| R1, 1 kΩ | Brown, black, red, gold | Either |
| R2, 10 kΩ | Brown, black, orange, gold | Either |
| R3, 470 Ω, for the LED | Yellow, violet, brown, gold | Either |
| C1, 100 µF, 16 V or more | Stripe marks negative | Negative to the rail |
| C2, 10 nF | 103 | Either |
| LED1, red, 5 mm | Flat edge, short leg | Cathode to the rail |
| Supply, 9 V battery | Red lead positive | Connect last |
With R1 = 1 kΩ, R2 = 10 kΩ and C1 = 100 µF, the LED is on for about 0.76 s and off for about 0.69 s.
```element table
{
"caption": "Parts for the 555 blinker, one kit per pair",
"columns": [
{
"label": "P",
"align": "left"
},
{
"label": "M",
"align": "left"
},
{
"label": "W",
"align": "left"
}
],
"rows": [
[
"U1, NE555 timer",
"Notch or dot at pin 1",
"Notch to the left"
],
[
"R1, 1 kΩ",
"Brown, black, red, gold",
"Either"
],
[
"R2, 10 kΩ",
"Brown, black, orange, gold",
"Either"
],
[
"R3, 470 Ω, for the LED",
"Yellow, violet, brown, gold",
"Either"
],
[
"C1, 100 µF, 16 V or more",
"Stripe marks negative",
"Negative to the rail"
],
[
"C2, 10 nF",
"103",
"Either"
],
[
"LED1, red, 5 mm",
"Flat edge, short leg",
"Cathode to the rail"
],
[
"Supply, 9 V battery",
"Red lead positive",
"Connect last"
]
],
"notes": "With R1 = 1 kΩ, R2 = 10 kΩ and C1 = 100 µF, the LED is on for about 0.76 s and off for about 0.69 s."
}
```The battery goes on last, after the teacher has looked at the board.
Sections
- 1The circuit in wordsObservation, keyPins 8 and 4 to the positive rail, pin 1 to the negative. R1 from positive to pin 7, R2 from pin 7 to pins 6 and 2, joined; C1 from pin 2 to negative.
- 2Hazard: short circuit across the batteryRisk, keyA wire straight across the rails heats fast. Battery on last, off first, and never in a pocket with coins or keys.
- 3Hazard: electrolytic capacitor the wrong way roundRisk, keyReversed or over its voltage, it can swell and vent. Stripe to the negative rail; check before the battery goes on.
- 4Place the 555 across the centre gapNotch to the left, pins 1 to 4 along the bottom row, pins 5 to 8 along the top, counting anticlockwise from the notch.
- 5Time ten flashesStart the stopwatch on a flash and stop it on the eleventh; divide by ten. Expected: about 1.45 s per flash.
- 6LED lights but never goes outProblem, 1 notePins 2 and 6 not joined, so the timer never resets. Found on three boards in the first session.
- 7QuestionsQuestion, 4 questionsWhat happens to the flash if R2 is doubled? Why is the LED on for longer than it is off?
and 2 more sections
Electronics 101Lab 3 — LEDs, and the resistor that keeps them alive
6of 8
Expected resultsan LED is not a resistor
Evidence, key section, 1 highlight, 164 words
My readings on the bench, 12 September, with the kit’s bench supply and one multimeter moved between current and voltage. The resistor is the 1 kΩ from the kit; the LED is the 5 mm red, in series with 330 Ω, with the voltage measured across the LED alone.
Current against voltage for a 1 kΩ resistor and a red LED
| Point | Voltage across the part | Current | Group |
|---|---|---|---|
| Point 1 | 1 V | 1.02 mA | 1 kΩ resistor |
| Point 2 | 2 V | 2.03 mA | 1 kΩ resistor |
| Point 3 | 3 V | 3.05 mA | 1 kΩ resistor |
| Point 4 | 4 V | 4.07 mA | 1 kΩ resistor |
| Point 5 | 5 V | 5.09 mA | 1 kΩ resistor |
| Point 6 | 1.6 V | 0.01 mA | Red LED |
| Point 7 | 1.7 V | 0.2 mA | Red LED |
| Point 8 | 1.8 V | 1.5 mA | Red LED |
| Point 9 | 1.85 V | 3.4 mA | Red LED |
| Point 10 | 1.9 V | 6.2 mA | Red LED |
| Red LED, 10 mA at 1.95 V | 1.95 V | 10.1 mA | Red LED |
Bench readings, 12 September; the resistor measures 983 Ω.
Current against voltage for a 1 kΩ resistor and a red LED
Voltage across the part is drawn from 0 V to 5 V.
Current is drawn from 0 mA to 12 mA.
| Point | Voltage across the part | Current | Group |
|---|---|---|---|
| Point 1 | 1 V | 1.02 mA | 1 kΩ resistor |
| Point 2 | 2 V | 2.03 mA | 1 kΩ resistor |
| Point 3 | 3 V | 3.05 mA | 1 kΩ resistor |
| Point 4 | 4 V | 4.07 mA | 1 kΩ resistor |
| Point 5 | 5 V | 5.09 mA | 1 kΩ resistor |
| Point 6 | 1.6 V | 0.01 mA | Red LED |
| Point 7 | 1.7 V | 0.2 mA | Red LED |
| Point 8 | 1.8 V | 1.5 mA | Red LED |
| Point 9 | 1.85 V | 3.4 mA | Red LED |
| Point 10 | 1.9 V | 6.2 mA | Red LED |
| Red LED, 10 mA at 1.95 V | 1.95 V | 10.1 mA | Red LED |
Source: Bench readings, 12 September; the resistor measures 983 Ω.
```element scatter
{
"caption": "Current against voltage for a 1 kΩ resistor and a red LED",
"xLabel": "Voltage across the part",
"xUnits": "V",
"xMin": 0,
"xMax": 5,
"yLabel": "Current",
"yUnits": "mA",
"yMin": 0,
"yMax": 12,
"points": [
{
"x": 1,
"y": 1.02,
"group": "1 kΩ resistor"
},
{
"x": 2,
"y": 2.03,
"group": "1 kΩ resistor"
},
{
"x": 3,
"y": 3.05,
"group": "1 kΩ resistor"
},
{
"x": 4,
"y": 4.07,
"group": "1 kΩ resistor"
},
{
"x": 5,
"y": 5.09,
"group": "1 kΩ resistor"
},
{
"x": 1.6,
"y": 0.01,
"group": "Red LED"
},
{
"x": 1.7,
"y": 0.2,
"group": "Red LED"
},
{
"x": 1.8,
"y": 1.5,
"group": "Red LED"
},
{
"x": 1.85,
"y": 3.4,
"group": "Red LED"
},
{
"x": 1.9,
"y": 6.2,
"group": "Red LED"
},
{
"x": 1.95,
"y": 10.1,
"label": "Red LED, 10 mA at 1.95 V",
"group": "Red LED"
}
],
"source": "Bench readings, 12 September; the resistor measures 983 Ω."
}
```The resistor’s points lie on a straight line through zero: double the voltage, double the current, which is Ohm’s law. The LED passes almost nothing below 1.7 V, then its current climbs steeply over a tenth of a volt. Nothing in the LED itself limits the current, so a series resistor has to.
How it works
Take a class from Ohm’s law to a blinking 555 timer. Each lab lists its parts, describes the circuit pin by pin and ends with a measurement table. Beside the LED lab sits a calculator: pick a resistor’s bands to read its value, or enter a supply and an LED to get the resistor that keeps it alive.