>
= Thermometry : Automated data acquisition =
{{{#!wiki note
Note
Based on a page created by Navot Arad and circuits created by Navot and Peter Crew. All programs and circuits by Navot with edits by Alston.}}}
{{{#!wiki important
Important
This page is not meant to be comprehensive. It is assumed that you will have read and created the diode-based digital thermometer using the instructions provided in the [[attachment:scm-coffee_cooling_parts_bc.pdf|Scientific Measurement Thermometery script (parts B & C)]]. Below we provide a brief summary and instructions to automate the data acquisition for this experiment.
}}}
Digital thermometer using a Wheatstone bridge and a DMM. This is calibrated by varying the $200\Omega$ resistance at low temperatures and the $10k\Omega$ resistance at high temperatures such that 1mV corresponds to 1oC.
{{attachment:wheatstone_bridge_schem.png||width=600}}
The Arduino board has analog inputs which have a voltage range of 0V to 5V, to make full use of this range it is necessary to amplify the signal as the values measured across the Wheatstone bridge is in the mV range. To accomplish this we use a pre-built buffered amplifier based on three operational amplifiers, or op-amps. This circuit diagram is shown below.
{{attachment:amplifier_with_notes-scm.png||width=600}}
For the connections see the [[attachment:scm-coffee_cooling_parts_bc.pdf|Thermometry script.]]
The important part here is that all devices (the Wheatstone bridge, the amplifier, the Arduino and the power supply) share the same ground. To ensure this, the Arduino Uno needs to have one of its ground (Gnd) pins connected to the common ground. Without this connection there will be significant errors in the readouts on pins A0 and A1.
[[attachment:OpAmp amplifier for thermometer]]
{{{
/*
OpAmp Thermometer
written by: Navot Arad, Queen Mary University of London
Modified: AJM 23 Oct 2015 to use single input from Peter's new amplifier.
*/
int InputPin = 0; // A0 is the amplified signal pin
float temp = 0; // Variable to store temperature reading
float Voltage10 = 0; // Voltage read using 10 bit ADC
float AmpVoltage = 0;
float G = 50.0; // Amplification factor
float scaleG = 0;
float conversion = 0; // Conversion rate to degrees
float average = 0;
void setup() // Only runs once after board is reset
{
Serial.begin(9600); //Rate at which data is sent to serial monitor
Serial.println("Time Temperature"); // Sends everything inside " " as a string to the serial monitor
}
void loop() // Runs continuously on repeat
{
// average temperature over first second
for (int i = 0; i < 100; i++) {
Voltage10 = analogRead(InputPin); // Read data from input pin (A0) on a 10 bit scale
/*
Navot used an empirical correction to account for amplification changes.
We will not use it with Peter's new amplifiers
scaleG = G + ((temp - 1023) * 1.5 * 0.00147);
conversion = (1023 * scaleG)/50; // conversion factor
AmpVoltage = temp *(100.0/conversion); // Converts signal to temperature
*/
/*
simple voltage conversion:
Voltage10 is a 10bit number from 0 to 1023 (=2^10-1)
Voltage10 = 0 corresponds to 0mV
and Voltage10 = 1023 corresponds to 100 mV, so the conversion from Voltage10 to
a reading in mV is:
V = Voltage10 * 100 / 1023
This gives us V in mV. As this is also the temperature in Centigrade, we have T = V.
*/
temp = Voltage10*(100.0/1023.0); // Converts signal to the amp voltage in mV == temperature
average = average + temp;
delay(10);
}
Serial.print(millis()/1000); // Sends value stored on AmpVoltage
// to serial monitor and starts new line
Serial.print(" ");
average = average/100;
Serial.println(average,1);
average = 0;
delay(29000); // 29 second delay before loop runs again
}
}}}
{{{#!wiki important
Important
If the above code doesn't work, use the following code.
}}}
[[attachment:OpAmp amplifier for thermometer : One input code : old version]]
{{{
/*
OpAmp Thermometer
written by: Navot Arad, Queen Mary University of London
*/
int opAmp = 0; // A0 is the amplified signal pin
int ground = 1; // A1 is the ground pin
float temp0 = 0, temp1 = 0;// Variable to store data from pin A0
float temp = 0;
float AmpVoltage = 0; // Use float to convert data from A0 to voltage
float G = 50.0; // Amplification factor
float scaleG = 0;
float conversion = 0; // Conversion rate to degrees
float average = 0;
void setup() // Only runs once after board is reset
{
Serial.begin(9600); //Rate at which data is sent to serial monitor
Serial.println("Time Temperature"); // Sends everything inside " " as a string to the serial monitor
}
void loop() // Runs continuously on repeat
{
// average temperature over first second
for (int i = 0; i < 100; i++) {
temp0 = analogRead(opAmp); // Read data from pin A0 on a 10 bit scale
//temp1 = analogRead(ground); // Same for pin A1
temp = abs(temp0 - temp1);
scaleG = G + ((temp - 1023) * 1.5 * 0.00147);
conversion = (1023 * scaleG)/50; // conversion factor
AmpVoltage = temp *(100.0/conversion); // Converts signal to temperature
average = average + AmpVoltage;
delay(10);
}
Serial.print(millis()/1000); // Sends value stored on AmpVoltage
// to serial monitor and starts new line
Serial.print(" ");
average = average/100;
Serial.println(average,1);
average = 0;
delay(2000); // 29 second delay before loop runs again
}
}}}
= Other Stuff : Do not use =
[[attachment:OpAmp amplifier for thermometer : Two input code]]
{{{
/*
OpAmp Thermometer
written by: Navot Arad, Queen Mary University of London
*/
int opAmp = 0; // A0 is the amplified signal pin
int ground = 1; // A1 is the ground pin
float temp0 = 0, temp1 = 0;// Variable to store data from pin A0
float temp = 0;
float AmpVoltage = 0; // Use float to convert data from A0 to voltage
float G = 50.0; // Amplification factor
float scaleG = 0;
float conversion = 0; // Conversion rate to degrees
float average = 0;
void setup() // Only runs once after board is reset
{
Serial.begin(9600); //Rate at which data is sent to serial monitor
Serial.println("Time Temperature"); // Sends everything inside " " as a string to the serial monitor
}
void loop() // Runs continuously on repeat
{
// average temperature over first second
for (int i = 0; i < 100; i++) {
temp0 = analogRead(opAmp); // Read data from pin A0 on a 10 bit scale
temp1 = analogRead(ground); // Same for pin A1
temp = abs(temp0 - temp1);
scaleG = G + ((temp - 1023) * 1.5 * 0.00147);
conversion = (1023 * scaleG)/50; // conversion factor
AmpVoltage = temp *(100.0/conversion); // Converts signal to temperature
average = average + AmpVoltage;
delay(10);
}
Serial.print(millis()/1000); // Sends value stored on AmpVoltage
// to serial monitor and starts new line
Serial.print(" ");
average = average/100;
Serial.println(average,1);
average = 0;
delay(29000); // 29 second delay before loop runs again
}
}}}
[[attachment:Older code]]
{{{
/*
OpAmp Thermometer
written by: Navot Arad, Queen Mary University of London
*/
int opAmp = 0; // Set a variable to read the analogue input to pin A0
int diode = 1;
int R10 = 4700, R11 = 10000, R12 = 300;
float lowlim = 0, uplim = 0;
int temp = 0, temp1 = 0; // Variable to store data from pin A0
float AmpVoltage = 0; // Use float to convert data from A0 to voltage
float G = 0, scaleG = 0; // Amplification factor;
float conversion = 0; // Conversion rate to degrees
float average = 0;
void setup() // Only runs once after board is reset
{
Serial.begin(9600); //Rate at which data is sent to serial monitor
G = (R10 + R11 + R12) / R12;
lowlim = G * 0.98;
uplim = G * 0.99;
Serial.println("Time Temperature"); // Sends everything inside " " as a string to the serial monitor
}
void loop() // Runs continuously on repeat
{
// average temperature over first second
for (int i = 0; i < 100; i++) {
temp = analogRead(opAmp); // Read data from pin A0 on a 10 bit scale
temp1 = analogRead(diode);
temp = abs(temp - temp1);
scaleG = G + ((temp - 1023) * ((uplim - lowlim) * 0.00167));
constrain(scaleG, lowlim, uplim);
conversion = (1023 * scaleG)/50; // conversion factor
AmpVoltage = temp *(100.0/conversion); // Converts signal to temperature
average = average + AmpVoltage;
delay(10);
}
Serial.print(millis()/1000); // Sends value stored on AmpVoltage to serial monitor and starts new line
Serial.print(" ");
average = average/100;
Serial.println(average, 1);
average = 0;
delay(29000); // 29 second delay before loop runs again
}
}}}
This will read out the temperature to the serial monitor in degrees celsius.
== Sample Data ==
Below is a series of tables comparing the readings between a mercury thermometer, DMM which has been calibrated such that 1mV corresponds to 1oC, and the arduino.
|| Time(s) || Thermometer (oC) || DMM (oC) || Arduino (oC) ||
|| 0 || 21.5 || 21.4 || 21.5 ||
|| 1 || 21.5 || 21.4 || 21.5 ||
|| 2 || 21.5 || 21.4 || 21.5 ||
|| 3 || 21.5 || 21.4 || 21.5 ||
|| 4 || 21.5 || 21.4 || 21.4 ||
|| 5 || 21.5 || 21.4 || 21.5 ||
|| 6 || 21.5 || 21.4 || 21.4 ||
|| 7 || 21.5 || 21.4 || 21.5 ||
|| 8 || 21.5 || 21.4 || 21.5 ||
|| 9 || 21.5 || 21.4 || 21.5 ||
|| 10 || 21.5 || 21.4 || 21.4 ||
|| 11 || 21.5 || 21.4 || 21.4 ||
|| 12 || 21.5 || 21.4 || 21.5 ||
|| 13 || 21.5 || 21.4 || 21.4 ||
|| 14 || 21.5 || 21.4 || 21.5 ||
|| 15 || 21.5 || 21.4 || 21.5 ||
|| Time(s) || Thermometer (oC) || DMM (oC) || Arduino (oC) ||
|| 0 || 50.0 || 50.0 || 50.0 ||
|| 30 || 50.0 || 49.5 || 49.6 ||
|| 60 || 49.5 || 49.2 || 49.3 ||
|| 90 || 49.0 || 48.8 || 48.8 ||
|| 120 || 49.0 || 48.6 || 48.6 ||
|| 150 || 48.5 || 48.2 || 48.2 ||
|| 180 || 47.5 || 47.7 || 47.9 ||
|| 210 || 47.5 || 47.6 || 47.6 ||
|| 240 || 47.5 || 47.2 || 47.3 ||
|| 270 || 47.0 || 46.9 || 47.0 ||
|| 300 || 47.0 || 46.6 || 46.6 ||
|| 330 || 46.5 || 46.3 || 46.3 ||
|| 360 || 46.5 || 46.0 || 46.1 ||
|| 390 || 46.0 || 45.7 || 45.8 ||
|| 420 || 45.5 || 45.4 || 45.5 ||
|| Time(s) || Thermometer (oC) || DMM (oC) || Arduino (oC) ||
|| 0 || 71.0 || 71.4 || 70.9 ||
|| 30 || 69.0 || 70.1 || 69.9 ||
|| 60 || 68.5 || 69.2 || 68.9 ||
|| 90 || 68.0 || 68.3 || 68.1 ||
|| 120 || 67.0 || 67.5 || 67.2 ||
|| 150 || 67.0 || 66.7 || 66.4 ||
|| 180 || 66.0 || 66.0 || 65.7 ||
|| 210 || 65.5 || 65.2 || 64.9 ||
|| 240 || 64.5 || 64.4 || 64.2 ||
|| 270 || 64.0 || 63.8 || 63.5 ||
|| 300 || 63.0 || 63.1 || 62.8 ||
|| 330 || 62.5 || 62.3 || 62.1 ||
|| 360 || 62.0 || 61.7 || 61.5 ||
|| 390 || 61.0 || 61.1 || 60.9 ||
|| 420 || 60.5 || 60.5 || 60.3 ||