예제 #1
0
 def measurestep(self, value=None):
     if value == None:
         stdinput = stdin("",
                          exitevent=self.fanctrl.exitevent,
                          mutex=self.fanctrl.mutex,
                          displaylater=False,
                          background=False)
         print("Enter PWM value for step response")
         inptxt = "Enter PWM: "
         inp = stdinput.input(inptxt)
         if inp:
             value = self.fanctrl.gettype(inp, False)
             if value == None:
                 print("Invalid input!")
                 del stdinput
                 return None
         del stdinput
     print("Measuring fan step response (PWM = {:.2f}%)".format(value))
     self.fanctrl.fanoutput.set(0)
     self.fanctrl.exitevent.wait(2 * LIN_SLEEP)
     tm = []
     rpm = []
     self.fanctrl.fanoutput.set(value)
     starttime = time()
     nowtime = starttime
     while nowtime - starttime <= STEP_LENGTH and not self.fanctrl.exitevent.is_set(
     ):
         self.fanctrl.exitevent.wait(STEP_SLEEP)
         nowtime = time()
         nowrpm = self.fanctrl.rpm.get()
         tm.append(nowtime - starttime)
         rpm.append(nowrpm)
     self.fanctrl.fanoutput.set(0)
     print("Finished measuring fan step response")
     return (tm, rpm)
예제 #2
0
 def testPID(self, Kp, Ki):
     print("Test PID parameters")
     self.fanctrl.start(Kp=Kp, Ki=Ki)
     stdinput = stdin()
     value = 0
     step = 500  # check pwm < 1, don't count
     nowpwm = 0
     rpms = []
     r2 = []
     while nowpwm < 100 and not self.fanctrl.exitevent.is_set():
         self.fanctrl.set(value)
         self.fanctrl.exitevent.wait(LIN_SLEEP)
         nowrpm = self.fanctrl.rpm.get()
         nowpwm = self.fanctrl.fanoutput.get()
         if (nowpwm > 1.0) and (nowpwm < 99.0):
             rpms.append(value)
             r2.append(pow(nowrpm - value, 2))
             #print("{:.2f}\t{:.2f}\t{:.2f}".format(value,nowrpm,pow(nowrpm - value,2)))
         value += step
     if len(r2) > 1:
         r = sqrt(sum(r2) / (len(r2) - 1))
     else:
         r = 1
     if len(rpms) > 0:
         avg = sum(rpms) / len(rpms)
     else:
         avg = 1
     perc = 100 * r / avg
     #print(r,avg,perc)
     self.fanctrl.stop()
     self.fanctrl.exitevent.wait(LIN_SLEEP / 5)
     print("Finished test PID parameters")
     return perc
예제 #3
0
 def determine(self):
     stdinput = stdin("", exitevent=self.fanctrl.exitevent)
     print("Determining Pgain and Igain")
     Kp = ((self.fanctrl.max() - self.fanctrl.min()) /
           (self.tempfull - self.tempstart)) * 0.9
     Ki = Kp * 0.1 / (150.0)
     print("Results: Pgain = {:.3f}, Igain = {:.3f}".format(Kp, Ki))
     Ok = stdinput.yn_choice("Store results?", "Y")
     return Ok, round(Kp, 3), round(Ki, 3)
예제 #4
0
    def plotstep(self, sr):
        print("Fan step response plot")
        stdinput = stdin()
        stdinput.eprint("Time [ms]\tRPM [1/min]")
        for i in range(0, len(sr[0])):
            stdinput.eprint("{:.2f}\t{:.2f}".format(sr[0][i], sr[1][i]))

        del stdinput
        print("Finished fan step response plot")
        return
예제 #5
0
 def plotlinear(self):
     print("Fan linear plot")
     stdinput = stdin()
     value = 0
     step = 5
     stdinput.eprint("Linear step: " + str(step))
     stdinput.eprint("PWM [%]\tRPM [1/min]")
     while value <= 100:
         self.fanctrl.fanoutput.set(value)
         self.fanctrl.exitevent.wait(LIN_SLEEP)
         nowrpm = self.fanctrl.rpm.get()
         stdinput.eprint("{:.2f}\t{:.2f}".format(value, nowrpm))
         value += step
     del stdinput
     print("Finished fan linear plot")
     return
예제 #6
0
 def tune(self):
     sp = 50
     exit = False
     Ok = False
     ans = 'n'
     auto = True
     stdinput = stdin("", exitevent=self.fanctrl.exitevent)
     while not exit and not self.fanctrl.exitevent.is_set():
         correctResults = False
         while not correctResults and not self.fanctrl.exitevent.is_set():
             if auto:
                 Kp = 0
                 Ki = 0
                 sr = self.measurestep(sp)
                 if sr:
                     #self.plotstep(sr)
                     Kp, Ki = self.calcparams(sr, sp)
             print("Results: Pgain = {:.3f}, Igain = {:.3f}".format(Kp, Ki))
             if (Kp == 0 or Kp > GAINMAX or Ki == 0 or
                     Ki > GAINMAX) and not self.fanctrl.exitevent.is_set():
                 correctResults = stdinput.yn_choice(
                     "Incorrect autotuning results. Try again?", 'y')
             else:
                 correctResults = True
         if correctResults:
             r = self.testPID(Kp, Ki)
             Ok = r < 1
             print("RMS error = {:.2f}%, Ok (< 1% is Ok): {}".format(r, Ok))
         if not self.fanctrl.exitevent.is_set():
             ans = 'n' if Ok else 'y'
             exit = not stdinput.yn_choice("Retry tuning?", ans)
         else:
             exit = True
         if not exit and not self.fanctrl.exitevent.is_set():
             auto, Kp, Ki, sp = self._tuneMenu(stdinput, Kp, Ki, sp)
     if not self.fanctrl.exitevent.is_set():
         ans = 'Y' if Ok else 'n'
         Ok = stdinput.yn_choice("Store results?", ans)
     del stdinput
     if self.fanctrl.exitevent.is_set():
         Ok = False
         Kp = 0
         Ki = 0
     return Ok, round(Kp, 3), round(Ki, 3)
예제 #7
0
    def manualCalibrate(self):
        print("Manual calibration")
        self.mutex.acquire()
        pwmlevel = MINPWM - MANUALPWMDELTA
        choice = False
        stdinput = stdin("", exitevent=self.exitevent)
        while not choice and pwmlevel < MAXPWM and not self.exitevent.is_set():
            pwmlevel += MANUALPWMDELTA
            self.fanoutput.set(pwmlevel)
            choice = stdinput.yn_choice(
                "Is the fan running? (PWM = {})".format(pwmlevel), 'n')

        if not self.exitevent.is_set():
            self.valuemin = pwmlevel
            self.fanoutput.set(MINPWM)
            self.mutex.release()
            print("Manual calibration finished, minimum PWM: {}".format(
                self.valuemin))

        return self.valuemin