diff --git a/bin/apscttr b/bin/apscttr
index ed22f09e2b5709789ef08208d0f799c9da4dd30d..2030dca05c1416d5aede6c8742446f23894aba11 100755
--- a/bin/apscttr
+++ b/bin/apscttr
@@ -1,2 +1,2 @@
 #!/bin/bash
-hwtr -p 4843 -c APSCTTR
+hwtr -p 4843 -c APSCTTR --lockfile=/tmp/pypcc_i2c.lock
diff --git a/bin/apsputr b/bin/apsputr
index 5bb2b9a4aaca61b347850584a2d703879bfff207..4bba457517a3e7d8c074cd1401f981097fa90a40 100755
--- a/bin/apsputr
+++ b/bin/apsputr
@@ -1,2 +1,2 @@
 #!/bin/bash
-hwtr -p 4842 -c APSPUTR
+hwtr -p 4842 -c APSPUTR --lockfile=/tmp/pypcc_i2c.lock
diff --git a/bin/unb2tr b/bin/unb2tr
index 8ae634d581d0f708fe249466bacf2aa0dd80ef20..a64ae7297a8fc8389d74f13001a91d12fd0457d5 100755
--- a/bin/unb2tr
+++ b/bin/unb2tr
@@ -1,2 +1,2 @@
 #!/bin/bash
-hwtr -p 4841 -c UNB2TR
+hwtr -p 4841 -c UNB2TR --lockfile=/tmp/pypcc_i2c.lock
diff --git a/pypcc/i2cserv/i2cthread.py b/pypcc/i2cserv/i2cthread.py
index fb1841dd37d91badd138f08701aa87e04aedeb9d..0714c291372c4033832d6e6b63778fa88269b367 100644
--- a/pypcc/i2cserv/i2cthread.py
+++ b/pypcc/i2cserv/i2cthread.py
@@ -148,7 +148,11 @@ def I2Cserver(Qin,Qout,name,lock=None):
 #           self.statevar.set_value("busy");
            #print("SetVar",item)#,self.conf.variables[item.id])
            if not(lock is None): 
-              lock.acquire()
+              try:
+                lock.acquire()
+              except:
+                logging.error("I2C lock timeout!!")
+                #continue;
 #              print('lock');
            try:
             if (item.type==InstType.varSet):
@@ -162,7 +166,10 @@ def I2Cserver(Qin,Qout,name,lock=None):
             else: print("OPCUA call not implemented!");
            finally:
              if not(lock is None): 
-                  lock.release()
+                  try:
+                     lock.release()
+                  except:
+                     logging.error("I2C lock release error")
 #                  print('unlock');
 #           print("TODO: Set ready")
         logging.info("End i2c process "+name)
diff --git a/pypcc/pypcc.py b/pypcc/pypcc.py
index 8e795bc6488c38466cf684cc3d6c16f8a52ea2c9..d09e0d0389be0798dc17508b1620cb49fb6400a0 100755
--- a/pypcc/pypcc.py
+++ b/pypcc/pypcc.py
@@ -5,6 +5,7 @@ import signal
 import sys
 import threading
 import time
+from pypcc.simpleflock import simpleflock
 
 parser = argparse.ArgumentParser()
 parser.add_argument("-s", "--simulator", help="Do not connect to I2c, but simulate behaviour.", action="store_true")
@@ -12,6 +13,7 @@ parser.add_argument("-t", "--test", help="Do not start OPC-UA server.", action="
 parser.add_argument("-p", "--port", help="Port number to listen on [%(default)s].", type=int, default=4842)
 parser.add_argument("-l", "--loglevel", help="Log level [%(default)s].", type=str, choices=["DEBUG","INFO","WARNING","ERROR"], default="WARNING")
 parser.add_argument("--loghost", help="Logstash host to which to forward logs [%(default)s]",type=str, default='')
+parser.add_argument("--lockfile", help="Lock while using I2C [%(default)s]",type=str, default='')
 parser.add_argument("-c", "--config", help="YAML config files, comma seperated [%(default)s]",type=str, default='RCU')
 args = parser.parse_args()
 
@@ -50,7 +52,9 @@ if not(args.simulator):
   import multiprocessing as mp
 #  lock=mp.Lock()
 #else:
-lock=None;
+#lock=None;
+lock = None if args.lockfile=='' else simpleflock(args.lockfile,10)
+
 #I2Cports=['UNB2','RCU','CLK']
 #I2Cports=['RCU']
 I2Cports=[x for x in args.config.split(',')]
diff --git a/pypcc/simpleflock.py b/pypcc/simpleflock.py
new file mode 100644
index 0000000000000000000000000000000000000000..25e2e39f0aa82851f72e2100ae39ea4f31604d55
--- /dev/null
+++ b/pypcc/simpleflock.py
@@ -0,0 +1,57 @@
+from __future__ import print_function
+import time
+import os
+import fcntl
+import errno
+
+class simpleflock:
+   """Provides the simplest possible interface to flock-based file locking. Intended for use with the `with` syntax. It will create/truncate/delete the lock file as necessary."""
+
+   def __init__(self, path, timeout = None):
+      self._path = path
+      self._timeout = timeout
+#      self._fd = None
+      self._fd = os.open(self._path, os.O_CREAT)
+   def __del__(self):
+      os.close(self._fd)
+      self._fd = None
+   def acquire(self):
+       return self.__enter__()
+   def release(self):
+       return self.__exit__()
+
+   def __enter__(self):
+      start_lock_search = time.time()
+      while True:
+         try:
+            fcntl.flock(self._fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+            # Lock acquired!
+            return
+         except (OSError, IOError) as ex:
+            if ex.errno != errno.EAGAIN: # Resource temporarily unavailable
+               raise
+            elif self._timeout is not None and time.time() > (start_lock_search + self._timeout):
+               # Exceeded the user-specified timeout.
+               raise
+         
+         # TODO It would be nice to avoid an arbitrary sleep here, but spinning
+         # without a delay is also undesirable.
+         time.sleep(0.1)
+
+   def __exit__(self, *args):
+      fcntl.flock(self._fd, fcntl.LOCK_UN)
+
+      # Try to remove the lock file, but don't try too hard because it is
+      # unnecessary. This is mostly to help the user see whether a lock
+      # exists by examining the filesystem.
+#      try:
+#         os.unlink(self._path)
+#      except:
+#         pass
+
+if __name__ == "__main__":
+   print("Acquiring lock...")
+   with SimpleFlock("locktest", 2):
+      print("Lock acquired.")
+      time.sleep(3)
+   print("Lock released.")
\ No newline at end of file
diff --git a/scripts/get_all_pi.py b/scripts/get_all_pi.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9098b58813341355be22731f8dee3b6d2739c94
--- /dev/null
+++ b/scripts/get_all_pi.py
@@ -0,0 +1,11 @@
+from test_common import *
+from time import sleep
+connect("opc.tcp://localhost:4899/")
+
+
+names=get_all_variables()
+for name in names:
+  att=get_value(name)
+  print(name,'=',att)
+
+disconnect();