A small antenna array you steer electronically. And mostly, a study of what happens when you try to make it do what the theory says it should.
- Status: first board designed and its experiments specified; no hardware built yet
- Last reviewed: 2026-09-28
The short version. AetherArray is four antennas working at 2.44 GHz. You steer the beam by switching short lengths of line in and out of each antenna's feed, so nothing moves. Steering isn't the hard part, though. Calibration is. Every real array points a little wrong, and this project asks two things: how few measurements does it take to fix that, and can an array that's been calibrated before use its own history to do it faster next time? Nothing is built yet. The first board is designed down to its schematic. The experiments that will judge it are written, with their pass or fail rules fixed before any data exists. And the first hardware is waiting on one short visit to a network analyser. This repository is the public lab notebook for all of it.
An antenna array is a group of small antennas, each fed on its own. Change the phase of the signal going to each one and you steer the beam. No motors.
element 0 element 1 element 2 element 3
| | | |
phase φ0 phase φ1 phase φ2 phase φ3
| | | |
+---------------+--------------+--------------+
|
same source signal
If all the elements radiate in phase, the beam goes straight ahead. Shift the phases step by step along the row and it tilts. That's how modern radars and phone base station antennas work.
On paper it's simple. A real array never points exactly where you ask, though, and that gap is what this whole project is about.
Here's how theory describes a line of antennas:
Piece by piece:
-
$N$ is how many elements there are. -
$a_n$ is the amplitude sent to element$n$ . No unit. -
$\phi_n$ is the phase we give it, in radians. It's our control knob. -
$d$ is the gap between neighbouring elements, in metres. -
$k = 2\pi/\lambda$ is the wavenumber, in radians per metre. It turns a distance into a phase shift: one wavelength of travel turns the phase by$2\pi$ . -
$\theta$ is the angle you look from, measured from the line straight out of the array. -
$n k d \sin\theta$ is the phase shift you get for free, because the wave from element$n$ travels a slightly different distance to reach you. -
$AF(\theta)$ is the total field in direction$\theta$ : every element's contribution, added up.
What it means: contributions add when they arrive in phase, and cancel when they
arrive opposite. To point the beam at
So you cancel out, in advance, the phase shift the geometry would add.
Rough numbers for four elements, half a wavelength apart:
| Quantity | Approximate value | Meaning |
|---|---|---|
| Beam width | about 25 degrees | with only four elements the beam is not narrow |
| Side lobe level | about -13 dB | there is still energy outside the main beam |
| Array gain | about 6 dB over a single element | doubling the element count adds 3 dB |
All of that assumes everything is perfect.
This one calculation is enough to justify the whole project.
In ordinary coaxial cable, a signal travels at about 66 percent of the speed of
light. With that velocity factor,
So every millimetre of cable shifts the phase by:
Make one cable a centimetre longer than another and you've added about 44 degrees of phase error. Cut your cables by hand and the pattern falls apart.
And cable length is just one source of error:
| Error source | Origin | Order of magnitude | Correctable? |
|---|---|---|---|
| Cable length | fabrication | tens of degrees | yes, by calibration |
| Component tolerance | manufacturing spread | a few degrees to a few dB | yes |
| Coupling between neighbouring elements | the antennas see each other | depends on spacing, often significant | partly |
| Thermal drift | temperature change | a few degrees | yes, if you recalibrate |
| Connectors | tightening, wear | a few degrees | yes, but variable |
| Environment | reflections off nearby objects | highly variable | no, you have to control the measurement site |
Put them together and it adds up fast. A handy rule: if the phase errors are random,
with standard deviation
With tools/rfkit/budget.py uses the exact version.
In plain terms: an uncalibrated array works. It just works badly, and you can't predict how badly.
Instead of chasing each defect separately, you can put all of them into one complex matrix:
-
$\mathbf{x} \in \mathbb{C}^{N}$ is what we command: one complex number per channel, meaning the amplitude and phase we ask for. -
$\mathbf{y} \in \mathbb{C}^{N}$ is what actually comes out of each element. -
$\mathbf{H} \in \mathbb{C}^{N \times N}$ holds everything else: each channel's gain and phase error on the diagonal, and the coupling between elements off it.
If
Calibrating means measuring
This is where it stops being tinkering and becomes applied maths. Measuring
For the first board we model
-
How many measurements does calibration take? An array with
$N$ channels has at least$N$ complex unknowns, and a lot more if you want the coupling too. Every measurement takes time and comes with noise. - Can you calibrate without measuring phase? Lots of simple setups only measure power. Getting phases back from power alone is a classic maths problem, and it isn't easy.
- Is a classical method enough? Least squares, regularisation, direct inversion. They're old, proven and cheap, and you need to know how far they go before trying anything fancier.
- Can a learned method cut the number of measurements? Not on a first calibration, as it turns out. With four elements, the classical methods already sit at the information limit for power only measurement, so there's nothing left to save. What survives is a narrower question, and a more interesting one: once the array has been calibrated before, can a prior learned from its own drift history recalibrate it with fewer measurements than starting from scratch?
- How long does a calibration stay valid? People rarely look at this. It's easy to measure, directly useful, and it's now the question the learning track depends on.
The order isn't an accident. The project doesn't start with machine learning. It
starts with what already works, then looks for where that stops being enough. Question
4 came out of exactly that: the obvious claim about learning didn't survive a simple
counting argument, and the one that replaced it is sharper. The reasoning is in
docs/architecture/ml-calibration.md, and the choice is recorded in
decisions/0002-learning-as-a-drift-prior.md. Learning only ever enters as a prior
inside a physical inverse problem. It never becomes a black box that predicts a
command: docs/mathematics/inverse-calibration.md.
The first board, Rev A, comes from decisions 0003, 0004 and 0005. It's really two boards, joined by four short cables.
antenna board beamforming board
-------------- --------------------------------------------
patch 0 --SMA==jumper==SMA-- enable --- 3 phase bits --+
patch 1 --SMA==jumper==SMA-- enable --- 3 phase bits --+-- 4-way -- path -- analyser
patch 2 --SMA==jumper==SMA-- enable --- 3 phase bits --+ divider select or on board
patch 3 --SMA==jumper==SMA-- enable --- 3 phase bits --+ detector
|
16 control lines, ribbon cable
|
DE1-SoC board, FPGA and processor
Why two boards? Each antenna gets its own connector. That means we can measure every element on its own, measure the coupling between any two, and use the one calibration method that needs no outside probe at all: it transmits on one element and listens on another. Put everything on one board and all three of those doors close for good.
How the beam gets steered. Each channel has three switched line phase bits: 45, 90 and 180 degrees. In each bit, a pair of small RF switches, PE4259, picks either a short path or a longer one. Three bits give eight phase states, 45 degrees apart. That leaves a rounding error of about 13 degrees rms per channel, and no calibration can remove it. It's the yardstick every other error in the project gets measured against. Two bits would've been cheaper, but they'd have damaged the very baseline the measurement counts are compared with. There's no amplitude control. Phase only.
How you measure one channel alone. A seventh switch in each channel either lets the signal through or terminates it. So any single channel can be measured while the others are switched off electronically, and nobody has to touch a cable. That's twenty nine switches in total.
How the board measures itself. The four channels meet in a divider. A path selector connects that common port either to the network analyser, which measures phase, or to a detector on the board, an AD8318, which only measures power but can run on its own for days. Two temperature sensors, MCP9808, and the detector's own die temperature are logged too, because drift with temperature is exactly what the learning track studies.
What drives it. An external DE1-SoC board, which has an FPGA and an ARM processor on it. The FPGA sets all sixteen switch lines on the same clock edge, holds them still while the detector is sampled, and timestamps everything from one clock. The processor stores the data and runs the inference. A microcontroller could steer the beam fine. The problem is that switching lines right next to the receiver would add an error that follows the commanded state, and that error looks exactly like a calibration coefficient. EXP-005 checks whether that worry is real.
Why 2.44 GHz? It's the only licence free band at this size that lets you transmit continuously: 2400 to 2483.5 MHz, at 10 mW. And the analyser goes up to 3 GHz. The lower bands limit how often you're allowed to transmit, which a swept measurement can't respect. That's decision 0004.
Where it stands. The schematic is drawn in KiCad by a script, so the four channels are identical by construction, and it passes its electrical rule check. It still has to be redrawn for the DE1-SoC controller. Line lengths and antenna sizes wait for the board stack up. Nothing has been ordered, and decision 0006 says what each purchase is waiting for.
| Tool | What it does in this project | Where it runs |
|---|---|---|
| Ansys HFSS, full wave electromagnetic solver | simulates the antenna board: the coupling between the four patches as a 4 port S parameter matrix, and each element's embedded radiation pattern. That's what gate G4 judges, EXP-011. Later, the switched line section, as a check on the circuit model | HFSS Student at home, as long as the converged mesh stays under its documented limit of 64,000 volume elements; the full licence at school only for a model that goes over |
| PyAEDT | scripting HFSS, for geometry sweeps | planned, not used yet |
| Keysight ADS, circuit simulator | a separate model of the switched line channel and the divider, to cross check HFSS under decision 0007 | at school only, and optional: nothing in the repository needs it to be reproduced |
| scikit-rf | reads every S parameter file, from any tool, as a Touchstone network, and has transmission line models, so a circuit model can be built at home too | everywhere |
| rfkit, this repository's own layer on top of scikit-rf | turns those files into answers: it compares only over the band two tools share, takes phase differences around the circle, compares state by state, builds the array state |
everywhere, 104 tests, tools/rfkit/
|
| Network analyser, a Rohde and Schwarz ZVL | every real RF measurement: 9 kHz to 3 GHz, phase and magnitude, and it exports Touchstone files | the school lab |
| KiCad | the schematic, generated by hardware/rev-a/tools/generate-schematic.py
|
at home |
| DE1-SoC with Quartus | the controller, and the acquisition test of EXP-005 | at home |
| Python, NumPy, matplotlib, reportlab | analysis, figures, and the PDF runbooks | everywhere |
Every measurement and every simulation gets to the analysis the same way:
HFSS ---.
ADS ---+--> Touchstone file --> scikit-rf --> rfkit --> comparison report
analyser -' --> array state H
--> G4 verdict on coupling
--> dataset for inference
Home and school. The analyser, the full HFSS licence and ADS are all at school. So
every task in the repository is tagged LOCAL, SCHOOL-SOFTWARE, SCHOOL-BENCH or
EITHER. Work stays at home whenever that's good enough scientifically. It only moves
to school for an instrument, or for a limit a home tool can't meet. Every school task
gets a step by step PDF, built from a Markdown file and checked automatically, so you
can follow it at the machine days later without having to remember the whole project.
They're all listed in docs/runbooks/register.md, and the first one that's ready is
docs/runbooks/pdf/SCH-001-exp004-analyser-audit.pdf.
Simulation before hardware. Anything a formula or a simulator can answer gets answered that way first. In a simulation you know the defects exactly, so you can check whether a method really works. Decision 0001.
Rules written before the data. When an experiment decides something, its rule is committed before a single number exists, and the commit is the timestamp. The acquisition test of EXP-005, the thresholds of decision 0007 and the coupling test of decision 0008 were all done this way. If a rule turns out to be unusable, that's recorded as a failure and the experiment is redone. It's never adjusted to fit a result.
Nothing made up. A threshold either comes from a derivation you can rerun, or it says "unresolved" and names what's missing. An unverified figure is marked as unverified. A value that isn't decided yet is written as a placeholder that names the decision that will fix it.
Decisions so far.
| Decision | What it settles |
|---|---|
| 0001 | simulator before hardware |
| 0002 | learning enters as a prior over drift, not as a shortcut to first calibration |
| 0003 | the Rev A architecture: two boards, four elements, three bit switched lines, phase only |
| 0004 | the working frequency, 2.44 GHz |
| 0005 | an external DE1-SoC as the controller |
| 0006 | purchases staged by what they unblock, so that none waits on a question it is needed to answer |
| 0007 | provisional acceptance thresholds, derived from the three bit rounding floor |
| 0008 | gate G4, the test of whether coupling can be left out of the calibration model |
Gates still open. G2 asks whether drift over a few hours is bigger than the measurement's own repeatability, and it decides whether the learning track exists at all. G4 has its test and is waiting for coupling data. The budget gate gets settled at order time.
| Done | In progress | Waiting |
|---|---|---|
| architecture, frequency and controller decided | the analyser audit, EXP-004: four of nine readings complete, four partial, one not taken; one visit finishes it, runbook SCH-001 | the purchases, which wait on that visit |
| schematic captured, rule check clean | the acquisition test, EXP-005 Phase A, ready to run at home | the repeatability floor, EXP-005 Phase B, which needs antennas and a detector |
| RF data layer, error budget and coupling test, tested | the antenna geometry, and with it EXP-011 | |
| school runbook system and register | fabrication, after the pre-fabrication gate of decision 0006 |
To measure a radiation pattern properly, you have to stand far enough away that the wave has become flat. The usual minimum distance is:
where
For four elements at 2.44 GHz, half a wavelength apart, that's 61.5 mm between them,
so
Under a metre. It fits on a table. But in a normal room the signal bounces off walls, the floor, furniture and whoever's doing the measuring. Those echoes add to the direct signal and can shift it by several decibels, which is about the size of what we're trying to measure.
That's the real obstacle, and the design works around it:
| Route | Principle | Where it stands |
|---|---|---|
| Conducted measurement, channel by channel | measure each channel through a cable at its connector | the backbone: the labels the learning track needs are conducted end to end |
| Coupling measured between element pairs | transmit on one element, receive on another | possible because every element has its own connector |
| Careful free space measurement | distance, differential measurements, absorbers | for the radiated experiments; its quality is what EXP-005 Phase B measures |
| Time domain gating on the analyser | separate the direct path from later echoes | depends on the installed options, reading O8 of EXP-004 |
| An acoustic array | the same mathematics at 40 kHz, with a microphone | not chosen for the first board; kept as the documented response if room reflections prove to dominate |
| Configuration | What it represents |
|---|---|
| Ideal simulation | what theory predicts |
| Real system, uncalibrated | what you get for free |
| Classical calibration | inversion, least squares, regularisation |
| Rotating element field vector, at its own minimum | the power only baseline, not padded to flatter a rival |
| Orthogonal coding | all elements measured at once, the strongest count baseline |
| Mutual coupling | calibration with no external probe, which the per element connectors allow |
| Adaptive measurement selection | choosing each measurement for information gain |
| Learned drift prior | recalibrating from history rather than from nothing |
For each one: pointing error, gain, side lobe level, beam width, how many measurements it needs, how long calibration takes, and how stable it stays over time. Every count is also compared with the information limit, so a method gets judged by what's possible, not just by what its rivals managed.
| Source | What you find there | What you do not |
|---|---|---|
| Academic | array theory, mutual coupling, calibration methods including power only ones, inverse problems | how many physical measurements each method actually needs, compared |
| Industry | fully documented educational kits, beamforming integrated circuits, application notes | how long a calibration stays valid outside a climate chamber |
| Open source | S parameter processing, Bayesian optimisation, amateur projects that document their failures | a cross validation between a radio frequency array and an acoustic one |
The details are in research/state-of-the-art.md, and the checked references are in
docs/references/bibliography.md.
What we count isn't computer time. It's the number of physical measurements. A measurement means moving something, waiting for it to settle, and taking a noisy reading. The maths afterwards takes milliseconds.
| Criterion | Threshold |
|---|---|
| Number of measurements consumed by the method | mandatory next to any calibration result |
| Validation in simulation, where the injected defects are known | mandatory, it is the only place correctness is checkable |
| Measurement repeatability quantified | mandatory, it sets the significance threshold |
| Repetition over several defect draws | mandatory, one draw concludes nothing |
| Measurement conditions and environment recorded | mandatory, room echoes look like lobes |
| Simulated against measured labelling | mandatory |
The reference is the uncalibrated array. It's what tells you how much calibration actually buys you.
All of this runs on a normal computer. No licence, no instrument.
python -m pip install -r requirements.txt
cd tools
python -m pytest rfkit/tests -q # the RF data layer, on synthetic data
python -m rfkit.cli example --out /tmp/rfkit # a worked example, synthetic and labelled so
python -m rfkit.cli budget # the error budget and how each threshold is derived
python -m rfkit.cli g4-chart # the coupling test on synthetic matrices
cd ..
bash tools/check-docs.sh # the documentation conventions
python tools/runbooks/build.py --check # the school runbooks and their PDFsNothing these commands print is a measurement of a real array. Every trace they use is
marked synthetic.
Regenerating the schematic, python hardware/rev-a/tools/generate-schematic.py, also
needs KiCad 10. It's free and open source, and the generator reads its stock symbol
libraries. Right now it expects them where the Windows installer puts them by default.
| You want to | Go to |
|---|---|
| the scope and the questions | docs/scope.md |
| the equations, explained | docs/mathematics/formulation.md and docs/mathematics/inverse-calibration.md |
| why the first board looks the way it does | docs/architecture/rev-a-rf-architecture.md and decisions/0003-rev-a-rf-architecture.md |
| where learning fits, and where it does not | docs/architecture/ml-calibration.md |
| the schematic | hardware/rev-a/ |
| the RF data layer and its tools | docs/architecture/rf-data-layer.md and tools/rfkit/ |
| the experiments, their rules and their results | experiments/plan.md and results/ |
| every decision, and what would reopen it | decisions/ |
| what is known, assumed and still to verify | docs/uncertainties.md |
| the instruments, and what runs where | docs/hardware/measurement-bench.md and docs/runbooks/ |
| how the documents are written | CONVENTIONS.md |
Not decided yet. The repository has code, will have measurements, and already has
board design files. The analysis is in LICENSE-NOTES.md.