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