diff --git a/lib/iictask/GwIicTask.cpp b/lib/iictask/GwIicTask.cpp
index 889d539..51f3633 100644
--- a/lib/iictask/GwIicTask.cpp
+++ b/lib/iictask/GwIicTask.cpp
@@ -31,7 +31,6 @@ static SensorList sensors;
 void initIicTask(GwApi *api){
     GwLog *logger=api->getLogger();
     #ifndef _GWIIC
-        vTaskDelete(NULL);
         return;
     #else
     bool addTask=false;
diff --git a/tools/flashtool/flashtool.py b/tools/flashtool/flashtool.py
index 47f6d50..9f0c048 100755
--- a/tools/flashtool/flashtool.py
+++ b/tools/flashtool/flashtool.py
@@ -18,9 +18,130 @@ import serial.tools.list_ports
 from tkinter import filedialog as FileDialog
 
 import builtins
+import esptool
+
+VERSION="Version 2.0"
+class Flasher():
+    def getVersion(self):
+        return ("Version %s, esptool %s"%(VERSION,str(esptool.__version__)))
+
+    UPDATE_ADDR = 0x10000
+    HDROFFSET = 288
+    VERSIONOFFSET = 16
+    NAMEOFFSET = 48
+    IDOFFSET=12 #2 byte chipid
+    MINSIZE = HDROFFSET + NAMEOFFSET + 32
+    CHECKBYTES = {
+        288: 0x32,  # app header magic
+        289: 0x54,
+        290: 0xcd,
+        291: 0xab
+    }
+    #flash addresses for full images based on chip id
+    FLASH_ADDR={
+        0: 0x1000,
+        9: 0
+    }
+    def getString(self,buffer, offset, len):
+        return buffer[offset:offset + len].rstrip(b'\0').decode('utf-8')
+    def getFirmwareInfo(self,filename,isFull):
+        with open(filename,"rb") as ih:
+            buffer = ih.read(self.MINSIZE)
+            if len(buffer) != self.MINSIZE:
+                return self.setErr("invalid image file %s, to short"%filename)
+            if buffer[0] != 0xe9:
+                return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
+            chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
+            flashoffset=self.FLASH_ADDR.get(chipid)
+            if flashoffset is None:
+                return self.setErr("unknown chip id in image %d",chipid);
+            if isFull:
+                offset=self.UPDATE_ADDR-flashoffset;
+                offset-=self.MINSIZE
+                ih.seek(offset,os.SEEK_CUR)
+                buffer=ih.read(self.MINSIZE)
+                if len(buffer) != self.MINSIZE:
+                    return self.setErr("invalid image file %s, to short"%filename)
+                if buffer[0] != 0xe9:
+                    return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
+            for k, v in self.CHECKBYTES.items():
+                if buffer[k] != v:
+                    return self.setErr("invalid magic at %d, expected %d got %d"
+                                % (k+offset, v, buffer[k]))
+            name = self.getString(buffer, self.HDROFFSET + self.NAMEOFFSET, 32)
+            version = self.getString(buffer, self.HDROFFSET + self.VERSIONOFFSET, 32)
+            chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
+            flashoffset=flashoffset if isFull else self.UPDATE_ADDR
+            return {
+                'error':False,
+                'info':"%s:%s"%(name,version),
+                'chipid':chipid,
+                'flashbase':flashoffset
+            }
+    def setErr(self,err):
+        return {'error':True,'info':err}
+    def checkImageFile(self,filename,isFull):
+        if not os.path.exists(filename):
+            return self.setErr("file %s not found"%filename)
+        return self.getFirmwareInfo(filename,isFull)
+    
+    def checkSettings(self,port,fileName,isFull):
+        if port is None:
+            print("ERROR: no com port selected")
+            return
+        if fileName is None or fileName == '':
+            print("ERROR: no filename selected")
+            return
+        info = self.checkImageFile(fileName, isFull)
+        if info['error']:
+            print("ERROR: %s" % info['info'])
+            return
+        return {'fileName': fileName,'port':port,'isFull':isFull,'info':info}
+    def runEspTool(self,command):
+        print("run esptool: %s" % " ".join(command))
+        try:
+            esptool.main(command)
+            print("esptool done")
+            return True
+        except Exception as e:
+            print("Exception in esptool %s" % e)
+    def verifyChip(self,param):
+        if not param:
+            print("check failed")
+            return
+        imageChipId=param['info']['chipid']
+        chip=esptool.ESPLoader.detect_chip(param['port'])
+        print("Detected chip %s, id=%d"%(chip.CHIP_NAME,chip.IMAGE_CHIP_ID))
+        if (chip.IMAGE_CHIP_ID != imageChipId):
+            print("##Error: chip id in image %d does not match detected chip"%imageChipId)
+            return
+        print("Checks OK")
+        param['chipname']=chip.CHIP_NAME
+        return param
+    def runCheck(self,port,fileName,isFull):
+        param = self.checkSettings(port,fileName,isFull)
+        if not param:
+            return
+        print("Settings OK")
+        param=self.verifyChip(param)
+        if not param:
+            print("Check Failed")
+            return
+        print("flashbase=0x%x"%param['info']['flashbase'])
+        return param
+    def runFlash(self,param):
+        if not param:
+            return
+        if param['isFull']:
+            command=['--chip',param['chipname'],'--port',param['port'],'write_flash',str(param['info']['flashbase']),param['fileName']]
+            self.runEspTool(command)
+        else:
+            command=['--chip',param['chipname'],'--port',param['port'],'erase_region','0xe000','0x2000']
+            self.runEspTool(command)
+            command = ['--chip', param['chipname'], '--port', param['port'], 'write_flash', str(param['info']['flashbase']), param['fileName']]
+            self.runEspTool(command)
 
 def main():
-    VERSION="Version 2.0, esptool 3.2"
 
     oldprint=builtins.print
     def print(*args, **kwargs):
@@ -32,6 +153,7 @@ def main():
 
     class App:
         def __init__(self, root):
+            self.flasher=Flasher()
             root.title("ESP32 NMEA2000 Flash Tool")
             root.geometry("800x600")
             root.resizable(width=True, height=True)
@@ -47,7 +169,7 @@ def main():
             frame.columnconfigure(1, weight=3)
             tk.Label(frame,text="ESP32 NMEA2000 Flash Tool").grid(row=row,column=0,columnspan=2,sticky='ew')
             row+=1
-            tk.Label(frame, text=VERSION).grid(row=row,column=0,columnspan=2,sticky="ew",pady=10)
+            tk.Label(frame, text=self.flasher.getVersion()).grid(row=row,column=0,columnspan=2,sticky="ew",pady=10)
             row+=1
             self.mode=tk.IntVar()
             self.mode.set(1)
@@ -108,7 +230,7 @@ def main():
             fn=FileDialog.askopenfilename()
             if fn:
                 self.filename.set(fn)
-                info=self.checkImageFile(fn,self.mode.get() == 1)
+                info=self.flasher.checkImageFile(fn,self.mode.get() == 1)
                 if info['error']:
                     self.fileInfo.set("***ERROR: %s"%info['info'])
                 else:
@@ -141,68 +263,6 @@ def main():
                 self.interrupt=False
                 raise Exception("User cancel")
 
-        UPDATE_ADDR = 0x10000
-        HDROFFSET = 288
-        VERSIONOFFSET = 16
-        NAMEOFFSET = 48
-        IDOFFSET=12 #2 byte chipid
-        MINSIZE = HDROFFSET + NAMEOFFSET + 32
-        CHECKBYTES = {
-            288: 0x32,  # app header magic
-            289: 0x54,
-            290: 0xcd,
-            291: 0xab
-        }
-        #flash addresses for full images based on chip id
-        FLASH_ADDR={
-            0: 0x1000,
-            9: 0
-        }
-
-        def getString(self,buffer, offset, len):
-            return buffer[offset:offset + len].rstrip(b'\0').decode('utf-8')
-
-        def getFirmwareInfo(self,filename,isFull):
-            with open(filename,"rb") as ih:
-                buffer = ih.read(self.MINSIZE)
-                if len(buffer) != self.MINSIZE:
-                    return self.setErr("invalid image file %s, to short"%filename)
-                if buffer[0] != 0xe9:
-                    return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
-                chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
-                flashoffset=self.FLASH_ADDR.get(chipid)
-                if flashoffset is None:
-                    return self.setErr("unknown chip id in image %d",chipid);
-                if isFull:
-                    offset=self.UPDATE_ADDR-flashoffset;
-                    offset-=self.MINSIZE
-                    ih.seek(offset,os.SEEK_CUR)
-                    buffer=ih.read(self.MINSIZE)
-                    if len(buffer) != self.MINSIZE:
-                        return self.setErr("invalid image file %s, to short"%filename)
-                    if buffer[0] != 0xe9:
-                        return self.setErr("invalid magic in file, expected 0xe9 got 0x%02x"%buffer[0])
-                for k, v in self.CHECKBYTES.items():
-                    if buffer[k] != v:
-                        return self.setErr("invalid magic at %d, expected %d got %d"
-                                    % (k+offset, v, buffer[k]))
-                name = self.getString(buffer, self.HDROFFSET + self.NAMEOFFSET, 32)
-                version = self.getString(buffer, self.HDROFFSET + self.VERSIONOFFSET, 32)
-                chipid= buffer[self.IDOFFSET]+256*buffer[self.IDOFFSET+1]
-                return {
-                    'error':False,
-                    'info':"%s:%s"%(name,version),
-                    'chipid':chipid,
-                    'flashbase':flashoffset if isFull else self.UPDATE_ADDR
-                }
-
-        def setErr(self,err):
-            return {'error':True,'info':err}
-        def checkImageFile(self,filename,isFull):
-            if not os.path.exists(filename):
-                return self.setErr("file %s not found"%filename)
-            return self.getFirmwareInfo(filename,isFull)
-
         def runCheck(self):
             self.text_widget.delete("1.0", "end")
             idx = self.port.current()
@@ -212,63 +272,31 @@ def main():
                 return
             port = self.serialDevices[idx]
             fn = self.filename.get()
-            if fn is None or fn == '':
-                self.addText("ERROR: no filename selected")
-                return
-            info = self.checkImageFile(fn, isFull)
-            if info['error']:
-                print("ERROR: %s" % info['info'])
-                return
-            return {'port':port,'isFull':isFull,'info':info}
+            param = self.flasher.runCheck(port,fn,isFull)
+            return param
 
-        def runEspTool(self,command):
+        def runFlash(self,param):
             for b in self.actionButtons:
                 b.configure(state=tk.DISABLED)
             self.cancelButton.configure(state=tk.NORMAL)
-            print("run esptool: %s" % " ".join(command))
             root.update()
             root.update_idletasks()
-            try:
-                esptool.main(command)
-                print("esptool done")
-            except Exception as e:
-                print("Exception in esptool %s" % e)
+            self.flasher.runFlash(param)
             for b in self.actionButtons:
                 b.configure(state=tk.NORMAL)
             self.cancelButton.configure(state=tk.DISABLED)
-        def verifyChip(self):
-            param = self.runCheck()
-            if not param:
-                print("check failed")
-                return
-            imageChipId=param['info']['chipid']
-            chip=esptool.ESPLoader.detect_chip(param['port'])
-            print("Detected chip %s, id=%d"%(chip.CHIP_NAME,chip.IMAGE_CHIP_ID))
-            if (chip.IMAGE_CHIP_ID != imageChipId):
-                print("##Error: chip id in image %d does not match detected chip"%imageChipId)
-                return
-            print("Checks OK")
-            param['chipname']=chip.CHIP_NAME
-            return param
+        
         def buttonCheck(self):
-            param = self.verifyChip()
+            param = self.runCheck()
             
             
 
         def buttonFlash(self):
-            param=self.verifyChip()
+            param=self.runCheck()
             if not param:
                 return
-            if param['isFull']:
-                command=['--chip',param['chipname'],'--port',param['port'],'write_flash',str(param['info']['flashbase']),self.filename.get()]
-                self.runEspTool(command)
-            else:
-                command=['--chip',param['chipname'],'--port',param['port'],'erase_region','0xe000','0x2000']
-                self.runEspTool(command)
-                command = ['--chip', param['chipname'], '--port', param['port'], 'write_flash', str(param['info']['flashbase']), self.filename.get()]
-                self.runEspTool(command)
-
-
+            self.runFlash(param)
+            
         def buttonCancel(self):
             self.interrupt=True