Lichtschranke mit dem Raspberry in C
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
[codesyntax lang=”text”]
cd git clone git://git.drogon.net/wiringPi cd wiringPi ./build
[/codesyntax]
Programm
Für zeitkritische Anwendungen möchte ich mich nicht auf Python verlassen. Daher wurde das Programm in C erstellt.
[codesyntax lang=”text”]
/* * 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()
[/codesyntax]
Programm compilieren + starten
[codesyntax lang=”text”]
gcc -I. -o lichtschranke lichtschranke.c -lwiringPi sudo ./lichtschranke
[/codesyntax]
Hardware
Einen Schaltplan kann man hier sehen: https://hoeser-medien.de/?p=1184