HAM::Device::IcomCIVSerialIO - Low Level Serial IO for Icom CI-V Radios


Version 0.02 02. Dec. 2007


  use HAM::Device::IcomCIVSerialIO;

  $ser = HAM::Device::IcomCIVSerialIO->new( '/dev/ttyS2', 19200, undef, debuglevel );
  $ser->set_callback ( $thiscivadress, $myradio );
  $ser->send_civ( $thiscivadress, $own_adress, $command );
  $ser->clear_callback( $thiscivadress );


This module is the basic part of a bundle of modules that supports remote control of Icom radios equipped with the CI-V interface. It is used mainly by HAM::Device::IcomCIV and it's descendants. To use it you need to open the serial port, send commands to the radio with send_civ() and receive callbacks (set with set_callback() to process received CI-V data.


This module is considered private, it will change it's interface and functionality in the future, when it will support multiple serial ports at the same time. Do not use it directly, use HAM::Device::IcomCIV or one of it's desceandants instead.


Nothing by default.




new( device, baudrate, uselock, debug )

Opens the serial device with baudrate, and returns handle of serial port. Dies on various reasons (lock not possible, open not possible etc.).

This function also starts the ualarm() timer which polls regularly the incoming data. If data is received it is passed to the callback function.

  • device Is any valid devicename for a serial port, e.g. '/dev/ttyS1'.

  • baudrate Is any valid baudrate supported by the attached Icom radio, e.g. 9600, 19200 etc. For performance reasons you should use 9600 and above.

  • uselock If defined will try to lock the serial device with a lockfile in /var/lock. No locking if undefined.

    Note: When using different distributions I found that Device::SerialPort sometimes uses 'sleep', at other times 'nanosleep' in the locking function. This leads to unexpected delays when using locking (2 seconds). If you experience this, don't use locking or patch your Device::SerialPort module.

  • debug Debug flag, if >0 results in some diagnostic messages printed to STDERR.

The new method clears the callback table! Set your callback[s] right after you have initiated a new serial device.

stop_serial( )

Closes the serial port. Returns nothing.

send_civ( to_adr, fm_adr, command )

Assembles the data (to_adr, fm_adr, command) with header and tail of the CI-V frame and sends this out over the serial line. Returns true if all data was sent ok, otherwise false.

  • to_adr Is the Icom CI-V bus adress of the radio to which this command is directed. Must be Integer, will be converted to a char.

  • fm_adr Is the senders adress, usually 0xE0 for the controlling computer. Must be integer, will be converted to a char.

  • command Is the data to be sent (a string of bytes), everything after the adresses and up to, but not including the final 0xFD.

set_callback( civadress, object )

Sets the callback object reference which is used for callback routine 'process_buffer', to be called whenever a complete CI-V telegram has been received by the serial routine. It's the responsibilty of this called routine to decode and act on the received telegram.

This method must be called with the appropiate data for each upper level instance of IcomCIV, otherwise it won't work!

  • civadress The CI-V bus adress for which this callback adress feels responsible, as integer, not char. Callbacks are multiplexed to different IcomCIV instances, depending on CI-V adress. This enables an application to have several instances of IcomCIV and handle each separately.

    Currently this does not allow for duplicate CI-V bus adresses on the same serial port. So if you have two or more identical devices with identical adresses, you have to change them to make then unique to each radio. This is likely to change in the future, using a unique identifier for each radio (and will break the API).

  • object The blessed reference of a an instance of a IcomCIV object (or descendant thereof). The actual method which is called is named 'process_buffer' and receives one parameter (besides the usual $self), and that is the entire CI-V telegram from the leading 0xFE 0xFE up to and including the final 0xFD.

clear_callback ( civadress )

Deletes this CI-V bus adress from the callback table. Returns true on success, false if adress was not in table.

  • civadress The CI-V bus adress for which this callback adress feels responsible, as integer, not char.print "Serdev: $self->{SERDEV}\n";


    and other IcomCIV modules

    Icom CI-V Protocol Specification by Icom
    Documentation of the CI-V protocol in any recent Icom radio manual
    Documentation of the CI-V protocol at the authors website:

If you are looking for a library which supports more radios than just Icoms, look for 'grig' or 'hamlib'.


Due to the use of %SIG and Time::Hires this module is probably not very portable. The author has developed and used it only on various Linux platforms. If you have any feedback on the use of this module on other platforms, please let the author know. Thanks.


Ekkehard (Ekki) Plicht, DF4OR, <>


Copyright (c) 2007 Ekkehard (Ekki) Plicht. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.