/*********************************************************************************
|
* 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 <stdio.h>
|
#include <stdlib.h>
|
#include <unistd.h>
|
#include <fcntl.h>
|
#include <dirent.h>
|
#include <string.h>
|
#include <time.h>
|
#include <errno.h>
|
#include <signal.h>
|
#include <getopt.h>
|
#include <libgen.h>
|
|
#include <gpiod.h>
|
#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; i<ctx->count; 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; i<ctx->count; 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;
|
}
|