commit b746a9907c1484672c1e9eaa65d90f87639ef307 Author: Thomas Klaehn Date: Tue Jan 16 20:24:01 2018 +0100 relay-switch: Initial commit Signed-off-by: Thomas Klaehn diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20dcf3d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode/ +build/ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..875177b --- /dev/null +++ b/Makefile @@ -0,0 +1,21 @@ + +DEPENDENCIES := -lpthread -lrt +CFLAGS := -Wall -Wextra -Iftdi + +CC ?= gcc + +BUILDDIR := build +APP = $(BUILDDIR)/relay-switch + +all: $(APP) + +$(APP): src/main.c + @mkdir -p $(BUILDDIR) + $(CC) src/main.c -o $(APP) $(CFLAGS) -lftdi $(DEPENDENCIES) + +clean: + -rm -f $(APP) + +install: all + install -m 755 $(APP) /usr/local/bin/ + install -m 644 udev/* /etc/udev/rules.d/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae799af --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# RELAY + +Switch 4 channel relay (QY15). + +## Prerequisites + +* libftdi-dev + +## Build + +```bash +make all +``` + +## Install + +```bash +make install +``` + +## Execute + +```bash +relay-switch -r [1..4] -s [0..1] +``` + +with: + +```bash +r: relay +s: state +``` diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..8172b47 --- /dev/null +++ b/src/main.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include + +#define RELAY_1 1 +#define RELAY_2 2 +#define RELAY_3 3 +#define RELAY_4 4 + +int main(int argc, char **argv) +{ + struct ftdi_context *ftdi; + int f, opt; + unsigned int relay = 0, state = 0; + unsigned char buf[1]; + int retval = 0; + + openlog("relay_switch", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1); + + while((opt = getopt(argc, argv, "r:s:")) != -1) { + switch(opt) { + case 'r': + relay = atoi(optarg); + if((relay != RELAY_1) && (relay != RELAY_2) && (relay != RELAY_3) && (relay != RELAY_4)) { + syslog(LOG_ERR, "Invalid relay choosen (%d). Choose one of [1..4].\n", relay); + return 1; + } + break; + case 's': + state = atoi(optarg); + if((state != 0) && (state != 1)) { + syslog(LOG_ERR, "Invalid state choosen (%d). Choose one of [0/1].\n", state); + return 1; + } + break; + } + } + + if ((ftdi = ftdi_new()) == 0) + { + syslog(LOG_ERR, "ftdi_new failed\n"); + return EXIT_FAILURE; + } + + f = ftdi_usb_open(ftdi, 0x0403, 0x6001); + + if (f < 0 && f != -5) { + syslog(LOG_ERR, "unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); + retval = 1; + goto done; + } + + f = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG); + if(f < 0) { + syslog(LOG_ERR, "unable to set bit bang mode: %d (%s)\n", f, ftdi_get_error_string(ftdi)); + retval = 1; + goto done; + } + + f = ftdi_read_data(ftdi, buf, 1); + if(f < 0) { + syslog(LOG_ERR, "unable to readfrom ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi)); + retval = 1; + goto done; + } + + if(state == 1) { + buf[0] |= (char)(1 << (relay - 1)); + } + else { + buf[0] &= ~(char)(1 << (relay - 1)); + } + + f = ftdi_write_data(ftdi, buf, 1); + if(f < 0) { + syslog(LOG_ERR, "write failed for 0x%x, error %d (%s)\n",buf[0], f, ftdi_get_error_string(ftdi)); + } + + ftdi_usb_close(ftdi); +done: + ftdi_free(ftdi); + closelog(); + + return retval; +} diff --git a/udev/90-ftdi.rules b/udev/90-ftdi.rules new file mode 100644 index 0000000..ec02adb --- /dev/null +++ b/udev/90-ftdi.rules @@ -0,0 +1 @@ +ATTR{idVendor}=="0403", ATTR{idProduct}=="6001", MODE="0666"