diff options
author | Tito Jankowski <tito@openpcr.org> | 2011-06-25 17:32:49 -0700 |
---|---|---|
committer | Tito Jankowski <tito@openpcr.org> | 2011-06-25 17:32:49 -0700 |
commit | c7a5a692bdea54ccb1bcefc8b144cca6230453de (patch) | |
tree | 487ab709c0f46950d549bf3aeefceff675e268b0 | |
parent | 5ae054e52ea096c6539e2dcc7efd86b9577803d7 (diff) | |
parent | b69dcd175e3b45edc13b08b7400b642834dda786 (diff) | |
download | openpcr-c7a5a692bdea54ccb1bcefc8b144cca6230453de.tar.gz openpcr-c7a5a692bdea54ccb1bcefc8b144cca6230453de.zip |
Merge branch 'master' of github.com:jperfetto/OpenPCR
-rw-r--r-- | arduino/OpenPCR/Makefile | 2 | ||||
-rw-r--r-- | arduino/OpenPCR/display.cpp | 45 | ||||
-rw-r--r-- | arduino/OpenPCR/pcr_includes.h | 1 | ||||
-rw-r--r-- | arduino/OpenPCR/serialcontrol.cpp | 104 | ||||
-rw-r--r-- | arduino/OpenPCR/serialcontrol.h | 9 | ||||
-rw-r--r-- | arduino/OpenPCR/thermocycler.cpp | 27 | ||||
-rw-r--r-- | arduino/OpenPCR/thermocycler.h | 1 | ||||
-rw-r--r-- | arduino/OpenPCR/util.cpp | 4 |
8 files changed, 126 insertions, 67 deletions
diff --git a/arduino/OpenPCR/Makefile b/arduino/OpenPCR/Makefile index 4bdfd28..8a6857d 100644 --- a/arduino/OpenPCR/Makefile +++ b/arduino/OpenPCR/Makefile @@ -18,6 +18,6 @@ # Where to find header files and libraries. INC_DIRS = ./inc LIB_DIRS = $(addprefix $(ARD_HOME)/libraries/, $(LIBS)) - LIBS = LiquidCrystal Wire Wire/utility + LIBS = LiquidCrystal EEPROM Wire Wire/utility include ./Makefile.master
\ No newline at end of file diff --git a/arduino/OpenPCR/display.cpp b/arduino/OpenPCR/display.cpp index 46578ab..3e858b8 100644 --- a/arduino/OpenPCR/display.cpp +++ b/arduino/OpenPCR/display.cpp @@ -29,7 +29,18 @@ const char HEATING_STR[] PROGMEM = "Heating"; const char COOLING_STR[] PROGMEM = "Cooling"; const char LIDWAIT_STR[] PROGMEM = "Heating Lid"; const char STOPPED_STR[] PROGMEM = "Ready"; -const char LID_FORM_STR[] PROGMEM = "Lid: %3d C"; +const char RUN_COMPLETE_STR[] PROGMEM = "*** Run Complete ***"; +const char OPENPCR_STR[] PROGMEM = "OpenPCR"; +const char POWERED_OFF_STR[] PROGMEM = "Powered Off"; +const char VERSION_STR[] PROGMEM = "Firmware v1.0"; +const char ETA_OVER_10H_STR[] PROGMEM = "ETA: >10h"; + +const char LID_FORM_STR[] PROGMEM = "Lid: %3d C"; +const char CYCLE_FORM_STR[] PROGMEM = "%d of %d"; +const char ETA_HOURMIN_FORM_STR[] PROGMEM = "ETA: %d:%02d"; +const char ETA_SEC_FORM_STR[] PROGMEM = "ETA: %2ds"; +const char BLOCK_TEMP_FORM_STR[] PROGMEM = "%s C"; +const char STATE_FORM_STR[] PROGMEM = "%-13s"; Display::Display(): iLcd(6, 7, 8, A5, 16, 17), @@ -93,16 +104,22 @@ void Display::Update() { DisplayEta(); } else if (state == Thermocycler::EComplete) { iLcd.setCursor(0, 3); - iLcd.print("*** Run Complete ***"); + iLcd.print(rps(RUN_COMPLETE_STR)); } break; case Thermocycler::EOff: + case Thermocycler::EStartup: iLcd.setCursor(6, 1); - iLcd.print("OpenPCR"); - - iLcd.setCursor(4, 2); - iLcd.print("Powered Off"); + iLcd.print(rps(OPENPCR_STR)); + + if (state == Thermocycler::EOff) { + iLcd.setCursor(4, 2); + iLcd.print(rps(POWERED_OFF_STR)); + } else { + iLcd.setCursor(3, 2); + iLcd.print(rps(VERSION_STR)); + } break; } } @@ -115,21 +132,19 @@ void Display::DisplayEta() { int secs = timeRemaining % 60; if (hours >= 10) - strcpy(timeString, "ETA: >10h"); + strcpy_P(timeString, ETA_OVER_10H_STR); else if (mins >= 1 || hours >= 1) - sprintf(timeString, "ETA: %d:%02d", hours, mins); + sprintf_P(timeString, ETA_HOURMIN_FORM_STR, hours, mins); else - sprintf(timeString, "ETA: %2ds", secs); + sprintf_P(timeString, ETA_SEC_FORM_STR, secs); iLcd.setCursor(11, 3); iLcd.print(timeString); } void Display::DisplayLidTemp() { - char pbuf[16]; char buf[16]; - strcpy_P(pbuf, LID_FORM_STR); - sprintf(buf, pbuf, (int)(GetThermocycler().GetLidTemp() + 0.5)); + sprintf_P(buf, LID_FORM_STR, (int)(GetThermocycler().GetLidTemp() + 0.5)); iLcd.setCursor(10, 2); iLcd.print(buf); @@ -140,7 +155,7 @@ void Display::DisplayBlockTemp() { char floatStr[16]; sprintFloat(floatStr, GetThermocycler().GetPlateTemp(), 1, true); - sprintf(buf, "%s C", floatStr); + sprintf_P(buf, BLOCK_TEMP_FORM_STR, floatStr); iLcd.setCursor(13, 0); iLcd.print(buf); @@ -150,7 +165,7 @@ void Display::DisplayCycle() { char buf[16]; iLcd.setCursor(0, 3); - sprintf(buf, "%d of %d", GetThermocycler().GetCurrentCycleNum(), GetThermocycler().GetNumCycles()); + sprintf_P(buf, CYCLE_FORM_STR, GetThermocycler().GetCurrentCycleNum(), GetThermocycler().GetNumCycles()); iLcd.print(buf); } @@ -187,6 +202,6 @@ void Display::DisplayState() { } iLcd.setCursor(0, 0); - sprintf(buf, "%-13s", stateStr); + sprintf_P(buf, STATE_FORM_STR, stateStr); iLcd.print(buf); } diff --git a/arduino/OpenPCR/pcr_includes.h b/arduino/OpenPCR/pcr_includes.h index 8c35b4b..48e53cd 100644 --- a/arduino/OpenPCR/pcr_includes.h +++ b/arduino/OpenPCR/pcr_includes.h @@ -37,7 +37,6 @@ extern "C" void __cxa_pure_virtual(void); #define STEP_NAME_LENGTH 16 #define MAX_CYCLE_ITEMS 16 #define MAX_COMMAND_SIZE 256 -#define COMMAND_SIGNATURE "s=ACGTC" enum PcrStatus { ESuccess = 0, diff --git a/arduino/OpenPCR/serialcontrol.cpp b/arduino/OpenPCR/serialcontrol.cpp index f6efa93..2019297 100644 --- a/arduino/OpenPCR/serialcontrol.cpp +++ b/arduino/OpenPCR/serialcontrol.cpp @@ -34,6 +34,7 @@ SerialControl::SerialControl(Display* pDisplay) , lastPacketSeq(0xff) , bEscapeCodeFound(false) , iCommandId(0) +, iReceivedStatusRequest(false) { Serial.begin(BAUD_RATE); } @@ -140,6 +141,7 @@ void SerialControl::ProcessPacket(byte* data, int datasize) break; case STATUS_REQ: + iReceivedStatusRequest = true; SendStatus(); break; default: @@ -152,53 +154,20 @@ void SerialControl::ProcessPacket(byte* data, int datasize) #define STATUS_FILE_LEN 128 -void SerialControl::SendStatus() -{ - char* szStatus; +void SerialControl::SendStatus() { Thermocycler::ProgramState state = GetThermocycler().GetProgramState(); - switch (state) { - case Thermocycler::EOff: - case Thermocycler::EStopped: - szStatus = "stopped"; - break; - case Thermocycler::ELidWait: - szStatus = "lidwait"; - break; - case Thermocycler::ERunning: - szStatus = "running"; - break; - case Thermocycler::EComplete: - szStatus = "complete"; - break; - case Thermocycler::EError: - default: - szStatus = "error"; - } - - char* szThermState = "\0"; - switch (GetThermocycler().GetThermalState()) { - case Thermocycler::EHeating: - szThermState = "heating"; - break; - case Thermocycler::ECooling: - szThermState = "cooling"; - break; - case Thermocycler::EHolding: - szThermState = "holding"; - break; - case Thermocycler::EIdle: - szThermState = "idle"; - break; - } + const char* szStatus = GetProgramStateString_P(state); + const char* szThermState = GetThermalStateString_P(GetThermocycler().GetThermalState()); char statusBuf[STATUS_FILE_LEN]; char* statusPtr = statusBuf; Thermocycler& tc = GetThermocycler(); + statusPtr = AddParam(statusPtr, 'd', (unsigned long)iCommandId, true); - statusPtr = AddParam(statusPtr, 's', szStatus); + statusPtr = AddParam_P(statusPtr, 's', szStatus); statusPtr = AddParam(statusPtr, 'l', (int)tc.GetLidTemp()); statusPtr = AddParam(statusPtr, 'b', tc.GetPlateTemp(), 1, false); - statusPtr = AddParam(statusPtr, 't', szThermState); + statusPtr = AddParam_P(statusPtr, 't', szThermState); if (state == Thermocycler::ERunning || state == Thermocycler::EComplete) { statusPtr = AddParam(statusPtr, 'e', tc.GetElapsedTimeS()); @@ -268,3 +237,60 @@ char* SerialControl::AddParam(char* pBuffer, char key, const char* szVal, boolea return pBuffer; } + +char* SerialControl::AddParam_P(char* pBuffer, char key, const char* szVal, boolean init) { + if (!init) + *pBuffer++ = '&'; + *pBuffer++ = key; + *pBuffer++ = '='; + strcpy_P(pBuffer, szVal); + while (*pBuffer != '\0') + pBuffer++; + + return pBuffer; +} + +const char STOPPED_STR[] PROGMEM = "stopped"; +const char LIDWAIT_STR[] PROGMEM = "lidwait"; +const char RUNNING_STR[] PROGMEM = "running"; +const char COMPLETE_STR[] PROGMEM = "complete"; +const char STARTUP_STR[] PROGMEM = "startup"; +const char ERROR_STR[] PROGMEM = "error"; +const char* SerialControl::GetProgramStateString_P(Thermocycler::ProgramState state) { + switch (state) { + case Thermocycler::EOff: + case Thermocycler::EStopped: + return STOPPED_STR; + case Thermocycler::ELidWait: + return LIDWAIT_STR; + case Thermocycler::ERunning: + return RUNNING_STR; + case Thermocycler::EComplete: + return COMPLETE_STR; + case Thermocycler::EStartup: + return STARTUP_STR; + case Thermocycler::EError: + default: + return ERROR_STR; + } +} + +const char HEATING_STR[] PROGMEM = "heating"; +const char COOLING_STR[] PROGMEM = "cooling"; +const char HOLDING_STR[] PROGMEM = "holding"; +const char IDLE_STR[] PROGMEM = "idle"; +const char* SerialControl::GetThermalStateString_P(Thermocycler::ThermalState state) { + switch (state) { + case Thermocycler::EHeating: + return HEATING_STR; + case Thermocycler::ECooling: + return COOLING_STR; + case Thermocycler::EHolding: + return HOLDING_STR; + case Thermocycler::EIdle: + return IDLE_STR; + default: + return ERROR_STR; + } +} + diff --git a/arduino/OpenPCR/serialcontrol.h b/arduino/OpenPCR/serialcontrol.h index 055ced3..5e5b7fe 100644 --- a/arduino/OpenPCR/serialcontrol.h +++ b/arduino/OpenPCR/serialcontrol.h @@ -19,10 +19,11 @@ #ifndef _SERIALCONTROL_H_ #define _SERIALCONTROL_H_ +#include "thermocycler.h" + #define START_CODE 0xFF #define ESCAPE_CODE 0xFE -class Thermocycler; class Display; class ProgramComponent; class Cycle; @@ -55,6 +56,7 @@ public: void Process(); byte* GetBuffer() { return buf; } //used for stored program parsing at start-up only if no serial command received + boolean CommandReceived() { return iReceivedStatusRequest; } private: void ReadPacket(); @@ -65,6 +67,10 @@ private: char* AddParam(char* pBuffer, char key, unsigned long val, boolean init = false); char* AddParam(char* pBuffer, char key, float val, int decimalDigits, boolean pad, boolean init = false); char* AddParam(char* pBuffer, char key, const char* szVal, boolean init = false); + char* AddParam_P(char* pBuffer, char key, const char* szVal, boolean init = false); + + const char* GetProgramStateString_P(Thermocycler::ProgramState state); + const char* GetThermalStateString_P(Thermocycler::ThermalState state); private: byte buf[MAX_COMMAND_SIZE + 1]; //read or write buffer @@ -80,6 +86,7 @@ private: uint8_t lastPacketSeq, checksum; uint16_t packetLen, packetRealLen, iCommandId; boolean bEscapeCodeFound; + boolean iReceivedStatusRequest; Display* ipDisplay; }; diff --git a/arduino/OpenPCR/thermocycler.cpp b/arduino/OpenPCR/thermocycler.cpp index 423ed0b..66b75be 100644 --- a/arduino/OpenPCR/thermocycler.cpp +++ b/arduino/OpenPCR/thermocycler.cpp @@ -80,7 +80,7 @@ PROGMEM const unsigned int LID_RESISTANCE_TABLE[] = { #define PLATE_PID_DEC_P 500 #define PLATE_PID_DEC_I 400 -#define PLATE_PID_DEC_D 200 +#define PLATE_PID_DEC_D 200 //400 #define PLATE_PID_DEC_LOW_THRESHOLD 35 #define PLATE_PID_DEC_LOW_P 2000 @@ -100,6 +100,8 @@ PROGMEM const unsigned int LID_RESISTANCE_TABLE[] = { #define MAX_LID_PWM 255 #define MIN_LID_PWM 0 +#define STARTUP_DELAY 5000 + //public Thermocycler::Thermocycler(boolean restarted): iRestarted(restarted), @@ -233,6 +235,19 @@ void Thermocycler::Loop() { ReadLidTemp(); switch (iProgramState) { + case EStartup: + if (millis() - iProgramStartTimeMs > STARTUP_DELAY) { + iProgramState = EStopped; + + if (!iRestarted && !ipSerialControl->CommandReceived()) { + //check for stored program + SCommand command; + if (ProgramStore::RetrieveProgram(command, (char*)ipSerialControl->GetBuffer())) + ProcessCommand(command); + } + } + break; + case ELidWait: if (iLidTemp >= iTargetLidTemp - LID_START_TOLERANCE) { //advance to running state @@ -313,14 +328,8 @@ void Thermocycler::CheckPower() { float voltage = analogRead(0) * 5.0 / 1024 * 10 / 3; // 10/3 is for voltage divider boolean externalPower = digitalRead(A0); //voltage > 7.0; if (externalPower && iProgramState == EOff) { - iProgramState = EStopped; - - if (!iRestarted) { - //check for stored program - SCommand command; - if (ProgramStore::RetrieveProgram(command, (char*)ipSerialControl->GetBuffer())) - ProcessCommand(command); - } + iProgramState = EStartup; + iProgramStartTimeMs = millis(); } else if (!externalPower && iProgramState != EOff) { Stop(); diff --git a/arduino/OpenPCR/thermocycler.h b/arduino/OpenPCR/thermocycler.h index 9c5f76d..bad5326 100644 --- a/arduino/OpenPCR/thermocycler.h +++ b/arduino/OpenPCR/thermocycler.h @@ -29,6 +29,7 @@ class Thermocycler { public: enum ProgramState { EOff = 0, + EStartup, EStopped, ELidWait, ERunning, diff --git a/arduino/OpenPCR/util.cpp b/arduino/OpenPCR/util.cpp index 24a5987..416c781 100644 --- a/arduino/OpenPCR/util.cpp +++ b/arduino/OpenPCR/util.cpp @@ -97,7 +97,9 @@ double absf(double val) { } char* rps(const char* progString) { - static char buf[32]; + static char buf[21]; strcpy_P(buf, progString); return buf; } + + |