Wer hat schon einmal was mit Lazarus/FPC und SDR gemacht?

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
juelin
Beiträge: 310
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Wer hat schon einmal was mit Lazarus/FPC und SDR gemacht?

Beitrag von juelin »

Hallo Lazarus Gemeinde,
ich habe heute mal ein sehr spezielles Problem.
Ich möchte gerne in Lazarus meinen SDR (RTL2832SDR) programmieren.
Ich möchte da ADSB (Daten von Flugzeugen) empfangen und auswerten.
Habe Lazarus 4.2 und FPC 3.2.2
Benutze librtlsdr.dll und rtl_sdr.pas.
Leider habe ich da ein paar Probleme.
Ich kann zwar den SDR OPEN und CLOSE. Auch kann ich den SDR auslesen (RTL Type und Tuner Type)
und Empfangsfrequenz, Sample Rate und Tuner Gain setzen.
Wenn ich aber Daten empfange (mit rtlsdr_read_ Sync oder Async) bekomme ich nur Schrott.
Habe mir als Beispiel den Sourcecode von dump1090 genommen (der ist allerdings in C).
https://github.com/antirez/dump1090
Ich möchte ja in Pascal mit Lazarus arbeiten.
Gibt es Jemand der schon einmal was mit dem SDR in Lazarus gemacht hat?
Habe mal librtlsdr64.dll und rtl_sdr.pas als ZIP-File im Anhang.
Bin auf die Antwort gespannt.
Danke und Gruß
Jürgen
Dateianhänge
adsb.zip
(521.94 KiB) 21-mal heruntergeladen

Mathias
Beiträge: 7002
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Wer hat schon einmal was mit Lazarus/FPC und SDR gemacht?

Beitrag von Mathias »

Ich habe mal etwas mit Hilfe von ChatGPT gemacht, ob dir dies weiter hilft kann ich nicht sagen, auf jedenfalls werden Daten empfangen.
Den orignal C-Code von ChatrGPT habe ich nicht mehr, habe es auf Pascal übersetzt,

Code: Alles auswählen

program project1;
uses
  rtl_sdr;

  function printInfo: longint;
  var
    device_count: Tuint32_t;
    i: integer;
    vendor, product, serial: array[0..255] of ansichar;
  begin
    device_count := rtlsdr_get_device_count;
    WriteLn('Device Couint: ', device_count);

    for i := 0 to device_count - 1 do begin
      WriteLn(i: 3, '. ', rtlsdr_get_device_name(i));
      rtlsdr_get_device_usb_strings(i, vendor, product, serial);
      WriteLn('    Hersteller: ', vendor, ' Produkt: ', product, ' Serie: ', serial);
    end;
    WriteLn();
    Exit(device_count);
  end;

  procedure printBuffer;
  const
    DEFAULT_SAMPLE_RATE = 2400000; // 2.4 MHz
//    DEFAULT_FREQ = 100000000;  // 100 MHz
    DEFAULT_FREQ = 102800000;  // 102.8 MHz
    SAMPLE_COUNT = 256 * 1024;// 256k Samples

  var
    dev: Prtlsdr_dev_t;
    device_index: Tuint32_t = 0;
    buffer: pbyte;
    r, n_read, status: longint;

  begin
    // Gerät öffnen
    if rtlsdr_open(@dev, device_index) < 0 then begin
      WriteLn('Konnte RTL-SDR Gerät nicht öffnen !');
      Exit;
    end else begin
      WriteLn('RTL-SDR Open [Ok]');
    end;

    // 1. Mittenfrequenz einstellen (z.B. 100 MHz für UKW-Radio)
    status := rtlsdr_set_center_freq(dev, DEFAULT_FREQ);
    if status < 0 then begin
      WriteLn('Fehler beim Einstellen der Frequenz !');
      rtlsdr_close(dev);
      Exit;
    end else begin
      WriteLn('Set Frequenz [Ok]');
    end;

    // 2. Abtastrate einstellen (z.B. 2.4 MS/s)
    status := rtlsdr_set_sample_rate(dev, DEFAULT_SAMPLE_RATE);
    if status < 0 then begin
      WriteLn('Fehler beim Einstellen der Abstastrate !');
      rtlsdr_close(dev);
      Exit;
    end else begin
      WriteLn('Set Abstastrate [Ok]');
    end;


    // 3. Automatische Verstärkungsregelung (AGC) aktivieren
    status := rtlsdr_set_tuner_gain_mode(dev, 0);
    if status < 0 then begin
      WriteLn('Fehler beim Aktivieren von AGC !');
      rtlsdr_close(dev);
      Exit;
    end else begin
      WriteLn('Set AGC [Ok]');
    end;

    rtlsdr_reset_buffer(dev);

    buffer := GetMem(SAMPLE_COUNT * 2);

    // Samples lesen
    status := rtlsdr_read_sync(dev, buffer, SAMPLE_COUNT * 2, @n_read);
    if status < 0 then begin
      WriteLn('Fehler beim Lesen der Samples.');
    end else begin
      WriteLn(n_read, ' Bytes gelesen. [Ok]');
    end;

    // Aufräumen
    Freemem(buffer);
    rtlsdr_close(dev);
  end;


begin
  if printInfo > 0 then  begin
    printBuffer;
  end;
end.
Ausgabe:

Code: Alles auswählen

Device Couint: 1
  0. Generic RTL2832U OEM
    Hersteller: Realtek Produkt: RTL2838UHIDIR Serie: 00000001

Found Fitipower FC0013 tuner
RTL-SDR Open [Ok]
Set Frequenz [Ok]
Set Abstastrate [Ok]
Set AGC [Ok]
524288 Bytes gelesen. [Ok]
Was ich auch festgestellt habe, das ganze ist wählerisch, was für ein USB-Port man nimmt.

So nebenbei mit diesem Kommando kann man Radio hören:

Code: Alles auswählen

rtl_fm -M fm -f 102.8M -s 200k -l 0 -E deemp | aplay -r 48000 -f S16_LE
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
juelin
Beiträge: 310
Registriert: Sa 24. Jul 2021, 18:03
OS, Lazarus, FPC: Linux Ubuntu 22. Windows 10 Delphi 11.3 (L 0.9.xy FPC 2.2.z)
CPU-Target: 64Bit
Wohnort: Mannheim

Re: Wer hat schon einmal was mit Lazarus/FPC und SDR gemacht?

Beitrag von juelin »

Hallo Mathias,
Dein Post hat mir schon sehr geholfen, Danke.
Anbei die Ausgabe von meinem Programm.
Nur noch eine Frage:
Wie kann ich die Daten, die ich gelesen habe auswerten?

Code: Alles auswählen

    he4:=0;
    he5:=ADSB_DATA_LEN;
    he3:=@he4;
    buffer:=GetMem(ADSB_DATA_LEN);
    he6:=rtlsdr_read_sync(sdropennum, buffer, he5, he3);
Ich meine wie greife ich auf diese Daten zu?
Ich brauche jedes Byte als Char.
Kannst Du mir da ein Beispiel geben?
Danke und Gruß
Jürgen
Dateianhänge
fenster.jpg
(332.91 KiB) Noch nie heruntergeladen

Antworten