diff --git a/Source/Processors/DataThreads/RHD2000Editor.cpp b/Source/Processors/DataThreads/RHD2000Editor.cpp
index 081e47007eb4ad09bd04264c4111cac1f1f1a997..7a0a3589743c2e4e178952a0afba758b9b43dd5a 100644
--- a/Source/Processors/DataThreads/RHD2000Editor.cpp
+++ b/Source/Processors/DataThreads/RHD2000Editor.cpp
@@ -541,6 +541,9 @@ RHD2000Editor::RHD2000Editor(GenericProcessor* parentNode,
     measureWhenRecording = false;
     saveImpedances = false;
 
+	impedanceData = new ImpedanceData();
+	impedanceData->valid = false;
+
     // add headstage-specific controls (currently just an enable/disable button)
     for (int i = 0; i < 4; i++)
     {
@@ -689,14 +692,18 @@ void RHD2000Editor::scanPorts()
 
 void RHD2000Editor::measureImpedance()
 {
-    Array<int> stream, channel;
-    Array<float> magnitude, phase;
-    board->runImpedanceTest(stream,channel,magnitude,phase);
+	impedanceData->valid = false;
+	board->runImpedanceTest(impedanceData);
+}
 
+void RHD2000Editor::handleAsyncUpdate()
+{
+	if (!impedanceData->valid)
+		return;
     if (canvas == nullptr)
         VisualizerEditor::canvas = createNewCanvas();
     // update components...
-    canvas->updateImpedance(stream,channel,magnitude,phase);
+	canvas->updateImpedance(impedanceData->streams, impedanceData->channels, impedanceData->magnitudes, impedanceData->phases);
     if (saveImpedances)
     {
         getProcessorGraph()->getRecordNode()->createNewDirectory();
@@ -711,14 +718,14 @@ void RHD2000Editor::measureImpedance()
 
         XmlDocument doc(file);
         ScopedPointer<XmlElement> xml = new XmlElement("CHANNEL_IMPEDANCES");
-        for (int i = 0; i < channel.size(); i++)
+		for (int i = 0; i < impedanceData->channels.size(); i++)
         {
             XmlElement* chan = new XmlElement("CHANNEL");
             chan->setAttribute("name",board->getChannelName(i));
-            chan->setAttribute("stream",stream[i]);
-            chan->setAttribute("channel_number",channel[i]);
-            chan->setAttribute("magnitude",magnitude[i]);
-            chan->setAttribute("phase",phase[i]);
+			chan->setAttribute("stream", impedanceData->streams[i]);
+			chan->setAttribute("channel_number", impedanceData->channels[i]);
+			chan->setAttribute("magnitude", impedanceData->magnitudes[i]);
+			chan->setAttribute("phase", impedanceData->phases[i]);
             xml->addChildElement(chan);
         }
         xml->writeToFile(file,String::empty);
diff --git a/Source/Processors/DataThreads/RHD2000Editor.h b/Source/Processors/DataThreads/RHD2000Editor.h
index 66da62c90901051a6320d305533828e844d52067..b20b7b6a79c97b1674f999b275688cb22b0a8e58 100644
--- a/Source/Processors/DataThreads/RHD2000Editor.h
+++ b/Source/Processors/DataThreads/RHD2000Editor.h
@@ -38,6 +38,7 @@ class AudioInterface;
 class RHD2000Thread;
 
 class UtilityButton;
+struct ImpedanceData;
 
 /**
 
@@ -157,7 +158,7 @@ public:
     ScopedPointer<FPGAchannelList> channelList;
 };
 
-class RHD2000Editor : public VisualizerEditor, public ComboBox::Listener
+class RHD2000Editor : public VisualizerEditor, public ComboBox::Listener, public AsyncUpdater
 
 {
 public:
@@ -184,6 +185,8 @@ public:
     bool getSaveImpedance();
     bool getAutoMeasureImpedance();
 
+	void handleAsyncUpdate();
+
 private:
 
     OwnedArray<HeadstageOptionsInterface> headstageOptionsInterfaces;
@@ -208,6 +211,9 @@ private:
 
     RHD2000Thread* board;
     FPGAcanvas* canvas;
+
+	ScopedPointer<ImpedanceData> impedanceData;
+
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Editor);
 
 };
diff --git a/Source/Processors/DataThreads/RHD2000Thread.cpp b/Source/Processors/DataThreads/RHD2000Thread.cpp
index 7bc9ce5e0a5e0f27b24938ed02ff489d24991d43..d210a6e028e9ffad383f82a172f57400d2993ac0 100644
--- a/Source/Processors/DataThreads/RHD2000Thread.cpp
+++ b/Source/Processors/DataThreads/RHD2000Thread.cpp
@@ -22,6 +22,7 @@
 */
 
 #include "RHD2000Thread.h"
+#include "RHD2000Editor.h"
 #include "../SourceNode/SourceNode.h"
 
 #if defined(_WIN32)
@@ -82,6 +83,7 @@ RHD2000Thread::RHD2000Thread(SourceNode* sn) : DataThread(sn),
     audioOutputL(-1), audioOutputR(-1) ,numberingScheme(1),
     newScan(true)
 {
+	impedanceThread = new RHDImpedanceMeasure(this);
 
     for (int i=0; i < MAX_NUM_HEADSTAGES; i++)
         headstagesArray.add(new RHDHeadstage(static_cast<Rhd2000EvalBoard::BoardDataSource>(i)));
@@ -427,6 +429,7 @@ void RHD2000Thread::scanPorts()
         return;
     }
 
+	impedanceThread->stopThreadSafely();
     //Clear previous known streams
     enabledStreams.clear();
 
@@ -930,7 +933,7 @@ float RHD2000Thread::getAdcBitVolts(int chan)
 
 double RHD2000Thread::setUpperBandwidth(double upper)
 {
-
+	impedanceThread->stopThreadSafely();
     desiredUpperBandwidth = upper;
 
     updateRegisters();
@@ -941,6 +944,7 @@ double RHD2000Thread::setUpperBandwidth(double upper)
 
 double RHD2000Thread::setLowerBandwidth(double lower)
 {
+	impedanceThread->stopThreadSafely();
     desiredLowerBandwidth = lower;
 
     updateRegisters();
@@ -950,7 +954,7 @@ double RHD2000Thread::setLowerBandwidth(double lower)
 
 double RHD2000Thread::setDspCutoffFreq(double freq)
 {
-
+	impedanceThread->stopThreadSafely();
     desiredDspCutoffFreq = freq;
 
     updateRegisters();
@@ -966,6 +970,7 @@ double RHD2000Thread::getDspCutoffFreq()
 
 void RHD2000Thread::setDSPOffset(bool state)
 {
+	impedanceThread->stopThreadSafely();
     dspEnabled = state;
     updateRegisters();
 }
@@ -1130,7 +1135,7 @@ void RHD2000Thread::enableAdcs(bool t)
 
 void RHD2000Thread::setSampleRate(int sampleRateIndex, bool isTemporary)
 {
-
+	impedanceThread->stopThreadSafely();
     if (!isTemporary)
     {
         savedSampleRateIndex = sampleRateIndex;
@@ -1360,7 +1365,7 @@ void RHD2000Thread::setCableLength(int hsNum, float length)
 
 bool RHD2000Thread::startAcquisition()
 {
-
+	impedanceThread->waitSafely();
     dataBlock = new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams());
 
     std::cout << "Expecting " << getNumChannels() << " channels." << std::endl;
@@ -1690,6 +1695,13 @@ int RHD2000Thread::getHeadstageChannel(int& hs, int ch)
     return -1;
 }
 
+void RHD2000Thread::runImpedanceTest(ImpedanceData* data)
+{
+	impedanceThread->stopThreadSafely();
+	impedanceThread->prepareData(data);
+	impedanceThread->startThread();
+}
+
 
 RHDHeadstage::RHDHeadstage(Rhd2000EvalBoard::BoardDataSource stream) :
     numStreams(0), channelsPerStream(32), dataStream(stream), halfChannels(false)
@@ -1744,7 +1756,7 @@ bool RHDHeadstage::isPlugged()
 /***********************************/
 /* Below is code for impedance measurements */
 
-RHDImpedanceMeasure::RHDImpedanceMeasure(RHD2000Thread* b, ImpedanceData* d) : Thread(""), data(d), board(b)
+RHDImpedanceMeasure::RHDImpedanceMeasure(RHD2000Thread* b) : Thread(""), data(nullptr), board(b)
 {
 	// to perform electrode impedance measurements at very low frequencies.
 	const int maxNumBlocks = 120;
@@ -1752,7 +1764,40 @@ RHDImpedanceMeasure::RHDImpedanceMeasure(RHD2000Thread* b, ImpedanceData* d) : T
 	allocateDoubleArray3D(amplifierPreFilter, numStreams, 32, SAMPLES_PER_DATA_BLOCK * maxNumBlocks);
 }
 
+RHDImpedanceMeasure::~RHDImpedanceMeasure()
+{
+	stopThreadSafely();
+}
 
+void RHDImpedanceMeasure::stopThreadSafely()
+{
+	if (isThreadRunning())
+	{
+		sendActionMessage("Impedance measure in progress. Stopping it.");
+		if (!stopThread(3000)) //wait three seconds max for it to exit gracefully
+		{
+			std::cerr << "ERROR: Impedance measurement thread did not exit. Force killed it. This might led to crashes." << std::endl;
+		}
+	}
+}
+
+void RHDImpedanceMeasure::waitSafely()
+{
+	if (!waitForThreadToExit(120000)) //two minutes should be enough for completing a scan
+	{
+		sendActionMessage("Impedance measurement took too much. Aborting.");
+		if (!stopThread(3000)) //wait three seconds max for it to exit gracefully
+		{
+			std::cerr << "ERROR: Impedance measurement thread did not exit. Force killed it. This might led to crashes." << std::endl;
+		}
+	}
+}
+
+void RHDImpedanceMeasure::prepareData(ImpedanceData* d)
+{
+	addActionListener(board->sn->getMessageCenter());
+	data = d;
+}
 
 
 // Update electrode impedance measurement frequency, after checking that
@@ -1955,6 +2000,20 @@ void RHDImpedanceMeasure::empiricalResistanceCorrection(double& impedanceMagnitu
 }
 
 void RHDImpedanceMeasure::run()
+{
+	RHD2000Editor* ed;
+	ed = (RHD2000Editor*)board->sn->editor.get();
+	if (data == nullptr)
+		return;
+	runImpedanceMeasurement();
+	restoreFPGA();
+	ed->triggerAsyncUpdate();
+	data = nullptr;
+}
+
+#define CHECK_EXIT if (threadShouldExit()) return
+
+void RHDImpedanceMeasure::runImpedanceMeasurement()
 {
 	int commandSequenceLength, stream, channel, capRange;
 	double cSeries;
@@ -1967,7 +2026,7 @@ void RHDImpedanceMeasure::run()
 	Array<int> enabledStreams;
 	for (stream = 0; stream < MAX_NUM_DATA_STREAMS; ++stream)
 	{
-
+		CHECK_EXIT;
 		if (board->evalBoard->isStreamEnabled(stream))
 		{
 			enabledStreams.add(stream);
@@ -1987,6 +2046,7 @@ void RHDImpedanceMeasure::run()
 	}
 	// Create a command list for the AuxCmd1 slot.
 	commandSequenceLength = board->chipRegisters.createCommandListZcheckDac(commandList, actualImpedanceFreq, 128.0);
+	CHECK_EXIT;
 	board->evalBoard->uploadCommandList(commandList, Rhd2000EvalBoard::AuxCmd1, 1);
 	board->evalBoard->selectAuxCommandLength(Rhd2000EvalBoard::AuxCmd1,
 		0, commandSequenceLength - 1);
@@ -1994,7 +2054,7 @@ void RHDImpedanceMeasure::run()
 	{
 		board->evalBoard->enableExternalFastSettle(false);
 	}
-
+	CHECK_EXIT;
 	board->evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortA,
 		Rhd2000EvalBoard::AuxCmd1, 1);
 	board->evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortB,
@@ -2011,12 +2071,14 @@ void RHDImpedanceMeasure::run()
 	int numBlocks = ceil((numPeriods + 2.0) * period / 60.0);  // + 2 periods to give time to settle initially
 	if (numBlocks < 2) numBlocks = 2;   // need first block for command to switch channels to take effect.
 
+	CHECK_EXIT;
 	board->actualDspCutoffFreq = board->chipRegisters.setDspCutoffFreq(board->desiredDspCutoffFreq);
 	board->actualLowerBandwidth = board->chipRegisters.setLowerBandwidth(board->desiredLowerBandwidth);
 	board->actualUpperBandwidth = board->chipRegisters.setUpperBandwidth(board->desiredUpperBandwidth);
 	board->chipRegisters.enableDsp(board->dspEnabled);
 	board->chipRegisters.enableZcheck(true);
 	commandSequenceLength = board->chipRegisters.createCommandListRegisterConfig(commandList, false);
+	CHECK_EXIT;
 	// Upload version with no ADC calibration to AuxCmd3 RAM Bank 1.
 	board->evalBoard->uploadCommandList(commandList, Rhd2000EvalBoard::AuxCmd3, 3);
 	board->evalBoard->selectAuxCommandLength(Rhd2000EvalBoard::AuxCmd3, 0, commandSequenceLength - 1);
@@ -2025,6 +2087,7 @@ void RHDImpedanceMeasure::run()
 	board->evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortC, Rhd2000EvalBoard::AuxCmd3, 3);
 	board->evalBoard->selectAuxCommandBank(Rhd2000EvalBoard::PortD, Rhd2000EvalBoard::AuxCmd3, 3);
 
+	CHECK_EXIT;
 	board->evalBoard->setContinuousRunMode(false);
 	board->evalBoard->setMaxTimeStep(SAMPLES_PER_DATA_BLOCK * numBlocks);
 
@@ -2066,7 +2129,6 @@ void RHDImpedanceMeasure::run()
 	for (capRange = 0; capRange < 3; ++capRange)
 	{
 
-
 		switch (capRange)
 		{
 		case 0:
@@ -2089,6 +2151,7 @@ void RHDImpedanceMeasure::run()
 		// Check all 32 channels across all active data streams.
 		for (channel = 0; channel < 32; ++channel)
 		{
+			CHECK_EXIT;
 			cout << "running impedance on channel " << channel << endl;
 
 			board->chipRegisters.setZcheckChannel(channel);
@@ -2119,6 +2182,7 @@ void RHDImpedanceMeasure::run()
 			// and repeat the previous steps.
 			if (rhd2164ChipPresent)
 			{
+				CHECK_EXIT;
 				board->chipRegisters.setZcheckChannel(channel + 32); // address channels 32-63
 				commandSequenceLength =
 					board->chipRegisters.createCommandListRegisterConfig(commandList, false);
@@ -2214,7 +2278,12 @@ void RHDImpedanceMeasure::run()
 			}
 		}
 	}
+	data->valid = true;
+	
+}
 
+void RHDImpedanceMeasure::restoreFPGA()
+{
 	board->evalBoard->setContinuousRunMode(false);
 	board->evalBoard->setMaxTimeStep(0);
 	board->evalBoard->flush();
diff --git a/Source/Processors/DataThreads/RHD2000Thread.h b/Source/Processors/DataThreads/RHD2000Thread.h
index 3cba97cd8e94ec4a2c066628e119526a8df74c99..ad02e086a6f9295ae6ff3251c3f2390e7d011f6a 100644
--- a/Source/Processors/DataThreads/RHD2000Thread.h
+++ b/Source/Processors/DataThreads/RHD2000Thread.h
@@ -52,6 +52,7 @@ struct ImpedanceData
 	Array<int> channels;
 	Array<float> magnitudes;
 	Array<float> phases;
+	bool valid;
 };
 
 /**
@@ -123,6 +124,8 @@ public:
     /*Gets the headstage relative channel index from the absolute channel index*/
     int getHeadstageChannel(int& hs, int ch);
 
+	void runImpedanceTest(ImpedanceData* data);
+
 private:
 
     bool enableHeadstage(int hsNum, bool enabled, int nStr = 1, int strChans = 32);
@@ -196,6 +199,7 @@ private:
     int numberingScheme ;
     Array<float> adcBitVolts;
     bool newScan;
+	ScopedPointer<RHDImpedanceMeasure> impedanceThread;
 
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHD2000Thread);
 };
@@ -221,12 +225,18 @@ private:
     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHDHeadstage);
 };
 
-class RHDImpedanceMeasure : public Thread
+class RHDImpedanceMeasure : public Thread, public ActionBroadcaster
 {
 public:
-	RHDImpedanceMeasure(RHD2000Thread* b, ImpedanceData* d);
+	RHDImpedanceMeasure(RHD2000Thread* b);
+	~RHDImpedanceMeasure();
+	void prepareData(ImpedanceData* d);
+	void stopThreadSafely();
+	void waitSafely();
 	void run();
 private:
+	void runImpedanceMeasurement();
+	void restoreFPGA();
 	void measureComplexAmplitude(std::vector<std::vector<std::vector<double>>>& measuredMagnitude,
 		std::vector<std::vector<std::vector<double>>>& measuredPhase,
 		int capIndex, int stream, int chipChannel, int numBlocks,
@@ -246,6 +256,8 @@ private:
 
 	ImpedanceData* data;
 	RHD2000Thread* board;
+
+	JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(RHDImpedanceMeasure);
 };
 
 #endif  // __RHD2000THREAD_H_2C4CBD67__