Browse Source

added stable PID loop

subDesTagesMitExtraKaese 4 years ago
parent
commit
91ec76aff4

+ 0 - 1
software/analogPressure/mcp3008.py

@@ -12,7 +12,6 @@ class MCP3008:
     
     def read(self, channel = 0):
         adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
-        print(adc)
         data = ((adc[1] & 3) << 8) + adc[2]
         return data
 

+ 39 - 18
software/appWindow.py

@@ -15,9 +15,11 @@ import tk_tools
 from tkinter import filedialog
 import time
 import numpy as np
+import threading
 
 
 class Main(tk.Tk, Table):
+  running = True
   def __init__(self, *args, **kwargs):
     print('initializing window...')
     tk.Tk.__init__(self, *args, **kwargs)
@@ -93,6 +95,15 @@ class Main(tk.Tk, Table):
 
     print('program ready!')
 
+    self.windspeed = 0
+    self.adcValue = 0
+    self.pwmValue = 0
+    self.pidDelay = 100
+
+    self.pidThread = threading.Thread(target=self.pidThreadFunction)
+    self.pidThread.daemon = True
+    self.pidThread.start()
+
     self.intervalDelay = 300 # ms
     self.interval()
 
@@ -114,6 +125,28 @@ class Main(tk.Tk, Table):
     self.saveAsCsv(f)
     f.close()
 
+  def pidThreadFunction(self):
+    while self.running:
+      start = time.time()
+      self.adcValue = self.adc.getVoltage(0)
+      self.windSpeed = self.adcValue * 5
+      tmp = self.pid.update(self.windSpeed, start)
+
+      if self.motorEnabled.get() == 0:
+        self.pid.clear()
+        self.pwmValue = 0
+      elif tmp > 100:
+        self.pwmValue = 100
+      elif tmp < 0:
+        self.pwmValue = 0
+      else:
+        self.pwmValue = tmp
+
+      self.motorController.setDutyCycle(self.pwmValue)
+
+      elapsed = time.time() - start
+      time.sleep(max(0, self.pidDelay / 1000 - elapsed))
+
   def interval(self):
     self.after(self.intervalDelay, self.interval)
     start = time.time()
@@ -121,27 +154,13 @@ class Main(tk.Tk, Table):
     setValue = self.frames['Page_1'].speedSlider.get()
     self.pid.setInput(setValue)
 
-    adcValue = self.adc.getVoltage(0)
-    windSpeed = adcValue * 5
-    pwmValue = self.pid.update(windSpeed)
-    
-    if self.motorEnabled.get() == 0:
-      self.pid.clear()
-      pwmValue = 0
-    elif pwmValue > 100:
-      pwmValue = 100
-    elif pwmValue < 0:
-      pwmValue = 0
-
-    self.motorController.setDutyCycle(pwmValue)
-
     i2cValues = self.pressureSensors.getValues()
     btValues = self.forceSensors.getForces()
 
     self.addRow(
-      [windSpeed, setValue, pwmValue] + 
+      [self.windSpeed, setValue, self.pwmValue] + 
       i2cValues +
-      [adcValue] +
+      [self.adcValue] +
       list(np.sum(btValues, axis = 0, initial=0)) +
       list(btValues.flatten())
     )
@@ -154,8 +173,10 @@ class Main(tk.Tk, Table):
     print("draw:    {:8.3f} ms".format((time.time() - start)*1000))
     
   def stop(self):
-    self.forceSensors.stop()
     self.motorEnabled.set(0)
-    self.motorController.setDutyCycle(0)
+    self.running = False
+    self.forceSensors.stop()
+    self.pidThread.join()
     self.adc.close()
+    self.motorController.stop()
     self.quit()

+ 5 - 0
software/motorController/pwmOutput.py

@@ -15,6 +15,11 @@ class PWM:
     #self.pwm.ChangeDutyCycle(val)
     pass
 
+  def stop(self):
+    #self.pwm.stop()
+    #GPIO.output(self.pin, 0)
+    pass
+
 if __name__ == '__main__':
   try:
     #GPIO.setmode(GPIO.BOARD)

+ 7 - 1
software/ui/Page_4.py

@@ -14,11 +14,16 @@ class Page_4(tk.Frame):
     frame = tk.LabelFrame(self, text="Einstellungen")
     frame.pack(side=tk.LEFT, fill=tk.BOTH)
 
-    tk.Label(frame, text="Aktualisierungsinterval in ms").pack()
+    tk.Label(frame, text="Aktualisierungsinterval in ms").pack(padx=5, pady=5)
     self.intervalSlider = tk.Scale(frame, from_=50, to=1000, resolution=10, orient=tk.HORIZONTAL)
     self.intervalSlider.set(300)
     self.intervalSlider.pack(side="top", fill="both", padx=5, pady=5)
 
+    tk.Label(frame, text="PID-Interval in ms").pack(padx=5, pady=5)
+    self.pidSlider = tk.Scale(frame, from_=5, to=500, resolution=1, orient=tk.HORIZONTAL)
+    self.pidSlider.set(100)
+    self.pidSlider.pack(side="top", fill="both", padx=5, pady=5)
+
     gridFrame = tk.LabelFrame(self, text="System Check")
     gridFrame.pack(side=tk.LEFT, fill=tk.BOTH)
 
@@ -38,6 +43,7 @@ class Page_4(tk.Frame):
   def update(self, visible):
     if visible:
       self.controller.intervalDelay = self.intervalSlider.get()
+      self.controller.pidDelay = self.pidSlider.get()
       row = self.controller.getLastRows(1)[0]
       for i in range(len(row)):
         nameLabel, valueLabel = self.sysLabels[i]