Kjetil's Information Center: A Blog About My Projects

USB Relay Control Simplified

I got a USB controlled relay board a while ago, which is identified with the USB ID 16c0:05df. There are various controller programs for these on GitHub, but all of them are rather complicated, so I decided to write my own simplified version using the same principles. Like others, it has a dependency against the hidapi library.

The result is this C program:

#include <hidapi/hidapi.h>
#include <wchar.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define TARGET_DEVICE L"USBRelay2"

#define RELAY_OFF 0xfd
#define RELAY_ON  0xff

int main(int argc, char *argv[])
{
  struct hid_device_info *hidinfo;
  hid_device *hiddev;
  unsigned char buf[8];
  int result, relay_number, relay_operation;

  hidinfo = hid_enumerate(0, 0);
  while (hidinfo != NULL) {
    if (0 == wcscmp(hidinfo->product_string, TARGET_DEVICE)) {
      break;
    }
    hidinfo = hidinfo->next;
  }

  if (hidinfo == NULL) {
    fprintf(stderr, "Did not find '%ls' in USB devices!\n", TARGET_DEVICE);
    return 1;
  }

  hiddev = hid_open_path(hidinfo->path);
  if (hiddev == NULL) {
    fprintf(stderr, "hid_open_path() failed on: %s\n", hidinfo->path);
    return 1;
  }

  if (argc > 2) {
    relay_number = atoi(argv[1]) & 0b11; /* Limit to 2 relays. */
    relay_operation = 0;
    if (0 == strcasecmp(argv[2], "on")) {
      relay_operation = RELAY_ON;
    } else if (0 == strcasecmp(argv[2], "off")) {
      relay_operation = RELAY_OFF;
    } else {
      fprintf(stderr, "Invalid relay operation\n");
      hid_close(hiddev);
      return 1;
    }

    memset(buf, 0x00, sizeof(buf));
    buf[0] = 0x00;
    buf[1] = relay_operation;
    buf[2] = relay_number;
    result = hid_write(hiddev, buf, sizeof(buf));
    if (result == -1) {
      fprintf(stderr, "hid_write() failed!\n");
      hid_close(hiddev);
      return 1;
    }
  }

  buf[0] = 0x01;
  result = hid_get_feature_report(hiddev, buf, sizeof(buf));
  if (result == -1) {
    fprintf(stderr, "hid_get_feature_report() failed!\n");
    hid_close(hiddev);
    return 1;
  }

  printf("Relay #1: %d\n",  buf[7] & 0b01);
  printf("Relay #2: %d\n", (buf[7] & 0b10) >> 1);
  printf("Usage: %s <relay number> <on|off>\n", argv[0]);

  hid_close(hiddev);
  return 0;
}
          


Compile it like so: gcc -o usbrelay2 usbrelay2.c -lhidapi-hidraw

Topic: Scripts and Code, by Kjetil @ 02/01-2021, Article Link