     (swap! state assoc-in [:last-stage-positions (core getFocusDevice)]
            (last absolute-slices))))
   
-(defn pop-burst-image []
-  (while (and (. mmc isSequenceRunning) (zero? (. mmc getRemainingImageCount)))
-    (Thread/sleep 5))
+(defn pop-burst-image [timeout-ms]
+  (let [start-time (System/currentTimeMillis)]
+    (while (and (. mmc isSequenceRunning)
+                (zero? (. mmc getRemainingImageCount)))
+      (if (< timeout-ms (- (System/currentTimeMillis) start-time))
+        (throw (Exception. "Timed out waiting for image to arrive from camera."))
+        (Thread/sleep 5))))
   (let [md (Metadata.)
         pix (core popNextImageMD md)
         tags (parse-core-metadata md)]

      (or 
        (successful? (attempt#)) ; first attempt
        (do (log "second attempt") (successful? (attempt#)))
        (do (log "reload and try a third time")
            (successful? (reload-device ~device) (attempt#)))) ; third attempt after reloading
      (throw (Exception. (str "Device failure: " ~device)))
      (swap! state assoc :stop true)
      nil)))

                   (or (pos? (core getRemainingImageCount))
                       (and (core isSequenceRunning)
                            (not (@state :circular-buffer-overflow)))))
          (let [image (pop-burst-image (* 10 (:exposure event)))
                cam-chan (if-let [cam-chan-str (get-in image [:tags camera-index])]
                           (Long/parseLong cam-chan-str)
                           0)
