Index: trunk/FACT++/src/ConnectionUSB.cc
===================================================================
--- trunk/FACT++/src/ConnectionUSB.cc	(revision 13286)
+++ trunk/FACT++/src/ConnectionUSB.cc	(revision 13294)
@@ -69,18 +69,18 @@
 // ------------------------ close --------------------------
 // close from another thread
-void ConnectionUSB::CloseImp(bool restart)
+void ConnectionUSB::CloseImp(int64_t delay)
 {
     if (IsConnected())
-    {
-        ostringstream str;
-        str << "Closing connection to " << URL() << ".";
-        Info(str);
-    }
+        Info("Closing connection to "+URL()+".");
 
     // Close possible open connections
     bs::error_code ec;
     cancel(ec);
-    if (ec)
-        Error("Cancel async requests on "+URL()+": "+ec.message());
+    if (ec && ec!=ba::error::basic_errors::bad_descriptor)
+    {
+        ostringstream msg;
+        msg << "Cancel async requests on " << URL() << ": " << ec.message() << " (" << ec << ")";
+        Error(msg);
+    }
 
     if (IsConnected())
@@ -88,7 +88,11 @@
         close(ec);
         if (ec)
-            Error("Closing "+URL()+": "+ec.message());
+        {
+            ostringstream msg;
+            msg << "Closing " << URL() << ": " << ec.message() << " (" << ec << ")";
+            Error(msg);
+        }
         else
-            Info("Connection closed succesfully.");
+            Info("Closed connection to "+URL()+" succesfully.");
     }
 
@@ -96,4 +100,5 @@
     fInTimeout.cancel();
     fOutTimeout.cancel();
+    fConnectTimeout.cancel();
 
     // Reset the connection status
@@ -112,10 +117,48 @@
 #endif
 
-    if (!restart || IsConnecting())
+    if (delay<0 || IsConnecting())
         return;
 
     // We need some timeout before reconnecting!
     // And we have to check if we are alreayd trying to connect
-    // We shoudl wait until all operations in progress were canceled
+    // We should wait until all operations in progress were canceled
+    fConnectTimeout.expires_from_now(boost::posix_time::seconds(delay));
+    fConnectTimeout.async_wait(boost::bind(&ConnectionUSB::HandleReconnectTimeout, this, dummy::error));
+}
+
+void ConnectionUSB::PostClose(int64_t delay)
+{
+    get_io_service().post(boost::bind(&ConnectionUSB::CloseImp, this, delay));
+}
+
+void ConnectionUSB::HandleReconnectTimeout(const bs::error_code &error)
+{
+    if (error==ba::error::basic_errors::operation_aborted)
+        return;
+
+    // 125: Operation canceled (bs::error_code(125, bs::system_category))
+    if (error)
+    {
+        ostringstream str;
+        str << "Reconnect timeout of " << URL() << ": " << error.message() << " (" << error << ")";// << endl;
+        Error(str);
+
+        CloseImp(-1);
+        return;
+    }
+
+
+    if (is_open())
+    {
+        Error("HandleReconnectTimeout - "+URL()+" is already open.");
+        return;
+    }
+
+    // Check whether the deadline has passed. We compare the deadline
+    // against the current time since a new asynchronous operation
+    // may have moved the deadline before this actor had a chance
+    // to run.
+    if (fConnectTimeout.expires_at() > ba::deadline_timer::traits_type::now())
+        return;
 
     // Start trying to reconnect
@@ -123,8 +166,4 @@
 }
 
-void ConnectionUSB::PostClose(bool restart)
-{
-    get_io_service().post(boost::bind(&ConnectionUSB::CloseImp, this, restart));
-}
 
 // ------------------------ write --------------------------
@@ -141,5 +180,5 @@
         Error(str);
 
-        CloseImp(false);
+        CloseImp(-1);
         return;
     }
@@ -161,5 +200,5 @@
     Error("fOutTimeout has expired, writing data to "+URL());
 
-    CloseImp(false);
+    CloseImp(-1);
 }
 
@@ -172,5 +211,5 @@
         Error(str);
 
-        CloseImp(false);
+        CloseImp(-1);
         return;
     }
@@ -329,5 +368,5 @@
 fCharacterSize(8), fParity(parity::none), fStopBits(stop_bits::one),
 fFlowControl(flow_control::hardware),
-fInTimeout(ioservice), fOutTimeout(ioservice), 
+fInTimeout(ioservice), fOutTimeout(ioservice), fConnectTimeout(ioservice),
 fConnectionStatus(kDisconnected)
 {
Index: trunk/FACT++/src/ConnectionUSB.h
===================================================================
--- trunk/FACT++/src/ConnectionUSB.h	(revision 13286)
+++ trunk/FACT++/src/ConnectionUSB.h	(revision 13294)
@@ -36,4 +36,5 @@
 private:
     boost::asio::deadline_timer   fOutTimeout;
+    boost::asio::deadline_timer   fConnectTimeout;
     std::deque<std::vector<uint8_t>> fOutQueue;
 
@@ -52,5 +53,5 @@
 
 protected:
-    void CloseImp(bool restart=true);
+    void CloseImp(int64_t delay=0);
 
 private:
@@ -60,4 +61,5 @@
     void HandleWriteTimeout(const boost::system::error_code &error);
     void HandleSentData(const boost::system::error_code& error, size_t);
+    void HandleReconnectTimeout(const boost::system::error_code &error);
 
     int Write(const Time &t, const std::string &txt, int qos=kInfo);
@@ -75,5 +77,5 @@
 
     // ------------------------ close --------------------------
-    void PostClose(bool restart=true);
+    void PostClose(int64_t delay=0);
 
     // ------------------------ write --------------------------
Index: trunk/FACT++/src/biasctrl.cc
===================================================================
--- trunk/FACT++/src/biasctrl.cc	(revision 13286)
+++ trunk/FACT++/src/biasctrl.cc	(revision 13294)
@@ -55,4 +55,5 @@
     uint32_t fUpdateTime;
     uint16_t fSyncTime;
+    uint32_t fReconnectDelay;
 
     int  fIsInitializing;
@@ -61,4 +62,6 @@
 
     vector<uint64_t> fCounter;
+
+    Time fLastConnect;
 
 protected:
@@ -274,4 +277,22 @@
 
 private:
+    void DelayedReconnect()
+    {
+        const Time now;
+
+        // If we have been connected without a diconnect for at least 60s
+        // we can reset the delay.
+        if (now-fLastConnect>boost::posix_time::seconds(60))
+            fReconnectDelay = 1;
+
+        ostringstream msg;
+        msg << "Automatic reconnect in " << fReconnectDelay << "s after being connected for ";
+        msg << (now-fLastConnect).seconds() << "s";
+        Info(msg);
+
+        CloseImp(fReconnectDelay);
+        fReconnectDelay *= 2;
+    }
+
     void HandleReceivedData(const vector<uint8_t> &buf, size_t bytes_received, int command, int send_counter)
     {
@@ -312,5 +333,5 @@
             (cmd==kExpertChannelSet && !CheckMessageLength(bytes_received, 3,                "CmdExpertChannelSet")))
         {
-            CloseImp(false);
+            CloseImp(-1);
             return;
         }
@@ -321,5 +342,5 @@
             if (!EvalAnswer(buf.data(), i, command))
             {
-                CloseImp(false);
+                DelayedReconnect();
                 return;
             }
@@ -345,5 +366,6 @@
             msg << "Corrupted answer: received wrap counter " << fWrapCounter  << " is not send counter " << send_counter << "%8.";
             Error(msg);
-            CloseImp(false);
+
+            DelayedReconnect();
         }
 
@@ -418,5 +440,4 @@
         if (command==kCmdGlobalSet)
             fCounter[7]++;
-
     }
 
@@ -443,5 +464,5 @@
                 Error(str);
             }
-            CloseImp(false);//err!=ba::error::basic_errors::operation_aborted);
+            CloseImp(-1);//err!=ba::error::basic_errors::operation_aborted);
             return;
         }
@@ -452,5 +473,5 @@
         {
             Error("Number of received bytes not a multiple of 3, can't read data.");
-            CloseImp(false);
+            CloseImp(-1);
             return;
         }
@@ -517,5 +538,5 @@
             Error(str);
 
-            CloseImp(false);
+            CloseImp(-1);
             return;
         }
@@ -538,5 +559,5 @@
             {
                 Error("Synchronization attempt timed out.");
-                CloseImp(false);
+                CloseImp(-1);
                 return;
             }
@@ -576,4 +597,6 @@
         fIsRamping      = false;
 
+        fLastConnect = Time();
+
         // Send a single 0 (and possible two consecutive 0's
         // to make sure we are in sync with the device)
@@ -603,5 +626,5 @@
             Error(str);
 
-            PostClose(false);
+            CloseImp(-1);
             return;
         }
@@ -763,6 +786,6 @@
             Error(str);
 
-            PostClose(false);
             fIsRamping = false;
+            CloseImp(-1);
             return;
         }
@@ -813,4 +836,5 @@
         fUpdateTime(3000),
         fSyncTime(333),
+        fReconnectDelay(1),
         fIsRamping(false),
         fWaitingForAnswer(-1),
@@ -860,5 +884,5 @@
             ostringstream msg;
             msg << "CheckChannelVoltage - Set voltage " << volt << "V of channel " << ch << " exeeds absolute limit of " << fVoltageMaxAbs << "V.";
-            Error(msg);
+            Warn(msg);
             return false;
         }
@@ -1448,4 +1472,9 @@
         return BIAS::kVoltageOn;
     }
+
+    void SetReconnectDelay(uint32_t delay=1)
+    {
+        fReconnectDelay = delay;
+    }
 };
 
@@ -1745,5 +1774,5 @@
     {
         // Close all connections
-        fBias.PostClose(false);
+        fBias.PostClose(-1);
 
         /*
@@ -1759,5 +1788,5 @@
     {
         // Close all connections to supress the warning in SetEndpoint
-        fBias.PostClose(false);
+        fBias.PostClose(-1);
 
         // Now wait until all connection have been closed and
@@ -1769,5 +1798,6 @@
 
         // Now we can reopen the connection
-        fBias.PostClose(true);
+        fBias.SetReconnectDelay();
+        fBias.PostClose(0);
 
         return T::GetCurrentState();
