RaspberrPi project source code
Guo Wenxue
6 days ago f7889e2ceddbc3e15ea4b5377d831f4432169f76
commit | author | age
d6b4a7 1 /*********************************************************************************
G 2  *      Copyright:  (C) 2023 LingYun IoT System Studio
3  *                  All rights reserved.
4  *
5  *       Filename:  led.c
6  *    Description:  This file is HC-SR501 infrared sensor code
7  *
8  *
9  * Pin connection:
10  *               HC-SR501 Module           Raspberry Pi Board
11  *                  VCC       <----->      5V
851749 12  *                  I/O       <----->      #Pin16(BCM GPIO23)
d6b4a7 13  *                  I/O       <----->      #Pin18(BCM GPIO24)
G 14  *                  GND       <----->      GND
15  *
16  * System install:
17  *                  sudo apt install -y libgpiod-dev gpiod
18  *
19  *
20  ********************************************************************************/
21
22
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <signal.h>
29 #include <getopt.h>
30 #include <libgen.h>
31
32 #include <gpiod.h>
33
34 /* infrared code */
35 enum
36 {
37     IR1 = 0,
851749 38     IR2,
d6b4a7 39     IR_CNT,
G 40 };
41
42 /* infrared hardware information */
43 typedef struct ir_info_s
44 {
45     const char         *name;  /* infrared name  */
46     int                 gpio;  /* infrared BCM pin number */
47     int                 active;/* infrared active GPIO level: 0->low 1->high */
48     struct gpiod_line  *line;  /* libgpiod line */
49 } ir_info_t;
50
51 static ir_info_t    ir_info[IR_CNT] =
52 {
53     {"IR1", 23, 1, NULL },
851749 54     {"IR2", 24, 1, NULL },
d6b4a7 55 };
G 56
57 /* infrared API context */
58 typedef struct ir_ctx_s
59 {
60     struct gpiod_chip   *chip;
61     ir_info_t           *ir;
62     int                  count;
63 } ir_ctx_t;
64
65 int init_infrared(ir_ctx_t *ctx);
66 int term_infrared(ir_ctx_t *ctx);
67 int detect_infrared(ir_ctx_t *ctx, int which);
68 static inline void msleep(unsigned long ms);
69
70 static inline void banner(const char *progname)
71 {
72     printf("%s program Version v1.0.0\n", progname);
73     printf("Copyright (C) 2023 LingYun IoT System Studio.\n");
74 }
75
76 static void program_usage(const char *progname)
77 {
78
79     printf("Usage: %s [OPTION]...\n", progname);
80     printf(" This is infrared detect program. \n");
81
82     printf(" -d[device  ]  Specify infrared device, such as 0\n");
83     printf(" -h[help    ]  Display this help information\n");
84     printf(" -v[version ]  Display the program version\n");
85
86     printf("\n");
87     banner(progname);
88     return;
89 }
90
91 int g_stop = 0;
92 void sig_handler(int signum)
93 {
94     switch( signum )
95     {
96         case SIGINT:
97         case SIGTERM:
98             g_stop = 1;
99
100         default:
101             break;
102     }
103
104     return ;
105 }
106
107 int main(int argc, char **argv)
108 {
109     int             i, rv;
110     char           *progname=NULL;
111
112     ir_ctx_t        ir_ctx =
113     {
114         .chip  = NULL,
115         .ir    = ir_info,
116         .count = IR_CNT,
117     };
118
119     struct option long_options[] = {
120         {"version", no_argument, NULL, 'v'},
121         {"help", no_argument, NULL, 'h'},
122         {NULL, 0, NULL, 0}
123     };
124
125     progname = basename(argv[0]);
126
127     /* Parser the command line parameters */
128     while ((rv = getopt_long(argc, argv, "vh", long_options, NULL)) != -1)
129     {
130         switch (rv)
131         {
132             case 'v':  /* Get software version */
133                 banner(progname);
134                 return EXIT_SUCCESS;
135
136             case 'h':  /* Get help information */
137                 program_usage(progname);
138                 return 0;
139
140             default:
141                 break;
142         }
143     }
144
145     if( (rv=init_infrared(&ir_ctx)) < 0 )
146     {
147         printf("initial infrared gpio failure, rv=%d\n", rv);
148         return 1;
149     }
150
151     signal(SIGINT,  sig_handler);
152     signal(SIGTERM, sig_handler);
153
154     while( !g_stop )
155     {
156         for( i=0; i<ir_ctx.count; i++ )
157         {
158             rv = detect_infrared(&ir_ctx, i);
159             printf("Infrared[%d] monitor: %s\n", i, rv ? "Someone is closing!":"No one nearby!");
160         }
161         sleep(1);
162     }
163
164     term_infrared(&ir_ctx);
165     return 0;
166 }
167
168 int term_infrared(ir_ctx_t *ctx)
169 {
170     int            i;
171     ir_info_t     *ir;
172
173     if( !ctx )
174     {
175         printf("Invalid input arguments\n");
176         return -1;
177     }
178
179     if( !ctx->chip )
180         return 0;
181
182     for(i=0; i<ctx->count; i++)
183     {
184         ir = &ctx->ir[i];
185
186         if( ir->line )
187             gpiod_line_release(ir->line);
188     }
189
190     gpiod_chip_close(ctx->chip);
191     return 0;
192 }
193
194 int init_infrared(ir_ctx_t *ctx)
195 {
196     int            i, rv;
197     ir_info_t     *ir;
198
199     if( !ctx )
200     {
201         printf("Invalid input arguments\n");
202         return -1;
203     }
204
205     ctx->chip = gpiod_chip_open_by_name("gpiochip0");
206     if( !ctx->chip )
207     {
208         printf("open gpiochip failure, maybe you need running as root\n");
209         return -2;
210     }
211
212
213     for(i=0; i<ctx->count; i++)
214     {
215         ir = &ctx->ir[i];
216
217         ir ->line = gpiod_chip_get_line(ctx->chip, ir->gpio);
218         if( !ir->line )
219         {
220             printf("open gpioline for %s[%d] failed\n", ir->name, ir->gpio);
221             rv = -3;
222             goto failed;
223         }
224
225         rv  = gpiod_line_request_input(ir->line, ir->name);
226         if( rv )
227         {
228             printf("request gpio input for %s[%d] failed\n", ir->name, ir->gpio);
229             rv = -4;
230             goto failed;
231         }
232     }
233
234     return 0;
235
236 failed:
237     term_infrared(ctx);
238     return rv;
239 }
240
241 int detect_infrared(ir_ctx_t *ctx, int which)
242 {
243     int            rv = 0;
244     ir_info_t     *ir;
245
246     if( !ctx || which<0 || which>=ctx->count )
247     {
248         printf("Invalid input arguments\n");
249         return 0;
250     }
251
252     ir = &ctx->ir[which];
253
254     return gpiod_line_get_value(ir->line)==ir->active ? 1 : 0;
255 }
256
257
258 static inline void msleep(unsigned long ms)
259 {
260     struct timespec cSleep;
261     unsigned long ulTmp;
262
263     cSleep.tv_sec = ms / 1000;
264     if (cSleep.tv_sec == 0)
265     {
266         ulTmp = ms * 10000;
267         cSleep.tv_nsec = ulTmp * 100;
268     }
269     else
270     {
271         cSleep.tv_nsec = 0;
272     }
273
274     nanosleep(&cSleep, 0);
275
276     return ;
277 }