Close

Event Capture and Recording with Raspberry Pi (Part 2b)

A project log for Cosmic Array

An array of cosmic ray detectors across a landscape that demonstrates in light and sound how cosmic rays are constantly all around us.

paul-schulzPaul Schulz 07/06/2017 at 08:480 Comments

This log entry follows on from Part 1, and Part 2a.

Transmitting Cosmic Array Detection Events

The RaspberryPi 3 (or RaspberryPi Zero W) receives events from the detector via the toggling of the General Purpose IO (GPIO) lines. These lines are monitored by software on the Pi, which registers interrupt functions for each line, which is called when an event is detected.

This means that the processor doesn't need to continually poll the GPIO lines for their state, saving processing time, and can also react immediately (interrupting whatever it was doing), improving reaction time.

The previous program written to send UDP event packets across the network (udpsend) has been changed to use interrupt functions. While doing this, it was discovered that the WiringPi library also allows multiple programs to be triggered by the same interrupts. This has proven useful for also getting the detector to produce sound effects (eg. play wav files) and the code for this is below:

/*
 * cosmicray-play.c - Play an audio file on a cosmicray event.
 * usage: cosmicray-play
 */
#include <stdio.h>
#include <stdlib.h>
#include <wiringpi.h>
/*  error - wrapper for perror */
void error(char *msg) {
  perror(msg);
  exit(0);
}
/* interrupt functions */
void my_interrupt(int i) {
  system("aplay audio/beep.wav > /dev/null 2>&1 &");
}
void my_interrupt_0 (void) { my_interrupt(0); }
void my_interrupt_1 (void) { my_interrupt(1); }
void my_interrupt_2 (void) { my_interrupt(2); }
void my_interrupt_3 (void) { my_interrupt(3); }
void my_interrupt_4 (void) { my_interrupt(4); }
void my_interrupt_5 (void) { my_interrupt(5); }
void my_interrupt_6 (void) { my_interrupt(6); }
void my_interrupt_7 (void) { my_interrupt(7); }
int main(int argc, char **argv) {
  wiringPiSetup();
  /* check command line arguments */
  if (argc != 1) {
    fprintf(stderr,"usage: %s\n", argv[0]);
    exit(0);
  }
  /* setup interrupt handlers */
  wiringPiISR (0, INT_EDGE_FALLING, &my_interrupt_0) ;
  wiringPiISR (1, INT_EDGE_FALLING, &my_interrupt_1) ;
  wiringPiISR (2, INT_EDGE_FALLING, &my_interrupt_2) ;
  wiringPiISR (3, INT_EDGE_FALLING, &my_interrupt_3) ;
  wiringPiISR (4, INT_EDGE_FALLING, &my_interrupt_4) ;
  wiringPiISR (5, INT_EDGE_FALLING, &my_interrupt_5) ;
  wiringPiISR (6, INT_EDGE_FALLING, &my_interrupt_6) ;
  wiringPiISR (7, INT_EDGE_FALLING, &my_interrupt_7) ;
  for(;;){
    delay(100);
  }
  return 0;
}

Can be compiled with:

gcc -o cosmicray-play cosmicray-play.c -lwiringPi

Then run it from a directory where a suitable 'wav' file is available.

Next time: Collecting and storing event data in a database (Part 3).

Discussions