/********************************************************************************* * Copyright: (C) 2021 LingYun IoT System Studio * All rights reserved. * * Filename: relay.c * Description: This file is used to control Relay * * * Pin connection: * Relay Module Raspberry Pi Board * VCC <-----> 5V * I <-----> #Pin16(BCM GPIO23) * GND <-----> GND * * System install: * sudo apt install -y libgpiod-dev gpiod * * ********************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include "logger.h" #include "relay.h" #define DELAY 500 static relay_info_t relay_info[RELAY_CNT] = { {"relay1", 23, 1, NULL }, }; int init_relay(relay_ctx_t *ctx) { int i, rv; relay_info_t *relay; if( !ctx ) { log_error("Invalid input arguments\n"); return -1; } ctx->relay = relay_info; ctx->count = RELAY_CNT; ctx->chip = gpiod_chip_open_by_name("gpiochip0"); if( !ctx->chip ) { log_error("open gpiochip failure, maybe you need running as root\n"); return -2; } for(i=0; icount; i++) { relay = &ctx->relay[i]; relay->line = gpiod_chip_get_line(ctx->chip, relay->gpio); if( !relay->line ) { log_error("open gpioline for %s[%d] failed\n", relay->name, relay->gpio); rv = -3; goto failed; } rv = gpiod_line_request_output(relay->line, relay->name, !relay->active); if( rv ) { log_error("request gpio output for %5s[%d] failed\n", relay->name, relay->gpio); rv = -4; goto failed; } log_debug("request %s[%d] for gpio output okay\n", relay->name, relay->gpio); } return 0; failed: term_relay(ctx); return rv; } int term_relay(relay_ctx_t *ctx) { int i; relay_info_t *relay; if( !ctx ) { log_error("Invalid input arguments\n"); return -1; } if( !ctx->chip ) return 0; for(i=0; icount; i++) { relay = &ctx->relay[i]; if( relay->line ) gpiod_line_release(relay->line); } gpiod_chip_close(ctx->chip); return 0; } int turn_relay(int which, int cmd) { int rv = 0; relay_info_t *relay; relay_ctx_t ctx; if( which<0 || which>=RELAY_CNT ) { log_error("Invalid input arguments\n"); return -1; } if( (rv=init_relay(&ctx)) < 0 ) { log_error("Initial relay failure, rv=%d\n", rv); return -2; } relay = &ctx.relay[which]; if( OFF == cmd ) { gpiod_line_set_value(relay->line, !relay->active); } else { gpiod_line_set_value(relay->line, relay->active); } term_relay(&ctx); return 0; }