V23
authorjoan <joan@abyz.me.uk>
Tue, 25 Nov 2014 13:24:49 +0000 (13:24 +0000)
committerjoan <joan@abyz.me.uk>
Tue, 25 Nov 2014 13:24:49 +0000 (13:24 +0000)
EXAMPLES/C/COUNTER_1/README [new file with mode: 0644]
EXAMPLES/C/COUNTER_1/freq_count_1.c [new file with mode: 0644]
EXAMPLES/C/COUNTER_2/README [new file with mode: 0644]
EXAMPLES/C/COUNTER_2/freq_count_2.c [new file with mode: 0644]
EXAMPLES/C/Readme [deleted file]
EXAMPLES/placeholder [deleted file]

diff --git a/EXAMPLES/C/COUNTER_1/README b/EXAMPLES/C/COUNTER_1/README
new file mode 100644 (file)
index 0000000..5eec110
--- /dev/null
@@ -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 (file)
index 0000000..31b5d38
--- /dev/null
@@ -0,0 +1,238 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <pigpio.h>
+
+/*
+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<MAX_GPIOS; g++) g_pulse_count[g] = 0;
+   }
+
+   /* only record low to high edges */
+   if (level == 1) g_pulse_count[gpio]++;
+}
+
+int main(int argc, char *argv[])
+{
+   int i, rest, g, wave_id, mode;
+   gpioPulse_t pulse[2];
+   int count[MAX_GPIOS];
+
+   /* command line parameters */
+
+   rest = initOpts(argc, argv);
+
+   /* get the gpios to monitor */
+
+   g_num_gpios = 0;
+
+   for (i=rest; i<argc; i++)
+   {
+      g = atoi(argv[i]);
+      if ((g>=0) && (g<32))
+      {
+         g_gpio[g_num_gpios++] = g;
+         g_mask |= (1<<g);
+      }
+      else fatal(1, "%d is not a valid g_gpio number\n", g);
+   }
+
+   if (!g_num_gpios) fatal(1, "At least one gpio must be specified");
+
+   printf("Monitoring gpios");
+   for (i=0; i<g_num_gpios; i++) printf(" %d", g_gpio[i]);
+   printf("\nSample rate %d micros, refresh rate %d deciseconds\n",
+      g_opt_s, g_opt_r);
+
+   gpioCfgClock(g_opt_s, 1, 1);
+
+   if (gpioInitialise()<0) return 1;
+
+   gpioWaveClear();
+
+   pulse[0].gpioOn  = g_mask;
+   pulse[0].gpioOff = 0;
+   pulse[0].usDelay = g_opt_p;
+
+   pulse[1].gpioOn  = 0;
+   pulse[1].gpioOff = g_mask;
+   pulse[1].usDelay = g_opt_p;
+
+   gpioWaveAddGeneric(2, pulse);
+
+   wave_id = gpioWaveCreate();
+
+   /* monitor g_gpio level changes */
+
+   for (i=0; i<g_num_gpios; i++) gpioSetAlertFunc(g_gpio[i], edges);
+
+   mode = PI_INPUT;
+
+   if (g_opt_t)
+   {
+      gpioWaveTxSend(wave_id, PI_WAVE_MODE_REPEAT);
+      mode = PI_OUTPUT;
+   }
+
+   for (i=0; i<g_num_gpios; i++) gpioSetMode(g_gpio[i], mode);
+
+   while (1)
+   {
+      for (i=0; i<g_num_gpios; i++) count[i] = g_pulse_count[g_gpio[i]];
+
+      g_reset_counts = 1;
+
+      for (i=0; i<g_num_gpios; i++)
+      {
+         printf(" %d=%d", g_gpio[i], count[i]);
+      }
+
+      printf("\n");
+
+      gpioDelay(g_opt_r * 100000);
+   }
+
+   gpioTerminate();
+}
+
diff --git a/EXAMPLES/C/COUNTER_2/README b/EXAMPLES/C/COUNTER_2/README
new file mode 100644 (file)
index 0000000..2a9f1e3
--- /dev/null
@@ -0,0 +1,6 @@
+A program showing how to use the gpioSetGetSamplesFunc function to set a callback for accumulated gpio state changes over the last millisecond.
+
+A frequency count is generated for each monitored gpio (frequencies up to 500KHz and beyond).
+
+Generally the method used is more complicated but more efficient than frequency counter 1.
+
diff --git a/EXAMPLES/C/COUNTER_2/freq_count_2.c b/EXAMPLES/C/COUNTER_2/freq_count_2.c
new file mode 100644 (file)
index 0000000..fbe84b1
--- /dev/null
@@ -0,0 +1,257 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include <pigpio.h>
+
+/*
+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<g_num_gpios; g++) g_pulse_count[g] = 0;
+   }
+
+   for (s=0; s<numSamples; s++)
+   {
+      level = samples[s].level;
+      high = ((state ^ level) & g_mask) & level;
+      state = level;
+      /* only interested in low to high */
+      if (high)
+      {
+         for (g=0; g<g_num_gpios; g++)
+         {
+            if (high & (1<<g_gpio[g])) g_pulse_count[g]++;
+         }
+      }
+   }
+}
+
+int main(int argc, char *argv[])
+{
+   int i, rest, g, wave_id, mode;
+   gpioPulse_t pulse[2];
+   int count[MAX_GPIOS];
+
+   /* command line parameters */
+
+   rest = initOpts(argc, argv);
+
+   /* get the gpios to monitor */
+
+   g_num_gpios = 0;
+
+   for (i=rest; i<argc; i++)
+   {
+      g = atoi(argv[i]);
+      if ((g>=0) && (g<32))
+      {
+         g_gpio[g_num_gpios++] = g;
+         g_mask |= (1<<g);
+      }
+      else fatal(1, "%d is not a valid g_gpio number\n", g);
+   }
+
+   if (!g_num_gpios) fatal(1, "At least one gpio must be specified");
+
+   printf("Monitoring gpios");
+   for (i=0; i<g_num_gpios; i++) printf(" %d", g_gpio[i]);
+   printf("\nSample rate %d micros, refresh rate %d deciseconds\n",
+      g_opt_s, g_opt_r);
+
+   gpioCfgClock(g_opt_s, 1, 1);
+
+   if (gpioInitialise()<0) return 1;
+
+   gpioWaveClear();
+
+   pulse[0].gpioOn  = g_mask;
+   pulse[0].gpioOff = 0;
+   pulse[0].usDelay = g_opt_p;
+
+   pulse[1].gpioOn  = 0;
+   pulse[1].gpioOff = g_mask;
+   pulse[1].usDelay = g_opt_p;
+
+   gpioWaveAddGeneric(2, pulse);
+
+   wave_id = gpioWaveCreate();
+
+   /* monitor g_gpio level changes */
+
+   gpioSetGetSamplesFunc(samples, g_mask);
+
+   mode = PI_INPUT;
+
+   if (g_opt_t)
+   {
+      gpioWaveTxSend(wave_id, PI_WAVE_MODE_REPEAT);
+      mode = PI_OUTPUT;
+   }
+
+   for (i=0; i<g_num_gpios; i++) gpioSetMode(g_gpio[i], mode);
+
+   while (1)
+   {
+      for (i=0; i<g_num_gpios; i++) count[i] = g_pulse_count[i];
+
+      g_reset_counts = 1;
+
+      for (i=0; i<g_num_gpios; i++)
+      {
+         printf(" %d=%d", g_gpio[i], count[i]);
+      }
+
+      printf("\n");
+
+      gpioDelay(g_opt_r * 100000);
+   }
+
+   gpioTerminate();
+}
+
diff --git a/EXAMPLES/C/Readme b/EXAMPLES/C/Readme
deleted file mode 100644 (file)
index 677024c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pigpio C examples
diff --git a/EXAMPLES/placeholder b/EXAMPLES/placeholder
deleted file mode 100644 (file)
index 3b94f91..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Placeholder