diff --git a/EXAMPLES/C/COUNTER_1/README b/EXAMPLES/C/COUNTER_1/README new file mode 100644 index 0000000..5eec110 --- /dev/null +++ b/EXAMPLES/C/COUNTER_1/README @@ -0,0 +1,3 @@ +A program showing how to use the gpioSetAlertFunc function to set a callback for gpio state changes. + +A frequency count is generated for each monitored gpio (frequencies up to 500KHz and beyond). diff --git a/EXAMPLES/C/COUNTER_1/freq_count_1.c b/EXAMPLES/C/COUNTER_1/freq_count_1.c new file mode 100644 index 0000000..31b5d38 --- /dev/null +++ b/EXAMPLES/C/COUNTER_1/freq_count_1.c @@ -0,0 +1,238 @@ +#include +#include +#include +#include + +#include + +/* +2014-08-20 + +gcc -o freq_count_1 freq_count_1.c -lpigpio -lpthread +$ sudo ./freq_count_1 4 7 8 + +This program uses the gpioSetAlertFunc function to request +a callback (the same one) for each gpio to be monitored. + +EXAMPLES + +Monitor gpio 4 (default settings) +sudo ./freq_count_1 4 + +Monitor gpios 4 and 8 (default settings) +sudo ./freq_count_1 4 8 + +Monitor gpios 4 and 8, sample rate 2 microseconds +sudo ./freq_count_1 4 8 -s2 + +Monitor gpios 7 and 8, sample rate 4 microseconds, report every second +sudo ./freq_count_1 7 8 -s4 -r10 + +Monitor gpios 4,7, 8, 9, 10, 23 24, report five times a second +sudo ./freq_count_1 4 7 8 9 10 23 24 -r2 + +Monitor gpios 4, 7, 8, and 9, report once a second, sample rate 1us, +generate 2us edges (4us square wave, 250000 highs per second). +sudo ./freq_count_1 4 7 8 9 -r 10 -s 1 -p 2 +*/ + +#define MAX_GPIOS 32 + +#define OPT_P_MIN 1 +#define OPT_P_MAX 1000 +#define OPT_P_DEF 20 + +#define OPT_R_MIN 1 +#define OPT_R_MAX 10 +#define OPT_R_DEF 5 + +#define OPT_S_MIN 1 +#define OPT_S_MAX 10 +#define OPT_S_DEF 5 + +static volatile int g_pulse_count[MAX_GPIOS]; +static volatile int g_reset_counts; +static uint32_t g_mask; + +static int g_num_gpios; +static int g_gpio[MAX_GPIOS]; + +static int g_opt_p = OPT_P_DEF; +static int g_opt_r = OPT_R_DEF; +static int g_opt_s = OPT_S_DEF; +static int g_opt_t = 0; + +void usage() +{ + fprintf + (stderr, + "\n" \ + "Usage: sudo ./freq_count_1 gpio ... [OPTION] ...\n" \ + " -p value, sets pulses every p micros, %d-%d, TESTING only\n" \ + " -r value, sets refresh period in deciseconds, %d-%d, default %d\n" \ + " -s value, sets sampling rate in micros, %d-%d, default %d\n" \ + "\nEXAMPLE\n" \ + "sudo ./freq_count_1 4 7 -r2 -s2\n" \ + "Monitor gpios 4 and 7. Refresh every 0.2 seconds. Sample rate 2 micros.\n" \ + "\n", + OPT_P_MIN, OPT_P_MAX, + OPT_R_MIN, OPT_R_MAX, OPT_R_DEF, + OPT_S_MIN, OPT_S_MAX, OPT_S_DEF + ); +} + +void fatal(int show_usage, char *fmt, ...) +{ + char buf[128]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buf); + + if (show_usage) usage(); + + fflush(stderr); + + exit(EXIT_FAILURE); +} + +static int initOpts(int argc, char *argv[]) +{ + int i, opt; + + while ((opt = getopt(argc, argv, "p:r:s:")) != -1) + { + i = -1; + + switch (opt) + { + case 'p': + i = atoi(optarg); + if ((i >= OPT_P_MIN) && (i <= OPT_P_MAX)) + g_opt_p = i; + else fatal(1, "invalid -p option (%d)", i); + g_opt_t = 1; + break; + + case 'r': + i = atoi(optarg); + if ((i >= OPT_R_MIN) && (i <= OPT_R_MAX)) + g_opt_r = i; + else fatal(1, "invalid -r option (%d)", i); + break; + + case 's': + i = atoi(optarg); + if ((i >= OPT_S_MIN) && (i <= OPT_S_MAX)) + g_opt_s = i; + else fatal(1, "invalid -s option (%d)", i); + break; + + default: /* '?' */ + usage(); + exit(-1); + } + } + return optind; +} + +void edges(int gpio, int level, uint32_t tick) +{ + int g; + + if (g_reset_counts) + { + g_reset_counts = 0; + for (g=0; g=0) && (g<32)) + { + g_gpio[g_num_gpios++] = g; + g_mask |= (1< +#include +#include +#include + +#include + +/* +2014-08-20 + +gcc -o freq_count_2 freq_count_2.c -lpigpio -lpthread +$ sudo ./freq_count_2 4 7 8 + +This program uses the gpioSetGetSamplesFunc function to request +a callback once a millisecond for all accumulated gpio changes +in that millisecond. + +This tends to be more efficient then calling a callback for each +gpio change during the millisecond. + +EXAMPLES + +Monitor gpio 4 (default settings) +sudo ./freq_count_2 4 + +Monitor gpios 4 and 8 (default settings) +sudo ./freq_count_2 4 8 + +Monitor gpios 4 and 8, sample rate 2 microseconds +sudo ./freq_count_2 4 8 -s2 + +Monitor gpios 7 and 8, sample rate 4 microseconds, report every second +sudo ./freq_count_2 7 8 -s4 -r10 + +Monitor gpios 4,7, 8, 9, 10, 23 24, report five times a second +sudo ./freq_count_2 4 7 8 9 10 23 24 -r2 + +Monitor gpios 4, 7, 8, and 9, report once a second, sample rate 1us, +generate 2us edges (4us square wave, 250000 highs per second). +sudo ./freq_count_2 4 7 8 9 -r 10 -s 1 -p 2 + +*/ + +#define MAX_GPIOS 32 + +#define OPT_P_MIN 1 +#define OPT_P_MAX 1000 +#define OPT_P_DEF 20 + +#define OPT_R_MIN 1 +#define OPT_R_MAX 10 +#define OPT_R_DEF 5 + +#define OPT_S_MIN 1 +#define OPT_S_MAX 10 +#define OPT_S_DEF 5 + +static volatile int g_pulse_count[MAX_GPIOS]; +static volatile int g_reset_counts; +static uint32_t g_mask; + +static int g_num_gpios; +static int g_gpio[MAX_GPIOS]; + +static int g_opt_p = OPT_P_DEF; +static int g_opt_r = OPT_R_DEF; +static int g_opt_s = OPT_S_DEF; +static int g_opt_t = 0; + +void usage() +{ + fprintf + (stderr, + "\n" \ + "Usage: sudo ./freq_count_2 gpio ... [OPTION] ...\n" \ + " -p value, sets pulses every p micros, %d-%d, TESTING only\n" \ + " -r value, sets refresh period in deciseconds, %d-%d, default %d\n" \ + " -s value, sets sampling rate in micros, %d-%d, default %d\n" \ + "\nEXAMPLE\n" \ + "sudo ./freq_count_2 4 7 -r2 -s2\n" \ + "Monitor gpios 4 and 7. Refresh every 0.2 seconds. Sample rate 2 micros.\n" \ + "\n", + OPT_P_MIN, OPT_P_MAX, + OPT_R_MIN, OPT_R_MAX, OPT_R_DEF, + OPT_S_MIN, OPT_S_MAX, OPT_S_DEF + ); +} + +void fatal(int show_usage, char *fmt, ...) +{ + char buf[128]; + va_list ap; + + va_start(ap, fmt); + vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + fprintf(stderr, "%s\n", buf); + + if (show_usage) usage(); + + fflush(stderr); + + exit(EXIT_FAILURE); +} + +static int initOpts(int argc, char *argv[]) +{ + int i, opt; + + while ((opt = getopt(argc, argv, "p:r:s:")) != -1) + { + i = -1; + + switch (opt) + { + case 'p': + i = atoi(optarg); + if ((i >= OPT_P_MIN) && (i <= OPT_P_MAX)) + g_opt_p = i; + else fatal(1, "invalid -p option (%d)", i); + g_opt_t = 1; + break; + + case 'r': + i = atoi(optarg); + if ((i >= OPT_R_MIN) && (i <= OPT_R_MAX)) + g_opt_r = i; + else fatal(1, "invalid -r option (%d)", i); + break; + + case 's': + i = atoi(optarg); + if ((i >= OPT_S_MIN) && (i <= OPT_S_MAX)) + g_opt_s = i; + else fatal(1, "invalid -s option (%d)", i); + break; + + default: /* '?' */ + usage(); + exit(-1); + } + } + return optind; +} + +void samples(const gpioSample_t *samples, int numSamples) +{ + static uint32_t state = 0; + uint32_t high, level; + int g, s; + + if (g_reset_counts) + { + g_reset_counts = 0; + for (g=0; g=0) && (g<32)) + { + g_gpio[g_num_gpios++] = g; + g_mask |= (1<