/* * thermocycler.h - OpenPCR control software. * Copyright (C) 2010-2011 Josh Perfetto. All Rights Reserved. * * OpenPCR control software is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenPCR control software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * the OpenPCR control software. If not, see . */ #ifndef _THERMOCYCLER_H_ #define _THERMOCYCLER_H_ #include "PID_v1.h" #include "program.h" class Display; class SerialControl; class Thermocycler { public: enum ProgramState { EOff = 0, EStartup, EStopped, ELidWait, ERunning, EComplete, EError, EClear //for Display clearing only }; enum ThermalState { EHolding = 0, EHeating, ECooling, EIdle }; enum ThermalDirection { OFF, HEAT, COOL }; Thermocycler(boolean restarted); ~Thermocycler(); // accessors ProgramState GetProgramState() { return iProgramState; } ThermalState GetThermalState(); Step* GetCurrentStep() { return ipCurrentStep; } Cycle* GetDisplayCycle() { return ipDisplayCycle; } int GetNumCycles(); int GetCurrentCycleNum(); const char* GetProgName() { return iszProgName; } Display* GetDisplay() { return ipDisplay; } ProgramComponentPool& GetCyclePool() { return iCyclePool; } ProgramComponentPool& GetStepPool() { return iStepPool; } boolean Ramping() { return iRamping; } int GetPeltierPwm() { return iPeltierPwm; } float GetPlateTemp() { return iPlateTemp; } float GetLidTemp() { return iLidTemp; } unsigned long GetTimeRemainingS() { return iEstimatedTimeRemainingS; } unsigned long GetElapsedTimeS() { return (millis() - iProgramStartTimeMs) / 1000; } // control void SetProgram(Cycle* pProgram, Cycle* pDisplayCycle, const char* szProgName, int lidTemp); //takes ownership of cycles void Stop(); PcrStatus Start(); void ProcessCommand(SCommand& command); // internal void Loop(); private: void CheckPower(); void ReadLidTemp(); void ReadPlateTemp(); void ControlPeltier(); void ControlLid(); void UpdateEta(); //util functions void SetPlateTarget(double target); void SetLidTarget(double target); void SetPeltier(ThermalDirection dir, int pwm); uint8_t mcp342xWrite(uint8_t config); uint8_t mcp342xRead(int32_t &data); float TableLookup(const unsigned long lookupTable[], unsigned int tableSize, int startValue, unsigned long searchValue); float TableLookup(const unsigned int lookupTable[], unsigned int tableSize, int startValue, unsigned long searchValue); private: // constants static const int PLATE_TEMP_SENSOR_PIN = 0; // components Display* ipDisplay; SerialControl* ipSerialControl; ProgramComponentPool iCyclePool; ProgramComponentPool iStepPool; // state ProgramState iProgramState; double iPlateTemp; double iTargetPlateTemp; double iLidTemp; double iTargetLidTemp; Cycle* ipProgram; Cycle* ipDisplayCycle; char iszProgName[21]; Step* ipCurrentStep; unsigned long iCycleStartTime; boolean iRamping; boolean iDecreasing; enum ControlMode { EBangBang, EPID }; boolean iRestarted; ControlMode iPlateControlMode; ControlMode iLidControlMode; // peltier control PID iPlatePid; PID iLidPid; ThermalDirection iThermalDirection; //holds actual real-time state double iPeltierPwm; double iLidPwm; // program eta calculation unsigned long iProgramStartTimeMs; unsigned long iProgramHoldDurationS; double iProgramRampDegrees; double iElapsedRampDegrees; unsigned long iElapsedRampDurationMs; double iRampStartTemp; unsigned long iRampStartTime; unsigned long iEstimatedTimeRemainingS; boolean iHasCooled; }; #endif