Web Client to GNU Radio

As part of the “Remote SDR” project, it is necessary to send an audio stream and parameters from a web page to the remote SSB transmitter coded in GNU Radio.

Among the processing blocks present in GNURADIO-companion, there is the source UDP block for entering an audio data stream. To send this stream from a web client, you can use websockets. The program proposed below in python 3, retrieves the audio stream received from the web client according to the websocket protocol (port 8005) and passes this data to GNU Radio according to the UDP protocol (port 9005).

In addition this program each time an audio frame is received (packet of 512 bytes), changes the pin 26 of the GPIO of the Orange PI One Plus. This generates an alternating signal which, once rectified, will energize relays to power the transmitter. See details here.

#!/usr/bin/python3           # This is client.py file


import socket
import asyncio
import websockets
import os                       # To execute system command

# create a socket object
s_audio = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 


# get local machine name
host = '127.0.0.1'                           

port_audio_Web = 8005
port_audio_GR = 9005

numgpio=227								 # GPIO 227 corresponds to pin 26 in Orange PI One PLUS H6
numgpio=str(numgpio)                         

# Préparation port commande relais
os.system("sudo echo "+numgpio+" > /sys/class/gpio/export")              #activation
os.system("sudo echo out > /sys/class/gpio/gpio"+numgpio+"/direction")   # Output
                                      


# connection to hostname on the port.

                             
print ("Passerelle audio client Web vers TX")


# Receive   bytes audio
async def audio(websocket_a, path):
    etat=True
    while True:
# on recupere les data du micro du client

        donnee_audio = await websocket_a.recv()
   
        s_audio.sendto(donnee_audio,(host,port_audio_GR))

        # Oscillateur pour activer le relais alimentation via un condensateur et un redressement
		# Oscillator on pin 26 as watchdog
        etat=not etat     #inversion à chaque trame recue
        
        if etat:
             os.system("echo 1 > /sys/class/gpio/gpio"+numgpio+"/value")
        else:
             os.system("echo 0 > /sys/class/gpio/gpio"+numgpio+"/value")
        


start_server_audio = websockets.serve(audio, "", port_audio_Web)

asyncio.get_event_loop().run_until_complete(start_server_audio)

asyncio.get_event_loop().run_forever()

For sending transmitter configuration commands, we use the xmlrpc protocol on the GNU Radio side (port 9004) and always websockets on the web client side (port 8004).

#!/usr/bin/python3           # 



import asyncio
import websockets
import json
import xmlrpc.client

# create a socket object



# get local machine name
host = 'localhost'                           

port_para_Web = 8004
adr_local = "http://localhost:9004"

Sxml = xmlrpc.client.ServerProxy(adr_local)



print("Passerelle Parametres TX du client WEB")

async def consumer_handler(websocket_p, path):
    async for message_recu in websocket_p:
        F=json.loads(message_recu)
       
        if "Fr_TX" in F :
              print("Fr_TX ",F["Fr_TX"])
              Sxml.set_Fr_TX(float(F["Fr_TX"]))              
       

        if "GRF_TX" in F :
              print("GainRF TX ",F["GRF_TX"])
              Sxml.set_GainRF_TX(float(F["GRF_TX"]))
			  
        if "GIF_TX" in F :
              print("GainIF TX ",F["GIF_TX"])
              Sxml.set_GainIF_TX(float(F["GIF_TX"]))	

        if "GBB_TX" in F :
              print("GainBB TX ",F["GBB_TX"])
              Sxml.set_GainBB_TX(float(F["GBB_TX"]))	  
			  
        if "LSB_USB" in F :
              print("LSB USB ",F["LSB_USB"])
              Sxml.set_LSB_USB(float(F["LSB_USB"]))
        await websocket_p.send("OK")			  
            
  



start_server_para = websockets.serve(consumer_handler, "", port_para_Web)

loop = asyncio.get_event_loop()

try:
    loop.run_until_complete(start_server_para)
    loop.run_forever()
except KeyboardInterrupt:
    logging.info("Process Para interrupted")
finally:
    loop.close()
    logging.info("Arret Para service.")

For the receiver described here, we use the same protocols to pass the configuration parameters.

The source files are available on Github F1ATB / Remote-SDR.

Posts on Remote-SDR

Leave a Reply

Your email address will not be published. Required fields are marked *