Hello, I am fairly new to Arduino and extremely new to Bonsai, and I need to interface these to perform a fluorescence photometry experiment in mice.
My Bonsai file acquires fluorescence imaging data but also synchronously captures behavioral video so that I can later time-lock my behavior to the fluorescent signal. I am also using an Arduino to control a water pump to deliver water drops to the mouse's head at random times. I would like to send a copy of the TTL waterdrop control signal to Bonsai so that I can have this signal synchronized with the behavior and fluorescence data.
As far as I understand I need to use the Firmata library, but I am having a lot of trouble figuring out which lines of code are needed to do what I want to do. For instance, it's not clear to me exactly what I need to initiate for Firmata to work, in the examples I've seen there are several loops other than the "setup" and "loop" that I am used to in Arduino.
I've tried to combine the "SimpleDigitalFirmata" example with my simple test code that cues a 900ms TTL pulse every 5s. However I'm not sure which parts of the example are necessary for what I want to do, because I only need to send TTLs to Bonsai, not receive them, and the example code isn't commented very well.
Here's my test code as well as a screenshot of my Bonsai file. The relevant part of the Bonsai file is the part at the bottom where it says "DigitalInput"... at least as far as I understand, everything else about my Bonsai file is irrelevant to this question.
Thanks so much for any help, I have been banging my head against the wall trying to figure out how to do what seems like it should be really simple...
#include <Boards.h>
#include <Firmata.h>
#include <FirmataConstants.h>
#include <FirmataDefines.h>
#include <FirmataMarshaller.h>
#include <FirmataParser.h>
int testPin = 13;
byte sendPin = 13;
int pulsewidth = 900;
int trialN = 56;
int t = 0;
int portData = 1;
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() {
// put your setup code here, to run once:
pinMode(testPin, OUTPUT);
Serial.begin(57600);
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() {
for(int t=0; t < (trialN-1); ++t){
Serial.println(t);
//Turn on pulse
digitalWrite(testPin, HIGH);
Firmata.sendDigitalPort(sendPin, portData);
delay(pulsewidth);
digitalWrite(testPin, LOW);
delay(5000);
}
}