diff --git a/hp4194/cv.py b/hp4194/cv.py
index 06260fb245417b70015513d231f9479b3430a66b..7f346b54f3eec5326dae27a1fb0a70b2e3c7db0c 100644
--- a/hp4194/cv.py
+++ b/hp4194/cv.py
@@ -1,6 +1,9 @@
 from interface import *
 import control
 import matplotlib.pyplot as plt
+from help import *
+import time
+from IPython.display import clear_output
 
 
 #connect to device
@@ -8,37 +11,34 @@ device = control.hp4194()
 device.write('reset')
 
 #create interface
+sample,sample_dict = probendaten()
 messparameter,messparameter_dict = messparameter()
 sweep_parameter,sweep_parameter_dict = sweep_parameter()
-control_panel,measure,calibrate,clear_graphs,view=control_panel()
-
+control_panel,measure,clear_graphs,view=control_panel()
 
+#set up interface
 out = widgets.Output()
-
 hbox1 = widgets.HBox([sample,control_panel])
 display(hbox1)
 hbox2=widgets.HBox([messparameter,sweep_parameter])
 display(hbox2)
 display(out)
 
-def add_widgets_to_list(source_dictionary,target_list):
-    for widget in source_dictionary.values():
-        target_list.append(widget)
-
 
+#add widgets to a list for disabling them
 all_widgets = [measure,calibrate,clear_graphs]
 add_widgets_to_list(view,all_widgets)
 add_widgets_to_list(sweep_parameter_dict,all_widgets)
 add_widgets_to_list(messparameter_dict,all_widgets)
 
-def change_state(widgets_list):
-    for widget in widgets_list:
-        widget.disabled = not widget.disabled
 
-
-def on_calibrate_clicked(b):
+def on_measure_clicked(b):
     with out:
+        clear_output()
         change_state(all_widgets)
+        if check_values(messparameter_dict,sweep_parameter_dict) == False:
+            information('Invalid Voltage Settings or Observation of non-existent data points!')
+            change_state(all_widgets)
         device.write('reset')
 
     # perform an open calibration
@@ -68,11 +68,99 @@ def on_calibrate_clicked(b):
     device.set_parameter('set_delay_apperture',sweep_parameter_dict['d_apperture'].value)
     device.set_parameter('aver_num',sweep_parameter_dict['averaging'].value)
 
-    device.write('open_cal_on') #data saved in registers OG and OB
-    device.write('start_open_cal')
-    device.wait()
+    # Now that we have set the frequency values ask user for calibration
+    answer = ask_for_calibration()
+    if answer == True : #perform an open calibration
+        device.write('open_cal_on') #data saved in registers OG and OB
+        device.write('start_open_cal')
+        device.wait()
+
+    # open the file dialog
+    default_filename = f"{sample_dict['wafer'].value}_{sample_dict['sample'].value}_{sample_dict['field'].value}_CV.txt"
+    file = save_file(default_filename)
+
+    #now perform the measurement
+    device.write('autoscale_A') # Autoscale A
+    device.write('autoscale_B') # Autoscale B
+
+    # create the numpy list with the biases
+    # create the arrays with frequency, G and B 
+    frequency = []
+    G = []
+    B = []
+
+    num_of_points = abs(messparameter_dict["stop"].value-messparameter_dict["start"].value)/abs(messparameter_dict["step"].value) + 1
+
+    biases = np.linspace(messparameter_dict["start"].value,messparameter_dict["stop"].value,num_of_points,endpoint = True)
+
+    for bias in biases:
+        device.set_parameter('set_bias', bias) #set the bias
+        device.write('start_sweep') #start the measurement
+        device.wait() #wait for completition
+        
+        # read the registers
+        
+        current_freq = device.read_register('reg_sweep')
+        current_G = device.read_register('reg_A')
+        current_B = device.read_register('reg_B')
+
+        time.sleep(messparameter_dict["sleep"].value)
+
+        # Do A test plot
+        fig,ax1 = plt.subplots()
+        
+        color = 'b'
+        ax1.set_xlabel('Frequency (Hz)')
+        ax1.set_ylabel('G (S)', color=color)
+        ax1.plot(current_freq,current_G , color=color)
+        ax1.tick_params(axis='y', labelcolor=color)
+
+        ax2 = ax1.twinx()
+        color = 'y'
+        ax2.set_ylabel('B (S)', color=color)  # we already handled the x-label with ax1
+        ax2.plot(current_freq,current_B, color=color)
+        ax2.tick_params(axis='y', labelcolor=color)
+
+        fig.suptitle(f"Results for Bias = {bias}V")
+        fig.tight_layout()
+        display(fig)
+
+    if messparameter_dict["hysteris"].value == True:
+        reversed_biases = reversed_array(biases)
+        for bias in reversed_biases:
+            device.set_parameter('set_bias', bias) #set the bias
+            device.write('start_sweep') #start the measurement
+            device.wait() #wait for completition
+            
+            # read the registers
+            
+            current_freq = device.read_register('reg_sweep')
+            current_G = device.read_register('reg_A')
+            current_B = device.read_register('reg_B')
+    
+            time.sleep(messparameter_dict["sleep"].value)
+    
+            # Do A test plot
+            fig,ax1 = plt.subplots()
+            
+            color = 'b'
+            ax1.set_xlabel('Frequency (Hz)')
+            ax1.set_ylabel('G (S)', color=color)
+            ax1.plot(current_freq,current_G , color=color)
+            ax1.tick_params(axis='y', labelcolor=color)
+    
+            ax2 = ax1.twinx()
+            color = 'y'
+            ax2.set_ylabel('B (S)', color=color)  # we already handled the x-label with ax1
+            ax2.plot(current_freq,current_B, color=color)
+            ax2.tick_params(axis='y', labelcolor=color)
+    
+            fig.suptitle(f"Results for Bias = {bias}V")
+            fig.tight_layout()
+            display(fig)
+        
     
-
 
     change_state(all_widgets)
-    
\ No newline at end of file
+
+measure.on_click(on_measure_clicked)
\ No newline at end of file
diff --git a/hp4194/help.py b/hp4194/help.py
new file mode 100644
index 0000000000000000000000000000000000000000..f3aae65b5eba8abbbaf0be3ae0afa172ba67d81c
--- /dev/null
+++ b/hp4194/help.py
@@ -0,0 +1,88 @@
+import ipywidgets as widgets
+import tkinter as tk
+from tkinter import filedialog
+import tkinter.messagebox
+
+
+def add_widgets_to_list(source_dictionary,target_list):
+    for widget in source_dictionary.values():
+        target_list.append(widget)
+
+
+def change_state(widgets_list):
+    for widget in widgets_list:
+        widget.disabled = not widget.disabled
+
+
+def ask_for_calibration():
+    root = tk.Tk()
+    root.withdraw()
+    root.lift() #show window above all other applications
+
+    root.attributes("-topmost", True)#window stays above all other applications
+
+    answer=tk.messagebox.askyesno(message='Do you want to calibarate?')
+
+    root.destroy()
+    return answer
+
+def save_file(default_filename):
+    root = tk.Tk()
+    root.withdraw()
+    root.lift() #show window above all other applications
+
+    root.attributes("-topmost", True)#window stays above all other applications
+
+    file = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Txt files","*.txt")],title = "save results",initialfile =default_filename)
+
+    while file.endswith(".txt") == False:
+        file = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=[("Txt files","*.txt")],title = "save results",initialfile =default_filename)
+
+    root.destroy()
+    return file
+
+def information_box(information):
+    #open dialog and hide the main window
+    root = tk.Tk()
+    root.withdraw()
+    root.lift() #show window above all other applications
+
+    root.attributes("-topmost", True)#window stays above all other applications
+
+    #display meaagebox
+    tkinter.messagebox.showinfo(message=information)
+    root.destroy()
+
+def check_values(voltage:dict,freq:dict):
+
+    if abs(voltage["step"].value) > abs(voltage["stop"].value-voltage["start"].value) or voltage["step"].value == 0:
+        return False
+    
+    #Invert Polarity if nesaccary
+    if voltage["stop"].value > voltage["start"].value and voltage["step"].value < 0:
+        voltage["step"].value = -voltage["step"].value
+    elif voltage["stop"].value < voltage["start"].value and voltage["step"].value > 0:
+        voltage["step"].value = -voltage["step"].value
+    else:
+        pass
+
+    # Now lets check for correct plots
+
+    # calculate the number of points for voltage
+    voltage_points = abs(voltage["stop"].value-voltage["start"].value)/abs(voltage["step"].value) + 1
+
+    if voltage["v_point"].value > voltage_points and voltage["hysterisis"].value == False:
+        return False
+    elif voltage["v_point"].value > 2*voltage_points and voltage["hysterisis"].value == True:
+        return False:
+        
+    # prove that we check a valld frequency point
+    if voltage["f_point"].value > freq['nop'].value:
+        return False
+    return True
+
+# create array for hysteris and remove the last element
+def reversed_array(arr):
+    arr = arr[np.arange(arr.size - 1)]
+    reversed_arr = arr[::-1]
+    return reversed_array
\ No newline at end of file
diff --git a/hp4194/interface.py b/hp4194/interface.py
index bff1280a6fcea77abca5b685f4d6b03ae4217dfc..276ea3006badb456fe3cc15a1c3cebf7dfde5024 100644
--- a/hp4194/interface.py
+++ b/hp4194/interface.py
@@ -128,8 +128,7 @@ def control_panel():
     width =  'auto'
     control_panel = GridspecLayout(6,2)
 
-    control_panel[0,0] = widgets.Button(description = "Start Measurement",layout=Layout(height='auto', width = width))
-    control_panel[0,1] = widgets.Button(description = "Start Calibration",layout=Layout(height='auto', width = width))
+    control_panel[0,:] = widgets.Button(description = "Start Measurement",layout=Layout(height='auto', width = width))
     control_panel[1,0] = widgets.Label("V-Point",layout=Layout(height='auto', width = width))
     control_panel[1,1] = widgets.Label("f-Point",layout=Layout(height='auto', width = width))
 
@@ -141,8 +140,7 @@ def control_panel():
     control_panel[4,0] = widgets.Text(disabled = True,layout=Layout(height='auto', width = width))
     control_panel[4,1] = widgets.Checkbox(description = 'Clear Graphs',value = True,indent = False,layout=Layout(height='auto', width = width))
 
-    measure = control_panel[0,0]
-    calibrate = control_panel[0,1]
+    measure = control_panel[0,:]
     clear_graphs = control_panel[4,1]
 
     view = {
@@ -151,7 +149,7 @@ def control_panel():
         'v-value':control_panel[4,0]
     }
 
-    return control_panel,measure,calibrate,clear_graphs,view
+    return control_panel,measure,clear_graphs,view
 
 
     
diff --git a/hp4194/test_interface.ipynb b/hp4194/test_interface.ipynb
index 2da6bbc3c037e45a5915ac4fb3915dd430b6f552..c5d3a572d6888518b1940c27254bf8b813caa50d 100644
--- a/hp4194/test_interface.ipynb
+++ b/hp4194/test_interface.ipynb
@@ -18,8 +18,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "sample,sample_dict = probendaten()\n",
-    "\n"
+    "sample,sample_dict = probendaten()"
    ]
   },
   {
@@ -49,7 +48,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "control_panel,measure,calibrate,clear_graphs,view=control_panel()"
+    "control_panel,measure,clear_graphs,view=control_panel()"
    ]
   },
   {
@@ -71,7 +70,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "9d5320c4d8714f21907d8a2845d1361b",
+       "model_id": "bc379301efdf4d56bd004f2afe75775b",
        "version_major": 2,
        "version_minor": 0
       },
@@ -85,7 +84,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "0283052d535f40f3b9d71d12950bcf7f",
+       "model_id": "b8557efc4dc24cfcb28322f9b5a0c6fb",
        "version_major": 2,
        "version_minor": 0
       },
@@ -99,7 +98,7 @@
     {
      "data": {
       "application/vnd.jupyter.widget-view+json": {
-       "model_id": "f9b54cce2db34bf0b214703d0e08d560",
+       "model_id": "5bf5530eb11e41f494b3507550783893",
        "version_major": 2,
        "version_minor": 0
       },