Call Search
     

New to Ham Radio?
My Profile

Community
Articles
Forums
News
Reviews
Friends Remembered
Strays
Survey Question

Operating
Contesting
DX Cluster Spots
Propagation

Resources
Calendar
Classifieds
Ham Exams
Ham Links
List Archives
News Articles
Product Reviews
QSL Managers

Site Info
eHam Help (FAQ)
Support the site
The eHam Team
Advertising Info
Vision Statement
About eHam.net

   Home   Help Search  
Pages: [1]   Go Down
  Print  
Author Topic: HF Rig control of streaming audio server  (Read 21220 times)
KC5HHQ
Member

Posts: 10




Ignore
« on: November 09, 2011, 09:30:57 AM »

I recently set-up an audio stream of my father's HF rig at his house over the internet. (MMS://w5cqu.homeip.net:8000/hf) That was fairly easy using a Linux server and Ice-cast/DarkIce. But, I wanted to take it one step further and allow him to remotely control the frequency and mode of the rig using a web browser on a PC or mobile phone (specifically, iPhone). I have come up with the following solution that I will attempt to describe in case anyone would like to do this also.

Equipment:
Kenwood TS-570S
RS232 Cable
Audio cable
Ubuntu Linux server

I used the HamLib project’s rigctld utility to create a daemon to accept instructions for the HF rig. The website for this project is: http://sourceforge.net/projects/hamlib/

To launch the daemon, I created an init.d script to execute the following command upon boot: /usr/bin/rigctld -r /dev/ttyS0 -m 216 -s 9600 -T 127.0.0.1

Essentially, this connects the control daemon to COM1 on the computer, which is connected to the HF rig. The daemon listens only on the localhost.

I created a Perl CGI script that is called from a website I created to actually control the HF rig. It talks on to the rigctld daemon over a TCP/IP connection. (Code located below instructions)

I found a simple website template designed for the iPhone. It mimics the look and feel of iOS applications. I chose to use this as a base for my web application. It is called iSite and is available on the internet. I modified this template to control the HF rig using the Perl script I created. (HTML located below Perl code)

If anyone would like to stream from the server, direct FStream, VLC, or Windows Media Player to the following URL:
MMS://w5cqu.homeip.net:8000/hf

I hope someone finds this useful!

Chris, KC5HHQ
kc5hhq@gmail.com


Screenshots:

FStream (iOS application) streaming the audio:
http://img13.imageshack.us/img13/7775/photo5rh.png

Main page of site:
http://img849.imageshack.us/img849/8439/photofk.png

Get frequency:
http://img269.imageshack.us/img269/2885/photo1ua.png

Set frequency:
http://img831.imageshack.us/img831/1020/photo4s.png

Get mode:
http://img20.imageshack.us/img20/2145/photo2f.png

Set mode:
http://img10.imageshack.us/img10/2308/photo3p.png

#### BEGIN Perl CGI Code ####
#!/usr/bin/perl -W

use CGI;
use Switch;
use IO::Socket;
use IO::Select;

my $cmd = new CGI->param('cmd');
#my $cmd = @ARGV[0];
my $val1 = new CGI->param('val1');
#my $val1 = @ARGV[1];
my $val2 = new CGI->param('val2');
#my $val2 = @ARGV[2];

if(!$cmd) {
  print "Content-type: text/plain\n\nCommand or Value is Null. Halting.";
  exit(0);
}

# Create a socket
my $socket = new IO::Socket::INET (
  PeerAddr => '127.0.0.1',
  PeerPort => '4532',
  Proto => 'tcp',
);

if(!$socket) {
  print "Content-type: text/plain\n\nCould not create socket. Halting.";
  exit(0);
}

my $s = IO::Select->new();
$s->add($socket);
#$socket->autoflush(1);

my $results = '';

# Determine what command is being passed.
switch ($cmd) {
  case "get_freq" {
    getFreq();
  }
  case "set_freq" {
    setFreq($val1);
  }
  case "set_mode" {
    setMode($val1, 0);
  }
  case "get_mode" {
    getMode();
  }
  case "dump_caps" {
    $results = sendcommand($s,$socket,"+\\dump_caps\n", "Dump capabilities", '');
  }
}

close($socket);

sub getMode {
  my $results = sendcommand($s,$socket,"m\n", "Get mode", '');
  sendResults("The current mode is: $results");
}

sub setMode {
  my $mode = shift;
  my $passBand = shift;
  my $results = sendcommand($s,$socket,"M $mode $passBand\n", "Set mode", '');
  sendResults("The mode has been changed to: $mode");
}

sub setFreq {
  my $freq = shift;
  my $results = sendcommand($s,$socket,"F $freq\n", "Set frequency", '');
  sendRedirect();
}

sub getFreq {
  my $results = sendcommand($s,$socket,"f\n", "Get frequency", '');
  sendResults("The frequency is: $results");
}

 sub sendResults {
  my $results = shift;
  print "Content-type: text/html\n\n";
  my $returned = qq^
    <html>
    <head>
    </head>
    <body>
  ^;
  $returned = $results;
#  $returned .= qq^
#    </body>
#    </html>
#  ^;
  print $returned;
}

sub sendRedirect {
  print "Content-type: text/html\n\n";
  my $redirect = qq^
    <html>
    <head>
    <meta http-equiv="Refresh" content="0;url=http://your.site.net/dir" />
    </head>
    </html>
  ^;
  print $redirect;
}

sub sendcommand {
  my $s = shift;
  my $sock = shift;
  my $cmd = shift;
  my $desc = shift;
  my $comment = shift;
  my $res = '';
  my $return = '';
 
  my $retry = 1;
      $sock->send($cmd);
      #print $sock $cmd;
      sleep 1;
      while ($s->can_read(0)) {
        $sock->sysread($result,1);
    $return .= $result;
    }
  return $return;
}

#### END Perl CGI Code ####


#### BEGIN HTML ####

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Rig Control 0.1</title>
<meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
<style type="text/css" media="screen">@import "iphonenav.css";</style>
<script type="application/x-javascript" src="iphonenav.js"></script>

</head>

<body>
    <h1 id="pageTitle"></h1>
    <a id="homeButton" class="button" href="#settings">Settings</a>
    <a class="button" href="#manualForm">Set Freq.</a>
   
    <ul id="settings" title="Settings" selected="true">
        <li><a href="#Frequency">Frequency</a></li>
        <li><a href="#Mode">Mode</a></li>
    </ul>
    <ul id="Frequency" title="Frequency">
        <li><a href="#setFreq">Set Frequency</a></li>
        <li><a href="#getFreq">Get Frequency</a></li>
    </ul>
    <ul id="Mode" title="Mode">
        <li><a href="#setMode">Set Mode</a></li>
        <li><a href="#getMode">Get Mode</a></li>
    </ul>

    <div id="setMode" class="panel" title="Mode">
   <li><a class="clickButton" href="#" onclick="click_setMode('LSB');">LSB</a></li>
        <li><a class="clickButton" href="#USB" onclick="click_setMode('USB');">USB</a></li>
        <li><a class="clickButton" href="#AM onclick="click_setMode('AM');"">AM</a></li>
        <li><a class="clickButton" href="#FM" onclick="click_setMode('FM');">FM</a></li>
        <li><a class="clickButton" href="#CW" onclick="click_setMode('CW');">CW</a></li>
   <h2><div id="setModeText"></div></h2>
    </div>
   
    <div id="getFreq" class="panel" title="Frequency">
   <a class="clickButton" href="#" onclick="click_getFreq();">Get Frequency</a>
   <h2>
      <div id="freqText"></div>               
   </h2>
    </div>
    <div id="getMode" class="panel" title="Mode">
   <a class="clickButton" href="#" onclick="click_getMode();">Get Mode</a>
   <h2>
      <div id="modeText"></div>               
   </h2>
    </div>
    <div id="getMem" class="panel" title="Memory">
   <a class="clickButton" href="#" onclick="click_getMemory();">Get Memory</a>
   <h2>
      <div id="memText"></div>               
   </h2>
    </div>    <div id="searchResults" class="panel" title="Search">
        <h2>Search results go here...</h2>
    </div>
    <form id="manualForm" class="dialog" method="POST" action="/cgi-bin/ctl.pl?">
        <fieldset>
            <h1>Frequency Set</h1>
            <a class="button toolButton goButton" href="#" onclick="submit_manualForm();">Set Freq.</a>
            <input type="hidden" name="cmd" value="set_freq" />
            <label>Frequency:</label>
            <input type="text" name="val1" onkeypress="dokeypress(event, 'submit_manualForm')"/>
        </fieldset>
    </form>
    <form id="setFreq" class="dialog" method="POST" action="/cgi-bin/ctl.pl?">
        <fieldset>
            <h1>Frequency Set</h1>
            <a class="button toolButton goButton" href="#" onclick="submit_setFreq();">Set Freq.</a>
            <input type="hidden" name="cmd" value="set_freq" />
            <label>Frequency:</label>
            <input type="text" name="val1" onkeypress="dokeypress(event, 'submit_setFreq')"/>
        </fieldset>
    </form>

   
    <script language="javascript">
      function submit_manualForm() {
        document.forms["manualForm"].submit();
      }

      function submit_setFreq() {
        document.forms["setFreq"].submit();
      }

      function dokeypress(e,functionName)
      {
         if (e.which == 13)
            {   
                  document.activeElement.blur();
                  eval(functionName + "();");
            }
      }
      function click_getFreq() {
        var req = getReq();
   req.open("GET",'/cgi-bin/control_script.pl?cmd=get_freq', true);
       req.onreadystatechange = function () {
       document.getElementById('freqText').innerHTML = req.responseText;
   }
   req.send(null);   
      }
      function click_setMode(val1) {
        var req = getReq();
   req.open("GET",'/cgi-bin/control_script.pl?cmd=set_mode&val1='+val1, true);
       req.onreadystatechange = function () {
       document.getElementById('setModeText').innerHTML = req.responseText;
   }
   req.send(null);   
      }

      function click_getMode() {
        var req = getReq();
   req.open("GET",'/cgi-bin/control_script.pl?cmd=get_mode', true);
       req.onreadystatechange = function () {
       document.getElementById('modeText').innerHTML = req.responseText;
   }
   req.send(null);   
      }
     
      function getReq(url) {
        var req;

   // Browser compatibility check                 
   if (window.XMLHttpRequest) {
      req = new XMLHttpRequest();
       } else if (window.ActiveXObject) {
   
    try {
      req = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
   
      try {
        req = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {}
    }
   
   }
   return req;
      }
    </script>
   
</body>
</html>

#### END HTML ####
Logged
AK4KZ
Member

Posts: 84


WWW

Ignore
« Reply #1 on: November 09, 2011, 10:12:19 AM »

That is a pretty cool solution. Thanks for posting it.

73,
Chris
AK4KZ
Logged
KF6VB
Member

Posts: 19




Ignore
« Reply #2 on: April 27, 2012, 02:45:09 PM »

I recently set-up an audio stream of my father's HF rig at his house over the internet. (MMS://w5cqu.homeip.net:8000/hf) That was fairly easy using a Linux server and Ice-cast/DarkIce. But, I wanted to take it one step further and allow him to remotely control the frequency and mode of the rig using a web browser on a PC or mobile phone (specifically, iPhone). I have come up with the following solution that I will attempt to describe in case anyone would like to do this also.

*** Wow, this is excellent!  Thank you so much for posting the details.  Ever since the early 80's I have dreamed of being able to ham from any room in the house, and this could definitely do it.  And as it happens, I have spent a great deal of time over the past 5 years writing perl/CGI code.  This just begs for AJAX ( Asynchronous Javascript And XML )  - for things like animated knobs and meters.

                                                    - Jerry Kaidor, KF6VB


Logged
KC5HHQ
Member

Posts: 10




Ignore
« Reply #3 on: May 08, 2012, 09:17:34 AM »

Checkout WebSDR. It looks pretty neat. I have a Softrock kit on order; maybe I will setup a WebSDR station in the future.
Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!