Wiki SDR SA PRO
Frequency table and alarms
PRO The frequency table is the second list of the Scanner tab: frequency ranges with names that you know in advance. A signal of the list that lies in a range gets its name and type; a range can be split into channels of one width; and the alarm rules come from the table too. This page covers the table editor and CSV exchange, the class under a signal row, “width does not match”, the occupancy of ranges and channels, alarms, sound, the event log and IQ recording on an alarm. The signal search itself is described on the page Scanner: finding signals.
The frequency table
The switch at the top of the tab is Frequency table: N. Above the list of ranges is the Frequency table group with the buttons, the alarm settings and the message lines; the “?” circle before its heading briefly explains all of this.
A folded table row shows:
- the role icon: a grey square — label, a yellow circle — watch, a red circle — guard;
- the name;
- the range in megahertz, for example
87.5–108; - the occupancy in percent, or a dash while it has not been counted; in grey when the range is not in the current look.
A click on a row unfolds its fields; another click folds it. Only one row is unfolded at a time.
Row fields
Text in a field is applied with Enter or by leaving the field; Esc restores the previous value. The exception is the two Range, MHz fields: only Enter applies them, and leaving the field without Enter restores the value in force. A value with which the row would stop being a table row is not accepted: the field returns to the value in force, and the group above the list says Not accepted — … in red, with the reason.
- Name
- Cannot be empty.
- Type
- Any word of your choice: “broadcast”, “LTE”, “drone”. The alarm on types works by it.
- Range, MHz
- Two fields: the lower and the upper edge. Both are above zero, the lower is below the upper. Changing the edges restarts the occupancy count of this range.
- Width, kHz
- How wide a signal in the range is expected to be: from and to. An empty field means the bound is not given; you can give just one. The lower is not above the upper. The “width does not match” mark depends on these numbers.
- Channel step, kHz
- Empty — the range is not split into channels (next to it stands no channels). With a step, the range is split into channels of one width, and next to it is how many there are: channels: N. The step is no larger than the range itself and no finer than 4096 channels. See Channels.
- Role
- label (the default) — a name only; watch — an alarm on any signal in the range; guard — an alarm on a signal in the range that no narrower label row inside it explains. See Alarms.
- Priority
- A whole number from −999 to 999, default 0. Where ranges overlap, the name comes from the row with the higher priority.
- Comment
- Free text.
At the bottom of an unfolded row are the occupancy in words (see below) and a Remove button that removes this row at once.
Buttons
- Add
- A new row at the end of the table, named new, with the range you selected on the spectrum (how to select is on the page The main window and controls). If there is no usable selection, the range is 100–200 MHz, and you correct it in the fields. The new row is unfolded at once.
- From bands
- One row for each named band of the app — with the same name and edges as they are at that moment (see the “Bands” group). A row with the same name and edges is not added twice; the group says Rows added: N; already in the table: N.
- From a CSV file…
- Adds rows from a CSV file (see below). The same name and edges are not taken twice. A file with even one error gives no rows, and the message says which row is bad and why.
- To a CSV file…
- Writes the whole table to a CSV file. Active when the table is not empty.
- Remove all
- The first press only asks: the caption becomes Really remove all N? for four seconds. A second press within that time removes all rows, having first put a copy of what was in the file next to it — and it says where.
The table holds up to 2000 rows.
CSV format
The first line of the file is a header with the columns in any order. Required are name, f0_hz and f1_hz; the rest as needed. An unknown or repeated column is an error. Frequencies and widths are in hertz.
| Column | Row field |
|---|---|
name | Name |
kind | Type |
f0_hz, f1_hz | Range: lower and upper edge, Hz |
width_min_hz, width_max_hz | Expected width: from and to, Hz; empty — not given |
channel_step_hz | Channel step, Hz; empty — no channels |
role | Role: label, watch or guard; empty — label |
priority | Priority, a whole number from −999 to 999 |
comment | Comment |
- The separator is a comma, a semicolon or a tab: the program takes the one that occurs most in the header. If the separator is not a comma, numbers may use a decimal comma.
- The file must be in UTF-8. The program does not guess a table saved as a plain “CSV” in a Windows encoding and asks you to save it as “CSV UTF-8”.
- A file written by the program is UTF-8 with a byte-order mark, so a spreadsheet opens it without questions.
Where the table is kept
The table is saved after every edit to the file scanner\table.json in the SDR SA PRO data folder (for the program installed from a package — Documents\SDR SA PRO\scanner). Until anything in the table has changed, neither the file nor the folder exists.
- A file that could not be read is not overwritten. The tab says which row is bad and why, the table is locked (the editing buttons are inactive), and two buttons appear: Read the file again — after you have fixed the file by hand; Start a new table — then the broken file is renamed to
table.broken-N.json, not deleted. - Remove all leaves a copy
table.before-clear-N.jsonnext to it. - A file written by a newer version of the program is neither read nor overwritten.
The class under a signal row
A row of the signal list that lies in a range of the table gets a second line beneath it. It is made of parts separated by a dot “·”:
- the reason for an alarm, if there was one: alarm: guard, alarm: watch or alarm: type;
- the name of the range;
- channel N — when the row is a channel of a range with a step;
- the type of the range, if one is set;
- narrower than the expected … or wider than the expected … — see below.
The line is red when the alarm has not been acknowledged yet, yellow when the width does not match, grey otherwise. There is no line when the signal lies in no range.
- Where ranges overlap, the name and type come from one of them: the one with the higher priority, then the narrower, then the one higher in the table. The roles (watch, guard), however, are collected from all ranges covering the frequency.
- An edit of the table relabels what is already in the list at once — without waiting for the next look.
- It is a label of the frequency, not of the kind of signal: this version has no recognition of the signal type and no neural network. The Class line in the “How far to trust the list” fold of the Scanner tab says so too.
- The frequency for the class is the one the receiver itself shows: the table does not know the error of its reference oscillator.
Width does not match
If a range states an expected width and a signal row falls outside it, the row shows narrower than the expected … or wider than the expected … with the bound named.
- The tolerance is 10 % of the expected width and two bins: the list does not measure width more finely.
- The mark appears no earlier than after sixteen hits: until then the envelope of the row is not yet filled.
- “Narrower” is said only of a steady signal neither edge of which lies on a sweep tune seam or at the edge of the look: there it is the measurement that ends, not the signal.
- Channel rows and activity ranges do not get this mark.
Range occupancy
The percentage in a folded table row is the share of looks in which there was at least one detection in the range, confirmed or not. This also shows rare bursts, which the signal list by design does not keep. An unfolded row says the same in words:
- Occupancy N %: a detection in N looks out of N; noise alone would give N % — the last number says what noise alone would give: in a wide range a false detection happens even without a signal;
- with the suffix — out of view now when the range is not in view now;
- Occupancy has not been counted yet or Occupancy: the look does not cover this range.
A range counts as in view when at least half of it is measured. Counting starts afresh with Clear, with turning the search on again, and for a single row — with a change of its edges.
Channels
A range with a channel step is judged by the Scanner not bin by bin but by the power of each channel. Channels run from the lower edge of the range, each as wide as the step, and are numbered from one; a piece at the upper edge narrower than the step is not a channel.
- A channel is busy when its power above the floor exceeds the channel threshold, or when at least one of its bins stands above the bin threshold by itself — so a narrow carrier in a wide channel is not lost. The channel threshold is stated by the Channels line in the “How far to trust the list” fold of the Scanner tab.
- A busy channel is a separate row of the list with the channel’s edges; beneath it stand the range name and channel N. Neighbouring busy channels are separate rows even if their signals sit side by side; a busy channel and a wide signal over it are separate rows too.
- The level of a channel row is the power of the channel above the floor, not the peak of the signal in it.
- An alarm and an event-log row for such a row carry the channel number.
- Where ranges with channels overlap, the channels come from the one that wins the class.
- After the step is changed, a row is given a channel number only when it really sits on a channel of the new layout.
Below the step field of an unfolded row is the occupancy per channel: N of N looked-at channels busy; the busiest is channel N (N % of looks) or N channels looked at, none busy. It appears once the look has seen the channels of this range, and it is counted only for the edges and step under which the looks went.
When channels are not judged
Then the channels are searched in the ordinary way, bin by bin, and the Channels line says how many such there are:
- the channels of the range are narrower than 4 bins of the measurement;
- fewer than half of a channel’s bins are measured;
- there are over 4096 channels in the measurement;
- a channel is wider than the floor of this measurement can tell from noise (in tuned mode and in a sweep narrower than six tunes).
In a sweep the noise for channels is taken from the rest of the bins of the same tune, and when channels take up almost the whole tune — from the neighbouring tunes. A signal that fills such a tune entirely is then seen only from the level the Channels line states. In tuned mode and a narrow sweep there is no such spare noise: an unbroken run of busy channels wider than the floor sees past may read as free — the Channels line says how many channels stand in such runs.
Activity in a range
A hopping frequency and rare bursts usually do not become a signal row. They are seen in two ways: as a separate activity row in the signal list (see Activity ranges) and as the occupancy of a table range. An activity row gets a class from the table and raises alarms just like a signal row.
Alarms
The alarm rules are set by the frequency table — there is no separate list of rules.
- Watch
- An alarm on any signal that is there in the range of a row with the watch role.
- Guard
- An alarm on a signal in the range of a row with the guard role that no label row explains: the class of the signal does not come from a label. A known transmitter inside the zone is entered as a label row narrower than the zone — then it gives the class, and there is no alarm.
- Alarm on types
- The Alarm on types field above the list of ranges: types separated by commas (a semicolon works too). The alarm is on a signal whose class has a type from the list, wherever it appears. Upper and lower case are not told apart, repeats are dropped. An empty field — no such alarms.
- An alarm has one reason — the first by seniority: guard, watch, type.
- There is one alarm for one row of the list. A row that disappeared and came back, left the look and is in it again, or wavers around the threshold is the same row, and there will be no second alarm. A new alarm comes only for a new row, after Clear or after the search is turned on again.
- An activity range that later became a signal row at the same place does not raise a second alarm. A new signal that merely lies inside a wide activity range raises its own.
- A row is judged at every look until there has been an alarm about it: a watch zone placed over a signal that is already there speaks about it from the next look.
- A recording from a file and the demo signal give no alarms.
How an alarm shows
- The row’s dot and the line beneath it turn red; the line gives the reason.
- Above the signal list — Alarms: N and an Acknowledge button. It removes the highlight and resets the counter; the reason stays in the row.
- In the status bar at the bottom of the window — a red ALARMS: N counter, visible from any tab. Without unacknowledged alarms it takes no space.
- The signal’s mark on the spectrum is red.
- The Alarms line in the “How far to trust the list” fold of the Scanner tab says how many watched and guarded ranges there are and which types are listed, or there are no rules: the frequency table has no watched or guarded range, and the list of types is empty.
Sound, event log and IQ recording
Below the types field are three separate switches. All of them are off by default and are saved between runs. Below them is a message line: where the log is written, what could not be read, written or removed.
- Alarm sound
- The Windows system sound — one per look that had alarms, however many there were.
- Event log
- A row in a CSV file for every alarm. See below.
- Record IQ on an alarm
- A recording of the receiver stream when an alarm occurs. Next to it are a seconds field (active while the switch is on) and the caption s from the last alarm; tuned mode only. See below.
Event log
The log is written only while Event log is on. The files lie in the scanner folder of the SDR SA PRO data folder (for the program from a package — Documents\SDR SA PRO\scanner). The exact path is given by the line below the switches: Event log: … — a file per day (UTC), a row per alarm; no more than 1000 rows a day, the last 30 days are kept.
- One file per UTC day:
events-YYYY-MM-DD.csv, UTF-8 with a byte-order mark, the first line a header. - No more than 1000 rows a day. After that one row with the reason
limitgoes into the file, and further alarms are only counted: The limit of the day is reached: alarms not written — N. - The last 30 day files are kept: when a new one starts, the program itself removes the oldest beyond that — only those named exactly like a day file. A copy or an archive next to them is not touched.
- That a row was not written or an old file could not be removed, the tab says: The last alarm was not written to the log: …, Old log files that could not be removed: N.
| Column | What it holds |
|---|---|
time_utc | The time of the measurement in which the row first fell under the rule, UTC to the millisecond: 2026-10-10T12:34:56.789Z |
frequency_hz | The centre of the row, Hz |
width_hz | The width of the row, Hz |
level_db | The level in dB above the local floor, one decimal place; empty — no level |
reason | The reason: guard, watch or kind (type) |
name, kind | The class of the signal by the table: the name and type of the range |
what | signal — a signal row, activity — an activity range |
number | The serial number of the alarm since the list started, from one |
channel | The channel number; empty — the row is not a channel |
IQ recording on an alarm
- Tuned mode only. In a sweep the receiver does not stay on the signal: an alarm in a sweep gives no recording, and the IQ recording line in the “How far to trust the list” fold says tuned mode only — a sweep is running, the receiver does not stay on the signal.
- The ordinary recorder of the program writes it — into the same folder as manual recordings (see IQ recording), the whole receiver stream. The recording name starts with
scan-, the alarm frequency in megahertz and the UTC time, for examplescan-433.920MHz-20261020-101500. - Duration — in the seconds field: from 1 to 600, default 10. A value outside the limits is not accepted. The time counts from the last alarm: a second alarm during the recording extends it rather than starting a new one.
- There is no pre-trigger. The alarm comes after the row is confirmed, and what was before it is not recorded.
- A recording you started yourself is not touched by the Scanner: the alarm then stays without a recording, and the IQ recording line says so.
- If the program refused to record (for example, the disk is full or the device is transmitting), the IQ recording line says the recording did not start, and the Scanner does not ask again until you switch the option off and on.
- A recording stopped by you, the disk or an error is not resumed by the Scanner: the next alarm asks for a new one.
- What is happening with the recording is stated by the IQ recording line: on an alarm, N s from the last one — tuned mode only, no pre-trigger, then which name was requested and what is being written now.
Limits
- The class is a frequency label from the table, not a recognised kind of signal.
- Alarms come only from the table rules. There is no alarm on a level in dBm: the Scanner’s levels are dB above the floor.
- Recording on an alarm works only in tuned mode and without a pre-trigger.
- In tuned mode a channel inside a signal much wider than itself shows a level near zero for the first looks: the floor there was estimated from the signal itself. The level becomes true once the rows are confirmed.
- A strong carrier in the edge bin of a channel occupies the neighbouring channel too.
- A recording from a file and the demo signal give no alarms.