Developer manual
The board in detail
The product page covers what P1LOT One does. This page covers how. What it drives, what it reads, what it refuses to do, and what it can be used for outside a game.
What you can plug into it
One 12 V input, one USB-C socket to the computer, and one connector that carries everything else. Nothing on that connector runs off USB. The 12 V supply feeds all of it.
- Two CAN connectionsThis is what talks to car modules. Today that means instrument clusters, gear selectors and rotary controllers, and the list grows as each one is decoded. Two connections, so you can run everything on one or give a dashboard a set to itself. The rate matches what you connected rather than being fixed in the hardware.
- One LIN connectionThe other kind of car bus, and the one a steering wheel's button block speaks. It is a master. The board asks and the module answers, so nothing appears on it until the board is looking. One branch, because that is what a wheel needs and there is nothing else on the rig that wants one.
- Switched power out12 V for whatever you connected and 5 V for smaller accessories, both switched by the board and both protected against a short. This is what powers the dashboard, so there is no second supply on the desk.
- USB-C to the computerOne cable and nothing to install. The PC sees a serial port and two controllers, on the board's own identity, so its buttons never collide with your wheel's.
- Two analog inputsAnything that moves a wiper along a track: a pedal, a throttle body, a handbrake lever, a stick, a plain potentiometer. They arrive at the PC as two gamepad axes, so a game reads them in its own settings with nothing else in the path. Each one is calibrated by holding the control where you want an end and pressing a button, setting the resting end, the far end and, for a two-way control, the centre. Nothing is typed in volts, and a pot wired the other way round needs no rewiring. A stick gets the whole axis, centre at rest with one way negative and the other positive, rather than half of it.
- A gauge and a shift lightTwo signal outputs drive servo gauges straight from telemetry, and an LED strip output runs as a shift light off the revs. Both run on the board, with no host code beyond the telemetry you are already sending. What we do not sell is the gauge or the strip itself. Those are different products with their own approvals. The pins are in the map below.
The exact numbers
- Processor
- STM32G474CEU6, 512 K flashUpdated over USB from a signed file. An interrupted update leaves the working firmware in place.
- Power in
- 12 V DC, 3 A, barrel jackReverse-protected. This is the only power source for anything on the DB15. USB powers the processor and nothing else.
- USB
- USB-C, data onlyEnumerates as one virtual COM port and two controllers, a game pad and a second one for the automotive controls. All three are always present, on the board's own identity.
- CAN
- 2 × classic CANTwo independent pairs, and each runs at the rate the devices on it use. A pair with nothing chosen on it stays quiet, so a rig you are half way through building cannot put frames anywhere. Two pairs is what lets parts from two different marques share one connector. A message id means whatever the maker who defined it says it means, so each maker's parts get a pair to themselves.
- LIN
- 1 × master19 200 baud, set by the driver of whatever is on the line rather than typed in. The rate belongs to the module, as its identifiers do, so there is nothing here to get wrong. The transceiver is powered by the firmware rather than always live. This is the steering-wheel block's bus, the one branch on the connector that is not a CAN pair, and a LIN slave says nothing until it is asked, so the part exists only while the board is polling it.
- Analog inputs
- 2 × 0…5 V, 100 Hz hardware scanRead continuously in hardware and referenced to a measured internal reference rather than a nominal supply, so the reading does not drift with the rail. Each one can be CALIBRATED: hold the control at each end and press, so the board takes the reading it is looking at. Then say whether that travel is a pedal, which rests at one end, or a stick, which rests in the middle and reads negative one way and positive the other. A stick can also be given a deadband, because a rest position is a few millivolts wide and it wanders. Which way round the pot is wired does not matter: if the voltage falls as the control moves, take the resting end anyway and the travel runs that way. Nothing has to be typed and nothing is assumed about the pot.
- Signal outputs
- 2 × servo, or plain PWMEither channel can be mapped to a telemetry value on the board, so a gauge needle works with no host code. Both pins are modulated either way. What differs is what the far end reads. As a servo the pulse width is the signal, 50 Hz and 500 to 3500 µs, which is what a hobby servo and most aftermarket movements expect. As PWM the duty is the signal, for a movement driven through an RC filter and an amplifier, and the frame wants to be short so the filter can keep up. The frame is settable from 200 µs to 65 500 µs and both channels share it, because one timer drives them. The gauge itself is a different product with its own approvals. The output is here and it works.
- Serial LED
- 1 × WS2812 chain, up to 32Driven as a shift light from the revs, with no host code beyond the telemetry you are already sending. Tell the board how long the strip is and it does the rest.
- Switched 12 V
- DB15 pins 11 and 12High-side switch with current sense. Over 2.5 A, or a fault report from the switch, drops the rail for 5 s. Three trips in a row latch it off until something explicitly asks for it again. A single reading decides it, nothing is averaged, and the rail is only judged once it is up, so start-up inrush does not trip it.
- Switched 5 V
- DB15 pin 13, ≤ 1.8 AThrough an eFuse. A trip is retried three times, two seconds apart to let it cool, and held off after that until something asks again.
- Internal measurements
- Reference, die temperature, VBATOn the same 100 Hz scan as the external inputs, readable over the protocol and from the console.
Which pin is which
It is a VGA-style connector, chosen because the cable and the hoods are sold everywhere and cost nothing. The dashboard hangs on CAN 2, which is the bus the firmware selects by default; CAN 1 is the second one, free for whatever you put beside it. Everything else on the connector is there for whatever you add next: a shifter, a real steering wheel, a pedal, a strip of LEDs.
The colours are the wires. Both halves of a pair share a base colour. Solid is low, striped is high, and the two CAN pairs are twisted. CAN 2 is green and green/orange because that is what the cluster bus is in the car, and ground is brown for the same reason.
- 1Analog in 2yellow / white
- 2Signal out 2violet / white
- 3CAN 1 highcyan / white · twisted with its CAN 1 partner
- 4LINdark blue
- 5CAN 2 lowgreen · twisted with its CAN 2 partner
- 6Analog in 1yellow
- 7Signal out 1violet
- 8Serial LEDgrey
- 9CAN 1 lowcyan · twisted with its CAN 1 partner
- 10CAN 2 highgreen / orange · twisted with its CAN 2 partner
- 11+12 V switchedred
- 12+12 V switchedred
- 13+5 V fusedorange
- 14Groundbrown
- 15Groundbrown
Every pin, with what it expects
- 1ADC 2 in0…5 V at the connector, halved by a 1 k / 1 k divider. Not 12 V tolerantyellow / white
- 2Signal out 2servo: 50 Hz frame, 500–3500 µs · PWM: the duty, on a frame you setviolet / white
- 3CAN 1 highthe Porsche panel's pair by defaultcyan / white
- 4LINmaster, 19 200 baud. The steering-wheel block runs heredark blue
- 5CAN 2 lowthe BMW parts' pair by defaultgreen
- 6ADC 1 in0…5 V at the connector, halved by a 1 k / 1 k divider. Not 12 V tolerantyellow
- 7Signal out 1servo: 50 Hz frame, 500–3500 µs · PWM: the duty, on a frame you setviolet
- 8Serial LEDWS2812, up to 32grey
- 9CAN 1 lowthe Porsche panel's pair by defaultcyan
- 10CAN 2 highthe BMW parts' pair by defaultgreen / orange
- 11+12 V switchedhigh-side switch, current sensedred
- 12+12 V switchedsame rail as pin 11red
- 13+5 V fusedeFuse, ≤ 1.8 A, retried three times then held offorange
- 14GNDbrown
- 15GNDbrown
Read this before you wire anything to it
The 12 V pins are a switched rail, not a supply you can lean on. The firmware owns them, telemetry brings them up, and a 30-second timer takes them down. Do not power a bench from them and expect it to stay powered.
The two analog inputs expect 0…5 V and are divided for it. The two signal outputs are logic-level, timer-driven pins, not drivers. Anything that needs current needs its own stage. They idle low and pulse high, on a 20 ms frame, so a width of 1500 µs is 1500 µs of pulse at the pin. And the cluster harness that came with your unit belongs to the cluster printed on its label; the warning on the product page explains why that matters more than it sounds.
Talking to it
One USB cable gives you three functions at once, always all of them: a virtual COM port, a HID gamepad, and a second controller carrying the automotive buttons. The board has its own product id, so its button 1 does not collide with your wheel's. A game sees separate controllers rather than one with overlapping bindings. There is one wire format on that port and it is text, in both directions.
The text line
One line per update, semicolon-separated. This is what SimHub sends through a Custom Serial Device, and it is plain enough that anything able to open a port can drive the instruments. Our SimHub template is a worked example of writing it. One file, every game, with the property names it reads and what it does with each one.
P1;ign;gear;gearmode;fuel;rpm;speed;coolant;oil;oilp;boost;
theme;preprpm;shiftrpm;lights;status;clbtn;cruise;limit;
units;bright[;report;p1time]An empty column means keep the last known value. The board holds a snapshot and each line patches it, so you may send only what changed. Fields 0 to 20 are mandatory and a truncated line is rejected whole rather than applied half-way. The two-field tail, how often to report and the clock, can be left off entirely.
Both lines grow to the right and never in the middle, so split on the semicolon and read the columns you know. A reader that insists on an exact count breaks on the next firmware.
0P1 literal- Says which protocol this is. There is no other line starting P1
1ign O A I R- Off (dark), Accessory, Ignition, Running. The board walks the rungs one at a time in both directions, 200 ms each. A dashboard will not jump straight from Off to Running
2gear P R N or 1…9- The gear indicator
3gearmode A S M E- Who decides what the gearbox is doing. S and M name a letter outright. A asks the BOARD to work one out from where the lever physically is, which is what a motorised selector needs. E hands the gearbox to the lever entirely
4fuel 0…100 %- The fuel gauge. Moved in small steps a real cluster accepts, and held rather than parked when you stop sending, because a parked car does not drain its tank. Also what lights the two reserve lamps, which the board works out itself
5rpm rev/min- Tachometer, the shift-light bar, and a servo source
6speed km/h- Speedometer, and a servo source
7coolant °C, 0 = midrange- Coolant gauge, and a servo source
8oil °C, 0 = midrange- Oil display, and a servo source
9oilp 0…50, tenths of a bar- Oil pressure, 0 = no reading. Only some dashboards have the gauge. The rest ignore it
10boost −100…300, hundredths of a bar- Turbo boost against atmosphere. Negative is vacuum off the throttle. Carried end to end, but no dashboard we drive has a documented message for a boost gauge yet, so it reaches the board and stops there
11theme S C E D- The cluster skin: Sport, Comfort, Eco, Default
12preprpm rev/min, 0 → 4500- Where the rev bar starts filling
13shiftrpm rev/min, 0 → 5000- Where it is full. It blinks from 80 % of that window
14lights hex bits- The exterior lamps and the indicators. Table below
15status hex bits- Telltales and check-control messages. Table below
16clbtn 0…9- Which of the dashboard's OWN buttons you are holding. 1 is the board-computer stalk
17cruise km/h, 0 = none- The cruise-control readout, where a dashboard has one
18limit km/h, 0 = none- The speed-limit sign
19units 0 or 1- 0 is km/h and °C, 1 is mph and °F
20bright 0…255, 0 = default- Cluster backlight. Off entirely in ignition O
21report 0…255, 0 = off- How often the board answers with a status line, in units of 10 ms. Optional
22p1time hex seconds- The dashboard clock AND date, as seconds since 2025-01-01 00:00:00 in local time, because the host is the only end that knows its own offset. 0 means you are not telling it the time. Optional
What the board sends back
Field 21 of the line asks the board to report its own state, in units of 10 ms. Send 1 and it answers every 10 ms, 10 every 100 ms, 0 or an empty column and it says nothing. Switching it on answers at once rather than after a first period, because a silent gap is indistinguishable from a board that did not understand the request.
P1;...;bright;10;; -> a status line every 100 ms
P2;1;41;3300;1650;;1500;0;1- 1 link
- The board's own view of the link: 0 offline, 1 live, 2 stale
- 2 flags
- What is true right now, as hex. See below
- 3 adc1
- Analog input 1 (pin 6), millivolts at the processor pin. Double it for the connector, which is what a meter there reads
- 4 adc2
- Analog input 2 (pin 1), same
- 5 ma
- 12 V load current in mA. Empty means nothing is measuring, rather than zero
- 6 pwm1
- Signal output 1, microseconds
- 7 pwm2
- Signal output 2, microseconds
- 8 din
- Header inputs, debounced, as hex bits
The empty current column is not zero.Zero means the sense amplifier measured no draw. Empty means it is switched off and nobody measured anything. A reader that treats the two alike reports “nothing connected” for a rail that may be carrying three amps.
The flag word
0x0112 V rail on0x025 V rail on0x0412 V tripped, waiting out the retry0x0812 V out of retries, held off0x105 V protection has tripped0x20CAN controller is bus-off0x40Current sense on. The mA column means something0x80The button self-test is running
The board sends other lines unasked, on the same port and in the order they happened: BTN;<id>;<state> whenever a wired input changes, PR;<seq>;… when something has asked it a question (below), and console output while the console has the port. Nothing here is binary. The whole protocol can be read off a terminal.
Configuring it while it runs
A fourth prefix shares the port rather than taking it. PL;<seq>;<verb> asks the board something, such as what settings it has, what can be on the harness or what the connector is reading. It answers PR;<seq>;row;… zero or more times, then PR;<seq>;ok or PR;<seq>;err. The sequence number is echoed and never interpreted, so a late answer cannot be mistaken for the reply to the next question.
None of the four prefixes is the start of another, which is what lets a game drive the rig while something else configures it. Our own tool is the obvious client, but there is nothing privileged about it. The verbs are listed in the protocol reference that comes with the board, and anything able to open the port can use them. The one thing that does take the port is the console, and it says so.
The verbs a board answers are also a question you can ask it. caps lists them with a line of English each, so a program can ask a board what it understands rather than assume. That is what lets an older copy of a tool meet a newer board, or the other way round, and say plainly which part is missing instead of failing in a way that looks like a fault in the tool.
What it looks like to a game
Two controllers, on one cable. A game pad carries the two analog inputs as absolute axes, a hat, and thirty-two buttons. Beside it a second controller carries the automotive side, everything the rotary controller and the gear selector do, on its own buttons. A binding made on the lever cannot disturb one made on the pad.
Both are polled at 1 kHz. That is not about resolving a hand. A rig is a control loop with a person in it, and every millisecond between a movement and the game acting on it comes back as the thing feeling loose.
Nothing here needs a driver and nothing needs our software. The descriptor says game pad rather than steering wheel. The board has no idea what is wired to it, and a device claiming otherwise would be lying to every game that asks. Axes are clamped rather than wrapped, so a signal that overshoots reads as full deflection instead of snapping back to zero, and a pad switched off reports centred rather than at the stop.
Owning the port
The port has exactly one owner at a time and two lines swap it. Send G1VE_ME_CLI and the shell takes it, raw, so it behaves like any terminal. Send anything starting with P1 and telemetry takes it back, which is what SimHub does on every update, so the link recovers by itself. Only a P1 at the start of a line is the escape, so echo P1 at the shell does what you typed. Nothing is persisted, and the session also ends when the port does.
The status word
Field 15 of the line is 32 bits of hex. Each bit is one event, and the driver decides whether the cluster shows it as a latched warning light or as a rotating message on the text line. Several lights can be lit at once, and messages take their turn.
- b0
0x00001Handbrake - b1
0x00002Traction control intervening - b2
0x00004Check engine - b3
0x00008Stability control off - b4
0x00010Low tyre pressure - b5
0x00020Seat belt - b6
0x00040Steering malfunction - b7
0x00080Transmission malfunction - b8
0x00100Brake malfunction - b9
0x00200ABS malfunction - b10
0x00400Speed warning - b11
0x00800Damage to the car - b12
0x01000Engine overheating - b13
0x02000Oil pressure low - b14
0x04000Launch control - b15
0x08000Gearbox over temperature - b16
0x10000Clutch - b17
0x20000Fuel reserve - b18
0x40000Below reserve
Which of those a given cluster can physically show is a property of the cluster, not of the interface. Ask us which is which for the one you have. There are two different answers behind a signal that does nothing: it is not decoded yet, or that dashboard has no such display at all, and no update fixes the second one.
The lights
Field 14 is a bitfield too, and a smaller one. The indicators are in here rather than in a column of their own. They are exterior lamps like the other four, and a separate column meant a line could contradict itself, the lights saying one thing and the indicators another, with nothing to say which the panel should believe. Both bits together is a hazard flash.
- b0
0x01Low beam - b1
0x02High beam - b2
0x04Fog - b3
0x08Daytime running / sidelights / parking - b4
0x10Automatic-light switch - b5
0x20Left indicator - b6
0x40Right indicator
The console
Open any terminal on the port and send one line. Every command name is lowercase. The shell takes each one from the identifier it was declared with, so there is no capitalised spelling of any of them to get wrong. help in the shell is always authoritative. This is the current set.
G1VE_ME_CLIstatus- Link, both rails, both buses, and what is bound to them
setup- What is on the harness, and what fights what
config- What the board does with it
knob · shifter- The rotary controller and the gear selector: are they answering, and what do their controls mean
wheel- The steering wheel: which control is being held, by name, and a scorecard. Press every one once, stop it, and whatever never answered is listed
map- Who serves what on this rig: one line per job, naming the part that ended up doing it
power- The connector's supply switches: hold the rails up with no game running, and the current amplifier
setup servo · setup pwm · setup led · setup axis- Everything on the connector: what each signal pin follows, the shape those pins make and the frame, how long the LED strip is, and what is on each analog pin, a pedal, a stick or nothing, with the travel it actually has
save- Keep the whole configuration across a reset
dfu · reset- Reboot into the updater, or just reboot
uname [-a] · help- Build and identity, with the authoritative list taken from the board rather than from this page
It used to be eighteen commands. Everything removed only poked a pin. Paint the strip, drive a servo, switch a rail, park a bus in listen-only. A shipping console full of ways to make a rig behave unlike itself is a support case with a keyboard attached. What is left answers the two questions a service call actually asks: what is this rig, and is it working.
setup, what is on the harness
setup
setup <class>
setup <class> <id> can1|can2|def
setup <class> off
setup servo | setup pwm | setup led | setup axisThe classes are cluster, knob and shifter, and a rig has one of each at most. Bare, it prints a row per class, showing what is chosen and on which pair. Given a class, it lists everything this firmware can drive there.
There is no on. Naming a device is choosing it. A thing you have just picked and placed, which is then also switched off, is a state that exists only to be wondered at later. And nothing is assumed. A board out of the box drives no dashboard, no knob, no lever, no strip and no gauge, because it cannot see what is on the other end of the connector and guessing means a rig that does something nobody asked for on its first power-up.
config, what the board does with it
config
config <group>
config <group> <name>
config <group> <name> <value>Every value is a WORD out of a list the setting will show you, never a number. A rig configured by numbers cannot be read back by the person who owns it, and every number in a console is one more thing somebody has to be told.
A setting can belong to a PART rather than to the board, and the three gearbox ones do. They mean nothing on a rig with no gear selector on it. configprints the owner in brackets beside such a setting and the row over the protocol carries it as its last field, so a tool draws it under the part instead of on a settings page. Everything else here is the board’s own and is true of a bare board.
controls modedefault · game- Default hands each control to the first job on the rig that can use it, in the order dashboard menus, volume, mute, track, play/pause. Whatever nothing takes reaches your game. Game switches every one of those off, so all of it arrives at the title, which is what a binding dialog needs. The controls switch it themselves, and this is the stored value
gearbox modehold · pulse- Whether an emulated gear is a state the button holds, or a press. Hold is right for a game that reads the button as a state. Pulse is for one that only ever watches for events and would otherwise see a selection once and never again. Belongs to the gear selector’s driver, and is only offered while one is fitted
gearbox syncnone · neutral · all- How much of the game's own gear the lever's gearbox takes. None is the lever alone. Neutral believes a Neutral the game keeps insisting on. Under either, the number is the lever's as well, so pushing into Drive gives first, as it does in the car. All hands the readout to the game instead, and the lever stays worth binding as buttons. Belongs to the gear selector’s driver, and is only offered while one is fitted
gearbox timeout1s · 2s · 3s · 5s- How long the game must insist on neutral before it is taken. Only consulted under sync neutral. Belongs to the gear selector’s driver, and is only offered while one is fitted
led brightnessoff · low · medium · high · full- The status light on the board itself, not a strip on the connector. Turn it down if the board sits where you can see it while you drive. A fault ignores this and lights anyway, because a board turned down to nothing would report a problem by looking exactly like a board with no power. The values are an ORDER rather than a set, which is the one thing the protocol marks about a setting so a tool can draw it as a slider
power modedefault · eco- How soon the rig switches itself off with nothing driving it. The rails always follow the game. They come up on the first telemetry line and go down after the last, and this is only how long the board waits
board revauto · 1.0 · 1.1- Which hardware this is. Service only, and it is flagged as such over the protocol so a tool can keep it out of the way. Naming the wrong revision changes which way a pin is driven, so a board that is physically fine stops working and nothing says why. Auto reads it from the provision record and is the answer
save, and what survives
Nothing saves itself. A change takes effect at once and is gone on the next reset until you type save, which writes the whole configuration in one go: what is on the harness, the gauge mappings, what the controls do, the gamepad and the rails. There used to be five separate saves, one hanging off whichever command changed a value, and a person who moved a device, picked a dashboard and set the pointer gain had to remember which three owed one. Configuration is one thing to a person, so it is one command.
Each store reports on its own line, because a single "saved" over five writes hides the one that failed. A failed flash write is exactly what you need to know before powering down. What is saved lives in a part of flash the updater does not touch, so it survives both a power cycle and a firmware update. reset is what applies a saved setup change, because a device binds its hardware once, at boot.
What it will not tell you
No frame identifiers, no decoded payload bytes, no last-frame dumps. Whoever holds a unit can open this console, so everything it prints is published, and the ids and payload layouts are the part of this product that took a bench and months to find. Counters are named for what they count, which is also the better diagnostic. You want to know whether a device is talking, not on which id.
Gauges the board drives by itself
There are two signal outputs and only two. Channel 0 on pin 7 and channel 1 on pin 2. Either can be mapped to a telemetry value on the board, so a needle works with no host code beyond the telemetry you are already sending. Give it a source and, optionally, your own input range and your own on-time range. Swapping the ends of that range reverses the sweep, and the ends are signed, so a boost gauge reading below atmosphere maps from a negative number.
setup servo <ch> <src> [in_min in_max] [us_min us_max]
setup pwm <group> servo|pwm <frame µs>
saveThe SHAPE is separate, and it belongs to the group rather than to the channel, because one timer drives both pins and a timer has one frame for everything on it. As a servo that frame is 20 ms and the pulse may be anywhere from 500 to 3 500 µs. As PWM the duty is the signal and the frame wants to be short enough for the filter behind it to keep up. A channel with no range of its own gets 1 000 to 2 000 µs, which is what most gauges want. Off, nothing drives it at all.
rpm- Defaults to 0…7000rev/min
speed- Defaults to 0…300km/h
coolant- Defaults to 40…130°C
fuel- Defaults to 0…100%
oil- Defaults to 40…150°C
oilp- Defaults to 0…50tenths of a bar
boost- Defaults to −100…300hundredths of a bar, negative is vacuum
off- Defaults to —nothing drives the channel
Pulse defaults to 1000…2000 µs, and a mapped channel accepts anything from 500 to 3500 µs, wider than the nominal servo frame, because a gauge movement often needs the extra travel to reach the end of its own dial. Zero is refused. At the pin it releases the line rather than driving to it, so a mapping ending there goes limp instead of reading empty. While a channel is off it keeps its pulse pair, is not held to those bounds, and the host drives it directly. Going offline parks every mapped needle at its low end.
Outside a game
Most of what the board does has nothing to do with telemetry. All of it is on the unit you buy, running the P1LOT firmware. These are what the hardware is capable of rather than a separate toolkit.
- On every unit
A diagnostic with no computer at all
Unplug USB, leave the 12 V supply connected, and hold the button on the board for three seconds. The dashboard wakes, both needles cross their whole scale together, hold at the top, drop back to zero, and the ignition switches itself off. About fifteen seconds. It separates a hardware fault from a host-side one in a single gesture, which is otherwise three emails. The same hold with USB connected opens the firmware updater instead.
- On every unit
A dashboard, a knob, a gear lever and a wheel block, all at once
There are two sets of bus wires on the connector plus the LIN line, so you can run everything together on one pair, or give the dashboard a pair to itself if it wants one. You tell the board what you plugged in. `setup cluster`, `setup knob`, `setup shifter`, `setup wheel`, and it drives them. Nothing is assumed. A board out of the box drives nothing until you say what is there.
- On every unit
Driven by something that is not a game
The board takes one line of plain text per update, so it does not have to be a game sending it. A test rig, a replayed log, a script of your own, or a build server proving a dashboard still works. Anything that can open a serial port can move the needles.
The rules that will bite you
Every one of these has cost somebody an afternoon, which is why they are listed rather than left in the source.
- Keep sendingAt least 2 Hz. Six tenths of a second of silence is stale and the panel holds its last picture. Five seconds is offline, which walks the cluster down and parks everything.
- The rails are requestsThey come up when telemetry arrives and drop 30 seconds after it stops. They are supervised, so a fault can take one down under you. Read the state back rather than assuming.
- The 5 V fault flag pulsesIt is an edge, not a level. Polling it once and seeing zero tells you nothing. The verdict is the rail staying off.
- Ignore columns you do not knowBoth lines grow to the right and never in the middle. Split on the semicolon and read the columns you need. A reader that insists on an exact count breaks on the next firmware.
- Nothing saves itselfChange a setting and it takes effect at once, and is gone on the next reset unless you type
save. What is saved then survives both a power cycle and a firmware update.
Questions
Why is there only one COM port?
Because two identical-looking ports with nothing to say which is which is a support case waiting to happen. The console is not a second device, it is a mode of the only one. Send G1VE_ME_CLI on its own line and the shell takes the port; send any line starting with P1 and telemetry takes it back. SimHub sends one on every update, so the link recovers by itself the moment a host starts talking. Nothing is stored, and closing the port ends the session too.
Can I use the console and stream telemetry at the same time?
No, and that is deliberate. The console owns the byte stream raw, which is what makes it a real terminal. Characters echo as you type, backspace works, the arrow keys walk the history, Tab completes a command. Forwarding only whole lines to it would give you a command slot, not a console. Nobody services a board and drives a lap at the same moment.
I set the 12 V rail on and it turned itself off. Why?
Because the rails follow telemetry rather than a switch. They come up the instant a line arrives and drop together 30 seconds after the last one, once the cluster has been walked down properly. Keep sending and they stay up. Stop, and the rig puts itself to bed. What they are actually doing is in the status line’s flags, which you get by asking for the line with field 21.
The 5 V fault input reads zero, so nothing is wrong. Right?
No. That is the one input you cannot poll. The eFuse answers a short by cycling: limit, overheat, shut down, cool, retry. A single read lands in a gap far more often than not. The board catches the asserting edge in hardware and adds the flag time up. The verdict you want is the 5 V output going off and staying off, which is what the status line shows.
Why does the fuel gauge move slowly when everything else is instant?
Because a real cluster rejects a fuel level that appears out of nowhere. Power on straight into a full tank and the gauge stays dead. The board ramps it instead, in small steps the cluster accepts, so a full sweep takes about two seconds. It also does not park when you go offline, because a parked car does not drain its tank and the cluster computes its range readout from the same filtered value. Until a host states a level at all, the gauge sits at half rather than at empty with a reserve warning.
Why are the gamepad axes centred when nothing is wired to them?
Because each input reaches the processor through the resistor divider that scales 0…5 V down, and that divider holds the pin at zero on its own, so an unconnected input reads a clean zero rather than noise. Zero is one end of an axis, though, which a game will happily let you bind and then act on. Centred is the value that means nothing. The board enumerates the same either way, so nothing has to be re-detected when you do wire something.
Are the analog readings in volts at the connector?
No. They are millivolts at the processor pin, referenced against the chip's own factory-calibrated reference rather than a nominal 3.3 V, so the reading does not drift with the supply. The two DB15 inputs sit behind a 1 k / 1 k divider, a plain halving, so double them for volts at the connector. Everything the board itself reports about a calibration is already at the connector, because that is where a meter goes. The 12 V draw beside them is different again. That one is already converted, and is in milliamps.
That divider is a scale and not a protection. These pins are for the 5 V the connector hands out; 12 V on one of them reaches the processor as 6 V, which is past what it will take, and the damage is to the board rather than to whatever you plugged in. Nothing in the firmware sees it coming or can report it afterwards.
Do my settings survive a firmware update?
Yes, and a power cycle too. What is on the harness, the gauge mappings, what the controls do and the rail defaults live in a part of flash the updater does not touch, so a unit comes back from an update set up the way you left it. Nothing saves itself. Change something and type save before you power down, or it was only for this session.
How much do I have to send, and how often?
At least twice a second. After six tenths of a second of silence the board goes stale and holds the picture it has. After five it goes offline, which walks the cluster down, parks the needles and blanks the strip. You may send every field every time or only the ones that changed. An empty column means keep the last value.
Can I add support for a part you do not drive?
The firmware is built for exactly that, and not only for dashboards: clusters, selectors, controllers and wheel blocks are one registry, because an id, a place on the connector and a lifecycle describe all four. The fourth arriving on LIN rather than on a CAN pair changed a row rather than the registry. A new part is one driver file and one row, and the conflict rules, the console and the saved setup pick it up without being told. What it takes is not the code, it is the decoding. The frames, the counters and the checksums a given part refuses to work without. That is the work, and it is the work we do. Tell us what you have and it goes on the list.
Building something with it?
Tell us what you are wiring to it. The SimHub template is on the downloads page, the protocol reference and its Python mirror come with the board, and your email is answered by the engineers who wrote the firmware.
