/********************************************************************************* * Copyright: (C) 2023 LingYun IoT System Studio * All rights reserved. * * Filename: led.c * Description: This file is HC-SR501 infrared sensor code * * * Pin connection: * HC-SR501 Module Raspberry Pi Board * VCC <-----> 5V * I/O <-----> #Pin16(BCM GPIO23) * I/O <-----> #Pin18(BCM GPIO24) * GND <-----> GND * * System install: * sudo apt install -y libgpiod-dev gpiod * * ********************************************************************************/ #include #include #include #include #include #include #include #include #include /* infrared code */ enum { IR1 = 0, IR2, IR_CNT, }; /* infrared hardware information */ typedef struct ir_info_s { const char *name; /* infrared name */ int gpio; /* infrared BCM pin number */ int active;/* infrared active GPIO level: 0->low 1->high */ struct gpiod_line *line; /* libgpiod line */ } ir_info_t; static ir_info_t ir_info[IR_CNT] = { {"IR1", 23, 1, NULL }, {"IR2", 24, 1, NULL }, }; /* infrared API context */ typedef struct ir_ctx_s { struct gpiod_chip *chip; ir_info_t *ir; int count; } ir_ctx_t; int init_infrared(ir_ctx_t *ctx); int term_infrared(ir_ctx_t *ctx); int detect_infrared(ir_ctx_t *ctx, int which); static inline void msleep(unsigned long ms); static inline void banner(const char *progname) { printf("%s program Version v1.0.0\n", progname); printf("Copyright (C) 2023 LingYun IoT System Studio.\n"); } static void program_usage(const char *progname) { printf("Usage: %s [OPTION]...\n", progname); printf(" This is infrared detect program. \n"); printf(" -d[device ] Specify infrared device, such as 0\n"); printf(" -h[help ] Display this help information\n"); printf(" -v[version ] Display the program version\n"); printf("\n"); banner(progname); return; } int g_stop = 0; void sig_handler(int signum) { switch( signum ) { case SIGINT: case SIGTERM: g_stop = 1; default: break; } return ; } int main(int argc, char **argv) { int i, rv; char *progname=NULL; ir_ctx_t ir_ctx = { .chip = NULL, .ir = ir_info, .count = IR_CNT, }; struct option long_options[] = { {"version", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 'h'}, {NULL, 0, NULL, 0} }; progname = basename(argv[0]); /* Parser the command line parameters */ while ((rv = getopt_long(argc, argv, "vh", long_options, NULL)) != -1) { switch (rv) { case 'v': /* Get software version */ banner(progname); return EXIT_SUCCESS; case 'h': /* Get help information */ program_usage(progname); return 0; default: break; } } if( (rv=init_infrared(&ir_ctx)) < 0 ) { printf("initial infrared gpio failure, rv=%d\n", rv); return 1; } signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); while( !g_stop ) { for( i=0; ichip ) return 0; for(i=0; icount; i++) { ir = &ctx->ir[i]; if( ir->line ) gpiod_line_release(ir->line); } gpiod_chip_close(ctx->chip); return 0; } int init_infrared(ir_ctx_t *ctx) { int i, rv; ir_info_t *ir; if( !ctx ) { printf("Invalid input arguments\n"); return -1; } ctx->chip = gpiod_chip_open_by_name("gpiochip0"); if( !ctx->chip ) { printf("open gpiochip failure, maybe you need running as root\n"); return -2; } for(i=0; icount; i++) { ir = &ctx->ir[i]; ir ->line = gpiod_chip_get_line(ctx->chip, ir->gpio); if( !ir->line ) { printf("open gpioline for %s[%d] failed\n", ir->name, ir->gpio); rv = -3; goto failed; } rv = gpiod_line_request_input(ir->line, ir->name); if( rv ) { printf("request gpio input for %s[%d] failed\n", ir->name, ir->gpio); rv = -4; goto failed; } } return 0; failed: term_infrared(ctx); return rv; } int detect_infrared(ir_ctx_t *ctx, int which) { int rv = 0; ir_info_t *ir; if( !ctx || which<0 || which>=ctx->count ) { printf("Invalid input arguments\n"); return 0; } ir = &ctx->ir[which]; return gpiod_line_get_value(ir->line)==ir->active ? 1 : 0; } static inline void msleep(unsigned long ms) { struct timespec cSleep; unsigned long ulTmp; cSleep.tv_sec = ms / 1000; if (cSleep.tv_sec == 0) { ulTmp = ms * 10000; cSleep.tv_nsec = ulTmp * 100; } else { cSleep.tv_nsec = 0; } nanosleep(&cSleep, 0); return ; }