Lichtschranke mit dem Raspberry in C

18. Januar 2014 at 07:42
Print Friendly, PDF & Email

Die Auslösung der Lichtschranke wird über einen Interrupt erkannt. WiringPi bietet eine einfache Lösung hierfür.

Für eine Zeitmessung werden hier zwei Lichtschranken eingesetzt.

 

Installation wiringPI

 

cd 
git clone git://git.drogon.net/wiringPi
cd wiringPi
./build

 

Programm

Für zeitkritische Anwendungen möchte ich mich nicht auf Python verlassen. Daher wurde das Programm in C erstellt.

/*
 * lichtschranke.c:
 *    measure time with two lightbarriers
 *  2014-01-17 by Thomas Hoeser
 *
 * git clone git://git.drogon.net/wiringPi
 * cd wiringPi
 * ./build
 * gcc -lwiringPi -o lichtschranke lichtschranke.c
 *
 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <wiringPi.h>
#include <errno.h>
 
#define PIN_IN_1         3    // GPIO 22 - header PIN 15
#define PIN_IN_2         5    // GPIO 24 - header PIN 18
#define MYDEBUG       // rename to ignore debug code in final build
 
struct timeval t1_light       ;  // Time of first  light barrier
struct timeval t2_light       ;  // Time of second light barrier
static volatile int globalCounter = 0;
typedef enum { false, true } bool;
static volatile bool globalActive  = false; // set to 1 if 1st light barrier is passed
// i.e. measuring is active and signal for 1st ligth barrier should be ignored
static volatile bool globalEcho  = false;
 
// ----------------------------------------------------------------------------------
void showElapsedTime(void) { 
    static int t_delay,seconds,useconds;
 
    seconds  = t2_light.tv_sec  - t1_light.tv_sec;
      useconds = t2_light.tv_usec - t1_light.tv_usec;
      if(useconds < 0) {
        useconds += 1000000;
        seconds--;
        }
      printf("start #%d -> %d sec %d msec\n",globalCounter,t1_light.tv_sec,t1_light.tv_usec); 
      printf("end   #%d -> %d sec %d msec\n",globalCounter,t2_light.tv_sec,t2_light.tv_usec); 
      printf("Elapsed Time #%d -> var start/end: %d sec %d msec\n\n",globalCounter,seconds,useconds/1000);
} // end showElapsedTime()
 
// ----------------------------------------------------------------------------------
void myInterrupt1(void) { 
  if(globalActive==false){ // check if time measurement is already active
    globalActive = true;
    if(globalEcho==true){
      printf ("STD Light Barrier 1 - Global Counter = %d\n",++globalCounter);
    }
    gettimeofday(&t1_light, NULL); // get current time and save in variable t1_light
  } 
} // end myInterrupt1()
 
// ----------------------------------------------------------------------------------
void myInterrupt2(void) { 
  if(globalEcho==true){printf ("STD Light Barrier 2\n");}
  gettimeofday(&t2_light, NULL); // get current time and save in variable t2_light
  showElapsedTime(); 
  globalActive = false; // reset status for next measurement
} // end myInterrupt2()
 
// ----------------------------------------------------------------------------------
int main()
{
  globalCounter = 0;     // set global counter
  globalEcho    = true;  // enable printf in interrupt function
  globalActive  = false; // measurement is not active
 
  printf ("init - Global Counter = %d\n",globalCounter);
 
  // test code - no interrupt
  #ifdef MYDEBUG
  myInterrupt1();
  delay (123) ;                // wait for given time [milliseconds]
  myInterrupt2();
 
  myInterrupt1();
  delay (123) ;                // wait for given time [milliseconds]
  myInterrupt1();
  delay (200) ;                // wait for given time [milliseconds]
  myInterrupt2();
  #endif
  // end test code - no interrupt
 
  // wiring pi - interrupt
  globalEcho    = false; // do not waste time with printf; this may distort measurement
  wiringPiSetup();
  wiringPiISR(PIN_IN_1, INT_EDGE_RISING, &myInterrupt1);
  wiringPiISR(PIN_IN_2, INT_EDGE_RISING, &myInterrupt2);
 
    // Waste time but not CPU
    for (;;) {
        sleep(1000);
    }
 
  return 0;
} // end main()

 

Programm compilieren + starten

 

gcc -I. -o lichtschranke lichtschranke.c  -lwiringPi
sudo ./lichtschranke

Hardware

Einen Schaltplan kann man hier sehen: https://hoeser-medien.de/?p=1184