RaspberrPi project source code
Guo Wenxue
2023-09-08 47098ac0fb3a6bed9bd5c2acfc64d84387302cda
commit | author | age
d6b4a7 1 /*********************************************************************************
G 2  *      Copyright:  (C) 2021 LingYun IoT System Studio
3  *                  All rights reserved.
4  *
5  *       Filename:  relay.c
6  *    Description:  This file is used to control Relay
7  *
8  *
9  * Pin connection:
10  *                 Relay Module           Raspberry Pi Board
11  *                  VCC       <----->      5V
12  *                   I        <----->      #Pin16(BCM GPIO23)
13  *                  GND       <----->      GND
14  *
15  * System install:
16  *                  sudo apt install -y libgpiod-dev gpiod
17  *
18  *
19  ********************************************************************************/
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <dirent.h>
26 #include <string.h>
27 #include <time.h>
28 #include <errno.h>
29 #include <signal.h>
30 #include <getopt.h>
31 #include <libgen.h>
32
33 #include <gpiod.h>
34 #include "logger.h"
35 #include "relay.h"
36
37 #define DELAY     500
38
39 static relay_info_t    relay_info[RELAY_CNT] =
40 {
41     {"relay1",  23, 1, NULL },
42 };
43
44 int init_relay(relay_ctx_t *ctx)
45 {
46     int            i, rv;
47     relay_info_t  *relay;
48
49     if( !ctx )
50     {
51         log_error("Invalid input arguments\n");
52         return -1;
53     }
54
55     ctx->relay = relay_info;
56     ctx->count = RELAY_CNT;
57
58     ctx->chip = gpiod_chip_open_by_name("gpiochip0");
59     if( !ctx->chip )
60     {
61         log_error("open gpiochip failure, maybe you need running as root\n");
62         return -2;
63     }
64
65
66     for(i=0; i<ctx->count; i++)
67     {
68         relay = &ctx->relay[i];
69
70         relay->line = gpiod_chip_get_line(ctx->chip, relay->gpio);
71         if( !relay->line )
72         {
73             log_error("open gpioline for %s[%d] failed\n", relay->name, relay->gpio);
74             rv = -3;
75             goto failed;
76         }
77
78         rv  = gpiod_line_request_output(relay->line, relay->name, !relay->active);
79         if( rv )
80         {
81             log_error("request gpio output for %5s[%d] failed\n", relay->name, relay->gpio);
82             rv = -4;
83             goto failed;
84         }
85
86         log_debug("request %s[%d] for gpio output okay\n", relay->name, relay->gpio);
87     }
88
89     return 0;
90
91 failed:
92     term_relay(ctx);
93     return rv;
94 }
95
96 int term_relay(relay_ctx_t *ctx)
97 {
98     int            i;
99     relay_info_t  *relay;
100
101     if( !ctx )
102     {
103         log_error("Invalid input arguments\n");
104         return -1;
105     }
106
107     if( !ctx->chip )
108         return 0;
109
110     for(i=0; i<ctx->count; i++)
111     {
112         relay = &ctx->relay[i];
113
114         if( relay->line )
115             gpiod_line_release(relay->line);
116     }
117
118     gpiod_chip_close(ctx->chip);
119     return 0;
120 }
121
122
123 int turn_relay(int which, int cmd)
124 {
125     int             rv = 0;
126     relay_info_t   *relay;
127     relay_ctx_t     ctx;
128
129     if( which<0 || which>=RELAY_CNT )
130     {
131         log_error("Invalid input arguments\n");
132         return -1;
133     }
134
135     if( (rv=init_relay(&ctx)) < 0 )
136     {
137         log_error("Initial relay failure, rv=%d\n", rv);
138         return -2;
139     }
140
141     relay = &ctx.relay[which];
142
143     if( OFF == cmd )
144     {
145         gpiod_line_set_value(relay->line, !relay->active);
146     }
147     else
148     {
149         gpiod_line_set_value(relay->line, relay->active);
150     }
151
152     term_relay(&ctx);
153
154     return 0;
155 }
156