HADES-SA (SpinnyONE) Transmissions

any progress that you can share with us?

2 Likes

it try create python script, to convert from satnogs iq raw to demodulated usb. but not perfect and clear as if we convert it with sdr++ etc app.

i share here, maybe friends here can make it better

source code
#!/usr/bin/env python3
# Copyright 2026 hobisatelit
# https://github.com/hobisatelit/
# License: GPL-3.0-or-later


import numpy as np
from scipy import signal
from scipy.io import wavfile
import argparse

def main():
    parser = argparse.ArgumentParser(
        description="Convert raw IQ file (48 kHz sample rate) to USB-demodulated WAV. "
                    "Applies frequency offset adjustment and USB bandwidth filtering."
    )
    parser.add_argument("input_file", help="Input raw IQ file (interleaved I/Q samples)")
    parser.add_argument("output_wav", help="Output WAV file")
    parser.add_argument("--samp_rate", type=int, default=48000, help="Sample rate in Hz (default: 48000)")
    parser.add_argument("--freq_offset", type=float, default=-1230.0, help="Frequency offset adjustment in Hz (default: -1230)")
    parser.add_argument("--bandwidth", type=float, default=5000.0, help="USB bandwidth in Hz (default: 5000)")
    parser.add_argument("--dtype", default="int16", choices=["int16", "float32"], help="Input sample type (default: int16)")
    args = parser.parse_args()

    # Load raw IQ data
    if args.dtype == "int16":
        data = np.fromfile(args.input_file, np.int16)
        iq = (data[::2] + 1j * data[1::2]) / 32768.0
    else:
        data = np.fromfile(args.input_file, np.float32)
        iq = data[::2] + 1j * data[1::2]

    # Frequency shift to correct carrier offset
    n = np.arange(len(iq))
    iq_shifted = iq * np.exp(-2j * np.pi * args.freq_offset / args.samp_rate * n)

    # USB demodulation (extract real part after frequency shift)
    usb_demod = iq_shifted.real

    # Low-pass filter for audio bandwidth
    nyquist = args.samp_rate / 2.0
    normalized_cutoff = args.bandwidth / nyquist
    
    # Clamp cutoff to valid range (0 < cutoff < 1)
    if normalized_cutoff >= 1.0:
        normalized_cutoff = 0.99
    
    sos = signal.butter(4, normalized_cutoff, 'low', output='sos')
    audio = signal.sosfilt(sos, usb_demod)

    # Normalize to 80% of max for headroom
    max_val = np.max(np.abs(audio))
    if max_val > 0:
        audio = np.int16(audio / max_val * 32767 * 0.8)
    else:
        audio = np.int16(audio)

    # Save WAV file with correct sample rate
    wavfile.write(args.output_wav, args.samp_rate, audio)

if __name__ == "__main__":
    main()

the idea, if it work, we can put it at satnogs_post script, like we do for meteor decode script. and save the output as ogg file to replace the one created by satnogs_client

demod_usb2.py.txt (2.3 KB)

https://drive.google.com/file/d/1n_zvABd7pWEYiC5nwAiL4GYXj_IgDEUn/view?usp=sharing

I received signals from the HADES-SA satellite, but I was only able to decode images on the first day. During subsequent attempts, SoundModem failed to recognize the signal. I suspect this might be due to the Doppler effect, as I noticed the waterfall display in SoundModem shows a constant frequency shift.

1 Like

Not surprisingly (since he provided the SoundModem + the decoder app to create the .bin files), UZ7HO has been working on receiving & assembling the composite image from all these smaller image downloads. I wonder what we’re still missing and since it’s a bit difficult to see due to the exposure, what it is we’re looking at? Anyone figured it out?

6 Likes

selfie cam, actualy not selfie. but pointing to an experimental fabric with Spinning Around big logo :pensive_face:


6 Likes

Oh! Excellent - I’d not seen a version w/ such improved contrast.

Very cool!

“Can the sat operator shift the Spinning Around logo a little bit so it doesn’t cover the view/scenery behind it?” :pensive_face:

Soon…. :wink:

1 Like

HADES-SA over Brazil :brazil: !!

1 Like

I copied the new image #016 perfectly on the first try, without any errors!!! just now on the HADES-SA

6 Likes

Only got a portion of the new image today; when highest in my sky, the satellite changed to telemetry packets. Can’t win them all!

4 Likes

Image #016 received in :greece:. It took two days to receive all the packets.

5 Likes


HADES-SA over Brazil :brazil: !!

3 Likes

Hades-SA. 01:30 UTC. Image 032 (28 packets) + telemetry. Audio - same packets 0-36. Done in one try - had to sacrifice my sleeping time)
RTL SDR V4 + 7 el. Yagi

2 Likes