I am building a wireless control system for a magnetic loop antenna. The system uses an ESP32 microcontroller (that has Bluetooth and WiFi) that

  1. automatically drives the magloop capacitor by means of a DC motor, while
  2. minimising SWR in real time.

While "1" is easy, I failed at "2". I want to use FT817's own SWR meter, and assumed I could programmatically read-out the LCD readings via CAT control: this is what Omnirig does (if I am not mistaken).

I then got a (CAT) Bluetooth dongle on eBay and, using the "BluetoothSerial" Arduino library I managed to have the ESP32 and the FT817 communicating! For instance, the ESP32 can easily read (and set) mode + frequency, activate/release the PTT, and even switch ON/OFF the radio! I even managed to read out the S-Meter values (by the ad hoc CAT command).

Reading SWR programmatically, however, requires using an (undocumented) CAT command (mentioned by KA7OEI). Unfortunately, as I try that, the ESP3 gets a series of wrong numerical values, at odd with the number of "segments" on the LCD indicating SWR.

Something is wrong with my idea or with the (Arduino, C) code, whose extract is reported below:

#define CAT_sTX_DATA_CMD    0xBD

unsigned short int getSWR() {   
  byte outByte[5] = {0x00,0x00,0x00,0x00,0x00};
  outByte[4] = CAT_sTX_DATA_CMD;
  long elapsed = 0;
  byte reply1, reply2;
  unsigned int swr; 
  unsigned int pwr; 
  String SWR;
  long timeout = millis();

  sendCmd(outByte, 5); 
  while (SerialBT.available() < 2 && elapsed < 2000) {
    elapsed = millis() - timeout;

  reply1 = SerialBT.read();
  reply2 = SerialBT.read();

  pwr = (unsigned short) ((reply1 >> 4) & 0x0f);
  swr = (unsigned short) (reply1 & 0x0f);
  return swr;

void sendCmd(byte cmd[], byte len) {
  for (byte i=0; i<len; i++)

Any chance that some among you has already solved the same problem? Any hints or suggestions? Do you see a problem in my getSWR() function?

  • $\begingroup$ It looks right to me, comparing to hamlib code. Are you making sure to only call this when PTT is on? $\endgroup$ Commented Jun 1, 2022 at 15:45
  • $\begingroup$ Hi Michele, welcome to the site! What are the values you're getting back? The page you linked to indicates that you're going to be interested in the low-4 bits of the first of the 2 bytes returned, and that it's a BCD value. That gives a total of only 16 possible VSWR values, so there must be a mapping of those values to something meaningful. $\endgroup$
    – webmarc
    Commented Jun 1, 2022 at 15:54
  • $\begingroup$ FYI, even though you don't mention it above, apparently Yaesu removed the 0xBB command on the 818 for undue wear & tear on the chip, and it's recommended to avoid using that one. $\endgroup$
    – webmarc
    Commented Jun 1, 2022 at 19:17

1 Answer 1


it looks like the flrig folks have it sorted out.

From the flrig source file in src/rigs/yaesu/FT817.cxx:

static int swr_map[] = {
   0,  4,  8, 13, 25, 37, 60, 70, 80, 90, 100, 100, 100, 100, 100, 100};
// 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,  11,  12,  13,  14,  15

It's not clear to me what the mapped values actually mean, but it occurs to me that you could fire up flrig, run a trace, and actually see how it maps those values to the meter display.

Or you could also go spelunking in that code!

From the same source file just stumbled across this which should be helpful:

// uses undocumented command 0xBD
// returns two bytes b0 b1
// b0 PWR|SWR
// b1 ALC|MOD

int  RIG_FT817::get_power_out()
    cmd[4] = 0xBD;
    int ret = waitN(2, 100, "get PWR/SWR/ALC", HEX);

    if (ret < 2) return 0;

    int fwdpwr = (replystr[0] & 0xF0) >> 4;
    swr = (replystr[1] & 0xF0) >> 4;
    alc = (replystr[0] & 0x0F);

    if (fwdpwr > 8) fwdpwr = 8;
    if (fwdpwr < 0) fwdpwr = 0;
    return pmeter_map[fwdpwr];

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .