Launch the GUI to visualise the value of each capacitive channel on the sensor.
There are two important sensor settings that you may want to adjust when working with the Trill sensors: the threshold
and the prescaler
.
#include <libraries/Trill/Trill.h>
#include <libraries/Gui/Gui.h>
#include <libraries/Pipe/Pipe.h>
#include <poll.h>
#include <GPIOcontrol.h>
static const unsigned int kDigitalInEventPin = 1;
const size_t kGpioEventPin = 59;
unsigned int gTaskSleepTime = 12000;
float gTimePeriod = 0.015;
int bitResolution = 12;
typedef enum {
kPrescaler,
kBaseline,
kNoiseThreshold,
kNumBits,
kMode,
kReset,
kTransmissionWidth,
kTransmissionRightShift,
kChannelMask,
kEventMode,
kScanTriggerI2c,
kScanTriggerTimer,
kTimerPeriod,
kHostReadTrigger,
} ids_t;
ids_t id;
double value;
};
#include <tuple>
std::vector<std::pair<std::wstring, ids_t>> gKeys =
{
{L"prescaler", kPrescaler},
{L"baseline", kBaseline},
{L"noiseThreshold", kNoiseThreshold},
{L"numBits", kNumBits},
{L"mode", kMode},
{L"reset", kReset},
{L"transmissionWidth", kTransmissionWidth},
{L"transmissionRightShift", kTransmissionRightShift},
{L"channelMask", kChannelMask},
{L"eventMode", kEventMode},
{L"scanTriggerI2c", kScanTriggerI2c},
{L"scanTriggerTimer", kScanTriggerTimer},
{L"timerPeriod", kTimerPeriod},
{L"hostReadTrigger", kHostReadTrigger},
};
bool guiCallback(JSONObject& json, void*)
{
for(auto& k : gKeys)
{
if(json.find(k.first) != json.end())
{
if(json[k.first]->IsNumber())
command.
value = json[k.first]->AsNumber();
else if (json[k.first]->IsBool())
command.value = json[k.first]->AsBool();
else {
fprintf(stderr, "Unexpected JSON element: %s with incompatible argument\n", JSON::ws2s(k.first).c_str());
continue;
}
command.id = k.second;
}
}
return false;
}
void setScanTriggerMode(
const Command& cmd)
{
static int mode = 0;
if(cmd.value)
mode |= flag;
else
mode &= ~flag;
printf("setting scanTrigger (%s:%d) to 0x%02x\n", kScanTriggerI2c == cmd.id ? "I2C" : "timer", int(cmd.value), mode);
}
void loop(void*)
{
int numBits;
int speed = 0;
uint8_t transmissionWidth = 16;
uint8_t transmissionRightShift = 0;
enum { kHostReadTriggerEvt = 0, kHostReadTriggerDisabled = 1001 };
int hostReadTrigger = kHostReadTriggerDisabled;
int fd = -1;
{
bool shouldScan;
if(kHostReadTriggerEvt == hostReadTrigger)
{
struct pollfd pfd[1];
pfd[0].fd = fd;
pfd[0].events = POLLPRI;
int result = poll(pfd, 1, 50);
if(1 == result && (pfd[0].revents & POLLPRI)) {
char buf[16];
int ret = read(fd, &buf, sizeof(buf));
ret |= lseek(fd, SEEK_SET, 0);
if(ret <= 0) {
fprintf(stderr, "read error :%d\n", ret);
break;
} else {
}
shouldScan = true;
} else if (result < 0) {
fprintf(stderr, "Error while polling edge: %s %d\n", strerror(errno), errno);
break;
} else {
shouldScan = false;
}
} else if (kHostReadTriggerDisabled == hostReadTrigger) {
shouldScan = false;
usleep(10000);
} else {
usleep(hostReadTrigger * 1000);
shouldScan = true;
}
if(shouldScan)
while(1 == gPipe.
readRt(command))
{
double value = command.value;
switch(command.id)
{
case kPrescaler:
printf("setting prescaler to %.0f\n", value);
break;
case kBaseline:
printf("reset baseline\n");
break;
case kReset:
printf("reset chip\n");
usleep(500000);
break;
case kNoiseThreshold:
printf("setting noiseThreshold to %f\n", value);
break;
case kNumBits:
numBits = value;
printf("setting number of bits to %d\n", numBits);
break;
case kTransmissionWidth:
transmissionWidth = value;
printf("setting transmission width to %d\n", transmissionWidth);
break;
case kTransmissionRightShift:
transmissionRightShift = value;
printf("setting transmission right shift to %d\n", transmissionRightShift);
break;
case kChannelMask:
{
uint32_t mask = value;
printf("setting channel mask to %x\n", mask);
}
break;
case kEventMode:
printf("setting eventMode to %d\n", int(value));
break;
case kScanTriggerI2c:
case kScanTriggerTimer:
setScanTriggerMode(command);
break;
case kTimerPeriod:
printf("setting timerPeriod to %d\n", int(value));
break;
case kHostReadTrigger:
printf("host read trigger %f\n", value);
if(fd >= 0) {
close(fd);
fd = -1;
}
hostReadTrigger = value;
if(kHostReadTriggerEvt == hostReadTrigger) {
gpio_export(kGpioEventPin);
gpio_set_dir(kGpioEventPin, INPUT_PIN);
gpio_set_edge(kGpioEventPin, (char*) "rising");
fd = gpio_fd_open(kGpioEventPin, O_RDONLY);
}
break;
case kMode:
printf("setting mode to %.0f\n", value);
break;
}
}
}
}
{
fprintf(stderr, "Unable to initialise Trill Craft\n");
return false;
}
gPipe.
setup(
"guiToLoop");
pinMode(context, 0, kDigitalInEventPin, INPUT);
return true;
}
static std::vector<int> guiBuffer(7);
{
static unsigned int count = 0;
static unsigned int evtPinPeriodUs = -1;
{
static unsigned int evtPinCounterSamples;
static bool pastIn;
bool in =
digitalRead(context, n , kDigitalInEventPin);
if(in && ! pastIn)
{
static unsigned int evtPinCounterEvents = 0;
if(0 == evtPinCounterEvents)
evtPinCounterSamples = 0;
++evtPinCounterEvents;
if(evtPinCounterSamples > 10000)
{
float period = evtPinCounterSamples / float(evtPinCounterEvents - 1);
evtPinCounterEvents = 0;
}
}
evtPinCounterSamples++;
if(evtPinCounterSamples > 80000)
evtPinPeriodUs = -1;
pastIn = in;
}
for(
unsigned int n = 0; n < context->
audioFrames; n++) {
{
static int periodFromFrameIdUs;
static unsigned int periodCount = 0;
static uint32_t startFrameId = 0;
uint32_t frameCount = frameId - startFrameId;
if(periodCount >= 50 && frameCount > 20)
{
periodFromFrameIdUs = (gTimePeriod * periodCount) / float(frameCount) * 1000 * 1000;
periodCount = 0;
startFrameId = frameId;
}
periodCount++;
guiBuffer[5] = periodFromFrameIdUs;
guiBuffer[6] = evtPinPeriodUs;
count = 0;
}
count++;
}
}
{
}