Wavy mit vier Stationstasten

Ein Beitrag zum Oster-Contest 25 von Günther Zöppel

                                Elektronik-Labor  Literatur  Projekte  Lernpakete  UKW               




Die Osterfeiertage sind vorüber, und es blieb mir ein wenig Freizeit, um mich weiter mit den Sonderfunktionen des Bausteines zu befassen. Dabei habe ich festgestellt, dass nicht nur der Kontakt PA3, sondern auch die drei rechts davon auf der freien Kontaktleiste liegenden Pins eine Abruf-Funktion der gespeicherten  Sender reproduzierbar bewirken, wenn man diese kurz auf „0“ zieht. Deswegen habe ich den in meinem  Beitrag  zum Osterwettbewerb (WAVY OLED) vorgestellten Sketch und die Schaltung etwas erweitert, indem ich einen „Schnellabruf“ per Taster der gespeicherten Sender in die Schaltung eingefügt habe. Dieser bewirkt, dass ich im Zustand „Alternativanzeige“ (D6=0) die ersten 4 in einem vorherigen Bedienschritt im WAVY-Modul abgespeicherten Sender mit Namen und zugehöriger Frequenz auf dem Display anzeigen und natürlich auch hören kann. Also ein bequemer Schnellaufruf meiner maximal 4 Lieblingssender, der den Bedienkomfort des WAVY-Radios enorm erhöht. Ich muss dazu nur die Namen und zugehörigen Frequenzen vor dem Kompilieren des Sketches in den Quelltext eintragen und vier zusätzliche Taster an die freien Kontakte des Wavy Moduls und des ESP8266 anschließen.



Folgender Quelltext ist dabei entstanden:

//WAVY OLED mit Senderspeicher
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <ESP8266WiFi.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET    -1  // Reset-Pin nicht benötigt
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define A0_PIN A0  // Analoger Eingang für die Steuerspannung
#define A2_PIN A0  // Batteriespannungseingang (ESP8266 nutzt A0 für alle analogen Messungen)
#define SWITCH_PIN D6 // Digitaler Pin zur Umschaltung
#define BUTTON_PIN_1 D3 // Taster für Sender 1
#define BUTTON_PIN_2 D4 // Taster für Sender 2
#define BUTTON_PIN_3 D5 // Taster für Sender 3
#define BUTTON_PIN_4 D7 // Taster für Sender 4

#define V_MIN 0.0   // Minimale Spannung (0V -> 87,5 MHz)
#define V_MAX 1.0   // Maximale Spannung (1.0V -> 108 MHz, ESP8266 Analogspannung max 1V)
#define F_MIN 87.5  // Minimaler Frequenzwert
#define F_MAX 108.0 // Maximaler Frequenzwert
#define BATTERY_MAX 8.4 // Maximale Batteriespannung

// WLAN-Zugangsdaten
const char* ssid = "Mein-WLAN";
const char* password = "Mein-WLAN-Passwort";

// NTP Client setup
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", 7200, 60000); // Offset 7200  MESZ, 3600 MEZ

// Tabelle mit Sendernamen und Frequenzen
const char* stationNames[4] = {"RSA", "MDR JUMP", "PSR", "MDR SA"};
const float stationFrequencies[4] = {101.0, 89.8, 105.4, 92.8}; // Frequenzen und Namen der Sender eintragen
int currentStation = -1;

void setup() {
    pinMode(SWITCH_PIN, INPUT_PULLUP); // Schalter-Pin mit internem Pullup-Widerstand
    pinMode(BUTTON_PIN_1, INPUT_PULLUP);
    pinMode(BUTTON_PIN_2, INPUT_PULLUP);
    pinMode(BUTTON_PIN_3, INPUT_PULLUP);
    pinMode(BUTTON_PIN_4, INPUT_PULLUP);

    display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // I2C-Adresse 0x3C
    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(10, 5);
    display.print("FM Tuner WAVY");
    display.display();

    // Mit WLAN verbinden
    WiFi.begin(ssid, password);
    display.setCursor(10, 20);
    display.print("Connecting to WiFi");
    display.display();
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        display.print(".");
        display.display();
    }

    // NTP Client starten
    timeClient.begin();
}

void loop() {
    timeClient.update();

    display.clearDisplay();
    display.setCursor(10, 5);
    display.print("FM Tuner WAVY");

    if (digitalRead(SWITCH_PIN) == LOW) {
        // Externer Eingang aktiv
        if (digitalRead(BUTTON_PIN_1) == LOW) currentStation = 0;
        if (digitalRead(BUTTON_PIN_2) == LOW) currentStation = 1;
        if (digitalRead(BUTTON_PIN_3) == LOW) currentStation = 2;
        if (digitalRead(BUTTON_PIN_4) == LOW) currentStation = 3;

        if (currentStation != -1) {
            display.setCursor(10, 20);
            display.print(stationNames[currentStation]);
            display.print(": ");
            display.print(stationFrequencies[currentStation], 1);
            display.print(" MHz");
        } else {
            display.setCursor(10, 20);
            display.print("Alternativanzeige");
        }

        // Batteriespannung messen
        float batteryVoltage = analogRead(A2_PIN) * (1.0 / 1023.0) * (BATTERY_MAX / 1.0);
        display.setCursor(10, 35);
        display.print("Battery: ");
        display.print(batteryVoltage, 2);
        display.print(" V");

        // Zeit anzeigen
        display.setCursor(10, 50);
        display.print("Time: ");
        display.print(timeClient.getFormattedTime());
    } else {
        // Normale Anzeige
        currentStation = -1; // Zurücksetzen des Senders

        float voltage = analogRead(A0_PIN) * (1.0 / 1023.0);
        voltage = constrain(voltage, V_MIN, V_MAX);
        float frequency = mapFloat(voltage, V_MIN, V_MAX, F_MIN, F_MAX);

        display.setCursor(10, 20);
        display.print("FREQ: ");
        display.print(frequency, 1);
        display.print(" MHz");

        // Skala mit erhöhter Auflösung
        display.setCursor(10, 40);
        display.print("-|-|-|-|-|-|-|-|-|-");

        // Zeigerposition berechnen
        int position = map(voltage * 100, V_MIN * 100, V_MAX * 100, 10, 110);
        display.fillTriangle(position - 1, 55, position + 1, 55, position, 50, SSD1306_WHITE);

        // Pfeilspitze
        display.drawLine(position, 49, position - 2, 52, SSD1306_WHITE);
        display.drawLine(position, 49, position + 2, 52, SSD1306_WHITE);
    }

    display.display();
    delay(200);
}

// Hilfsfunktion für Gleitkommazahlen
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max) {
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
// Ende Sketch



Hiermit kann ich nun meine 4 Lieblingssender schnell aufrufen. Die Uhrzeit ist dank der Einwahl ins heimische WLAN auch immer aktuell, und die Batteriespannung kann überwacht werden, um rechtzeitig nachzuladen. Damit ist der Bedienkomfort sehr gestiegen. In einer weiteren Ausbaustufe könnte damit ein komplettes Stereo Media Center entstehen, ähnlich meinem ersten eingereichten Projekt, aber evtl. mit größerem Display und erweitertem Bedienfeld an der Frontplatte. Möglicherweise  könnte der PadaukController des Wavy-Moduls die hier mit dem ESP8266mini realisierten Funktionen noch mit übernehmen, um Hardware zu sparen. Dazu muss man sich aber näher mit der Programmierung  dieses Controllers (PGS134) und seinem Zusammenspiel mit dem Empfangs-Chip CL6017 befassen.

Günther Zöppel
April 2025


Elektronik-Labor  Literatur  Projekte  Lernpakete  Kurzwelle