diff --git a/Builds/Linux/Makefile b/Builds/Linux/Makefile
index 66d62dd8dc52ae67c4f0eb3a8f3b81a11e87b194..e92783d4d0b25efb9ff5920501adfc77f1fa251d 100644
--- a/Builds/Linux/Makefile
+++ b/Builds/Linux/Makefile
@@ -63,6 +63,7 @@ OBJECTS := \
   $(OBJDIR)/RootFinder_239a995f.o \
   $(OBJDIR)/State_22979684.o \
   $(OBJDIR)/AudioComponent_521bd9c9.o \
+  $(OBJDIR)/ArduinoOutput_391e90c4.o \
   $(OBJDIR)/Parameter_ae008024.o \
   $(OBJDIR)/SpikeDisplayNode_9c52e4ad.o \
   $(OBJDIR)/WiFiOutput_fa464ec5.o \
@@ -248,6 +249,11 @@ $(OBJDIR)/AudioComponent_521bd9c9.o: ../../Source/Audio/AudioComponent.cpp
 	@echo "Compiling AudioComponent.cpp"
 	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
 
+$(OBJDIR)/ArduinoOutput_391e90c4.o: ../../Source/Processors/ArduinoOutput.cpp
+	-@mkdir -p $(OBJDIR)
+	@echo "Compiling ArduinoOutput.cpp"
+	@$(CXX) $(CXXFLAGS) -o "$@" -c "$<"
+
 $(OBJDIR)/Parameter_ae008024.o: ../../Source/Processors/Parameter.cpp
 	-@mkdir -p $(OBJDIR)
 	@echo "Compiling Parameter.cpp"
diff --git a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
index 1d6614e0067b52ab825cb1b73a8c92eb543ac83f..974c112c0cea2377279c0c49ed7bbca5cde163d5 100644
--- a/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
+++ b/Builds/MacOSX/open-ephys.xcodeproj/project.pbxproj
@@ -37,6 +37,7 @@
 		8E138283FC265B58D252AAC3 = { isa = PBXBuildFile; fileRef = F4A53064BA75472765338C1D; };
 		EE1DC0B09AE0727BC7A5A99C = { isa = PBXBuildFile; fileRef = 0D20C3399D0492771F7A808A; };
 		4ACF816CB5CDB285D8005AB8 = { isa = PBXBuildFile; fileRef = F74662D3D82975EDB5AD42E0; };
+		AEB65E53845FA668D89CE15E = { isa = PBXBuildFile; fileRef = C42446F8ABB3627870E9677D; };
 		717D108DC8B2379D556C4B2F = { isa = PBXBuildFile; fileRef = 751C52F2BEA7F1328ED13333; };
 		1F67A9ACD509FB4DC5A633DF = { isa = PBXBuildFile; fileRef = 4AEDD076CCA918481C6F9CF2; };
 		B992DDBFF8928A985EEE1557 = { isa = PBXBuildFile; fileRef = 268005410FB62BCB9099A762; };
@@ -219,6 +220,8 @@
 		E27B5891A52FDAB2B00901A0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Utilities.h; path = ../../Source/Dsp/Utilities.h; sourceTree = SOURCE_ROOT; };
 		F74662D3D82975EDB5AD42E0 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = AudioComponent.cpp; path = ../../Source/Audio/AudioComponent.cpp; sourceTree = SOURCE_ROOT; };
 		FA55B9FDE138CCB1F16BA905 = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = AudioComponent.h; path = ../../Source/Audio/AudioComponent.h; sourceTree = SOURCE_ROOT; };
+		C42446F8ABB3627870E9677D = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ArduinoOutput.cpp; path = ../../Source/Processors/ArduinoOutput.cpp; sourceTree = SOURCE_ROOT; };
+		5779673F042A62E02C4AC06B = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ArduinoOutput.h; path = ../../Source/Processors/ArduinoOutput.h; sourceTree = SOURCE_ROOT; };
 		751C52F2BEA7F1328ED13333 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Parameter.cpp; path = ../../Source/Processors/Parameter.cpp; sourceTree = SOURCE_ROOT; };
 		7B825983F25D8984E02F6FFB = { isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Parameter.h; path = ../../Source/Processors/Parameter.h; sourceTree = SOURCE_ROOT; };
 		4AEDD076CCA918481C6F9CF2 = { isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SpikeDisplayNode.cpp; path = ../../Source/Processors/SpikeDisplayNode.cpp; sourceTree = SOURCE_ROOT; };
@@ -552,6 +555,8 @@
 				72123888A7DD78159AA032AF,
 				2164BFCDF57A5AA752CAA3A2 ); name = DataThreads; sourceTree = "<group>"; };
 		33A88A7C3FF426F051834D6A = { isa = PBXGroup; children = (
+				C42446F8ABB3627870E9677D,
+				5779673F042A62E02C4AC06B,
 				751C52F2BEA7F1328ED13333,
 				7B825983F25D8984E02F6FFB,
 				4AEDD076CCA918481C6F9CF2,
@@ -652,7 +657,7 @@
 		C3E8FB47D6069235EA9D6FD7 = { isa = XCBuildConfiguration; buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				PREBINDING = NO;
-				HEADER_SEARCH_PATHS = "/usr/local/include /usr/local/include/freetype2 $(inherited)";
+				HEADER_SEARCH_PATHS = " $(inherited)";
 				GCC_OPTIMIZATION_LEVEL = 0;
 				INFOPLIST_FILE = Info.plist;
 				INSTALL_PATH = "$(HOME)/Applications";
@@ -670,7 +675,7 @@
 		5D7484BAF16E272FF0E9EEAE = { isa = XCBuildConfiguration; buildSettings = {
 				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
 				PREBINDING = NO;
-				HEADER_SEARCH_PATHS = "/usr/local/include /usr/local/include/freetype2 $(inherited)";
+				HEADER_SEARCH_PATHS = " $(inherited)";
 				GCC_OPTIMIZATION_LEVEL = 3;
 				INFOPLIST_FILE = Info.plist;
 				INSTALL_PATH = "$(HOME)/Applications";
@@ -741,6 +746,7 @@
 				8E138283FC265B58D252AAC3,
 				EE1DC0B09AE0727BC7A5A99C,
 				4ACF816CB5CDB285D8005AB8,
+				AEB65E53845FA668D89CE15E,
 				717D108DC8B2379D556C4B2F,
 				1F67A9ACD509FB4DC5A633DF,
 				B992DDBFF8928A985EEE1557,
diff --git a/Builds/VisualStudio2010/open-ephys.vcxproj b/Builds/VisualStudio2010/open-ephys.vcxproj
index 3b1150b350d2daed4871c3ec3e1796368ceed61b..ad6aaeaa2d7ac8394ab9972436502051d8359528 100644
--- a/Builds/VisualStudio2010/open-ephys.vcxproj
+++ b/Builds/VisualStudio2010/open-ephys.vcxproj
@@ -142,6 +142,7 @@
     <ClCompile Include="..\..\Source\Dsp\RootFinder.cpp"/>
     <ClCompile Include="..\..\Source\Dsp\State.cpp"/>
     <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp"/>
+    <ClCompile Include="..\..\Source\Processors\ArduinoOutput.cpp"/>
     <ClCompile Include="..\..\Source\Processors\Parameter.cpp"/>
     <ClCompile Include="..\..\Source\Processors\SpikeDisplayNode.cpp"/>
     <ClCompile Include="..\..\Source\Processors\WiFiOutput.cpp"/>
@@ -239,6 +240,7 @@
     <ClInclude Include="..\..\Source\Dsp\Types.h"/>
     <ClInclude Include="..\..\Source\Dsp\Utilities.h"/>
     <ClInclude Include="..\..\Source\Audio\AudioComponent.h"/>
+    <ClInclude Include="..\..\Source\Processors\ArduinoOutput.h"/>
     <ClInclude Include="..\..\Source\Processors\Parameter.h"/>
     <ClInclude Include="..\..\Source\Processors\SpikeDisplayNode.h"/>
     <ClInclude Include="..\..\Source\Processors\WiFiOutput.h"/>
diff --git a/Builds/VisualStudio2010/open-ephys.vcxproj.filters b/Builds/VisualStudio2010/open-ephys.vcxproj.filters
index a5a0e0bac27099074fdd15f2e9cf8a464183a4e4..4ba9e28914a412ce685c4ea7521bed3d65a2b3e6 100644
--- a/Builds/VisualStudio2010/open-ephys.vcxproj.filters
+++ b/Builds/VisualStudio2010/open-ephys.vcxproj.filters
@@ -283,6 +283,9 @@
     <ClCompile Include="..\..\Source\Audio\AudioComponent.cpp">
       <Filter>open-ephys\Source\Audio</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\Source\Processors\ArduinoOutput.cpp">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\Source\Processors\Parameter.cpp">
       <Filter>open-ephys\Source\Processors</Filter>
     </ClCompile>
@@ -570,6 +573,9 @@
     <ClInclude Include="..\..\Source\Audio\AudioComponent.h">
       <Filter>open-ephys\Source\Audio</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\Source\Processors\ArduinoOutput.h">
+      <Filter>open-ephys\Source\Processors</Filter>
+    </ClInclude>
     <ClInclude Include="..\..\Source\Processors\Parameter.h">
       <Filter>open-ephys\Source\Processors</Filter>
     </ClInclude>
diff --git a/Source/Processors/ArduinoOutput.cpp b/Source/Processors/ArduinoOutput.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f2c2841e74977eae1ed8cd5869cb1a62ba0e6f2a
--- /dev/null
+++ b/Source/Processors/ArduinoOutput.cpp
@@ -0,0 +1,131 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "ArduinoOutput.h"
+
+#include <stdio.h>
+#include <unistd.h>  /*UNIX standard function definitions */
+#include <termios.h> /*POSIX terminal control definitions */
+#include <fcntl.h>   /*File control definitions */
+
+
+ArduinoOutput::ArduinoOutput()
+	: GenericProcessor("Arduino Output"), serialport("/dev/ttyACM0")
+{
+
+}
+
+ArduinoOutput::~ArduinoOutput()
+{
+
+}
+
+// AudioProcessorEditor* ArduinoOutput::createEditor()
+// {
+// 	editor = new ArduinoOutputEditor(this);
+// 	return editor;
+// }
+
+void ArduinoOutput::handleEvent(int eventType, MidiMessage& event)
+{
+    if (eventType == TTL)
+    {
+    	std::cout << "Received event!" << std::endl;
+
+    	const char byte = 0;
+    	write(handle, &byte, 1);
+        //startTimer((int) float(event.getTimeStamp())/getSampleRate()*1000.0);
+    }
+    
+}
+
+void ArduinoOutput::setParameter (int parameterIndex, float newValue)
+{
+
+}
+
+bool ArduinoOutput::enable()
+{
+	struct termios toptions;
+	int fd;
+
+	handle = open(serialport, O_RDWR | O_NOCTTY | O_NDELAY);
+
+	if (handle == -1)
+	{
+		std::cout << "Arduino Output unable to open port." << std::endl;
+		return false;
+	}
+
+	if (tcgetattr(handle, &toptions) < 0)
+	{
+		std::cout << "Arduino Output couldn't get term attributes" << std::endl;
+		return false;
+	}
+
+	speed_t brate = B9600;
+
+	cfsetispeed(&toptions, brate);
+	cfsetospeed(&toptions, brate);
+
+	  // 8N1
+    toptions.c_cflag &= ~PARENB;
+    toptions.c_cflag &= ~CSTOPB;
+    toptions.c_cflag &= ~CSIZE;
+    toptions.c_cflag |= CS8;
+    // no flow control
+    toptions.c_cflag &= ~CRTSCTS;
+
+    toptions.c_cflag |= CREAD | CLOCAL;  // turn on READ & ignore ctrl lines
+    toptions.c_iflag &= ~(IXON | IXOFF | IXANY); // turn off s/w flow ctrl
+
+    toptions.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
+    toptions.c_oflag &= ~OPOST; // make raw
+
+    // see: http://unixwiz.net/techtips/termios-vmin-vtime.html
+    toptions.c_cc[VMIN]  = 0;
+    toptions.c_cc[VTIME] = 20;
+    
+    if( tcsetattr(handle, TCSANOW, &toptions) < 0) {
+        std::cout << "Arduino Output couldn't set term attributes" << std::endl;
+        return false;
+    }
+}
+
+bool ArduinoOutput::disable()
+{
+
+
+
+}
+
+void ArduinoOutput::process(AudioSampleBuffer &buffer, 
+                            MidiBuffer &events,
+                            int& nSamples)
+{
+	
+
+	checkForEvents(events);
+	
+
+}
\ No newline at end of file
diff --git a/Source/Processors/ArduinoOutput.h b/Source/Processors/ArduinoOutput.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d42717e69ea298b7ba44e04588ad0acc00606fb
--- /dev/null
+++ b/Source/Processors/ArduinoOutput.h
@@ -0,0 +1,75 @@
+/*
+    ------------------------------------------------------------------
+
+    This file is part of the Open Ephys GUI
+    Copyright (C) 2012 Open Ephys
+
+    ------------------------------------------------------------------
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef __ARDUINOOUTPUT_H_F7BDA585__
+#define __ARDUINOOUTPUT_H_F7BDA585__
+
+#include "../../JuceLibraryCode/JuceHeader.h"
+
+#include "GenericProcessor.h"
+
+/** 
+
+	Provides a serial interface to an Arduino board.
+
+	Based on arduino-serial.c (http://todbot.com/blog/2006/12/06/arduino-serial-c-code-to-talk-to-arduino/)
+
+	@see GenericProcessor
+
+*/
+
+class ArduinoOutput : public GenericProcessor
+{
+public:
+	
+	ArduinoOutput();
+	~ArduinoOutput();
+	
+	void process(AudioSampleBuffer &buffer, MidiBuffer &events, int& nSamples);
+	
+	void setParameter (int parameterIndex, float newValue);
+
+    void handleEvent(int eventType, MidiMessage& event);
+
+    bool enable();
+    bool disable();
+    
+	//AudioProcessorEditor* createEditor();
+
+	bool isSink() {return true;}
+	
+private:
+
+	//void timerCallback();
+	int handle;
+
+	const char* serialport;
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ArduinoOutput);
+
+};
+
+
+
+
+#endif  // __ARDUINOOUTPUT_H_F7BDA585__
diff --git a/Source/Processors/DataThreads/DataBuffer.cpp b/Source/Processors/DataThreads/DataBuffer.cpp
index 0fa864fc67deafc38868bf132bbc8b1b7dde9566..acb6e8f7955c63750eb6fabf49445f2b5e906fa2 100644
--- a/Source/Processors/DataThreads/DataBuffer.cpp
+++ b/Source/Processors/DataThreads/DataBuffer.cpp
@@ -24,7 +24,12 @@
 #include "DataBuffer.h"
 
 DataBuffer::DataBuffer(int chans, int size)
-	 : abstractFifo (size), buffer(chans, size), numChans(chans) {}
+	 : abstractFifo (size), buffer(chans, size), numChans(chans) 
+{
+	timestampBuffer = new int64[size];
+	eventCodeBuffer = new int16[size];
+
+}
 
 
 DataBuffer::~DataBuffer() {}
@@ -33,7 +38,7 @@ void DataBuffer::clear() {
 	buffer.clear();
 }
 
-void DataBuffer::addToBuffer(float* data, int numItems) {
+void DataBuffer::addToBuffer(float* data, int64* timestamps, int16* eventCodes, int numItems) {
 	// writes one sample for all channels
 	int startIndex1, blockSize1, startIndex2, blockSize2;
 	abstractFifo.prepareToWrite(numItems, startIndex1, blockSize1, startIndex2, blockSize2);
@@ -45,6 +50,10 @@ void DataBuffer::addToBuffer(float* data, int numItems) {
 						data + chan,  // const float* source
 						1); // int num samples
 	 }
+	 
+	 *(timestampBuffer + startIndex1) = *timestamps;
+	 *(eventCodeBuffer + startIndex1) = *eventCodes;
+
 	abstractFifo.finishedWrite(numItems);
 }
 
@@ -53,7 +62,7 @@ int DataBuffer::getNumSamples() {
 }
 
 
-int DataBuffer::readAllFromBuffer (AudioSampleBuffer& data, int maxSize)
+int DataBuffer::readAllFromBuffer (AudioSampleBuffer& data, int64* timestamps, int16* eventCodes, int maxSize)
 {
 	// check to see if the maximum size is smaller than the total number of available ints
 	int numItems = (maxSize < abstractFifo.getNumReady()) ? 
@@ -63,6 +72,7 @@ int DataBuffer::readAllFromBuffer (AudioSampleBuffer& data, int maxSize)
 	abstractFifo.prepareToRead(numItems, startIndex1, blockSize1, startIndex2, blockSize2);
 
 	if (blockSize1 > 0) {
+		
 		for (int chan = 0; chan < data.getNumChannels(); chan++) {
 			data.copyFrom(chan, // destChan
 						   0,    // destStartSample
@@ -71,11 +81,14 @@ int DataBuffer::readAllFromBuffer (AudioSampleBuffer& data, int maxSize)
 						   startIndex1,     // sourceStartSample
 						   blockSize1); // numSamples
 		}
+
+		memcpy(timestamps, timestampBuffer+startIndex1, blockSize1*4);
+		memcpy(eventCodes, eventCodeBuffer+startIndex1, blockSize1*2);
 	}
 
-		if (blockSize2 > 0) {
+	if (blockSize2 > 0) {
 
-    for (int chan = 0; chan < data.getNumChannels(); chan++) {
+    	for (int chan = 0; chan < data.getNumChannels(); chan++) {
 			data.copyFrom(chan, // destChan
 						   blockSize1,    // destStartSample
 						   buffer, // source
@@ -83,6 +96,9 @@ int DataBuffer::readAllFromBuffer (AudioSampleBuffer& data, int maxSize)
 						   startIndex2,     // sourceStartSample
 						   blockSize2); // numSamples
 		}
+
+		memcpy(timestamps + blockSize1, timestampBuffer+startIndex2, blockSize2*4);
+		memcpy(eventCodes + blockSize1, eventCodeBuffer+startIndex2, blockSize2*2);
 	}
 
 	abstractFifo.finishedRead(numItems);
diff --git a/Source/Processors/DataThreads/DataBuffer.h b/Source/Processors/DataThreads/DataBuffer.h
index 290309b702ee0838e17a413e9939f77eb1fdc28c..4992331efcb734458d782ca09cffee0322e76153 100644
--- a/Source/Processors/DataThreads/DataBuffer.h
+++ b/Source/Processors/DataThreads/DataBuffer.h
@@ -39,13 +39,17 @@ public:
 	DataBuffer(int chans, int size);
 	~DataBuffer();
 	void clear();
-	void addToBuffer(float* data, int numItems);
+	void addToBuffer(float* data, int64* ts, int16* eventCodes, int numItems);
 	int getNumSamples();
-	int readAllFromBuffer(AudioSampleBuffer& data, int maxSize);
+	int readAllFromBuffer(AudioSampleBuffer& data, int64* ts, int16* eventCodes, int maxSize);
 
 private:
 	AbstractFifo abstractFifo;
 	AudioSampleBuffer buffer;
+
+    int64* timestampBuffer;
+    int16* eventCodeBuffer;
+
 	int numChans;
 
 	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DataBuffer);
diff --git a/Source/Processors/DataThreads/DataThread.h b/Source/Processors/DataThreads/DataThread.h
index d5d9084e13a6a2c7085e1bd9d2da52da7155a114..1c607cba3a2d9d2a0263caf8775bb7b85e1f48ea 100644
--- a/Source/Processors/DataThreads/DataThread.h
+++ b/Source/Processors/DataThreads/DataThread.h
@@ -60,11 +60,19 @@ public:
 	virtual int getNumChannels() = 0;
 	virtual float getSampleRate() = 0;
     virtual float getBitVolts() = 0;
+    virtual int getNumEventChannels() {return 0;}
 
 	SourceNode* sn;
 
+    int16 eventCode;
+    int64 timestamp;
+
+    Time timer;
+
 private:
 
+
+
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DataThread);
 
 
diff --git a/Source/Processors/DataThreads/FPGAThread.cpp b/Source/Processors/DataThreads/FPGAThread.cpp
index fba32709739c59e1a17ff40786db3be2cbd4e14d..4ccf07c4382d1a7eb4c698a9079beede1102a8a0 100644
--- a/Source/Processors/DataThreads/FPGAThread.cpp
+++ b/Source/Processors/DataThreads/FPGAThread.cpp
@@ -59,6 +59,8 @@ FPGAThread::FPGAThread(SourceNode* sn) : DataThread(sn),
 	
 	dataBuffer = new DataBuffer(32, 10000);
 
+	eventCode = 0;
+
 }
 
 
@@ -173,7 +175,11 @@ bool FPGAThread::updateBuffer() {
 					thisSample[n] = (float(samp) - 32768.0f)/92768.0f; 
 
 				}
-				dataBuffer->addToBuffer(thisSample,1);
+				
+				// should actually be converting timecode to timestamp: 
+				timestamp = timer.getHighResolutionTicks();
+
+				dataBuffer->addToBuffer(thisSample, &timestamp, &eventCode, 1);
 			}
 		j++; // keep scanning for timecodes
 	}
diff --git a/Source/Processors/DataThreads/FileReaderThread.cpp b/Source/Processors/DataThreads/FileReaderThread.cpp
index 91f1dc20cf2c96b7700e451e60781ec68e9bbc48..be0eb49b3313341978c3968f41ef69aff19443ac 100644
--- a/Source/Processors/DataThreads/FileReaderThread.cpp
+++ b/Source/Processors/DataThreads/FileReaderThread.cpp
@@ -43,7 +43,7 @@ FileReaderThread::FileReaderThread(SourceNode* sn) : DataThread(sn)
 
 	dataBuffer = new DataBuffer(16, bufferSize*3);
 
-   
+   eventCode = 0;
 
 	std::cout << "File Reader Thread initialized." << std::endl;
 
@@ -117,7 +117,8 @@ bool FileReaderThread::updateBuffer()
 
             if (chan == 15)
             {
-                dataBuffer->addToBuffer(thisSample,1);
+                timestamp = timer.getHighResolutionTicks();
+                dataBuffer->addToBuffer(thisSample, &timestamp, &eventCode, 1);
                 chan = 0;
             } else {
                 chan++;
diff --git a/Source/Processors/DataThreads/IntanThread.cpp b/Source/Processors/DataThreads/IntanThread.cpp
index 0d1d130ea7afc5634e87c4789be276e2401d1838..98efed098db2db83360ad1a47e87cd62b7a60596 100644
--- a/Source/Processors/DataThreads/IntanThread.cpp
+++ b/Source/Processors/DataThreads/IntanThread.cpp
@@ -34,10 +34,12 @@ IntanThread::IntanThread(SourceNode* sn) : DataThread(sn),
 
 {
 
-	 dataBuffer = new DataBuffer(16,4096);
+	 dataBuffer = new DataBuffer(17,4096);
 
      deviceFound = initializeUSB(true);
 
+     eventCode = 0;
+
 }
 
 IntanThread::~IntanThread() 
@@ -51,6 +53,11 @@ int IntanThread::getNumChannels()
     return 16;
 }
 
+int IntanThread::getNumEventChannels()
+{
+    return 6;   
+}
+
 float IntanThread::getSampleRate()
 {
     return 25000.0;
@@ -208,13 +215,13 @@ bool IntanThread::updateBuffer()
            
           ++ch;
            
-         for (int n = 0; n < 1; n++) { // 
+        // for (int n = 0; n < 1; n++) { // 
 
         // after accounting for bit volts:
-         thisSample[ch%16+n*16] = float((buffer[index] & 127) + 
+         thisSample[ch%16] = float((buffer[index] & 127) + 
                      ((buffer[index+1] & 127) << 7) + 
                      ((buffer[index+2] & 3) << 14)) * 0.1907f - 6175.0f;
-         // these samples should now be in microvolts!
+        // these samples should now be in microvolts!
 
          // bit volt calculation:
          // 2.5 V range / 2^16 = 38.14 uV
@@ -227,14 +234,27 @@ bool IntanThread::updateBuffer()
          //             ((buffer[index+1] & 127) << 7) + 
          //             ((buffer[index+2] & 3) << 14) - 32768)/32768;
 
-         }
-  
-         TTLval = (buffer[index+2] & 4) >> 2; // extract TTL value (bit 3)
+         //}
+
+         if (ch > 0 && ch < 7) // event channels
+        {
+            TTLval = (buffer[index+2] & 4) >> 2; // extract TTL value (bit 3)
+
+            eventCode += (TTLval << (ch-1));
+
+        }
+
          channelVal = buffer[index+2] & 60;   // extract channel value
 
          if (channelVal == 60) {
-         	dataBuffer->addToBuffer(thisSample,1);
+
+            timestamp = timer.getHighResolutionTicks();
+
+         	dataBuffer->addToBuffer(thisSample, &timestamp, &eventCode, 1);
+
+            // reset values
          	ch = -1;
+            eventCode = 0;
          }
 
     }
diff --git a/Source/Processors/DataThreads/IntanThread.h b/Source/Processors/DataThreads/IntanThread.h
index 254e2bbb36dbf1021b3811299a807c4d0b66f9a7..4a7b17c5e052490ba197ea7bab805e675c882829 100644
--- a/Source/Processors/DataThreads/IntanThread.h
+++ b/Source/Processors/DataThreads/IntanThread.h
@@ -50,6 +50,7 @@ public:
 	int getNumChannels();
 	float getSampleRate();
 	float getBitVolts();
+	int getNumEventChannels();
 	
 private:
 
@@ -68,7 +69,7 @@ private:
 	unsigned char startCode, stopCode;
 	unsigned char buffer[240]; // should be 5 samples per channel
 
-	float thisSample[16];
+	float thisSample[17]; // 17 continuous channels and one event channel
 
 	int ch;
 
diff --git a/Source/Processors/ProcessorGraph.cpp b/Source/Processors/ProcessorGraph.cpp
index f2c20aff089a9e5d18524c0ba1ba36af83150db3..b00bcc2d417debe12f92f2e402ae09b0fc852545 100644
--- a/Source/Processors/ProcessorGraph.cpp
+++ b/Source/Processors/ProcessorGraph.cpp
@@ -37,6 +37,7 @@
 #include "SourceNode.h"
 #include "SpikeDetector.h"
 #include "WiFiOutput.h"
+#include "ArduinoOutput.h"
 #include "Utilities/Splitter.h"
 #include "Utilities/Merger.h"
 #include "../UI/UIComponent.h"
@@ -455,6 +456,10 @@ GenericProcessor* ProcessorGraph::createProcessorFromDescription(String& descrip
 			std::cout << "Creating a WiFi node." << std::endl;
 			processor = new WiFiOutput();
 		}
+		else if (subProcessorType.equalsIgnoreCase("Arduino Output")) {
+			std::cout << "Creating an Arduino node." << std::endl;
+			processor = new ArduinoOutput();
+		}
 	
 		//sendActionMessage("New sink created.");
 	}
diff --git a/Source/Processors/SourceNode.cpp b/Source/Processors/SourceNode.cpp
index 4e1e5aa0f88de2aedf480c8eae75a26e33822d89..0a4f33b66f1415cf0e43b2190868cb607ff6db49 100644
--- a/Source/Processors/SourceNode.cpp
+++ b/Source/Processors/SourceNode.cpp
@@ -47,13 +47,26 @@ SourceNode::SourceNode(const String& name_)
 		{
 			enabledState(false);
 		}
+
+		numEventChannels = dataThread->getNumEventChannels();
+		eventChannelState = new int[numEventChannels];
+		for (int i = 0; i < numEventChannels; i++)
+		{
+			eventChannelState[i] = 0;
+		}
+
 	} else {
 		enabledState(false);
+		numEventChannels = 0;
 	}
 
 	// check for input source every few seconds
 	startTimer(sourceCheckInterval); 
 
+	timestampBuffer = new int64[10000]; // 10000 samples per buffer max?
+	eventCodeBuffer = new int16[10000];
+
+
 }
 
 SourceNode::~SourceNode() 
@@ -213,8 +226,33 @@ void SourceNode::process(AudioSampleBuffer &buffer,
 	//std::cout << "SOURCE NODE" << std::endl;
 
 	 buffer.clear();
-	 nSamples = inputBuffer->readAllFromBuffer(buffer,buffer.getNumSamples());
+	 nSamples = inputBuffer->readAllFromBuffer(buffer, timestampBuffer, eventCodeBuffer, buffer.getNumSamples());
 	
+	 // generate timestamp
+
+	 // generate events
+
+	 for (int i = 0; i < nSamples; i++)
+	 {
+	 	for (int c = 0; c < numEventChannels; c++)
+	 	{
+	 		int state = eventCodeBuffer[i] & (1 << c);
+
+	 		if (eventChannelState[c] != state)
+	 		{
+	 			if (state == 0)
+	 				std::cout << "Channel " << c << " off!" << std::endl;
+	 			else
+	 				addEvent(events, TTL, state);
+	 				//std::cout << "Channel " << c << " on!" << std::endl;
+
+	 			eventChannelState[c] = state;
+	 		}
+	 	}
+	 }
+
+	 //std::cout << *eventCodeBuffer << std::endl;
+
 }
 
 
diff --git a/Source/Processors/SourceNode.h b/Source/Processors/SourceNode.h
index be72bcd8b60b0ce83195a49e72b56f0a4a2fef61..3a025002971d5beb861f2eb911376c4f85bda2b2 100644
--- a/Source/Processors/SourceNode.h
+++ b/Source/Processors/SourceNode.h
@@ -77,6 +77,8 @@ public:
 	
 private:
 
+	int numEventChannels;
+
 	int sourceCheckInterval;
 
 	bool wasDisabled;
@@ -86,6 +88,10 @@ private:
 	ScopedPointer<DataThread> dataThread;
 	DataBuffer* inputBuffer;
 
+	int64* timestampBuffer;
+	int16* eventCodeBuffer;
+	int* eventChannelState;
+
 	void updateSettings();
 
 	int* numSamplesInThisBuffer;
diff --git a/Source/UI/ProcessorList.cpp b/Source/UI/ProcessorList.cpp
index 5f135a2c041b9df4bf5910f449471ea1775cbee4..fa34aae64aa99dec3cbca0bb163bf6512496e4a6 100644
--- a/Source/UI/ProcessorList.cpp
+++ b/Source/UI/ProcessorList.cpp
@@ -59,6 +59,7 @@ ProcessorList::ProcessorList() : isDragging(false),
 	sinks->addSubItem(new ProcessorListItem("LFP Viewer"));
 	sinks->addSubItem(new ProcessorListItem("Spike Viewer"));
 	sinks->addSubItem(new ProcessorListItem("WiFi Output"));
+	sinks->addSubItem(new ProcessorListItem("Arduino Output"));
 
 	ProcessorListItem* utilities = new ProcessorListItem("Utilities");
 	utilities->addSubItem(new ProcessorListItem("Splitter"));
diff --git a/open-ephys.jucer b/open-ephys.jucer
index 314b3828c2e43567ae5e6ea13b8df08c4fd345a0..7d7ee7dba3392bd54696c6c1f872e033e5e9d446 100644
--- a/open-ephys.jucer
+++ b/open-ephys.jucer
@@ -187,6 +187,10 @@
               file="Source/Audio/AudioComponent.h"/>
       </GROUP>
       <GROUP id="yQmqZWk" name="Processors">
+        <FILE id="wBm4y2" name="ArduinoOutput.cpp" compile="1" resource="0"
+              file="Source/Processors/ArduinoOutput.cpp"/>
+        <FILE id="1sbSwS7" name="ArduinoOutput.h" compile="0" resource="0"
+              file="Source/Processors/ArduinoOutput.h"/>
         <FILE id="pQaYQiE" name="Parameter.cpp" compile="1" resource="0" file="Source/Processors/Parameter.cpp"/>
         <FILE id="0jxvc4H" name="Parameter.h" compile="0" resource="0" file="Source/Processors/Parameter.h"/>
         <FILE id="arRy5R" name="SpikeDisplayNode.cpp" compile="1" resource="0"