diff --git a/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp b/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp
index c3b02ff8b3f60688dcdd5117fec107672a64cb90..827d816bf7ae383b93e35b39f9c7383e289e89db 100644
--- a/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp
+++ b/Source/Plugins/PCIeRhythm/RHD2000Thread.cpp
@@ -46,6 +46,7 @@
 
 //#define DEBUG_EMULATE_HEADSTAGES 8
 //#define DEBUG_EMULATE_64CH
+//#define DEBUG_REAL_HEADSTAGE 5
 
 #define INIT_STEP 256
 
@@ -277,6 +278,7 @@ void RHD2000Thread::initializeBoard()
 
     // Initialize the board
     std::cout << "Initializing acquisition board." << std::endl;
+	evalBoard->openPipe();
     evalBoard->initialize();
     // This applies the following settings:
     //  - sample rate to 30 kHz
@@ -319,7 +321,7 @@ void RHD2000Thread::initializeBoard()
 
     // Read the resulting single data block from the USB interface. We don't
     // need to do anything with this, since it was only used for ADC calibration
-    ScopedPointer<Rhd2000DataBlock> dataBlock = new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams());
+    ScopedPointer<Rhd2000DataBlock> dataBlock = new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams(), INIT_STEP);
 
 	evalBoard->readDataBlock(dataBlock, INIT_STEP);
     // Now that ADC calibration has been performed, we switch to the command sequence
@@ -333,7 +335,7 @@ void RHD2000Thread::initializeBoard()
 	evalBoard->selectAuxCommandBank(rhd2000PCIe::PortD, rhd2000PCIe::AuxCmd3,
                                     fastSettleEnabled ? 2 : 1);
 
-
+	evalBoard->closePipe();
 
 }
 
@@ -347,7 +349,7 @@ void RHD2000Thread::scanPorts()
 	impedanceThread->stopThreadSafely();
 	//Clear previous known streams
 	enabledStreams.clear();
-
+	evalBoard->openPipe();
 	// Scan SPI ports
 
 	int delay, hs, id;
@@ -422,7 +424,7 @@ void RHD2000Thread::scanPorts()
 	evalBoard->setContinuousRunMode(false);
 
 	ScopedPointer<Rhd2000DataBlock> dataBlock =
-		new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams());
+		new Rhd2000DataBlock(evalBoard->getNumEnabledDataStreams(), INIT_STEP);
 
 	Array<int> sumGoodDelays;
 	sumGoodDelays.insertMultiple(0, 0, 8);
@@ -494,12 +496,12 @@ void RHD2000Thread::scanPorts()
 	//std::cout << std::endl;
 
 #if DEBUG_EMULATE_HEADSTAGES > 0
-	if (tmpChipId[0] > 0)
+	if (tmpChipId[DEBUG_REAL_HEADSTAGE] > 0)
 	{
 		int chipIdx = 0;
 		for (int hs = 0; hs < DEBUG_EMULATE_HEADSTAGES && hs < MAX_NUM_HEADSTAGES ; ++hs)
 		{
-			if (enabledStreams.size() < MAX_NUM_DATA_STREAMS(evalBoard->isUSB3()))
+			if (enabledStreams.size() < MAX_NUM_DATA_STREAMS)
 			{
 #ifdef DEBUG_EMULATE_64CH
 				chipId.set(chipIdx++,CHIP_ID_RHD2164);
@@ -513,7 +515,7 @@ void RHD2000Thread::scanPorts()
 		}
 		for (int i = 0; i < enabledStreams.size(); i++)
 		{
-			enabledStreams.set(i,Rhd2000EvalBoard::PortA1);
+			enabledStreams.set(i,(rhd2000PCIe::BoardDataSource)DEBUG_REAL_HEADSTAGE);
 		}
 	}
         
@@ -591,6 +593,7 @@ void RHD2000Thread::scanPorts()
         evalBoard->estimateCableLengthMeters(max(optimumDelay[6],optimumDelay[7]));
 
     setSampleRate(savedSampleRateIndex); // restore saved sample rate
+	evalBoard->closePipe();
     //updateRegisters();
     newScan = true;
 }
@@ -1321,7 +1324,7 @@ bool RHD2000Thread::startAcquisition()
         // evalBoard->setContinuousRunMode(false);
         //  evalBoard->setMaxTimeStep(0);
         std::cout << "Flushing FIFO." << std::endl;
-        evalBoard->flush();
+        evalBoard->openPipe();
         evalBoard->setContinuousRunMode(true);
 		//evalBoard->printFIFOmetrics();
         evalBoard->run();
@@ -1365,7 +1368,7 @@ bool RHD2000Thread::stopAcquisition()
         evalBoard->setContinuousRunMode(false);
         evalBoard->setMaxTimeStep(0);
         std::cout << "Flushing FIFO." << std::endl;
-        evalBoard->flush();
+		evalBoard->closePipe();
         //   evalBoard->setContinuousRunMode(true);
         //   evalBoard->run();
 
@@ -2073,6 +2076,7 @@ void RHDImpedanceMeasure::run()
 	ed = (RHD2000Editor*)board->sn->editor.get();
 	if (data == nullptr)
 		return;
+	board->evalBoard->openPipe();
 	runImpedanceMeasurement();
 	restoreFPGA();
 	ed->triggerAsyncUpdate();
@@ -2159,7 +2163,7 @@ void RHDImpedanceMeasure::runImpedanceMeasurement()
 
 	CHECK_EXIT;
 	board->evalBoard->setContinuousRunMode(false);
-	board->evalBoard->setMaxTimeStep(SAMPLES_PER_DATA_BLOCK_PCIE * numBlocks);
+	board->evalBoard->setMaxTimeStep(INIT_STEP * numBlocks);
 
 	// Create matrices of doubles of size (numStreams x 32 x 3) to store complex amplitudes
 	// of all amplifier channels (32 on each data stream) at three different Cseries values.
@@ -2361,7 +2365,7 @@ void RHDImpedanceMeasure::restoreFPGA()
 {
 	board->evalBoard->setContinuousRunMode(false);
 	board->evalBoard->setMaxTimeStep(0);
-	board->evalBoard->flush();
+	board->evalBoard->closePipe();
 
 	// Switch back to flatline
 	board->evalBoard->selectAuxCommandBank(rhd2000PCIe::PortA, rhd2000PCIe::AuxCmd1, 0);
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp
index 923344b62b6bb42a582fe826566ec736f92f94be..bd898d827ebfd2fd31beb2dad4eb62a5c3779548 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.cpp
@@ -67,6 +67,7 @@ void rhd2000PCIe::writeRegister(controlAddr reg, int16_t value, int16_t mask)
 	{
 		int16_t curVal;
 		int rd = Read(fidControl, &curVal, 2);
+		if (rd < 2)
 		{
 			std::cerr << "Unsuccesful read to control addr " << regAddr << " code: " << rd << std::endl;
 			return;
@@ -125,25 +126,40 @@ bool rhd2000PCIe::open()
 		return false;
 	}
 
+	std::cout << "Device files opened" << std::endl;
+	return true;
+}
+
+bool rhd2000PCIe::openPipe()
+{
 	fidFIFO = Open("\\\\.\\xillybus_neural_data_32", O_RDONLY | O_BINARY);
 	if (fidFIFO < 0)
 	{
 		std:cerr << "Error opening data FIFO" << std::endl;
-		Close(fidControl);
-		Close(fidStatus);
-		fidControl = -1;
-		fidStatus = -1;
+		return false;
 	}
-	std::cout << "Device files opened" << std::endl;
+	std::cout << "Pipe opened" << std::endl;
 	return true;
 }
 
+void rhd2000PCIe::closePipe()
+{
+	if (fidFIFO >= 0)
+	{
+		Close(fidFIFO);
+		fidFIFO = -1;
+		std::cout << "Pipe closed" << std::endl;
+	}
+	else
+		std::cerr << "ERROR: pipe already closed" << std::endl;
+}
+
 // Initialize Rhythm FPGA to default starting values.
 void rhd2000PCIe::initialize()
 {
 	int i;
 
-	resetBoard();
+	//resetBoard();
 	setSampleRate(SampleRate30000Hz);
 	selectAuxCommandBank(PortA, AuxCmd1, 0);
 	selectAuxCommandBank(PortB, AuxCmd1, 0);
@@ -255,76 +271,78 @@ bool rhd2000PCIe::setSampleRate(AmplifierSampleRate newSampleRate)
 	// pulse DCM_prog_trigger high (e.g., using an okTriggerIn module).  If this module is reset, it
 	// reverts to a per-channel sampling rate of 30.0 kS/s.
 
-	unsigned long M, D;
-
+	unsigned long M, O, D;
+	D = 0;
 	switch (newSampleRate) {
 	case SampleRate1000Hz:
 		M = 7;
-		D = 125;
+		O = 125;
 		break;
 	case SampleRate1250Hz:
 		M = 7;
-		D = 100;
+		O = 100;
 		break;
 	case SampleRate1500Hz:
 		M = 21;
-		D = 250;
+		O = 125;
+		D = 0x8000;
 		break;
 	case SampleRate2000Hz:
 		M = 14;
-		D = 125;
+		O = 125;
 		break;
 	case SampleRate2500Hz:
 		M = 35;
-		D = 250;
+		O = 125;
+		D = 0x8000;
 		break;
 	case SampleRate3000Hz:
 		M = 21;
-		D = 125;
+		O = 125;
 		break;
 	case SampleRate3333Hz:
 		M = 14;
-		D = 75;
+		O = 75;
 		break;
 	case SampleRate4000Hz:
 		M = 28;
-		D = 125;
+		O = 125;
 		break;
 	case SampleRate5000Hz:
 		M = 7;
-		D = 25;
+		O = 25;
 		break;
 	case SampleRate6250Hz:
 		M = 7;
-		D = 20;
+		O = 20;
 		break;
 	case SampleRate8000Hz:
-		M = 112;
-		D = 250;
+		M = 56;
+		O = 125;
 		break;
 	case SampleRate10000Hz:
 		M = 14;
-		D = 25;
+		O = 25;
 		break;
 	case SampleRate12500Hz:
 		M = 7;
-		D = 10;
+		O = 10;
 		break;
 	case SampleRate15000Hz:
 		M = 21;
-		D = 25;
+		O = 25;
 		break;
 	case SampleRate20000Hz:
 		M = 28;
-		D = 25;
+		O = 25;
 		break;
 	case SampleRate25000Hz:
 		M = 35;
-		D = 25;
+		O = 25;
 		break;
 	case SampleRate30000Hz:
 		M = 42;
-		D = 25;
+		O = 25;
 		break;
 	default:
 		return(false);
@@ -336,7 +354,7 @@ bool rhd2000PCIe::setSampleRate(AmplifierSampleRate newSampleRate)
 	while (isDcmProgDone() == false) {}
 
 	// Reprogram clock synthesizer
-	writeRegister(DataFreqPll, (256 * M + D));
+	writeRegister(DataFreqPll, D+ ((M<<8)&0x7F00) + (O&0x00FF));
 
 	// Wait for DataClkLocked = 1 before allowing data acquisition to continue
 	while (isDataClockLocked() == false) {}
@@ -456,7 +474,7 @@ void rhd2000PCIe::uploadCommandList(const vector<int> &commandList, AuxCmdSlot a
 
 	for (i = 0; i < commandList.size(); ++i) {
 		int16_t value = commandList[i];
-		int wd = Write(fidControl, &value, 2);
+		int wd = Write(fidMem, &value, 2);
 		if (wd < 2)
 		{
 			std::cerr << "Error writing auxcmd " << auxCommandSlot << " index " << i << std::endl;
@@ -865,6 +883,7 @@ bool rhd2000PCIe::isStreamEnabled(int streamIndex)
 bool rhd2000PCIe::readRawDataBlock(unsigned char** bufferPtr, int nSamples)
 {
 	unsigned int numBytesToRead;
+	unsigned int numread = 0;
 
 	numBytesToRead = 2 * Rhd2000DataBlock::calculateDataBlockSizeInWords(numDataStreams, nSamples);
 
@@ -875,21 +894,20 @@ bool rhd2000PCIe::readRawDataBlock(unsigned char** bufferPtr, int nSamples)
 		return false;
 	}
 
-	int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
+	do {
+		int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
 
-	if (nr < 0)
-	{
-		std::cerr << "Error reading from pipe" << std::endl;
-	}
-	else if (nr < numBytesToRead)
-	{
-		cerr << "CRITICAL: Timeout on pipe read. Check block and buffer sizes." << endl;
-	}
+		if (nr < 0)
+		{
+			std::cerr << "Error reading from pipe" << std::endl;
+		}
+		numread += nr;
+	} while (numread < numBytesToRead);
 
 	*bufferPtr = dataBuffer;
 	return true;
 }
-
+/*
 void rhd2000PCIe::flush()
 {
 	int nr = 0;
@@ -899,7 +917,7 @@ void rhd2000PCIe::flush()
 
 	} while (nr > 0);
 
-}
+}*/
 
 // Read data block from the USB interface, if one is available.  Returns true if data block
 // was available.
@@ -907,6 +925,7 @@ bool rhd2000PCIe::readDataBlock(Rhd2000DataBlock *dataBlock, int nSamples)
 {
 	unsigned int numBytesToRead;
 	long res;
+	unsigned int numread = 0;
 
 	numBytesToRead = 2 * dataBlock->calculateDataBlockSizeInWords(numDataStreams, nSamples);
 
@@ -916,16 +935,17 @@ bool rhd2000PCIe::readDataBlock(Rhd2000DataBlock *dataBlock, int nSamples)
 		return false;
 	}
 
-	int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
+	do {
+		int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
 
-	if (nr < 0)
-	{
-		std::cerr << "Error reading from pipe" << std::endl;
-	}
-	else if (nr < numBytesToRead)
-	{
-		cerr << "CRITICAL: Timeout on pipe read. Check block and buffer sizes." << endl;
-	}
+		if (nr < 0)
+		{
+			std::cerr << "Error reading from pipe" << std::endl;
+			break;
+		}
+		numread += nr;
+	} while (numread < numBytesToRead);
+	
 
 	dataBlock->fillFromUsbBuffer(dataBuffer, 0, numDataStreams, nSamples);
 
@@ -934,14 +954,16 @@ bool rhd2000PCIe::readDataBlock(Rhd2000DataBlock *dataBlock, int nSamples)
 
 // Reads a certain number of USB data blocks, if the specified number is available, and appends them
 // to queue.  Returns true if data blocks were available.
-bool rhd2000PCIe::readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQueue)
+bool rhd2000PCIe::readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQueue, int nSamples)
 {
 	unsigned int numWordsToRead, numBytesToRead;
 	int i;
+	unsigned int numread = 0;
 	Rhd2000DataBlock *dataBlock;
+	
+	if (nSamples < 1) nSamples = SAMPLES_PER_DATA_BLOCK_PCIE;
 
-
-	numWordsToRead = numBlocks * dataBlock->calculateDataBlockSizeInWords(numDataStreams);
+	numWordsToRead = numBlocks * dataBlock->calculateDataBlockSizeInWords(numDataStreams, nSamples);
 
 
 	numBytesToRead = 2 * numWordsToRead;
@@ -952,18 +974,17 @@ bool rhd2000PCIe::readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQue
 		return false;
 	}
 
-	int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
+	do {
+		int nr = Read(fidFIFO, dataBuffer, numBytesToRead);
 
-	if (nr < 0)
-	{
-		std::cerr << "Error reading from pipe" << std::endl;
-	}
-	else if (nr < numBytesToRead)
-	{
-		cerr << "CRITICAL: Timeout on pipe read. Check block and buffer sizes." << endl;
-	}
+		if (nr < 0)
+		{
+			std::cerr << "Error reading from pipe" << std::endl;
+		}
+		numread += nr;
+	} while (numread < numBytesToRead);
 
-	dataBlock = new Rhd2000DataBlock(numDataStreams);
+	dataBlock = new Rhd2000DataBlock(numDataStreams, nSamples);
 	for (i = 0; i < numBlocks; ++i) {
 		dataBlock->fillFromUsbBuffer(dataBuffer, i, numDataStreams);
 		dataQueue.push(*dataBlock);
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h
index 638728a7157d82933befdf61974771e9dbf855cf..255f2554de0eaa095701323c9eff4f18f4e3c366 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000PCIe.h
@@ -107,9 +107,12 @@ namespace PCIeRhythm {
 
 		bool readRawDataBlock(unsigned char** bufferPtr, int nSamples = -1);
 		bool readDataBlock(Rhd2000DataBlock *dataBlock, int nSamples = -1);
-		bool readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQueue);
+		bool readDataBlocks(int numBlocks, queue<Rhd2000DataBlock> &dataQueue, int nSamples = -1);
 
-		void flush();
+		bool openPipe();
+		void closePipe();
+
+		//void flush();
 
 
 	private:
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.cpp b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.cpp
index 9363fb196c41554ce5849249cce7448d1360119d..6d52e8b78ef80bd50f9a5f914f9bbfe102fc8054 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.cpp
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.cpp
@@ -32,7 +32,7 @@ using namespace PCIeRhythm;
 // from a Rhythm FPGA interface controlling up to eight RHD2000 chips.
 
 // Constructor.  Allocates memory for data block.
-Rhd2000DataBlock::Rhd2000DataBlock(int numDataStreams) : samplesPerBlock(SAMPLES_PER_DATA_BLOCK_PCIE)
+Rhd2000DataBlock::Rhd2000DataBlock(int numDataStreams, int nSamples) : samplesPerBlock(nSamples)
 {
     allocateUIntArray1D(timeStamp, samplesPerBlock);
 	allocateIntArray3D(amplifierData, numDataStreams, 32, samplesPerBlock);
diff --git a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h
index b126b4f51fd135fa2115d2d6e1dc759250172705..d4aff22f4692c968b8dd5743fd74e1d6f7df3068 100644
--- a/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h
+++ b/Source/Plugins/PCIeRhythm/rhythm-api/rhd2000datablock.h
@@ -33,7 +33,7 @@ namespace PCIeRhythm {
 	class Rhd2000DataBlock
 	{
 	public:
-		Rhd2000DataBlock(int numDataStreams);
+		Rhd2000DataBlock(int numDataStreams, int nSamples = SAMPLES_PER_DATA_BLOCK_PCIE);
 
 		vector<unsigned int> timeStamp;
 		vector<vector<vector<int> > > amplifierData;
diff --git a/Source/UI/EditorViewport.cpp b/Source/UI/EditorViewport.cpp
index 3110f73e3cd0866e58043ec059a54e1f347778d0..b295b51bdb86a7e78eea44fd033635aeae11575f 100755
--- a/Source/UI/EditorViewport.cpp
+++ b/Source/UI/EditorViewport.cpp
@@ -80,8 +80,8 @@ EditorViewport::EditorViewport()
 
 EditorViewport::~EditorViewport()
 {
+	signalChainManager = nullptr;
     deleteAllChildren();
-    delete signalChainManager;
 }
 
 void EditorViewport::signalChainCanBeEdited(bool t)
diff --git a/Source/UI/EditorViewport.h b/Source/UI/EditorViewport.h
index bcc3266159f1c145d3d59465e24bd3c2057f2c1d..dc94421f53bc2b6b97bbb8dd88175e5d035e167d 100755
--- a/Source/UI/EditorViewport.h
+++ b/Source/UI/EditorViewport.h
@@ -188,7 +188,7 @@ private:
     Array<GenericEditor*, CriticalSection> editorArray;
     Array<SignalChainTabButton*, CriticalSection> signalChainArray;
 
-    SignalChainManager* signalChainManager;
+    ScopedPointer<SignalChainManager> signalChainManager;
 
     Font font;
     Image sourceDropImage;