EMBEDOSTOOLS TOOLSEM·LINKDOCS

EM·LINK

Universal Device Terminal - a single HTML file that talks to devices over USB serial or WiFi (WebSocket or MQTT over WebSocket), decodes industrial protocols, plots telemetry, and carries a suite of engineering calculators.

No install. No account. No server. Nothing you connect to, capture or calculate leaves your machine.

EM·LINK with the simulator running on the Ocean theme
EM·LINK with the simulator running on the Ocean theme


Quick start

  1. Open EM·LINK in a modern browser. For USB serial use desktop Chrome or Edge, which provide

the Web Serial API; WebSocket, MQTT, the simulator and the tools work in any modern browser.

  1. Pick a transport in the sidebar.
  2. Press CONNECT.

No hardware to hand? Choose SIMULATOR and connect. It streams synthetic telemetry, ANSI-coloured log lines, GNSS sentences, Modbus RTU frames and J1939 CAN frames, so every feature can be explored with nothing plugged in.

If you see a red banner

USB serial uses the Web Serial API, which needs a secure context and a desktop Chromium-based browser (Chrome or Edge). Opening the file directly with file:// works in some browser builds and not others. If the banner appears in Chrome or Edge, serve the file over local HTTP instead:

python3 -m http.server 8000

localhost counts as secure, so everything works from there. On phones, Safari and Firefox the banner says USB serial is not available there and the USB SERIAL option is greyed out; WebSocket, MQTT, the simulator and every tool still work.

Browser support

FeatureDesktop Chrome / EdgeSafari, Firefox, phones
USB Serialyesnot available
WebSocket · MQTTyesyes
Tools · plotter · decodersyesyes

USB serial needs the Web Serial API, which not every browser family implements. Everything else - the tool suite, the decoders, the plotter, the docs - works in any modern browser.

Themes

Three: OCEAN (navy + blue), SIGNAL (near-black + orange), and FIELD (light, for projectors and well-lit rooms). The choice persists across visits.

Signal theme - heads-down debugging
Signal theme - heads-down debugging

Field theme - for projectors or bright control rooms
Field theme - for projectors or bright control rooms


Transports

Three links and a simulator, one interface. Everything downstream - terminal, plotter, decoders, logging, file transfer - behaves identically no matter which you pick.

USB Serial

Uses the Web Serial API. Click CONNECT and the browser shows its own port picker; the page never sees ports you have not explicitly granted.

Granted ports appear in PREVIOUSLY GRANTED on later visits, so you can reconnect without the picker. ⟳ REFRESH PORTS re-reads that list.

Auto-baud detection

Select ◈ AUTO DETECT. The scan opens each rate from fastest to slowest, listens for about 1.1 s, and prints what it found:

AUTO-DETECT: scanning 17 rates for "BOOTING"…
   1500000 → 0 B, printable 0%
    921600 → 43 B, printable 12%
    115200 → 512 B, printable 99%
AUTO-DETECT: matched "BOOTING" at 115200.

Give it a search word of six characters or more taken from your boot banner and it stops on the first exact match. Leave the word blank and it falls back to picking the rate with the highest proportion of printable bytes. The full scan table is printed either way, so you can judge the result rather than trust it.

WiFi - WebSocket

Point it at a device running a WebSocket server. A few lines of firmware get you a bidirectional link with no relay and no cloud.

Binary and text frames are both accepted and handed to the terminal as bytes.

Mixed content: a page served over https:// may only open wss://. If you serve EM·LINK over HTTPS and your device speaks plain ws://, the browser blocks it. Open EM·LINK over http://localhost instead, or terminate TLS at the device.

WiFi - MQTT over WebSocket

Subscribes to a topic and prints each message as a line; transmitting publishes to a second topic.

The broker must expose a WebSocket listener - the plain 1883 TCP port will not work from a browser. A typical broker configuration:

listener 9001
protocol websockets

PREFIX LINES WITH TOPIC puts [embedos/plant1/telemetry] in front of each message, which matters when a wildcard subscription is pulling from many devices at once.

The MQTT client library is fetched from a CDN on first use, so this transport needs internet access even when the broker is local.

Simulator

Generates a synthetic device: boot messages with ANSI colour, four telemetry channels, periodic WARN and ERROR lines, checksum-valid GNSS sentences, CRC-valid Modbus RTU frames and J1939 CAN frames. Transmitted commands are echoed back with ACK.


Terminal

Display formats

Switching format changes only the display. Line counting, plotting and every decoder keep running on the byte stream underneath, so nothing is lost by looking at hex for a while.

ANSI / VT100

With ANSI / VT100 COLOUR on, the terminal handles:

than scrolling off the screen

Turn ANSI off to see the raw escape sequences, which is the faster way to debug firmware that is emitting them incorrectly.

UTF-8

UTF-8 DECODE uses a streaming decoder that keeps multi-byte sequences intact across chunk boundaries - without it, a → arriving split across two reads renders as â. Turn it off for strictly binary or latin-1 protocols.

Raw keyboard mode

RAW KEYBOARD (INTERACTIVE) sends keystrokes straight down the link instead of using the transmit box. This is what makes interactive serial consoles (a bootloader prompt, a Linux login shell, an AT command shell) usable:

KeySends
Ctrl+A … Ctrl+Z0x01 … 0x1A, so ^C, ^D, ^Z all work
ArrowsESC[A ESC[B ESC[C ESC[D
Home / EndESC[H / ESC[F
Delete / PgUp / PgDnESC[3~ / ESC[5~ / ESC[6~
Tab / Escape0x09 / 0x1B
Backspace^? (127) or ^H (8) - configurable

Pasting sends the clipboard contents down the link. Click into the terminal first so the transmit box does not have focus.

BACKSPACE SENDS exists because the two conventions are genuinely split: most Unix-like systems expect ^?, while many embedded monitors and older systems expect ^H. If backspace prints ^H or deletes the wrong character, switch it.

Other terminal options

Transmit

Type into the transmit box and press Enter. ↑ / ↓ walk command history.

TX LINE ENDING appends LF, CR, CRLF or nothing. AT-command modems generally want CR; Unix shells want LF; many industrial devices want CRLF.

MACROS are four editable command buttons, saved in the browser.


Plotter

Any line containing KEY: value or KEY = value becomes a plot channel automatically:

TEMP0: 24.5
PRESSURE = 3.412
RPM: 1670

The plotter with two viewports, one per group of channels
The plotter with two viewports, one per group of channels

GRAPH opens the plot area; + VIEWPORT adds another. Each viewport has:

When to use NORM

A shared Y axis is useless the moment magnitudes differ. Plot TEMP: 24 next to heap=27811 and the temperature is a flat line at the bottom. NORM maps each channel onto its own range so you can compare shape - when things move together, which leads which - rather than absolute value. Turn it off to read real numbers.


Decoders

GNSS / NMEA

Parses RMC, GGA, GSA, GSV, GLL, VTG and TXT with checksum validation. Invalid sentences are dropped silently rather than corrupting the fix.

GPS POPUP opens a draggable panel with a live map and track trail, position, altitude, speed, fix type, satellite count, HDOP, UTC, a course-over-ground compass and per-satellite SNR bars. ⧉ copies the coordinates.

The map uses OpenStreetMap tiles. With no internet it falls back to a self-drawn track plot with a scale grid, so the trail is still visible offline.

Modbus RTU

The Modbus RTU decoder pulling frames out of a live stream
The Modbus RTU decoder pulling frames out of a live stream

RTU has no start delimiter. Frames are separated only by an idle gap of at least 3.5 character times, which is why naive decoders produce garbage on a busy or mixed line.

This decoder does what a protocol analyser does:

  1. For each position in the buffer, work out which ADU lengths the function code permits - a

read-holding-registers request is 8 bytes, its response is 3 + byte_count + 2, an exception is 5.

  1. Test CRC-16 on each candidate length.
  2. On a match, emit the frame and jump past it. On no match, slide one byte and try again.

The result resyncs on a noisy bus and pulls valid frames out of a stream that also carries ASCII logging. Frames whose CRC fails are only reported if they at least look like an ADU - a valid slave address and a known function code - so random text does not fill the table.

Decoded function codes: 1, 2, 3, 4, 5, 6, 7, 8, 11, 12, 15, 16, 17, 20, 21, 22, 23, 43, plus all exception responses by name.

MODBUS FRAME GAP sets the idle timeout used to flush the tail of the buffer. Six milliseconds suits 9600–115200 baud; raise it on slow links.

CAN / J1939

Accepts two text formats, auto-detected:

t1238001122334455667788          SLCAN, 11-bit
T0CF004008F07D7D1027000000       SLCAN, 29-bit
  can0  18FEE500   [8]  10 27 00 00 50 C3 00 00
(1707.123) can0 0CF00400#F07D7D1027000000

29-bit identifiers are decoded to priority, data page, PDU format, PDU specific, PGN, source address and destination address per J1939.

GROUP BY ID collapses the table to one row per identifier with a message counter, which is how you read a live bus. Turn it off for a chronological trace.


Files

A local file store backed by IndexedDB. Files live in your browser and are never uploaded.

Captured session logs and converted firmware images land here too.

XMODEM

Implements XMODEM with 128-byte blocks and either CRC-16 or the simple checksum, chosen by whatever the other end asks for. Both directions are supported.

Sending: start the receiver on the target first (rx filename or your bootloader's equivalent), then pick the file. EM·LINK waits for the receiver's C or NAK handshake, then streams blocks, retrying any the receiver rejects. Progress shows in the bar at the bottom.

Receiving: click ◈ XMODEM RECEIVE, name the file, then start the sender on the target. EM·LINK sends C every three seconds until the transfer begins, and saves the result to the file store when it sees EOT.


Logging and export

Log modes

ModeCaptures
All session outputevery line, as displayed
Printable output onlystrips control characters
Raw hex dumpoffset, hex bytes, ASCII gutter
Nonenothing

AUTO-CAPTURE TO FILE STORE saves the log automatically when the link closes.

Exports

EXPORT or Ctrl+S:

FormatContents
.txtsession log with a header of link details and counters
plot .csvwide table, one column per channel, forward-filled to a shared time axis
Modbus .csvevery decoded frame with CRC status and raw bytes
CAN .csvevery frame with ID, PGN, source address, DLC and data bytes

The plot CSV is deliberately a wide table - one row per timestamp, one column per channel, values forward-filled. That form drops straight into a spreadsheet or data-frame library without reshaping.


Sessions

A named session profile stores every transport setting, decoder toggle, terminal option, theme and macro. SAVE AS creates one, LOAD restores it, ⚙ MANAGE SESSIONS lists, overwrites, deletes, exports and imports them.

Export produces a JSON file you can commit to a repo or hand to a colleague, so a whole team can share the exact settings for a given rig.

Passwords are not stored in session profiles.

Keyboard shortcuts

ShortcutAction
Ctrl+Sexport session log
Ctrl+Lclear terminal
Ctrl+ + / Ctrl+ -font size
↑ / ↓command history in the transmit box

In raw keyboard mode Ctrl combinations go to the device instead, as they should.


Limits in this version

ItemLimit
Saved sessions3
File store10 files, 10 MB in total
Plot viewports2
Plot channels8 at once
Plot history15 minutes
Scrollback20 000 lines

When you reach a limit, EM·LINK says which one, for example Limit reached in this version (3 saved sessions).


Tool methods and derivations

The tool suite is the piece that separates EM·LINK from generic calculator sites - every number is traceable to a published standard, and this section shows the derivation for each. The formula inside the tool is the one-liner; this is where the piecewise ranges, ancillary equations, and verified reference points live.

The tool suite, with the RTD calculator open
The tool suite, with the RTD calculator open

Number & Bit Inspector

Bit-level view of any 8/16/32/64-bit value. Bases, IEEE-754 field breakdown, click-to-toggle bits, endian swap.

IEEE-754 float decomposition. A float bit pattern splits into sign, exponent and mantissa:

value = (-1)^s · (1 + m / 2^n_m) · 2^(e - bias)

For 32-bit floats: sign = bit 31, exponent = bits 30…23 (bias 127), mantissa = bits 22…0. For 64-bit: sign = bit 63, exponent = bits 62…52 (bias 1023), mantissa = bits 51…0.

Two's-complement signed interpretation flips the top bit's weight from positive to negative, so an N-bit value is:

signed = unsigned - 2^N   if the MSB is set, else unsigned

CRC & Checksum Suite

13 preset polynomials plus a custom-poly mode. All match the published check values of the CRC catalogue for the standard test string 123456789.

The CRC tool showing MODBUS 0x4B37 for the standard test string
The CRC tool showing MODBUS 0x4B37 for the standard test string

General polynomial CRC. For a width-w CRC with polynomial p, initial value init, input reflection rin, output reflection rout, and final XOR xor:

crc = init
for each byte b:
    if rin: b = reflect(b, 8)
    crc = crc XOR (b << (w - 8))
    repeat 8 times:
        if MSB of crc set: crc = (crc << 1) XOR p
        else:              crc = (crc << 1)
    crc = crc AND ((1 << w) - 1)
if rout: crc = reflect(crc, w)
crc = crc XOR xor

Verified reference points - CRC of ASCII 123456789:

PresetExpected
CRC-16/MODBUS0x4B37
CRC-16/CCITT-FALSE0x29B1
CRC-16/XMODEM0x31C3
CRC-32 (zlib)0xCBF43926

Also computes the simpler checksums used in the same protocols: XOR-8 (as in the GNSS-sentence checksum), SUM-8, LRC (as in the Modbus-ASCII trailer), Fletcher-16.

Modbus Register Interpreter

The word-order problem, solved. Modbus transports 16-bit registers, but 32-bit floats and integers have four possible byte arrangements depending on how the device firmware packed them. The tool shows all four side by side, so the correct one is immediately obvious.

The four orderings. Given two consecutive 16-bit registers R0 (bytes A B) and R1 (bytes C D):

OrderByte layout in memoryCommon name
ABCDA B C Dbig-endian, standard IEEE-754 network order
CDABC D A Bword-swapped
BADCB A D Cbyte-swapped
DCBAD C B Afully reversed, little-endian

The float is then decoded per IEEE-754 from those four bytes. If the reading is 1e-40 or 1e38, the word order is wrong - try CDAB, which is the most common mismatch.

Also decodes as int16, int32 both orderings, uint32 both orderings, and treats each register byte as ASCII.

Fixed-Point Q Converter

Convert real values to and from Qm.n fixed-point integers.

Conversion. A Qm.n value has m integer bits and n fraction bits (plus a sign bit if signed):

raw        = round(x · 2^n)
back       = raw · 2^-n
resolution = 2^-n
range signed:   -2^m … 2^m - 2^-n
range unsigned: 0    … 2^(m+1) - 2^-n

If raw exceeds the range, the value saturates and quantisation error grows unboundedly - the tool flags this as SATURATED.

Example. Q15 (0 int, 15 fraction, signed, 16 bits total) is the most common DSP format for audio and control loops. 0.75 in Q15 is round(0.75 · 32768) = 24576 = 0x6000. Multiplying two Qm.n values gives Q2m.2n; shift right by n to get back to Qm.n.

C Struct Layout & Padding

Paste a struct definition, get real byte offsets and inserted padding. Also reports the byte savings from reordering members widest-first.

Alignment rules. Each member aligns to its own natural size:

offset(m_i) = smallest offset ≥ sum(size(m_j) + pad_j) for j < i
              such that offset(m_i) mod align(m_i) = 0

The struct itself aligns to its widest member, so trailing padding may be added at the end to make the struct size a multiple of that alignment. This is why an array of the struct works correctly - each element's members land on their natural alignment.

Target ABI. 32-bit ARM: long and pointers are 4 bytes, aligned to 4. 64-bit x86-64 or AArch64: long and pointers are 8 bytes, aligned to 8.

Common example. A struct of uint8, uint32, uint8, float, uint16 on 32-bit ARM ends up 20 bytes with 8 bytes of padding. Reordering widest-first (uint32, float, uint16, uint8, uint8) gives 12 bytes with 0 padding. On a 1000-record log buffer that's 8 kB of RAM saved.

Intel HEX / SREC Inspector

Parses Intel HEX and Motorola S-record firmware files. Validates every record's checksum, maps the contiguous segments, computes the image CRC-32, and converts to raw .bin with 0xFF gap fill (matching erased flash).

Intel HEX record structure. Each line is :LLAAAATTDD…DDCC where LL is data length, AAAA is the 16-bit address, TT is the record type (00 data, 01 EOF, 02 extended segment, 04 extended linear, 05 start linear), and CC is the two's-complement of the sum of every preceding byte. The checksum passes when the sum of all bytes on the line (including CC) mod 256 equals zero.

S-record checksum is the one's complement of the sum of the length, address and data bytes. Passes when the sum of all bytes mod 256 equals 0xFF.

Extended addressing. Record type 02 shifts the base address by 16; type 04 sets the upper 16 bits of a 32-bit address. Both are tracked so a firmware image that crosses a 64 KB boundary decodes to the correct absolute addresses.

MQTT Topic Matcher

Test wildcard subscription filters against a list of topics before deploying to a fleet.

Match rules. Split filter and topic on /. Compare level-by-level:

The $ prefix on system topics is treated specially by most brokers - wildcards do not cross it. # alone subscribes to everything, which should never be used in production.

4–20 mA / 0–10 V Loop Scaling

Full analogue-front-end arithmetic: sense-resistor voltage, ADC counts, engineering units, resolution per count, and wire-break detection.

Current-to-voltage. For a current loop with sense resistor R:

V      = I · R
counts = (V / V_ref) · (2^N - 1)
EU     = EU_min + ((I - I_min) / (I_max - I_min)) · (EU_max - EU_min)

Wire-break detection per NAMUR NE 43. For a 4-20 mA loop:

Sizing the sense resistor. For a 3.3 V ADC reference, a 165 Ω sense resistor makes 20 mA land exactly at V_ref (using the full ADC span cleanly). The traditional 250 Ω is intended for a 5 V system, where 20 mA gives 5 V; on a 3.3 V ADC that clips.

NTC Thermistor

Resistance-to-temperature both directions, with divider counts and self-heating.

Beta model - two-point fit, reasonable across a narrow range around the reference point:

1/T = 1/T_0 + (1/B) · ln(R / R_0)

where T, T_0 are in kelvin

Steinhart-Hart - three-term fit, accurate over much wider ranges:

1/T = A + B · ln(R) + C · (ln(R))^3

To solve for R at a given T, iterate the cubic numerically (the tool uses a bisection over ln(R)). Beta drifts several degrees at the ends of a wide temperature range; use Steinhart-Hart beyond about −20…+80 °C.

Divider output. With the NTC on the low side, series resistor R_s to V_ref, ADC on the NTC:

V_out  = V_ref · R / (R + R_s)
counts = (V_out / V_ref) · (2^N - 1)

Self-heating. Current through the NTC dissipates power that raises its own temperature and biases the reading. Typical dissipation coefficient is ~1 mW/°C in still air, so a 3.3 V divider across 10 kΩ dissipating ~0.3 mW adds ~0.3 °C to the reading. Keep it under 1 mW for laboratory work.

RTD PT100 / PT1000

Callendar-Van Dusen both directions, including the sub-zero cubic term that linear approximations get wrong.

Callendar-Van Dusen equation per the International Electrotechnical Commission's temperature-sensor standard (IEC 60751):

T ≥ 0 °C:  R = R_0 · (1 + A·T + B·T^2)
T < 0 °C:  R = R_0 · (1 + A·T + B·T^2 + C·T^3·(T - 100))

where R_0 = 100 Ω for PT100, 1000 Ω for PT1000
      A =  3.9083 × 10^-3
      B = -5.775  × 10^-7
      C = -4.183  × 10^-12

Inverse. Above 0 °C, the quadratic has a closed-form solution:

T = (-R_0·A + sqrt(R_0^2·A^2 - 4·R_0·B·(R_0 - R))) / (2·R_0·B)

Below 0 °C, the cubic term prevents a closed form; the tool uses the quadratic as a seed and refines with Newton's method to convergence.

Verified reference points per IEC 60751:

TemperaturePT100 resistance
−200 °C18.5201 Ω
0 °C100.0000 Ω
100 °C138.5055 Ω
850 °C390.481 Ω

Lead-wire error. A 2-wire configuration adds twice the one-way lead resistance directly to the reading. At 0.5 Ω/leg that's 1 Ω, which shifts a PT100 reading by ~2.5 °C. 3-wire cancels this provided all three legs match; 4-wire is immune.

Excitation self-heating. At 1 mA through a 100 Ω sensor, dissipation is 0.1 mW, which raises the sensor about 0.005 °C in still air. Above 1 mA the effect starts to matter for precision work.

Thermocouple K / J

Full NIST ITS-90 polynomials both directions, with cold-junction compensation.

Direct (temperature to millivolts). The National Institute of Standards and Technology publishes piecewise polynomial coefficients for each thermocouple type:

emf(T) = sum(c_i · T^i) for i = 0…n

Type K above 0 °C adds an exponential correction:
    emf(T) += a_0 · exp(a_1 · (T - a_2)^2)

Type K is piecewise across −270…0 °C and 0…1372 °C. Type J across −210…760 °C and 760…1200 °C. Coefficients are the ITS-90 reference table values.

Inverse (millivolts to temperature). A separate set of piecewise polynomial coefficients maps EMF back to temperature, split at 0 mV and, for K, at 20.644 mV.

Cold-junction compensation. A thermocouple only measures the difference between its two junctions. If the measurement circuit sits at 25 °C, the reading is low by the EMF that a K junction would produce at 25 °C - about 1 mV, or ~25 °C worth.

emf_absolute = emf_measured + emf(T_cold_junction)
T_hot        = inverse(emf_absolute)

Skipping this step is the classic ~25 °C error people find in hand-rolled thermocouple code.

Verified reference points per NIST ITS-90:

TypeTemperatureEMF
K100 °C4.096 mV
K500 °C20.644 mV
K1000 °C41.276 mV
J100 °C5.269 mV
J500 °C27.393 mV

ADC Resolution & Noise

LSB size, effective bits (ENOB), noise-free bits, and how much oversampling actually buys.

Ideal SNR of an N-bit converter:

SNR_ideal = 6.02 · N + 1.76 dB

Effective bits from measured noise. Given noise as RMS microvolts:

noise_LSB = noise / LSB_size
ENOB      = N - log2(noise_LSB · sqrt(12))

The sqrt(12) factor converts RMS noise to the equivalent peak-to-peak range for a Gaussian process, which matches the quantisation error convention.

Noise-free bits is the more conservative figure - the resolution you can quote in a datasheet without qualification:

NFB = floor(log2(2^N / (noise_LSB · 6.6)))

The 6.6 factor is the standard peak-to-peak-to-RMS ratio for a 99.9 % confidence bound.

Oversampling gain. Each 4× in sample rate adds 1 bit of resolution:

gain_bits = log2(oversample_ratio) / 2

This only works if the noise is at least 1 LSB - noise itself acts as the dither. A perfectly quiet input gains nothing from oversampling.

UART Baud Rate Error

Divisor register, actual baud, and error percentage for common register formats. Reproduces the well-known bad combinations that explain why certain "odd" crystal frequencies exist.

Standard divisor. For a peripheral clock f_clk and target baud b:

divisor = round(f_clk / b)
actual  = f_clk / divisor
error   = (actual - b) / b

With 16× or 8× oversampling (the two major register formats):

16×: divisor = round(f_clk / (16·b)) - 1   (register value)
     actual  = f_clk / (16 · (divisor + 1))

8×:  divisor = round(f_clk / (8·b)) - 1
     actual  = f_clk / (8 · (divisor + 1))

Error budget. A UART resynchronises only on the start bit, then samples in the middle of each bit for the rest of the frame. By the stop bit, error has accumulated across ~10 bit times. Each end has its own error; the combined figure must stay under ~50 % of a bit period.

Verified reference point. At a 16 MHz clock with 115200 baud and 16× oversampling:

I²C Pull-Up Calculator

Minimum and maximum pull-up resistor per the I²C specification, plus the E24 value closest to the geometric mean.

Minimum - set by sink current the low driver can pull:

R_p(min) = (V_DD - V_OL) / I_OL

Typical I²C receivers guarantee 3 mA sink at V_OL = 0.4 V, giving R_p(min) ≈ (3.3 - 0.4)/0.003 ≈ 970 Ω at 3.3 V.

Maximum - set by bus capacitance and required rise time:

R_p(max) = t_r / (0.8473 · C_b)

t_r limits:
    Standard mode (100 kHz):  1000 ns
    Fast mode      (400 kHz):  300 ns
    Fast mode plus (1 MHz):    120 ns

The 0.8473 factor is ln(0.7/0.3) - the number of RC time constants between the 30 % and 70 % of V_DD points that UM10204 uses to define I²C rise time.

When no pull-up works. If R_p(max) < R_p(min), the bus is over-capacitance for that speed - you must shorten the bus, split it with a repeater, or drop to a slower mode. Bus capacitance is roughly 10 pF per device plus 1 pF per cm of trace; the specification caps it at 400 pF for Standard and Fast mode and 550 pF for Fast-mode Plus.

RS-485 Termination & Bias

Fail-safe bias resistor, cable-length limit, stub-length limit, unit-load budget.

Bias resistors. A pair of resistors from the differential pair to V_CC and ground respectively, providing enough current through the termination network to hold ≥ 200 mV differential when the bus is idle.

V_diff = V_CC · R_load / (2·R_bias + R_load)

R_load = parallel(R_term_effective, sum of receiver input impedances)
       = 1 / (1/(Z_0/n_terminators) + 1/(12 kΩ / UL / n_nodes))

Rearrange for R_bias:
R_bias = (V_CC · R_load / V_diff_min - R_load) / 2

Length-rate product - an empirical rule for the maximum reliable cable length at a given data rate:

length · rate ≤ 10^8  m · bps

Stub length - 20 % of the round-trip time at the data rate, conservatively:

stub_max = 0.2 · (2 · 10^8 / rate)  metres

Unit load budget. A standard transceiver presents 1 UL (12 kΩ) to the bus. The specification allows up to 32 UL. Reduced-load transceivers present ½, ¼ or ⅛ UL, allowing 64, 128 or 256 nodes.

Timer & PWM Register Calculator

Ranked prescaler / period pairs for a target output frequency, with the PWM resolution each pair leaves you.

Frequency equation. A typical hardware timer has a prescaler PSC and an auto-reload period ARR:

f_out          = f_timer / ((PSC + 1) · (ARR + 1))
resolution     = log2(ARR + 1) bits
duty_register  = (ARR + 1) · duty%

Prefer the pair with the largest ARR - resolution is what you lose when the prescaler is too aggressive. At ARR = 4200 (~12 bits), duty steps in ~0.024 %. At ARR = 42, they step in 2.4 %.

Wire Gauge & Voltage Drop

Loop voltage drop for field wiring and 4–20 mA compliance-voltage budgets.

Wire diameter. American Wire Gauge is defined logarithmically:

d_mm     = 0.127 · 92^((36 - AWG) / 39)
area_mm² = π/4 · d²

Copper resistance with temperature correction (α = 0.00393 per °C):

ρ           = 1.724 × 10^-8 · (1 + α · (T - 20))  Ω · m
R_per_metre = ρ / (area · 10^-6)
R_loop      = R_per_metre · length · 2   (out and back)
V_drop      = I · R_loop
P_loss      = I² · R_loop

4-20 mA compliance-voltage budget. For a supply V_S driving a loop with cable drop V_drop and a sense resistor R_sense:

V_transmitter = V_S - V_drop - I · R_sense

At 20 mA with V_S = 24 V, 100 m of AWG 22 (copper at 25 °C), and R_sense = 250 Ω:
R_loop         ≈ 10.8 Ω
V_drop         ≈ 0.22 V
V_available at transmitter ≈ 24 - 0.22 - 5 = 18.8 V

Most industrial transmitters need at least 12 V compliance, so 6.8 V of margin is comfortable.


Privacy

Everything runs in the page. There is no backend, no telemetry and no account.

DataWhere it lives
Session logs, plot data, decoded framesmemory, until you clear or close the tab
Files, captured logsIndexedDB, in your browser
Sessions, macros, themelocalStorage, in your browser

Some features load files from the internet, only when you use them, so they need a connection: the MQTT and GPS map libraries come from unpkg.com, map tiles come from OpenStreetMap, and the fonts come from Google Fonts. Everything else runs without a network connection.


Troubleshooting

Red banner about USB serial. USB serial needs desktop Chrome or Edge. Serve over http://localhost instead of opening the file directly. WebSocket, MQTT, the simulator and the tools work without it.

Port picker is empty. The device is not enumerating. Check the cable - many are charge-only - and confirm the USB-serial driver is present. On Linux, add yourself to dialout and log back in.

Connected but nothing arrives. Wrong baud rate is the usual cause; try AUTO DETECT. Then check TX and RX are not swapped, and that both ends share a ground.

Text is mojibake. Baud rate is close but wrong - the framing survives, the bits do not. AUTO DETECT resolves it.

Progress bars scroll instead of updating. ANSI is switched off, so \r is being ignored.

Modbus table is empty. Confirm the traffic really is RTU and not ASCII - RTU is binary, and ASCII frames start with a colon. Raise the frame gap on slow links.

CAN table is empty. The adapter is probably emitting a binary protocol rather than SLCAN or candump text. Put the terminal in HEX and look at what actually arrives.


Verification summary

Every calculator is tested against published reference values, not eyeballed. The main ones:

CheckExpectedSource
Modbus CRC of 01 04 02 FF FFB8 80canonical test vector
CRC-16/MODBUS of 1234567890x4B37CRC catalogue
CRC-32 of 1234567890xCBF43926CRC catalogue
XMODEM CRC-16 of ABC0x3994XMODEM specification
J1939 ID 0x0CF00400PGN 61444 (EEC1)SAE J1939-71
PT100 at 0 / 100 / −200 °C100.0000 / 138.5055 / 18.5201 ΩIEC 60751
Type K at 100 / 500 / 1000 °C4.096 / 20.644 / 41.276 mVNIST ITS-90
UART baud at 16 MHz / 115200 (16× / 8×)−3.55 % / +2.12 %standard divisor equation

If any calculator ever produces a number that disagrees with its cited standard, that is a bug in the tool - please report it.