Icom CI-V with Perl

Since 2002 I switched to Linux, my work on Windows based software has largely stopped. Looking for a programming language under Linux I started to use Perl and C. Perl is fun to learn (and use) and extremely powerful, so my first results under Linux come in that language.

Here are two OO modules which make the usage of an Icom radio with Perl very simple.


This module supports the basic funtions found on practically any Icom radio (set/get frequency, set/get mode, switch to VFO or memory, select a memory, clear a memory, store to memory.

Manpage of HAM::Device::IcomCIV.

Download HAM-Device-IcomCIV-0.02.tar.gz


This module provides low level serial IO for the above mentioned module HAM::Device::IcomCIV. It's a necessary prerequisite.

Manpage of HAM::Device::IcomCIVSerialIO.

Download HAM-Device-IcomCIVSerialIO-0.03.tar.gz

Examples of use

The goal was to make the usage of an Icom radio as simple as possible. The module HAM::Device::IcomCIV supports two approaches: one procedural, the other by OO methods. Choose whatever you like.

Example 1: Procedural approach

This style is good for very short programs, say where you just want to set the radio to a certain mode, and that's it.

#!/usr/bin/perl -w use strict; use HAM::Device::IcomCIV; my $radio = HAM::Device::IcomCIV->new( undef, # Serial object, let undef for the moment '/dev/ttyS1', # Serial Device 19200, # Baudrate to radio undef, # Use locking for the serial device (or not) 'IC-R8500', # Model if Icom radio undef, # Use default CI-V Adr, set by IcomCIV module 0xE0, # My own adr 0 # debug ); # All frequencies are handled as integers and are always in Hz. # This removes all ambiguities and rounding errors. my $freq = $radio->frequency; print "My radio is on $freq Hz\n"; # Modes and Filters are always uses as string, # like 'AM', 'USB', 'NARROW' etc. # In scalar context the 'mode' function returns only the mode. my $mode = $radio->mode; print "My radio is in mode $mode\n"; my $filter; # In list context both, mode and filter is returned. ($mode, $filter) = $radio->mode; print "My radio is in mode $mode with filter $filter\n"; # Remember: frequencies are always expressed as integer in Hz $radio->frequency(6075000); # Set radio to 6075 kHz $radio->mode('AM'); # Set radio to AM $radio->mode('AM', 'NORMAL'); # Set radio to AM, filter width Normal # Learn about the tuning edges of your radio. my ($lo, $hi) = $radio->get_bandedges; print "My radio can be tuned from $lo to $hi\n"; # Destroy the radio object # (also closes and unlocks the serial port) undef($radio);


Example 2: OO approach

The object oriented and event-driven approach is useful for more complex (interactive) applications. I think. Here a callback function is called whenever something is received from the radio.

#!/usr/bin/perl -w use strict; use HAM::Device::IcomCIV qw ( :Constants :Events); my $rig = HAM::Device::IcomCIV->new( undef, # Ser.obj. '/dev/ttyS1', # Device 19200, # Baud undef, # Uselock 'IC-R8500', # Model undef, # CI-VAdr 0xE0, # own adr 1 # debug ); # The possible events are imported on demand, see 'use' above. my $cback = sub { my ($ev, $st, $d1, $d2 ) = @_; if ( $ev == evFREQ ) { printf ("%.1f kHz\n", $d1/1000); } elsif ( $ev == evMODE ) { print "Mode: $d1/$d2\n"; } elsif ( $ev == evEDGE ) { print "LoEdge: $d1 Hz, HiEdge: $d2 Hz\n"; } elsif (( $ev == evSTAT ) and ( $st == stFAIL )) { print "The radio reports an error.\n"; } elsif ( $ev == evUNKN ) { print "Unrecognized response from radio.\n" }; }; $rig->set_callback( $cback ); # Now wiggle the tuning control of your radio, or switch the mode. # The most simple command input to test the module follows. # enter 'f <frequency in Hz>' # or 'm AM' # etc. my %cmds = ( 'f' => sub { $rig->frequency( @_ ) }, 'm' => sub { $rig->mode( @_ ) }, 'v' => sub { $rig->select_vfo( @_ ) }, 'r' => sub { $rig->select_mem( @_ ) }, 'e' => sub { $rig->get_bandedges( @_ ) }, 'q' => sub { exit; }, ); print "cmd: "; while (<>) { chomp; my ($cmd, @parms) = split; if (($cmd) and ( exists $cmds{$cmd} )) { &{ $cmds{$cmd} }(@parms); }; print "cmd: "; };