Assignment

  1. Use a sensor from the JVC kit or borrowed components to measure a physical quantity using Arduino.
  2. Calibrate the sensor (in a chart or table show how the measured value relates to the indicated value).
  3. Include a circuit diagram and source code (IDF: code snippets) on your website.
  4. Bonus: Build your own capacitive sensor using a piece of conductive material and calibrate it.
  5. For inspiration, check the Arduino Projects Book.

Sensor

For this assignment, I decided to use an NTC thermistor that I had left over from my old Original Prusa MK3 which I upgraded to an MK3.5 late last year.

NTC Thermistor

NTC thermistors are resistors with a negative temperature coefficient, which means that their resistance decreases with increasing temperature. This makes them ideal for measuring temperature.

Usually, NTC thermistors are used in 3D printers to measure the temperature of the hotend and the heated bed. The heatbed thermistor is a glass bead thermistor, which is a type of NTC thermistor that is encapsulated in a glass bead. This type of thermistor is very accurate and has a fast response time.

Thermistor information

For this assignment, I used a thermistor with the following specifications:

*sourced from MK3S configuration in Prusa FW (based on Marlin)

Calibration

Method

I measured 3 different temperatures with the thermistor as well as a control thermometer that I found (a meat thermometer, I didnt have anything else with the same temp range). I stuck both together with aluminum foil so that the temperature difference between the two would be minimal and always left them in the conditions for a long enough time for the temperature to stabilise. 5 minutes at least. I took 5 measurements, restarting the thermometer every time, which also stirred around the liquid it was submerged in for example. Wrote down the resistance of the NTC as well as the temperature. I used a Metex M-3800 digital multimeter.

Measuring conditions

Calibration in ice water bath.
Calibration in ice water bath.
Calibration in hot water bath.
Calibration in hot water bath.

Measurements

Temperature (°C) Resistance (Ω)
1.43 306 400
20.43 121 560
68.26 17 436

How do you temperature?

For thermistors, there are two common methods of calculating the temperature from the resistance:

Steinhart-Hart

As I already have the Beta value from the Marlin firmware documentation, I decided to try the Steinhart-Hart equation first. The Steinhart-Hart equation is a third-order polynomial equation that relates the resistance of the thermistor to the temperature. The equation is as follows:

T = 1/(A + B * ln(R) + C * ln(R)^3)

Where:

To calculate the coefficients, I used the following equations:

Where:

I came across this cool applet that did the calcualtion for me, as I am lazy.

After entering the values, I got the following coefficients:

Beta parameter

For the Beta parameter equation, the equation is as follows:

T = 1/(1/T0 + (1/B) * ln(R/R0))

Where:

The applet automatically calculated this too. These are the values I got:

Which is very close to the values I had from the Marlin firmware documentation. Good way to check its not complete bullshit. Great!

Steinhart-Hart coefficient calculation using the applet.
Steinhart-Hart coefficient calculation using the applet.

Circuit diagram

The usual way to measure the resistance of a thermistor is to use a voltage divider. The voltage divider consists of two resistors in series, one of which is the thermistor the other is a pull-up resistor with a known value. The voltage across the thermistor is measured and used to calculate the resistance.

In the case of me using an Einsy Rambo, the appropriate pin is already set up as an analog input. The pull-up resistor is already built into the board, so I just need to connect the thermistor into one of the 3 temperature slots

Einsy Rambo pinout.
Einsy Rambo pinout.
Thermistor circuit schema.
Thermistor circuit schema.

Source code

The source code is very simple. I used the analogRead function to read the voltage across the thermistor and then used the Steinhart-Hart equation to calculate the temperature. The code is as follows:

// Thermistor readout to serial code: 
#include "pins_EINSY_RAMBO.h" // Include the pin definitions for the Einsy Rambo board, sourced from the Marlin firmware

// For a 100k NTC thermistor with 4.7k pull-up resistor:
const float CELSIUS_TO_KELVIN = 273.15; // Absolute zero in Celsius
const float PULLUP_RES = 4700; // the value of the resistor in series with the thermistor (usually 4.7k)
const float V_REF = 5.0; // Reference voltage for the ADC (usually 5V)

// For Beta thermistor calculations from Marlin:
const float MARLIN_NOMINAL_RES = 100000; // Resistance at 25 degrees C
const float MARLIN_NOMINAL_TEMP_C = 25; // Nominal temperature in Celsius
const float MARLIN_BETA_K = 4092; // The beta coefficient of the thermistor from Marlin

// For Beta thermistor calculation using my own values:
const float NOMINAL_RES = 98000; // Resistance at 25 degrees C
const float NOMINAL_TEMP_C = 25; // Nominal temperature in Celsius
const float BETA_K = 3950; // The beta coefficient of the thermistor

// For Steinhart-Hart calculations:
const float A = 0.0006608622952; // Coefficient A for Steinhart-Hart equation
const float B = 0.0002266935852; // Coefficient B for Steinhart-Hart equation
const float C = 0.00000005819722188; // Coefficient C for Steinhart-Hart equation

void setup()
{
Serial.begin(115200); // Start the serial communication at 115200 baud rate
Serial.println("Thermistor Test");
pinMode(TEMP_0_PIN, INPUT); // Set the thermistor pin as input
}

void loop()
{
// Read the thermistor value from the analog pin
int voltage = analogRead(TEMP_0_PIN); // Read the voltage from the thermistor
float measuredVoltage = voltage * V_REF / 1023.0; // Convert ADC reading to actual voltage
float resistance = (PULLUP_RES * measuredVoltage) / (V_REF - measuredVoltage); // Calculate the resistance of the
thermistor

// Calculate the temperature using the Steinhart-Hart equation
float steinhart = 1.0 / (A +
B * log(resistance) +
C * pow(log(resistance), 3));
steinhart -= CELSIUS_TO_KELVIN; // Convert to Celsius
Serial.print("Temperature from SH-H (C): ");
Serial.println(steinhart);

// Calculate the temperature using the Beta equations
float tempK = 1.0 / (1.0 / (NOMINAL_TEMP_C + CELSIUS_TO_KELVIN) +
(1.0 / BETA_K) * log(resistance / NOMINAL_RES));
tempK -= CELSIUS_TO_KELVIN; // Convert to Celsius
Serial.print("Temperature from Beta (C): ");
Serial.println(tempK);

// Calculate the temperature using the Marlin beta equations
float tempKMarlin = 1.0 / (1.0 / (MARLIN_NOMINAL_TEMP_C + CELSIUS_TO_KELVIN) +
(1.0 / MARLIN_BETA_K) * log(resistance / MARLIN_NOMINAL_RES));
tempKMarlin -= CELSIUS_TO_KELVIN; // Convert to Celsius
Serial.print("Temperature from Marlin Beta (C): ");
Serial.println(tempKMarlin);

delay(1000);
}
                

You can also download the code from the links below, or view it on GitLab. I have included the pin definitions for the Einsy Rambo board in a separate file. The pin definitions are sourced from the Marlin firmware, so they should be correct. I just made file be able to work on its own, so I just deleted conditionals that were used in conjunction with other files and safety checks (like if the board is Einsy Rambo or not).

Test

I tested the code on my Einsy Rambo board and it worked perfectly. I was able to read the temperature from the thermistor and display it on the serial monitor. I also compared the readings with the control beta value sourced from Prusa firmware and they were very close.

Serial output
Serial output
Comparison with the meat thermometer
Comparison with the meat thermometer

As you can see, the readings are very close to the control thermometer. The difference is around 0.5 degree Celsius, which is acceptable for my purposes.

Conclusion

I learned a lot about thermistors and how to use them with Arduino. I also learned how to calibrate them and how to calculate the temperature from the resistance. I also learned how to use the Steinhart-Hart equation and the Beta parameter equation to calculate the temperature. I am very happy with the results.

Most of the time was taken up by studying documentation for the Rambo board. I will probably make a tutorial on how to set that stuff up on a separate page.