<> = 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 ||