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