DIY Shortwave Propagation Monitor - Measure Ionosphere Conditions
Learn how to make a simple device for monitoring the state of the ionosphere and the quality of shortwave signals using the CA3089 chip.

This is affected by several factors such as Solar activity (the most important factor), time of day (day or night), seasons, and others. In this project I will present you a very simple way to measure the current conditions of the ionosphere, and therefore the conditions for receiving shortwave signals.
This is an extremely useful tool for SW listeners because at any moment with one glance at the instrument they know what quality of reception they can expect at a given moment. Basically I'm using an old circuit diagram from Elektor magazine from the 1990s.



At the beginning, I tested with a digital multimeter and an analog instrument (5V voltmeter).


The device is very simple to make and consists of one IC (CA3089), several passive elements (resistors, capacitors and inductance) and an output unit that displays the result, which can be a small analog instrument, a multimeter, or as in my case, an OLED display with Arduino.

In my special case, instead of a voltmeter, I use an Arduino with an OLED display.

Now let's see how the device works in real conditions: When turning on the display, a Relativity numerical value appears in the middle, and a small horizontal Bar indicator in the upper part. Currently, without an antenna connected, the value is about 150.
I map the entire input from 0 to 1023, which means that the values on the display from 0 to 1024 correspond to a voltage from 0 to 5V.

By connecting an antenna to the input, the bar moves to the right, and the numerical value also changes. In fact, these parameters show us the ability to reflect SW signals in the Ionosphere, i.e. SW propagation at that moment. After a short time of using this instrument, I can now notice even minimal changes in the reception conditions in this area.

And finally a short conclusion. This project is an extremely useful tool for any shortwave radio listener, allowing for precise monitoring of changes in the atmosphere. With a few passive elements you get a professional device for diagnosing radio signals.
// by mircemk April, 2026
#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
// ---- UI (поголем BOX долу) ---- const int BAR_Y = 2; const int BAR_H = 12; const int BAR_X = 2; const int BAR_W = 124;
const int BOX_X = 6; // помал margin const int BOX_Y = 20; // спуштено нагоре малку const int BOX_W = 116; // пошироко const int BOX_H = 44; // повисоко (скоро до дното) const int BOX_R = 8;
// ---- Analog ---- const int ANALOG_PIN = A0;
// ======= РАНГ (ADC) ======= int IN_MIN = 60; int IN_MAX = 1000;
static inline int clampInt(int v, int lo, int hi) { if (v < lo) return lo; if (v > hi) return hi; return v; }
static inline int mapLongToInt(long x, long in_min, long in_max, long out_min, long out_max) { if (in_max == in_min) return (int)out_min; return (int)((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min); }
void drawCenteredTextInBox(const char* txt, int textSize) { display.setTextSize(textSize);
int16_t x1, y1; uint16_t w, h; display.getTextBounds(txt, 0, 0, &x1, &y1, &w, &h);
int tx = BOX_X + (BOX_W - (int)w) / 2; int ty = BOX_Y + (BOX_H - (int)h) / 2;
display.setCursor(tx, ty); display.print(txt); }
void setup() { analogReference(DEFAULT); Wire.begin();
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { while (1) {} } display.clearDisplay(); display.setTextColor(SSD1306_WHITE); display.display(); }
void loop() { int raw = analogRead(ANALOG_PIN);
int a = IN_MIN, b = IN_MAX; if (a > b) { int t = a; a = b; b = t; }
int rawWin = clampInt(raw, a, b);
int rel1000 = mapLongToInt(rawWin, a, b, 0, 1000); int barFill = mapLongToInt(rawWin, a, b, 0, BAR_W);
display.clearDisplay();
// BAR display.drawRect(BAR_X, BAR_Y, BAR_W, BAR_H, SSD1306_WHITE); int innerW = barFill - 2; if (innerW < 0) innerW = 0; if (innerW > BAR_W - 2) innerW = BAR_W - 2; display.fillRect(BAR_X + 1, BAR_Y + 1, innerW, BAR_H - 2, SSD1306_WHITE);
// BOX display.drawRoundRect(BOX_X, BOX_Y, BOX_W, BOX_H, BOX_R, SSD1306_WHITE);
// број (auto size: 0-999 големо, 1000 помало) char buf[6]; snprintf(buf, sizeof(buf), "%d", rel1000);
int size = (rel1000 >= 1000) ? 3 : 4; // 1000 да собере drawCenteredTextInBox(buf, size);
display.display();
delay(1000);
}

Diskussion (0 Kommentare)