diff --git a/Source/Processors/DataThreads/RHD2000Editor.cpp b/Source/Processors/DataThreads/RHD2000Editor.cpp
index be4e292554735c41eef02fa816bbd5f729b667f3..c919920f7b57ff07a80c77d64c55b1b9d70e51df 100644
--- a/Source/Processors/DataThreads/RHD2000Editor.cpp
+++ b/Source/Processors/DataThreads/RHD2000Editor.cpp
@@ -27,6 +27,7 @@
 
 #include "../Editors/ChannelSelector.h"
 #include "../SourceNode/SourceNode.h"
+#include "../RecordNode/RecordNode.h"
 #include "RHD2000Thread.h"
 
 #ifdef WIN32
@@ -62,6 +63,18 @@ FPGAchannelList::FPGAchannelList(GenericProcessor* proc_, Viewport* p, FPGAcanva
     impedanceButton->addListener(this);
     addAndMakeVisible(impedanceButton);
 
+	RHD2000Editor *e = static_cast<RHD2000Editor*>(proc->getEditor());
+	saveImpedanceButton = new ToggleButton("Save impedance measurements");
+	saveImpedanceButton->setBounds(430,10,110,25);
+	saveImpedanceButton->setToggleState(e->getSaveImpedance(),dontSendNotification);
+	saveImpedanceButton->addListener(this);
+	addAndMakeVisible(saveImpedanceButton);
+	
+	autoMeasureButton = new ToggleButton("Measure impedance at acquisition start");
+	autoMeasureButton->setBounds(550,10,150,25);
+	autoMeasureButton->setToggleState(e->getAutoMeasureImpedance(),dontSendNotification);
+	autoMeasureButton->addListener(this);
+	addAndMakeVisible(autoMeasureButton);
 
     gains.clear();
     gains.add(0.01);
@@ -91,11 +104,19 @@ void FPGAchannelList::paint(Graphics& g)
 
 void FPGAchannelList::buttonClicked(Button* btn)
 {
+	RHD2000Editor* p = (RHD2000Editor*)proc->getEditor();
     if (btn == impedanceButton)
     {
-        RHD2000Editor* p = (RHD2000Editor*)proc->getEditor();
         p->measureImpedance();
     }
+	else if (btn == saveImpedanceButton)
+	{
+		p->setSaveImpedance(btn->getToggleState());
+	}
+	else if (btn == autoMeasureButton)
+	{
+		p->setAutoMeasureImpedance(btn->getToggleState());
+	}
 }
 
 void FPGAchannelList::update()
@@ -513,6 +534,8 @@ RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode,
     canvas = nullptr;
     desiredWidth = 330;
     tabText = "FPGA";
+	measureWhenRecording = false;
+	saveImpedances = false;
 
     // add headstage-specific controls (currently just an enable/disable button)
     for (int i = 0; i < 4; i++)
@@ -666,8 +689,57 @@ void RHD2000Editor::measureImpedance()
     Array<float> magnitude, phase;
     board->runImpedanceTest(stream,channel,magnitude,phase);
 
+	if (canvas == nullptr)
+		VisualizerEditor::canvas = createNewCanvas();
     // update components...
     canvas->updateImpedance(stream,channel,magnitude,phase);
+	if (saveImpedances)
+	{
+		getProcessorGraph()->getRecordNode()->createNewDirectory();
+
+		String path(getProcessorGraph()->getRecordNode()->getDataDirectory().getFullPathName() 
+			+ File::separatorString + "impedance_measurement.xml");
+		std::cout << "Saving impedance measurements in " << path << std::endl;
+		File file(path);
+
+		if (!file.getParentDirectory().exists())
+			file.getParentDirectory().createDirectory();
+
+		XmlDocument doc(file);
+		ScopedPointer<XmlElement> xml = new XmlElement("CHANNEL_IMPEDANCES");
+		for (int i = 0; i < channel.size(); i++)
+		{
+			XmlElement* chan = new XmlElement("CHANNEL");
+			chan->setAttribute("name",board->getChannelName(DATA_CHANNEL,stream[i],channel[i]));
+			chan->setAttribute("stream",stream[i]);
+			chan->setAttribute("channel_number",channel[i]);
+			chan->setAttribute("magnitude",magnitude[i]);
+			chan->setAttribute("phase",phase[i]);
+			xml->addChildElement(chan);
+		}
+		xml->writeToFile(file,String::empty);
+	}
+
+}
+
+void RHD2000Editor::setSaveImpedance(bool en)
+{
+	saveImpedances = en;
+}
+
+void RHD2000Editor::setAutoMeasureImpedance(bool en)
+{
+	measureWhenRecording = en;
+}
+
+bool RHD2000Editor::getSaveImpedance()
+{
+	return saveImpedances;
+}
+
+bool RHD2000Editor::getAutoMeasureImpedance()
+{
+	return measureWhenRecording;
 }
 
 void RHD2000Editor::comboBoxChanged(ComboBox* comboBox)
@@ -758,6 +830,8 @@ void RHD2000Editor::channelChanged(int chan)
 
 void RHD2000Editor::startAcquisition()
 {
+	if (measureWhenRecording)
+		measureImpedance();
 
     channelSelector->startAcquisition();
 
@@ -802,6 +876,8 @@ void RHD2000Editor::saveCustomParameters(XmlElement* xml)
     xml->setAttribute("DAC_HPF", dacHPFcombo->getSelectedId());
     xml->setAttribute("DSPOffset", dspoffsetButton->getToggleState());
     xml->setAttribute("DSPCutoffFreq", dspInterface->getDspCutoffFreq());
+	xml->setAttribute("save_impedance_measurements",saveImpedances);
+	xml->setAttribute("auto_measure_impedances",measureWhenRecording);
 }
 
 void RHD2000Editor::loadCustomParameters(XmlElement* xml)
@@ -821,6 +897,8 @@ void RHD2000Editor::loadCustomParameters(XmlElement* xml)
     dacHPFcombo->setSelectedId(xml->getIntAttribute("DAC_HPF"));
     dspoffsetButton->setToggleState(xml->getBoolAttribute("DSPOffset"), sendNotification);
     dspInterface->setDspCutoffFreq(xml->getDoubleAttribute("DSPCutoffFreq"));
+	saveImpedances = xml->getBoolAttribute("save_impedance_measurements");
+	measureWhenRecording = xml->getBoolAttribute("auto_measure_impedances");
 }
 
 
diff --git a/Source/Processors/DataThreads/RHD2000Editor.h b/Source/Processors/DataThreads/RHD2000Editor.h
index 290e95d011035f2cf2c63e56bd7356bd69df5c41..4caa6630cf1633bf7e5a9f851e83cf075d79d7bb 100644
--- a/Source/Processors/DataThreads/RHD2000Editor.h
+++ b/Source/Processors/DataThreads/RHD2000Editor.h
@@ -81,6 +81,8 @@ private:
     Viewport *viewport;
     FPGAcanvas *canvas;
     ScopedPointer<UtilityButton> impedanceButton;
+	ScopedPointer<ToggleButton> saveImpedanceButton;
+	ScopedPointer<ToggleButton> autoMeasureButton;
     ScopedPointer<ComboBox> numberingScheme;
     ScopedPointer<Label> numberingSchemeLabel;
     OwnedArray<Label> staticLabels;
@@ -176,6 +178,12 @@ public:
     void loadCustomParameters(XmlElement* xml);
     Visualizer* createNewCanvas(void);
     void measureImpedance();
+
+	void setSaveImpedance(bool en);
+	void setAutoMeasureImpedance(bool en);
+	bool getSaveImpedance();
+	bool getAutoMeasureImpedance();
+
 private:
 
     OwnedArray<HeadstageOptionsInterface> headstageOptionsInterfaces;
@@ -196,6 +204,8 @@ private:
 
     ScopedPointer<Label> audioLabel,ttlSettleLabel,dacHPFlabel ;
 
+	bool saveImpedances, measureWhenRecording;
+
     RHD2000Thread* board;
     FPGAcanvas *canvas;
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Editor);
diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp
index 83c08fbd71d51056bb40944045d9249dc3f71ebf..afe46cd62ea36febd679915befb35bc107863e13 100644
--- a/Source/Processors/DataThreads/RHD2000Thread.cpp
+++ b/Source/Processors/DataThreads/RHD2000Thread.cpp
@@ -733,6 +733,17 @@ int RHD2000Thread::modifyChannelName(channelType t, int str, int ch, String newN
     return -1;
 }
 
+String RHD2000Thread::getChannelName(channelType t, int str, int ch)
+{
+	for (int k=0; k<Names.size(); k++)
+    {
+        if (type[k] == t && stream[k] == str && originalChannelNumber[k] == ch)
+        {
+            return Names[k];
+        }
+    }
+}
+
 int RHD2000Thread::modifyChannelGain(channelType t, int str, int ch, float gain)
 {
     String dummy;
diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h
index 6f28cedc6ed3465e04b55922a3afc954555d5070..48f12de158c49f7c9b749d337e9e804615c54cb4 100644
--- a/Source/Processors/DataThreads/RHD2000Thread.h
+++ b/Source/Processors/DataThreads/RHD2000Thread.h
@@ -115,6 +115,8 @@ public:
     void setDACthreshold(int dacOutput, float threshold);
     void setDefaultNamingScheme(int scheme);
 
+	String getChannelName(channelType t, int str, int ch);
+
 private:
     void setDefaultChannelNamesAndType();
     bool channelModified(channelType t, int str, int k, String &oldName, float &oldGain, int &index);
diff --git a/Source/Processors/RecordNode/RecordNode.cpp b/Source/Processors/RecordNode/RecordNode.cpp
index 0f5786738f3fdf4c0823219fc7d201d3ecafc15e..1bc936469c6d91ba457a8bcf2953894ba9a542f9 100755
--- a/Source/Processors/RecordNode/RecordNode.cpp
+++ b/Source/Processors/RecordNode/RecordNode.cpp
@@ -25,6 +25,7 @@
 #include "../ProcessorGraph/ProcessorGraph.h"
 #include "../../UI/EditorViewport.h"
 #include "../../UI/ControlPanel.h"
+#include "RecordEngine.h"
 
 #define EVERY_ENGINE for(int eng = 0; eng < engineArray.size(); eng++) engineArray[eng]
 
diff --git a/Source/Processors/RecordNode/RecordNode.h b/Source/Processors/RecordNode/RecordNode.h
index 446ba15968ced19e3c20a4330d1f07958c46da3e..032db2f73c295c78b5bf9750d8cc88f8a48b7285 100755
--- a/Source/Processors/RecordNode/RecordNode.h
+++ b/Source/Processors/RecordNode/RecordNode.h
@@ -30,13 +30,15 @@
 
 #include "../GenericProcessor/GenericProcessor.h"
 #include "../Channel/Channel.h"
-#include "RecordEngine.h"
-
 
 
 #define HEADER_SIZE 1024
 #define BLOCK_LENGTH 1024
 
+struct SpikeRecordInfo;
+struct SpikeObject;
+class RecordEngine;
+
 /**
 
   Receives inputs from all processors that want to save their data.
diff --git a/Source/UI/ControlPanel.h b/Source/UI/ControlPanel.h
index 9ac30aef6580471fc41922b4d2ff472971547959..c9d178f0dbe8fbccaa55b140e6664429186667b4 100755
--- a/Source/UI/ControlPanel.h
+++ b/Source/UI/ControlPanel.h
@@ -29,6 +29,7 @@
 #include "../Processors/AudioNode/AudioEditor.h"
 #include "../Processors/ProcessorGraph/ProcessorGraph.h"
 #include "../Processors/RecordNode/RecordNode.h"
+#include "../Processors/RecordNode/RecordEngine.h"
 #include "CustomLookAndFeel.h"
 #include "../AccessClass.h"
 #include "../Processors/Editors/GenericEditor.h" // for UtilityButton