// lslder.cc -- GW/20200110 // // LSL Digital Event Recorder // // This program offers a maximum of eight LSL event streams, each triggered by positive edges on // raspberry pi GPIO digital inputs. Visual feedback is provided bij eight LEDs. // The stream type is "Digital Events - $HOSTNAME", where HOSTNAME is the ip hostname of // the raspberry. This is to uniquely identify devices on the network. // The data sent with the events is an int8 with value 1, with 1 indicating a rising edge. // Falling edges can be sent with a 0 value. However this is not implemented in this // program. // // Dependencies: labstreaminglayer C++ and wiringPi // CHANGES // GW/20180716 initial version for 8-channel LSL Digital Event Recorder #include #include #include #include #include #include // std::this_thread::sleep_for #include // std::chrono::seconds #include #include "led.h" #define DEBUG using namespace lsl; #ifdef LSLDER_1CHAN // 1 channel portable version without LEDs const int ngpio = 1; const int gpioinp[ngpio] = { 8 }; const int *ledgpio = 0; const int nled = 0; #endif #ifdef LSLDER_8CHAN // 8-chan version with 8 LEDs const int ngpio = 8; const int gpioinp[ngpio] = { 12, 7, 8, 25, 24, 23, 18, 15 }; const int ledgpio[] = { 21, 20, 16, 13, 5, 14, 3, 2 }; const int nled = 8; #endif int ledtime=1; // in 1/50 sec., see infinite loop in main() volatile int ledtimer[ngpio] = { 0, }; int ledstatus[ngpio] = { 0, }; #ifdef DEBUG volatile int interrupt_count[ngpio] = { 0, }; #endif stream_outlet *outlet[ngpio]; std::mutex lsl_mutex; typedef char int8; void gpioInterrupt(int channel) { std::lock_guard guard(lsl_mutex); #ifdef DEBUG std::cout << "Interrupt on channel " << channel << " (GPIO " << gpioinp[channel] << ")" << std::endl; #endif static int edge=1; outlet[channel]->push_sample(&edge); ledtimer[channel]=ledtime; #ifdef DEBUG interrupt_count[channel]++; std::cout << channel << " (count=" << interrupt_count[channel] << ")" << std::endl; #endif } void handleLeds() { for (int i=0; (i 0) { if (!ledstatus[i]) { //std::lock_guard guard(lsl_mutex); setled(i,1); ledstatus[i]=1; } ledtimer[i]--; } else { if (ledstatus[i]) { //std::lock_guard guard(lsl_mutex); setled(i,0); ledstatus[i]=0; } } } } void gpioISR_0() { gpioInterrupt(0); } void gpioISR_1() { gpioInterrupt(1); } void gpioISR_2() { gpioInterrupt(2); } void gpioISR_3() { gpioInterrupt(3); } void gpioISR_4() { gpioInterrupt(4); } void gpioISR_5() { gpioInterrupt(5); } void gpioISR_6() { gpioInterrupt(6); } void gpioISR_7() { gpioInterrupt(7); } typedef void(*gpioISR)(); gpioISR ISR[] = { gpioISR_0, gpioISR_1, gpioISR_2, gpioISR_3, gpioISR_4, gpioISR_5, gpioISR_6, gpioISR_7 }; int main(int argc, char* argv[]) { piHiPri(99); // shortcut for running at real time priority // configure inputs wiringPiSetupGpio(); initleds(nled, ledgpio); for (int i=0; i