mirror of
https://github.com/RobTillaart/Arduino.git
synced 2024-10-03 18:09:02 -04:00
0.3.0 PCR
This commit is contained in:
parent
62230e22d8
commit
4794e6adaf
@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
|
||||
## [0.3.0] - 2024-06-01
|
||||
- breaking change
|
||||
- duration in configuration function to **float seconds** as this is more convenient.
|
||||
- update examples to use seconds.
|
||||
- fix **getHoldTemp()** bug.
|
||||
- fix signature of functions in 0.2.1
|
||||
- clean up code (remove commented sections).
|
||||
- add **PCR_demo_aquarium.ino** example (for fun).
|
||||
- update readme.md
|
||||
- update unit tests
|
||||
|
||||
----
|
||||
|
||||
## [0.2.1] - 2024-05-31
|
||||
- add **setHeatPulseLength(uint16_t len)** to modify the pulse length of the heater / cooler.
|
||||
- add example **PCR_demo_DS18B20.ino** DS18B20 for PCR.
|
||||
@ -16,11 +29,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- update readme.md
|
||||
- minor edits
|
||||
|
||||
|
||||
## [0.2.0] - 2024-05-30
|
||||
- initial class version (published)
|
||||
|
||||
----
|
||||
|
||||
## [0.1.3] - 2024-05-30
|
||||
- initial class version (not published)
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// FILE: PCR.h
|
||||
// AUTHOR: Rob Tillaart
|
||||
// DATE: 2015-06-10
|
||||
// VERSION: 0.2.1
|
||||
// VERSION: 0.3.0
|
||||
// PURPOSE: Arduino library for PCR process control.
|
||||
// URL: https://github.com/RobTillaart/PCR
|
||||
// https://forum.arduino.cc/t/problem-with-arduino-pcr-amplifies-of-dna/314808
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define PCR_LIB_VERSION (F("0.2.1"))
|
||||
#define PCR_LIB_VERSION (F("0.3.0"))
|
||||
|
||||
enum PCRSTATE {
|
||||
PCR_STATE_IDLE = 0,
|
||||
@ -40,52 +40,52 @@ public:
|
||||
|
||||
|
||||
// PARAMETERS
|
||||
void setInitial(float Celsius, uint32_t ms)
|
||||
void setInitial(float Celsius, float seconds)
|
||||
{
|
||||
_initialTemp = Celsius;
|
||||
_initialTime = ms;
|
||||
_initialTime = seconds * 1000;
|
||||
}
|
||||
float getInitialTemp() { return _initialTemp; }
|
||||
uint32_t getInitialTime() { return _initialTime; }
|
||||
float getInitialTime() { return _initialTime * 0.001; }
|
||||
|
||||
void setDenature(float Celsius, uint32_t ms)
|
||||
void setDenature(float Celsius, float seconds)
|
||||
{
|
||||
_denatureTemp = Celsius;
|
||||
_denatureTime = ms;
|
||||
_denatureTime = seconds * 1000;
|
||||
}
|
||||
float getDenatureTemp() { return _denatureTemp; }
|
||||
uint32_t getDenatureTime() { return _denatureTime; }
|
||||
float getDenatureTime() { return _denatureTime * 0.001; }
|
||||
|
||||
void setAnnealing(float Celsius, uint32_t ms)
|
||||
void setAnnealing(float Celsius, float seconds)
|
||||
{
|
||||
_annealingTemp = Celsius;
|
||||
_annealingTime = ms;
|
||||
_annealingTime = seconds * 1000;
|
||||
}
|
||||
float getAnnealingTemp() { return _annealingTemp; }
|
||||
uint32_t getAnnealingTime() { return _annealingTime; }
|
||||
float getAnnealingTime() { return _annealingTime * 0.001; }
|
||||
|
||||
void setExtension(float Celsius, uint32_t ms)
|
||||
void setExtension(float Celsius, float seconds)
|
||||
{
|
||||
_extensionTemp = Celsius;
|
||||
_extensionTime = ms;
|
||||
_extensionTime = seconds * 1000;
|
||||
}
|
||||
float getExtensionTemp() { return _extensionTemp; }
|
||||
float getExtensionTime() { return _extensionTime; }
|
||||
float getExtensionTime() { return _extensionTime * 0.001; }
|
||||
|
||||
void setElongation(float Celsius, uint32_t ms)
|
||||
void setElongation(float Celsius, float seconds)
|
||||
{
|
||||
_elongationTemp = Celsius;
|
||||
_elongationTime = ms;
|
||||
_elongationTime = seconds * 1000;
|
||||
}
|
||||
float getElongationTemp() { return _elongationTemp; }
|
||||
float getElongationTime() { return _elongationTime; }
|
||||
float getElongationTime() { return _elongationTime * 0.001; }
|
||||
|
||||
void setHold(float Celsius) { _holdTemp = Celsius; }
|
||||
float getHoldTemp() { return _extensionTemp; }
|
||||
float getHoldTemp() { return _holdTemp; }
|
||||
|
||||
|
||||
// PROCESS CONTROL
|
||||
void reset(int iterations)
|
||||
void reset(uint16_t iterations)
|
||||
{
|
||||
_startTime = millis();
|
||||
_cycles = iterations;
|
||||
@ -94,7 +94,7 @@ public:
|
||||
debug();
|
||||
}
|
||||
|
||||
int iterationsLeft()
|
||||
uint16_t iterationsLeft()
|
||||
{
|
||||
return _cycles;
|
||||
}
|
||||
@ -104,11 +104,6 @@ public:
|
||||
uint8_t process(float temperature)
|
||||
{
|
||||
_temperature = temperature;
|
||||
/* 0.3.0
|
||||
if (_temperature < temp[_state]) heat();
|
||||
else if (_temperature > temp[_state]) cool();
|
||||
else off();
|
||||
*/
|
||||
switch(_state)
|
||||
{
|
||||
case PCR_STATE_IDLE:
|
||||
@ -190,18 +185,19 @@ public:
|
||||
|
||||
|
||||
// HEATER / COOLER CONTROL
|
||||
// ms = timing in milliseconds
|
||||
void setHeatPulseLength(uint16_t ms = 10)
|
||||
{
|
||||
if (ms > 1000) ms = 1000;
|
||||
_heatPulseLength = ms;
|
||||
}
|
||||
|
||||
// returns milliseconds.
|
||||
uint16_t getHeatPulseLength()
|
||||
{
|
||||
return _heatPulseLength;
|
||||
}
|
||||
|
||||
|
||||
void heat()
|
||||
{
|
||||
digitalWrite(_heatPin, HIGH);
|
||||
@ -222,26 +218,9 @@ public:
|
||||
digitalWrite(_coolPin, LOW);
|
||||
}
|
||||
|
||||
|
||||
// blocking version of single step.
|
||||
// to be tested what to do with it
|
||||
// could be a separate class / stand alone version.
|
||||
/*
|
||||
void keepTempTime(float temperature, uint32_t ms, float (*getTemp)())
|
||||
{
|
||||
_startTime = millis();
|
||||
_temperature = temperature;
|
||||
while (millis() - _startTime < ms)
|
||||
{
|
||||
if (getTemp() < _temperature ) heat();
|
||||
else if (getTemp() > _temperature) cool();
|
||||
else off();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// estimator timeLeft, assumes process is not stopped.
|
||||
uint32_t timeLeft()
|
||||
// returns value in seconds
|
||||
float timeLeft()
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
if (_state < PCR_STATE_DENATURE) sum += _initialTime;
|
||||
@ -249,7 +228,7 @@ public:
|
||||
sum += _annealingTime * _cycles;
|
||||
sum += _extensionTime * _cycles;
|
||||
if (_state <= PCR_STATE_ELONGATION) sum += _elongationTime;
|
||||
return sum;
|
||||
return sum * 0.001;
|
||||
}
|
||||
|
||||
|
||||
@ -257,12 +236,6 @@ protected:
|
||||
// development.
|
||||
void debug()
|
||||
{
|
||||
// log for plotting temperature
|
||||
//
|
||||
// Serial.print(_cycles);
|
||||
// Serial.print("\t");
|
||||
// Serial.println(_temperature);
|
||||
|
||||
// log for seeing state transitions.
|
||||
Serial.print(_startTime);
|
||||
Serial.print("\t");
|
||||
@ -278,16 +251,8 @@ protected:
|
||||
else if (_state == PCR_STATE_HOLD) Serial.println("\tHold");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// simplify the code. 0.3.0
|
||||
// maybe temperature only?
|
||||
float _temp[6] = { 94, 94, 54, 76, 76, 14 };
|
||||
float _time[6] = { 0, 1, 1, 1, 1, -1 };
|
||||
*/
|
||||
|
||||
float _initialTemp = 94;
|
||||
uint32_t _initialTime = 0;
|
||||
float _initialTemp = 94; // °Celsius
|
||||
uint32_t _initialTime = 0; // milliseconds
|
||||
float _denatureTemp = 94;
|
||||
uint32_t _denatureTime = 1000;
|
||||
float _annealingTemp = 54;
|
||||
@ -303,7 +268,7 @@ protected:
|
||||
int _heatPin = 0;
|
||||
int _coolPin = 0;
|
||||
PCRSTATE _state = PCR_STATE_IDLE;
|
||||
int _cycles = 0;
|
||||
uint16_t _cycles = 0;
|
||||
uint32_t _startTime = 0;
|
||||
uint16_t _heatPulseLength = 10; // milliseconds.
|
||||
};
|
||||
|
@ -19,7 +19,7 @@ Arduino library for PCR process control.
|
||||
|
||||
**Experimental**
|
||||
|
||||
From wikipedia:
|
||||
From Wikipedia:
|
||||
|
||||
_The polymerase chain reaction (PCR) is a method widely used to make millions to
|
||||
billions of copies of a specific DNA sample rapidly, allowing scientists to amplify
|
||||
@ -103,10 +103,21 @@ Some examples:
|
||||
- control an ice making machine.
|
||||
|
||||
|
||||
#### Breaking change 0.3.0
|
||||
|
||||
Since 0.3.0 the timing of the 6 steps is done in seconds instead of milliseconds.
|
||||
As the steps take up to 15 minutes of more, defining the time in seconds is a more
|
||||
natural order of magnitude than milliseconds.
|
||||
Note however that the internal math still is done in milliseconds so one can define
|
||||
a step as taking 15.75 seconds = 15750 milliseconds.
|
||||
|
||||
Pre 0.3.0 versions are now obsolete.
|
||||
|
||||
#### Related
|
||||
|
||||
- https://en.wikipedia.org/wiki/Polymerase_chain_reaction
|
||||
- https://github.com/RobTillaart/PCR
|
||||
- https://github.com/RobTillaart/Temperature scale conversions.
|
||||
- https://forum.arduino.cc/t/problem-with-arduino-pcr-amplifies-of-dna/314808
|
||||
- https://www.scientificamerican.com/article/the-unusual-origin-of-the-polymeras/ (paid site)
|
||||
|
||||
@ -121,15 +132,17 @@ Some examples:
|
||||
|
||||
- **PCR(uint8_t heatPin, uint8_t coolPin)** constructor defines the hardware pins to which
|
||||
the heater and cooler are connected.
|
||||
- **void reset(int iterations)** full stop of the process, also stops heating and cooling,
|
||||
- **void reset(uint16_t iterations)** full stop of the process, also stops heating and cooling,
|
||||
resets the state to IDLE and defines the number of iterations for the next run.
|
||||
The parameter iterations must be >= 0 so it changed to unsigned int in 0.3.0.
|
||||
- **uint8_t process(float temperature)** The worker core. This function runs the main process
|
||||
and iterates over the DENATURE, ANNEALING and EXTENSION phase. Returns the current state.
|
||||
The user **MUST** provide the actual temperature of the sample so process can heat and cool
|
||||
the sample on a need to basis.
|
||||
The user **MUST** call this function as often as possible in a tight loop.
|
||||
- **int iterationsLeft()** returns the number of iterations left.
|
||||
- **uint32_t timeLeft()** estimator of the time left to reach the HOLD state.
|
||||
- **float timeLeft()** estimator of the time left to reach the HOLD state.
|
||||
Since 0.3.0 returns its value in seconds.
|
||||
This function assumes that the duration per phase does not change runtime,
|
||||
however it will adapt its estimate.
|
||||
Returns the value in milliseconds.
|
||||
@ -137,29 +150,36 @@ Returns the value in milliseconds.
|
||||
|
||||
#### About phases
|
||||
|
||||
Temperatures are in °Celsius, timing is in milliseconds (for 0.2.x version).
|
||||
Temperatures are in **°Celsius**, timing is in **seconds** (since 0.3.0 version).
|
||||
|
||||
The timing is the time that the process will be in this state, so it includes
|
||||
the time to heat / cool to reach the temperature defined.
|
||||
The timing parameter is a float so you can use e.g. 10.5 seconds, or even use
|
||||
scientific notation like 1.2e2.
|
||||
In theory the maximum time is 4294967 seconds which is 49.7 days,
|
||||
In practice the phases are much shorter.
|
||||
- 1 hour = 3600 seconds, 1 day = 86400 seconds
|
||||
|
||||
Note that the parameters of the phases can change while the process is running,
|
||||
e.g. one can increase the duration of the extension phase per cycle to give
|
||||
that part of the PCR process more time.
|
||||
that part of the PCR process more time (adjust to concentration?).
|
||||
|
||||
|
||||
#### 1 Initial phase
|
||||
|
||||
This step used in **hot-start PCR** (Wikipedia) to bring the system to starting temperature.
|
||||
|
||||
- **void setInitial(float Celsius, uint32_t ms)** Sets temperature and duration.
|
||||
- **void setInitial(float Celsius, float seconds)** Sets temperature and duration.
|
||||
- **float getInitialTemp()** returns set value.
|
||||
- **uint32_t getInitialTime()** returns set value.
|
||||
- **float getInitialTime()** returns set value.
|
||||
|
||||
#### 2 Denature phase
|
||||
|
||||
This step breaks the double DNA helix into two single strands.
|
||||
|
||||
- **void setDenature(float Celsius, uint32_t ms)** Sets temperature and duration.
|
||||
- **void setDenature(float Celsius, float seconds)** Sets temperature and duration.
|
||||
- **float getDenatureTemp()** returns set value.
|
||||
- **uint32_t getDenatureTime()** returns set value.
|
||||
- **float getDenatureTime()** returns set value.
|
||||
|
||||
#### 3 Annealing phase
|
||||
|
||||
@ -167,16 +187,16 @@ This step let **primers** (Wikipedia) connect to the single strands.
|
||||
The primers create a starting point for the replication.
|
||||
The temperature and duration depends on many factors, so very specific for the reaction.
|
||||
|
||||
- **void setAnnealing(float Celsius, uint32_t ms)** Sets temperature and duration.
|
||||
- **void setAnnealing(float Celsius, float seconds)** Sets temperature and duration.
|
||||
- **float getAnnealingTemp()** returns set value.
|
||||
- **uint32_t getAnnealingTime()** returns set value.
|
||||
- **float getAnnealingTime()** returns set value.
|
||||
|
||||
#### 4 Extension phase
|
||||
|
||||
This step extends the primers with **dNTP's** nucleotides (Wikipedia) to complete
|
||||
the duplication process.
|
||||
|
||||
- **void setExtension(float Celsius, uint32_t ms)** Sets temperature and duration.
|
||||
- **void setExtension(float Celsius, float seconds)** Sets temperature and duration.
|
||||
- **float getExtensionTemp()** returns set value.
|
||||
- **float getExtensionTime()** returns set value.
|
||||
|
||||
@ -185,7 +205,7 @@ the duplication process.
|
||||
This step is used to finalize the remaining DNA strands that are not fully extended
|
||||
in step 4 Extension phase.
|
||||
|
||||
- **void setElongation(float Celsius, uint32_t ms)** Sets temperature and duration.
|
||||
- **void setElongation(float Celsius, float seconds)** Sets temperature and duration.
|
||||
- **float getElongationTemp()** returns set value.
|
||||
- **float getElongationTime()** returns set value.
|
||||
|
||||
@ -204,8 +224,9 @@ from their own code.
|
||||
|
||||
In 0.2.x version the heater / cooler are switched on/off for a short period.
|
||||
This prevent excessive heating or cooling due to not switching of the heater / cooler in time.
|
||||
This pulsed heating cooling makes the process safer and a bit slower to heat up / cool down.
|
||||
The length of the period can be adjusted between 0 and 1000 milliseconds to increase
|
||||
This pulsed heating / cooling makes the process safer as after the call it is switched off.
|
||||
Drawback is that the pulsed behaviour makes the process a bit slower to heat up / cool down.
|
||||
Therefore the length of the period can be adjusted between 0 and 1000 milliseconds to increase
|
||||
the efficiency of the process. Be aware that the heat() and cool() will block longer.
|
||||
|
||||
- **void heat()** Switches off cooler first, and then switches the heater for (default)
|
||||
@ -213,9 +234,10 @@ the efficiency of the process. Be aware that the heat() and cool() will block lo
|
||||
- **void cool()** switch on the cooler for (default) 10 milliseconds. Switches off heater first.
|
||||
- **void off()** switch off both heater and cooler.
|
||||
- **void setHeatPulseLength(uint16_t ms = 10)** adjust the timing for heat() and cool().
|
||||
- The maximum value is 1000 milliseconds == 1 second.
|
||||
- The maximum value is 1000 milliseconds == 1 second (this limit is to prevent overheating).
|
||||
- The minimum value is 0 milliseconds but it would slow down the heating / cooling.
|
||||
- warning the heat() and cool() will block for the set period.
|
||||
- Assumption: optimal time == time to increase 0.1°C. This depends on the specific heat.
|
||||
- Warning: the heat() and cool() will block for the set period.
|
||||
- **uint16_t getHeatPulseLength()** returns set value.
|
||||
|
||||
|
||||
@ -235,8 +257,6 @@ Users can patch this function when needed, or make it empty.
|
||||
|
||||
#### Should
|
||||
|
||||
- time of phases should be in seconds ==> breaking change
|
||||
- **void setAnnealing(float Celsius, float seconds)** Sets temperature and duration.
|
||||
- investigate the blocking version
|
||||
- void keepTempTime(temp, time, getTemperature());
|
||||
|
||||
@ -244,17 +264,17 @@ Users can patch this function when needed, or make it empty.
|
||||
|
||||
- PCR scripting language, simple example?
|
||||
- add examples
|
||||
- optimize code
|
||||
- have an array of times and temperatures to go through.
|
||||
- add continuous heating (unsafe mode) versus the current pulsed heating(safe mode).
|
||||
- add stir pin, to control the stirring of the PCR device.
|
||||
- add signalling pin to indicate ready by a buzzer.
|
||||
- add unit tests
|
||||
|
||||
#### Wont
|
||||
|
||||
- add callback function when ready (user can check state)
|
||||
|
||||
- Fahrenheit interface (C = (F-32) x 5/9.0; F = C x 9/5.0 + 32;
|
||||
- Kelvin or other temperature scale.
|
||||
- optimize code
|
||||
- have an array of times and temperatures to go through.
|
||||
- add continuous heating (unsafe mode) versus the current pulsed heating(safe mode).
|
||||
|
||||
## Support
|
||||
|
||||
|
@ -51,16 +51,16 @@ void setup()
|
||||
sensor.begin();
|
||||
sensor.setResolution(10); // 10 bit ==> 0.25 degrees precision
|
||||
sensor.requestTemperatures();
|
||||
delay(1000); // wait a second to get a first reading.
|
||||
delay(1000); // wait a second to get a first measurement.
|
||||
|
||||
|
||||
// configure PCR process
|
||||
// adjust timing and temperature to your needs.
|
||||
pcr.setInitial(98, 10000); // temp, ms
|
||||
pcr.setDenature(94.5, 5000); // temp, ms
|
||||
pcr.setAnnealing(54.2, 2000); // temp, ms
|
||||
pcr.setExtension(75.0, 3000); // temp, ms
|
||||
pcr.setElongation(75.0, 3000); // temp, ms
|
||||
pcr.setInitial(98, 10); // temp, seconds
|
||||
pcr.setDenature(94.5, 5); // temp, seconds
|
||||
pcr.setAnnealing(54.2, 2); // temp, seconds
|
||||
pcr.setExtension(75.0, 3); // temp, seconds
|
||||
pcr.setElongation(75.0, 5); // temp, seconds
|
||||
pcr.setHold(8.0); // temp only
|
||||
|
||||
pcr.reset(15); // iterations.
|
||||
|
@ -46,11 +46,11 @@ void setup()
|
||||
|
||||
// configure PCR process
|
||||
// adjust timing and temperature to your needs.
|
||||
pcr.setInitial(98, 10000); // temp, ms
|
||||
pcr.setDenature(94.5, 5000); // temp, ms
|
||||
pcr.setAnnealing(54.2, 2000); // temp, ms
|
||||
pcr.setExtension(75.0, 3000); // temp, ms
|
||||
pcr.setElongation(75.0, 3000); // temp, ms
|
||||
pcr.setInitial(98, 10); // temp, seconds
|
||||
pcr.setDenature(94.5, 5); // temp, seconds
|
||||
pcr.setAnnealing(54.2, 2); // temp, seconds
|
||||
pcr.setExtension(75.0, 3); // temp, seconds
|
||||
pcr.setElongation(75.0, 3); // temp, seconds
|
||||
pcr.setHold(8.0); // temp only
|
||||
|
||||
pcr.reset(15); // iterations.
|
||||
|
@ -0,0 +1,54 @@
|
||||
//
|
||||
// FILE: PCR_demo_aquarium.ino
|
||||
// AUTHOR: Rob Tillaart
|
||||
// PURPOSE: using PCR class to control temperature in a tropic aquarium
|
||||
// URL: https://github.com/RobTillaart/PCR
|
||||
//
|
||||
// Warning: example takes a day to do one cycle. Adjust timing to see effect.
|
||||
|
||||
|
||||
#include "PCR.h"
|
||||
|
||||
|
||||
PCR pcr(8, 9); // heatPin, coolPin
|
||||
|
||||
|
||||
float getTemperature()
|
||||
{
|
||||
return 30; // dummy, to be elaborated.
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
Serial.println();
|
||||
Serial.println(__FILE__);
|
||||
Serial.print("PCR_LIB_VERSION: ");
|
||||
Serial.println(PCR_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
// split 86400 seconds over three temperature levels
|
||||
pcr.setDenature(32, 23200); // temp, seconds
|
||||
pcr.setAnnealing(29, 43200); // temp, seconds
|
||||
pcr.setExtension(27, 20000); // temp, seconds
|
||||
|
||||
// just one cycle a day.
|
||||
pcr.reset(1);
|
||||
}
|
||||
|
||||
|
||||
void loop()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
float temp = getTemperature();
|
||||
pcr.process(temp);
|
||||
// break after a full cycle / day.
|
||||
if (pcr.iterationsLeft() == 0) break;
|
||||
}
|
||||
// do next cycle / day.
|
||||
pcr.reset(1);
|
||||
}
|
||||
|
||||
|
||||
// -- END OF FILE --
|
@ -28,25 +28,25 @@ void setup()
|
||||
Serial.println();
|
||||
|
||||
// configure all phases
|
||||
pcr[0].setInitial(98, 10000); // temp, ms
|
||||
pcr[0].setDenature(94.5, 5000); // temp, ms
|
||||
pcr[0].setAnnealing(54.2, 2000); // temp, ms
|
||||
pcr[0].setExtension(75.0, 3000); // temp, ms
|
||||
pcr[0].setElongation(75.0, 3000); // temp, ms
|
||||
pcr[0].setInitial(98, 10); // temp, seconds
|
||||
pcr[0].setDenature(94.5, 5); // temp, seconds
|
||||
pcr[0].setAnnealing(54.2, 2); // temp, seconds
|
||||
pcr[0].setExtension(75.0, 3); // temp, seconds
|
||||
pcr[0].setElongation(75.0, 3); // temp, seconds
|
||||
pcr[0].setHold(8.0); // temp only
|
||||
|
||||
pcr[1].setInitial(97, 8000);
|
||||
pcr[1].setDenature(94, 4000);
|
||||
pcr[1].setAnnealing(54, 2000);
|
||||
pcr[1].setExtension(70.0, 2000);
|
||||
pcr[1].setElongation(70.0, 2000);
|
||||
pcr[1].setInitial(97, 8);
|
||||
pcr[1].setDenature(94, 4);
|
||||
pcr[1].setAnnealing(54, 2);
|
||||
pcr[1].setExtension(70.0, 2);
|
||||
pcr[1].setElongation(70.0, 2);
|
||||
pcr[1].setHold(8.0);
|
||||
|
||||
pcr[2].setInitial(96, 15000);
|
||||
pcr[2].setDenature(93, 8000);
|
||||
pcr[2].setAnnealing(53, 4000);
|
||||
pcr[2].setExtension(75.0, 4000);
|
||||
pcr[2].setElongation(75.0, 4000);
|
||||
pcr[2].setInitial(96, 15);
|
||||
pcr[2].setDenature(93, 8);
|
||||
pcr[2].setAnnealing(53, 4);
|
||||
pcr[2].setExtension(75.0, 4);
|
||||
pcr[2].setElongation(75.0, 4);
|
||||
pcr[2].setHold(8.0);
|
||||
|
||||
pcr[0].reset(15); // iterations.
|
||||
|
@ -25,9 +25,9 @@ void setup()
|
||||
Serial.println(PCR_LIB_VERSION);
|
||||
Serial.println();
|
||||
|
||||
pcr.setDenature(94.5, 1000); // temp, ms
|
||||
pcr.setAnnealing(54.2, 1000); // temp, ms
|
||||
pcr.setExtension(75.0, 1000); // temp, ms
|
||||
pcr.setDenature(94.5, 1); // temp, seconds
|
||||
pcr.setAnnealing(54.2, 2); // temp, seconds
|
||||
pcr.setExtension(75.0, 3); // temp, seconds
|
||||
|
||||
pcr.reset(5); // iterations.
|
||||
|
||||
|
@ -27,11 +27,11 @@ void setup()
|
||||
Serial.println();
|
||||
|
||||
// configure all phases
|
||||
pcr.setInitial(98, 10000); // temp, ms
|
||||
pcr.setDenature(94.5, 5000); // temp, ms
|
||||
pcr.setAnnealing(54.2, 2000); // temp, ms
|
||||
pcr.setExtension(75.0, 3000); // temp, ms
|
||||
pcr.setElongation(75.0, 3000); // temp, ms
|
||||
pcr.setInitial(98, 10); // temp, seconds
|
||||
pcr.setDenature(94.5, 5); // temp, seconds
|
||||
pcr.setAnnealing(54.2, 2); // temp, seconds
|
||||
pcr.setExtension(75.0, 3); // temp, seconds
|
||||
pcr.setElongation(75.0, 5); // temp, seconds
|
||||
pcr.setHold(8.0); // temp only
|
||||
|
||||
pcr.reset(15); // iterations.
|
||||
|
@ -27,15 +27,15 @@ void setup()
|
||||
Serial.println();
|
||||
|
||||
// configure all phases
|
||||
pcr.setInitial(98, 10000); // temp, ms
|
||||
pcr.setDenature(94.5, 5000); // temp, ms
|
||||
pcr.setAnnealing(54.2, 2000); // temp, ms
|
||||
pcr.setExtension(75.0, 3000); // temp, ms
|
||||
pcr.setElongation(75.0, 3000); // temp, ms
|
||||
pcr.setInitial(98, 10); // temp, seconds
|
||||
pcr.setDenature(94.5, 5); // temp, seconds
|
||||
pcr.setAnnealing(54.2, 2); // temp, seconds
|
||||
pcr.setExtension(75.0, 3); // temp, seconds
|
||||
pcr.setElongation(75.0, 3); // temp, seconds
|
||||
pcr.setHold(8.0); // temp only
|
||||
|
||||
pcr.reset(10); // iterations.
|
||||
Serial.print("Estimated time (ms): ");
|
||||
Serial.print("Estimated time (seconds): ");
|
||||
Serial.println(pcr.timeLeft());
|
||||
|
||||
bool flagFive = false;
|
||||
@ -48,10 +48,10 @@ void setup()
|
||||
if ((pcr.iterationsLeft() == 5) && (flagFive == false))
|
||||
{
|
||||
flagFive = true;
|
||||
pcr.setDenature(94.5, 7500); // temp, ms
|
||||
pcr.setAnnealing(54.2, 4000); // temp, ms
|
||||
pcr.setExtension(75.0, 5000); // temp, ms
|
||||
Serial.print("Estimated time (ms): ");
|
||||
pcr.setDenature(94.5, 7.5); // temp, seconds
|
||||
pcr.setAnnealing(54.2, 4.25); // temp, seconds
|
||||
pcr.setExtension(75.0, 5.75); // temp, seconds
|
||||
Serial.print("Estimated time (seconds): ");
|
||||
Serial.println(pcr.timeLeft());
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/RobTillaart/PCR.git"
|
||||
},
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"license": "MIT",
|
||||
"frameworks": "*",
|
||||
"platforms": "*",
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=PCR
|
||||
version=0.2.1
|
||||
version=0.3.0
|
||||
author=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
|
||||
sentence=Arduino library for PCR process control.
|
||||
|
@ -54,8 +54,82 @@ unittest(test_constructor_parameters)
|
||||
{
|
||||
PCR pcr(8,9);
|
||||
|
||||
assertEqual(1, 1);
|
||||
// to elaborate configuration.
|
||||
pcr.setInitial(94, 50);
|
||||
assertEqualFloat(94, pcr.getInitialTemp(), 0.01);
|
||||
assertEqualFloat(50, pcr.getInitialTime(), 0.01);
|
||||
|
||||
pcr.setDenature(93, 30);
|
||||
assertEqualFloat(93, pcr.getDenatureTemp(), 0.01);
|
||||
assertEqualFloat(30, pcr.getDenatureTime(), 0.01);
|
||||
|
||||
pcr.setAnnealing(54, 40);
|
||||
assertEqualFloat(54, pcr.getAnnealingTemp(), 0.01);
|
||||
assertEqualFloat(40, pcr.getAnnealingTime(), 0.01);
|
||||
|
||||
pcr.setExtension(75, 60);
|
||||
assertEqualFloat(75, pcr.getExtensionTemp(), 0.01);
|
||||
assertEqualFloat(60, pcr.getExtensionTime(), 0.01);
|
||||
|
||||
pcr.setElongation(74, 90);
|
||||
assertEqualFloat(74, pcr.getElongationTemp(), 0.01);
|
||||
assertEqualFloat(90, pcr.getElongationTime(), 0.01);
|
||||
|
||||
pcr.setHold(17);
|
||||
assertEqualFloat(17, pcr.getHoldTemp(), 0.01);
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constructor_iterations)
|
||||
{
|
||||
PCR pcr(8,9);
|
||||
|
||||
assertEqual(0, pcr.iterationsLeft());
|
||||
for (int i = 1; i < 10; i++)
|
||||
{
|
||||
pcr.reset(i);
|
||||
assertEqual(i, pcr.iterationsLeft());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constructor_heat_pulse_length)
|
||||
{
|
||||
PCR pcr(8,9);
|
||||
|
||||
assertEqual(10, pcr.getHeatPulseLength());
|
||||
for (int i = 10; i <= 100; i+= 10)
|
||||
{
|
||||
pcr.setHeatPulseLength(i);
|
||||
assertEqual(i, pcr.getHeatPulseLength());
|
||||
}
|
||||
// test constrain
|
||||
pcr.setHeatPulseLength(5000);
|
||||
assertEqual(1000, pcr.getHeatPulseLength());
|
||||
|
||||
pcr.setHeatPulseLength();
|
||||
assertEqual(10, pcr.getHeatPulseLength());
|
||||
|
||||
}
|
||||
|
||||
|
||||
unittest(test_constructor_timeLeft)
|
||||
{
|
||||
PCR pcr(8,9);
|
||||
|
||||
assertEqualFloat(1, pcr.timeLeft(), 0.01);
|
||||
|
||||
pcr.setInitial(94, 50);
|
||||
pcr.setDenature(93, 30);
|
||||
pcr.setAnnealing(54, 40);
|
||||
pcr.setExtension(75, 60);
|
||||
pcr.setElongation(74, 90);
|
||||
pcr.setHold(17);
|
||||
|
||||
// note: zero cycles
|
||||
assertEqualFloat(140, pcr.timeLeft(), 0.1);
|
||||
|
||||
pcr.reset(10);
|
||||
assertEqualFloat(1440, pcr.timeLeft(), 0.1);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user