Commit cf6a703a authored by Your Name's avatar Your Name
Browse files

wiringPi -> pigpio mods

parent 20f8d01b
LSLBASE=../labstreaminglayer/build/install
CXXFLAGS+=-Wall -Wno-sign-compare -I$(LSLBASE)/include
LDFLAGS+=-L$(LSLBASE)/lib -llsl32 -lwiringPi -lboost_system -lpthread
LDFLAGS+=-L$(LSLBASE)/lib -llsl32 -lpigpio -lboost_system -lpthread
LDLIBS+=-lzmq -lpthread -lboost_system -lboost_regex -lboost_program_options
#INCLUDE+=RS-232
......@@ -10,8 +10,7 @@ CXXFLAGS+=-Wall -std=c++11
CXX=g++
CC=g++
TARGETS=lslder_1chan lslder_4chan lslder_8chan sendrand lslder_4chan_proto
TARGETS=lslder_1chan lslder_4chan lslder_8chan sendrand
all: $(TARGETS)
#lslder : CPPFLAGS+=-DLSLDER_8CHAN
......@@ -34,6 +33,7 @@ lslder_1chan.o: lslder_uni.cc
sendrand: sendrand.cc
lslder_4chan_proto: lslder_4chan_proto.cc
lslder_4chan_proto: LDFLAGS+=-lwiringPi
clean:
rm -f $(TARGETS) *.o
......
#include "led.h"
#include <wiringPi.h>
#include <pigpio.h>
#include <stdlib.h>
#include <unistd.h>
......@@ -16,7 +16,7 @@ void initleds(int _nled, const int *_ledgpio)
ledgpio = _ledgpio;
for (int i=0; i<nled; i++)
{
pinMode(ledgpio[i], OUTPUT);
gpioSetMode(ledgpio[i], PI_OUTPUT);
}
playleds();
}
......@@ -63,5 +63,10 @@ void setled(int lednr, int value)
else
bit = 0;
digitalWrite(ledgpio[lednr], bit);
int r= gpioWrite(ledgpio[lednr], bit);
if (r < 0)
{
perror("gpioWrite");
exit(1);
}
}
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -2,28 +2,34 @@
//
// 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.
// 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
// Dependencies: labstreaminglayer C++
// CHANGES
// GW/20180716 initial version for 8-channel LSL Digital Event Recorder
// GW/20210210 remove deprecated wiringPi and use pigpio instead
// TODO: use ISR tick for debounce timing
// TODO: add support to register falling edges
#include "led.h"
#include <chrono> // std::chrono::seconds
#include <cstring>
#include <iostream>
#include <lsl_cpp.h>
#include <mutex>
#include <pigpio.h>
#include <sched.h>
#include <signal.h>
#include <stdlib.h>
#include <thread> // std::this_thread::sleep_for
#include <unistd.h>
#include <iostream>
#include <mutex>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
#include <wiringPi.h>
#include "led.h"
#define DEBUG
......@@ -33,7 +39,7 @@ using namespace lsl;
// 1 channel portable version without LEDs
const int ngpio = 1;
const int gpioinp[ngpio] = { 8 };
const int gpioinp[ngpio] = {8};
const int default_debouncetime = 100;
......@@ -46,11 +52,11 @@ const int nled = 0;
// 4-chan version with 4 LEDs
const int ngpio = 4;
const int gpioinp[ngpio] = { 24, 23, 18, 15 };
const int gpioinp[ngpio] = {24, 23, 18, 15};
const int default_debouncetime = 0;
const int ledgpio[] = { 5, 14, 3, 2 };
const int ledgpio[] = {5, 14, 3, 2};
const int nled = 4;
#endif
......@@ -59,172 +65,185 @@ const int nled = 4;
// 8-chan version with 8 LEDs
const int ngpio = 8;
const int gpioinp[ngpio] = { 12, 7, 8, 25, 24, 23, 18, 15 };
const int gpioinp[ngpio] = {12, 7, 8, 25, 24, 23, 18, 15};
const int default_debouncetime = 0;
const int ledgpio[] = { 21, 20, 16, 13, 5, 14, 3, 2 };
const int ledgpio[] = {21, 20, 16, 13, 5, 14, 3, 2};
const int nled = 8;
#endif
int ledtime=2; // in 1/100 sec., see infinite loop in main()
volatile int ledtimer[ngpio] = { 0, };
int ledstatus[ngpio] = { 0, };
const int maxgpio = 54; // BCM chip has 54 GPIO
int gpiomap[maxgpio];
void init_gpiomap() {
// map channel wiring 0..ngpio-1 to BCM GPIO
for (int channel = 0; channel < ngpio; channel++) {
int bcmgpio = gpioinp[channel];
gpiomap[bcmgpio] = channel;
}
}
int debouncetimes[ngpio] = { 0, };
volatile int debouncetimer[ngpio] = { 0, };
int ledtime = 2; // in 1/100 sec., see infinite loop in main()
volatile int ledtimer[ngpio] = {
0,
};
int ledstatus[ngpio] = {
0,
};
int debouncetimes[ngpio] = {
0,
};
volatile int debouncetimer[ngpio] = {
0,
};
#ifdef DEBUG
volatile int interrupt_count[ngpio] = { 0, };
volatile int interrupt_count[ngpio] = {
0,
};
#endif
stream_outlet *outlet[ngpio];
std::mutex lsl_mutex;
typedef char int8;
void gpioInterrupt(int channel)
{
volatile int run = 1;
void stop(int signum) { run = 0; }
void gpioISR(int gpio, int level, uint32_t tick) {
if (level == 2) // timeout call
return;
int channel = gpiomap[gpio];
if (debouncetimer[channel])
return;
return;
else
debouncetimer[channel] = debouncetimes[channel];
debouncetimer[channel] = debouncetimes[channel];
#ifdef DEBUG
std::cout
<< "Interrupt on channel " << channel
<< " (GPIO " << gpioinp[channel] << ")"
<< std::endl;
std::cout << "Interrupt on channel " << channel << " (GPIO "
<< gpioinp[channel] << ")" << std::endl;
#endif
static int edge=1;
static int edge = 1;
std::lock_guard<std::mutex> guard(lsl_mutex);
outlet[channel]->push_sample(&edge);
ledtimer[channel]=ledtime;
ledtimer[channel] = ledtime;
#ifdef DEBUG
interrupt_count[channel]++;
std::cout << channel << " (count=" << interrupt_count[channel] << ")" << std::endl;
std::cout << channel << " (count=" << interrupt_count[channel] << ")"
<< std::endl;
#endif
}
void handleLeds()
{
for (int i=0; (i<ngpio) && (i<nled); i++)
{
if (ledtimer[i] > 0) {
if (!ledstatus[i]) {
setled(i,1);
ledstatus[i]=1;
}
ledtimer[i]--;
}
else {
if (ledstatus[i]) {
setled(i,0);
ledstatus[i]=0;
}
}
}
}
void gpioISR_0()
{
gpioInterrupt(0);
}
void gpioISR_1()
{
gpioInterrupt(1);
void handleLeds() {
for (int i = 0; (i < ngpio) && (i < nled); i++) {
if (ledtimer[i] > 0) {
if (!ledstatus[i]) {
setled(i, 1);
ledstatus[i] = 1;
}
ledtimer[i]--;
}
else {
if (ledstatus[i]) {
setled(i, 0);
ledstatus[i] = 0;
}
}
}
}
void gpioISR_2()
{
gpioInterrupt(2);
}
int rtpriority(int n) {
struct sched_param sched;
void gpioISR_3()
{
gpioInterrupt(3);
}
memset(&sched, 0, sizeof(sched));
void gpioISR_4()
{
gpioInterrupt(4);
}
if (n > sched_get_priority_max(SCHED_RR))
sched.sched_priority = sched_get_priority_max(SCHED_RR);
else
sched.sched_priority = n;
void gpioISR_5()
{
gpioInterrupt(5);
return sched_setscheduler(0, SCHED_RR, &sched);
}
void gpioISR_6()
{
gpioInterrupt(6);
}
int main(int argc, char *argv[]) {
init_gpiomap();
void gpioISR_7()
{
gpioInterrupt(7);
}
if (rtpriority(99) < 0) {
perror("rtpriority");
return 1;
}
typedef void(*gpioISR)();
// configure input channels
int r = gpioInitialise(); // use Broadcom pin numbering
if (r < 0) {
perror("gpioInitialise");
return 1;
}
gpioISR ISR[] = { gpioISR_0, gpioISR_1, gpioISR_2, gpioISR_3,
gpioISR_4, gpioISR_5, gpioISR_6, gpioISR_7 };
gpioSetSignalFunc(SIGINT, stop);
gpioSetSignalFunc(SIGABRT, stop);
int main(int argc, char* argv[]) {
piHiPri(99); // shortcut for running at real time priority
// configure inputs
wiringPiSetupGpio();
printf("Press control C to stop.\n");
initleds(nled, ledgpio);
initleds(nled, ledgpio);
for (int i=0; i<ngpio; i++)
{
pinMode(gpioinp[i], INPUT);
pullUpDnControl(gpioinp[i], PUD_UP);
for (int i = 0; i < ngpio; i++) {
int dinpin = gpiomap[i];
if (gpioSetMode(dinpin, PI_OUTPUT) < 0) {
perror("gpioSetMode");
return 1;
}
for (int i=0; i<ngpio; i++) {
debouncetimes[i] = default_debouncetime;
if (gpioSetPullUpDown(dinpin, PI_PUD_UP) < 0) {
perror("gpioSetMode");
return 1;
}
char hostname[255];
gethostname(hostname,255);
for (int i=0; i<ngpio; i++)
{
// make a new stream_info and open an outlet with it
char info_name[255];
sprintf(info_name, "Digital Events %d", i);
char info_type[255+18];
sprintf(info_type,"Digital Events @ %s",hostname);
debouncetimes[i] = default_debouncetime;
stream_info info(info_name, info_type, 1, lsl::IRREGULAR_RATE,
lsl::cf_int8,"Raspberry Pi Digital Event Recorder");
outlet[i] = new stream_outlet(info);
const int timeout_ms = 10000;
// The 4N35 optocoupler in the input circuit inverts the signal, we want
// to detect rising edges in the input signal, so here we program
// FALLING_EDGE.
if (gpioSetISRFunc(dinpin, FALLING_EDGE, timeout_ms, gpioISR) < 0) {
perror("gpioSetISRFunc");
return 1;
}
// The 4N35 optocoupler in the input circuit inverts the signal, we want to
// detect rising edges in the input signal, so here we program INT_EDGE_FALLING.
for (int i=0; i<ngpio; i++)
{
wiringPiISR(gpioinp[i], INT_EDGE_FALLING, ISR[i]);
}
char hostname[255];
gethostname(hostname, 255);
for (int i = 0; i < ngpio; i++) {
// make a new stream_info and open an outlet with it
char info_name[255];
sprintf(info_name, "Digital Events %d", i);
char info_type[255 + 18];
sprintf(info_type, "Digital Events @ %s", hostname);
stream_info info(info_name, info_type, 1, lsl::IRREGULAR_RATE,
lsl::cf_int8, "Raspberry Pi Digital Event Recorder");
outlet[i] = new stream_outlet(info);
}
// do this forever
while (run) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
handleLeds();
for (int i = 0; i < ngpio; i++) {
if (debouncetimer[i] > 0)
debouncetimer[i]--;
}
// do this forever
while(true) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
handleLeds();
for (int i=0; i<ngpio; i++) {
if (debouncetimer[i] > 0)
debouncetimer[i]--;
}
}
return 0;
}
gpioTerminate();
return 0;
}
No preview for this file type
No preview for this file type
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment