Hello everybody,
I am currently experiencing some issues with my project, and I would like to ask for any tip, help or explanation. I track an object via Bonsai (open-source software for processing streams of data): whenever it enters in a region of interest (ROI), the software sends out a digital signal to my Arduino Uno as long as the object stays there. Arduino then, which is running the SimpleDigitalFirmata sketch, activates a signal generator (PulsePal) as long as it receives the messages from Bonsai (i.e. as long as the object is in the ROI).
Now I would like to introduce a refractory period after the object exit from the ROI, so that once it moves out, for few seconds Arduino would not process the incoming signal (or send it out). I have tried various sketches, none of them working, but all along the line of this, which is my last one :
#include <Firmata.h>
byte previousPIN[TOTAL_PORTS]; // PIN means PORT for input
byte previousPORT[TOTAL_PORTS];
int period = 5000; // 5 sec pause
unsigned long time_now = 0;
int Unicorn = 5; // I need magic to make things working
void outputPort(byte portNumber, byte portValue)
{
// only send the data when it changes, otherwise you get too many messages!
if (previousPIN[portNumber] != portValue) {
Firmata.sendDigitalPort(portNumber, portValue);
previousPIN[portNumber] = portValue;
}
}
void setPinModeCallback(byte pin, int mode) {
if (IS_PIN_DIGITAL(pin)) {
pinMode(PIN_TO_DIGITAL(pin), mode);
}
}
void digitalWriteCallback(byte port, int value)
{
byte i;
byte currentPinValue, previousPinValue;
if (port < TOTAL_PORTS && value != previousPORT[port]) {
for (i = 0; i < 8; i++) {
currentPinValue = (byte) value & (1 << i);
previousPinValue = previousPORT[port] & (1 << i);
if (currentPinValue != previousPinValue) {
digitalWrite(i + (port * 8), currentPinValue);
}
}
previousPORT[port] = value;
}
}
void setup()
{
Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback);
Firmata.attach(SET_PIN_MODE, setPinModeCallback);
Firmata.begin(57600);
}
void loop()
{
if (Unicorn == 0) {
if (Firmata.available() > 0)) {
Unicorn = 3; // that delay should be neglegible for my purposes
}
else {
}
Unicorn = 0;
}
if ((Unicorn == 3) && (Firmata.available() > 0) {
while (Firmata.available() > 0) {
Firmata.processInput();
}
Unicorn = 5;
}
if (Unicorn == 5) {
time_now = millis();
while (millis() < time_now + period) {
}
Unicorn = 0;
}
}
In that case, once the object enters the ROI, there is a huge delay before Arduino gives a feedback (a bit more than the 5 sec of the pause, around 6 or 7), and then Arduino continues to send info to the signal generator even if the object got out (I bet this is due to the buffer, but puzzling enough the length of the stimulus sent is different from the effective permanence time of the object in the ROI).
Therefore I decided to try a simpler code, trying to have a better idea of the problem, using only those lines in the void loop
if (Unicorn == 0) {
while (Firmata.available() > 0) {
Firmata.processInput();
}
Unicorn = 5;
}
if (Unicorn == 5) {
time_now = millis();
while (millis() < time_now + period) {
}
Unicorn = 0;
}
But I still get similar delay and length issues. Unluckily the COM port is already engaged by Firmata, so it does not allow me to use Serial.print for debugging.
I would like then to ask if you have could help me proposing some alternative strategy or pointing out where my approach is wrong.
Thanks in advance and have a nice day,
Nicola