Video
# Lab: NTC Thermistor Sensor - Temperature Monitoring
## Objective
Learn to read temperature values from the TinkerBlock TK12 NTC Thermistor Sensor module. The sensor uses an NTC 3950 thermistor that changes resistance with temperature, providing analog output that increases as temperature rises. This lab introduces temperature sensing concepts and demonstrates how to read and display thermistor data.
## Learning Outcomes
- Understand NTC thermistor operation and temperature sensing
- Learn about negative temperature coefficient (NTC) behavior
- Master analogRead() function for temperature sensor input
- Create responsive temperature monitoring systems
- Use Serial communication for temperature value monitoring
- Understand resistance-temperature relationships
## Required Components

1. **Lonely Binary UNO R3** - Main Arduino board
2. **TinkerBlock UNO R3 Shield** - Expansion shield that plugs onto the UNO R3
3. **TinkerBlock TK12 - NTC Thermistor Sensor** - Temperature sensor module with 4-pin connector
## Theory
### NTC Thermistor Concepts
- **NTC (Negative Temperature Coefficient)**: Resistance decreases as temperature increases
- **Thermistor**: Temperature-sensitive resistor
- **NTC 3950**: Specific thermistor type with B-value of 3950K
- **Temperature Range**: Typically -40°C to +125°C
- **Accuracy**: ±0.5°C to ±2°C depending on calibration
### NTC Thermistor Operation
- **Resistance Change**: High resistance at low temperatures, low resistance at high temperatures
- **Non-linear Response**: Exponential relationship between resistance and temperature
- **B-Value**: Characterizes the thermistor's temperature sensitivity (3950K for this sensor)
- **Response Time**: Typically 1-10 seconds for temperature changes
- **Self-Heating**: Minimal due to low current operation
### Temperature-Resistance Relationship
```
R(T) = R0 × exp[B × (1/T - 1/T0)]
```
- **R(T)**: Resistance at temperature T
- **R0**: Reference resistance at temperature T0
- **B**: B-value (3950K for NTC 3950)
- **T**: Current temperature in Kelvin
- **T0**: Reference temperature in Kelvin
### Voltage Division Principle
```
Vout = Vin × (R2 / (R1 + R2))
```
- **Vin**: 5V (supply voltage)
- **R1**: NTC thermistor (variable resistance based on temperature)
- **R2**: Fixed resistor (voltage divider)
- **Vout**: Variable output voltage (0-5V)
### Key Functions Used
- `pinMode(pin, mode)`: Configures a pin as input or output
- `analogRead(pin)`: Reads analog value from specified pin (0-1023)
- `Serial.begin(baud)`: Initializes serial communication
- `Serial.print()` and `Serial.println()`: Outputs data to Serial Monitor
- `delay(milliseconds)`: Pauses the program for a specified time
- `map(value, fromLow, fromHigh, toLow, toHigh)`: Maps values between ranges
## Circuit Diagram

## Connection Instructions
1. **Assemble the Hardware:**
- Place the TinkerBlock UNO R3 Shield onto the Lonely Binary UNO R3
- Ensure all pins are properly aligned and seated
- The shield should fit snugly on top of the Arduino board
2. **Connect the Thermistor Module:**
- Take the TinkerBlock TK12 - NTC Thermistor Sensor module
- Align the 4-pin connector with any available 4-pin slot on the shield
- Gently push the module into the slot until it clicks into place
- The module will automatically connect:
- **GND** pin to ground
- **VCC** pin to 5V power
- **NC** pin remains unconnected
- **Signal** pin to analog pin A1
3. **Important Notes:**
- No breadboard or jumper wires required
- The TK12 sensor has a built-in voltage divider circuit
- The sensor provides smooth analog output based on temperature
- Multiple 4-pin slots are available on the shield for expansion
- The NTC 3950 thermistor is highly sensitive to temperature changes
## Code
```cpp
// Lab: NTC Thermistor Sensor - Basic Temperature Detection
// Temperature sensor connected to analog pin A1
// Define the analog pin
const int tempSensorPin = A1; // Temperature sensor input pin
// Variables for reading and processing
int tempValue = 0; // Raw analog value (0-1023)
int tempValueMapped = 0; // Mapped value (0-100)
float voltage = 0.0; // Calculated voltage (0-5V)
float temperatureC = 0.0; // Temperature in Celsius
int tempLevel = 0; // Temperature level category (0-4)
// Smoothing variables
const int numReadings = 10;
int readings[numReadings];
int readIndex = 0;
int total = 0;
void setup() {
// Configure temperature sensor pin as input (optional for analog pins)
pinMode(tempSensorPin, INPUT);
// Initialize serial communication for monitoring
Serial.begin(9600);
Serial.println("NTC Thermistor Sensor Lab Started");
Serial.println("Monitor temperature changes with the sensor");
Serial.println("----------------------------------------");
Serial.println("Format: Raw | Mapped | Voltage | Temp(°C) | Level");
Serial.println("----------------------------------------");
// Initialize smoothing array
for (int i = 0; i < numReadings; i++) {
readings[i] = 0;
}
}
void loop() {
// Read the analog value from the temperature sensor
tempValue = analogRead(tempSensorPin);
// Apply smoothing to reduce noise
tempValue = smoothReading(tempValue);
// Map the value to different ranges for demonstration
tempValueMapped = map(tempValue, 0, 1023, 0, 100);
// Calculate voltage (assuming 5V reference)
voltage = (tempValue * 5.0) / 1023.0;
// Calculate temperature in Celsius
temperatureC = calculateTemperatureC(tempValue);
// Determine temperature level category
tempLevel = determineTempLevel(tempValue);
// Display the values
Serial.print("Raw: ");
Serial.print(tempValue);
Serial.print(" | Mapped: ");
Serial.print(tempValueMapped);
Serial.print("% | Voltage: ");
Serial.print(voltage, 2);
Serial.print("V | Temp: ");
Serial.print(temperatureC, 1);
Serial.print("°C | Level: ");
Serial.print(tempLevel);
Serial.print(" | ");
// Display temperature level description
switch(tempLevel) {
case 0:
Serial.println("Very Cold");
break;
case 1:
Serial.println("Cold");
break;
case 2:
Serial.println("Cool");
break;
case 3:
Serial.println("Warm");
break;
case 4:
Serial.println("Hot");
break;
default:
Serial.println("Unknown");
break;
}
// Small delay to make the output readable
delay(500);
}
// Function to smooth analog readings
int smoothReading(int newReading) {
// Subtract the last reading
total = total - readings[readIndex];
// Read from the sensor
readings[readIndex] = newReading;
// Add the reading to the total
total = total + readings[readIndex];
// Advance to the next position in the array
readIndex = (readIndex + 1) % numReadings;
// Return the average
return total / numReadings;
}
// Function to calculate temperature in Celsius
float calculateTemperatureC(int sensorValue) {
// NTC 3950 thermistor temperature calculation based on TK12 schematic
// Circuit: NTC (R4) to VCC, 10kΩ (R7) to GND, signal from junction
// Convert ADC value to voltage
float voltage = (sensorValue * 5.0) / 1023.0;
// Calculate NTC resistance using voltage divider formula
// V_signal = VCC * R_fixed / (R_NTC + R_fixed)
// R_NTC = R_fixed * (VCC - V_signal) / V_signal
float resistance = (10000.0 * (5.0 - voltage)) / voltage;
// NTC 3950 temperature calculation using B-parameter equation
// R0 = 10kΩ at T0 = 25°C, B = 3950K
float temperatureK = 1.0 / ((log(resistance / 10000.0) / 3950.0) + (1.0 / 298.15));
float temperatureC = temperatureK - 273.15;
// Clamp temperature to reasonable range
if (temperatureC < -40.0) temperatureC = -40.0;
if (temperatureC > 125.0) temperatureC = 125.0;
return temperatureC;
}
// Function for temperature calibration (optional)
float calibrateTemperature(int sensorValue, float knownTemp) {
// Simple calibration function
// Use this when you have a known temperature reference
// Example: calibrateTemperature(456, 25.0) for room temperature
// Calculate offset based on known temperature
float calculatedTemp = calculateTemperatureC(sensorValue);
float offset = knownTemp - calculatedTemp;
Serial.print("Calibration: Known temp = ");
Serial.print(knownTemp);
Serial.print("°C, Calculated = ");
Serial.print(calculatedTemp);
Serial.print("°C, Offset = ");
Serial.print(offset);
Serial.println("°C");
return calculatedTemp + offset;
}
// Function to determine temperature level category
int determineTempLevel(int sensorValue) {
if (sensorValue < 200) {
return 0; // Very Cold
} else if (sensorValue < 400) {
return 1; // Cold
} else if (sensorValue < 600) {
return 2; // Cool
} else if (sensorValue < 800) {
return 3; // Warm
} else {
return 4; // Hot
}
}
```
## Code Explanation
### Setup Function
```cpp
void setup() {
pinMode(tempSensorPin, INPUT);
Serial.begin(9600);
}
```
- Configures analog pin A1 as input for temperature sensor
- Initializes serial communication for value monitoring
- Sets up smoothing array for noise reduction
### Main Loop Logic
```cpp
void loop() {
tempValue = analogRead(tempSensorPin);
tempValue = smoothReading(tempValue);
tempValueMapped = map(tempValue, 0, 1023, 0, 100);
voltage = (tempValue * 5.0) / 1023.0;
tempLevel = determineTempLevel(tempValue);
}
```
**Temperature Sensor Reading:**
- `analogRead(tempSensorPin)`: Reads raw temperature sensor value (0-1023)
- **Low values**: Cold temperatures (high resistance)
- **High values**: Hot temperatures (low resistance)
- **Smoothing**: Reduces noise and fluctuations
**Value Processing:**
- **Mapping**: Converts to percentage (0-100%)
- **Voltage Calculation**: Shows actual voltage across sensor
- **Level Classification**: Categorizes temperature intensity
### Smoothing Function
```cpp
int smoothReading(int newReading) {
total = total - readings[readIndex];
readings[readIndex] = newReading;
total = total + readings[readIndex];
readIndex = (readIndex + 1) % numReadings;
return total / numReadings;
}
```
- **10-point moving average**: Reduces noise and jitter
- **Stable readings**: Smooth transitions between temperature levels
- **Responsive**: Still responds to temperature changes
### Temperature Calculation Function
```cpp
float calculateTemperatureC(int sensorValue) {
// NTC 3950 thermistor temperature calculation based on TK12 schematic
// Circuit: NTC (R4) to VCC, 10kΩ (R7) to GND, signal from junction
// Convert ADC value to voltage
float voltage = (sensorValue * 5.0) / 1023.0;
// Calculate NTC resistance using voltage divider formula
// V_signal = VCC * R_fixed / (R_NTC + R_fixed)
// R_NTC = R_fixed * (VCC - V_signal) / V_signal
float resistance = (10000.0 * (5.0 - voltage)) / voltage;
// NTC 3950 temperature calculation using B-parameter equation
// R0 = 10kΩ at T0 = 25°C, B = 3950K
float temperatureK = 1.0 / ((log(resistance / 10000.0) / 3950.0) + (1.0 / 298.15));
float temperatureC = temperatureK - 273.15;
return temperatureC;
}
```
**Temperature Calculation:**
- **Accurate Circuit Model**: Based on TK12 schematic with 10kΩ voltage divider
- **Correct Mapping**: Higher ADC values = higher temperatures (as NTC resistance decreases)
- **Steinhart-Hart Equation**: Precise NTC 3950 temperature calculation
- **Temperature Range**: -40°C to +125°C (clamped to reasonable range)
- **Reference Values**: R0 = 10kΩ at T0 = 25°C, B = 3950K
### Temperature Level Classification
```cpp
int determineTempLevel(int sensorValue) {
if (sensorValue < 200) return 0; // Very Cold
else if (sensorValue < 400) return 1; // Cold
else if (sensorValue < 600) return 2; // Cool
else if (sensorValue < 800) return 3; // Warm
else return 4; // Hot
}
```
**Temperature Level Categories:**
- **Level 0 (0-199)**: Very Cold - Freezing temperatures
- **Level 1 (200-399)**: Cold - Low temperatures
- **Level 2 (400-599)**: Cool - Moderate temperatures
- **Level 3 (600-799)**: Warm - Elevated temperatures
- **Level 4 (800-1023)**: Hot - High temperatures
### Key Variables
- **tempValue**: Raw temperature sensor reading (0-1023)
- **tempValueMapped**: Percentage value (0-100)
- **voltage**: Calculated voltage (0-5V)
- **temperatureC**: Temperature in degrees Celsius
- **tempLevel**: Categorized temperature level (0-4)
- **readings[]**: Array for smoothing calculations
### Value Ranges
- **Raw ADC**: 0-1023 (10-bit resolution)
- **Mapped**: 0-100 (percentage)
- **Voltage**: 0.00-5.00V (2 decimal places)
- **Temperature**: -40°C to +125°C (approximate range)
- **Temperature Level**: 0-4 (categorized levels)
## Testing and Verification
1. **Upload the code to Lonely Binary UNO R3**
2. **Open Serial Monitor** in Arduino IDE (Tools → Serial Monitor)
3. **Test different temperature conditions:**
- **Cold test**: Place sensor in cold environment, should show lower values
- **Warm test**: Warm the sensor with your hand, should show higher values
- **Room temperature**: Normal ambient conditions
- **Heat test**: Expose to heat source, should show highest values
4. **Verify value ranges:**
- **Raw values**: 0-1023
- **Mapped values**: 0-100%
- **Voltage**: 0.00-5.00V
- **Temperature**: -40°C to +125°C (approximate)
- **Temperature levels**: 0-4 with appropriate descriptions
5. **Verify connections:**
- Ensure the TK12 module is firmly connected to the shield
- Check that the shield is properly seated on the Arduino
- Confirm the sensor responds to temperature changes
## Troubleshooting
### Temperature sensor doesn't respond:
- Check if the TinkerBlock shield is properly seated on the Arduino
- Ensure the TK12 module is firmly connected to the shield
- Verify the module is connected to a slot that uses A1 pin
- Check if code uploaded successfully to the Lonely Binary UNO R3
- Open Serial Monitor to see if values are being read
### Values not changing with temperature:
- Check if the sensor is exposed to temperature changes
- Verify the module is connected to analog pin A1
- Check Serial Monitor output to see if readings are stable
- Ensure the sensor surface is clean and unobstructed
- Try warming or cooling the sensor with your hand
### Values jumping or unstable:
- Check if the module is properly seated in the shield
- Verify all pins are making good contact
- Try reconnecting the module to a different 4-pin slot
- Check for loose connections or bent pins
- Increase smoothing by changing `numReadings` to a higher value
### Values not in expected range:
- Check if the sensor is properly exposed to temperature changes
- Verify the mapping calculations are correct
- Ensure the reference voltage is 5V
- Try calibrating the sensor for your specific temperature range
### Temperature readings seem incorrect:
- Verify the sensor is properly connected and not affected by heat sources
- Check if the reference voltage is exactly 5V
- Use the calibration function with a known temperature reference for fine-tuning
- Example: If room temperature is 22°C but sensor shows 24°C, use calibration
- The calculation is now based on the actual TK12 circuit schematic
### Serial Monitor shows no output:
- Ensure Serial Monitor is set to 9600 baud rate
- Check that Serial.begin(9600) is in setup()
- Verify the correct COM port is selected in Arduino IDE
## Experiment Variations
### 1. Temperature-Dependent Actions
Add actions based on temperature levels:
```cpp
void loop() {
int tempValue = analogRead(tempSensorPin);
int tempLevel = determineTempLevel(tempValue);
switch(tempLevel) {
case 0: // Very Cold
Serial.println("Freezing conditions detected");
break;
case 1: // Cold
Serial.println("Cold conditions detected");
break;
case 2: // Cool
Serial.println("Cool conditions detected");
break;
case 3: // Warm
Serial.println("Warm conditions detected");
break;
case 4: // Hot
Serial.println("Hot conditions detected");
break;
}
delay(1000);
}
```
### 2. Temperature Threshold Detection
Add threshold-based monitoring:
```cpp
const int COLD_THRESHOLD = 300;
const int HOT_THRESHOLD = 700;
bool wasCold = false;
bool wasHot = false;
void loop() {
int tempValue = analogRead(tempSensorPin);
// Detect transitions
if (tempValue < COLD_THRESHOLD && !wasCold) {
Serial.println("Temperature dropped - entering cold mode");
wasCold = true;
wasHot = false;
} else if (tempValue > HOT_THRESHOLD && !wasHot) {
Serial.println("Temperature increased - entering hot mode");
wasHot = true;
wasCold = false;
}
delay(100);
}
```
### 3. Temperature Data Logging
Add data logging functionality:
```cpp
unsigned long startTime = 0;
int readingCount = 0;
void setup() {
// ... existing setup code ...
startTime = millis();
}
void loop() {
int tempValue = analogRead(tempSensorPin);
unsigned long currentTime = millis();
// Log data every 10 readings
if (readingCount % 10 == 0) {
Serial.print("Time: ");
Serial.print((currentTime - startTime) / 1000);
Serial.print("s | Temp: ");
Serial.print(tempValue);
Serial.print(" | Level: ");
Serial.println(determineTempLevel(tempValue));
}
readingCount++;
delay(100);
}
```
### 4. Temperature Calibration
Add calibration functionality:
```cpp
int minTempValue = 1023;
int maxTempValue = 0;
bool calibrated = false;
void loop() {
int tempValue = analogRead(tempSensorPin);
if (!calibrated) {
// Update min and max values
if (tempValue < minTempValue) minTempValue = tempValue;
if (tempValue > maxTempValue) maxTempValue = tempValue;
Serial.print("Calibrating... Min: ");
Serial.print(minTempValue);
Serial.print(" Max: ");
Serial.println(maxTempValue);
// Calibrate for 10 seconds
if (millis() > 10000) {
calibrated = true;
Serial.println("Calibration complete!");
}
} else {
// Use calibrated range
int calibratedValue = map(tempValue, minTempValue, maxTempValue, 0, 100);
Serial.print("Calibrated temperature: ");
Serial.print(calibratedValue);
Serial.println("%");
}
delay(500);
}
```
## Questions for Understanding
1. How does an NTC thermistor change resistance with temperature?
2. What is the B-value and what does it represent?
3. Why do we use smoothing for temperature sensor readings?
4. How does the voltage divider circuit work in the temperature sensor?
5. What are the advantages of categorizing temperature levels?
6. How would you modify the code to detect sudden temperature changes?
7. What are the limitations of using an NTC thermistor for temperature sensing?
## Next Steps
- Try connecting the temperature sensor to control other devices based on temperature
- Experiment with different temperature sources and their effects on readings
- Learn about other temperature sensors (thermocouples, RTDs, digital sensors)
- Explore other TinkerBlock sensor modules for environmental monitoring
- Try creating temperature-based automation systems
- Implement temperature logging and trend analysis
## Safety Notes
- Always disconnect power before connecting or disconnecting modules
- Handle the TinkerBlock shield and modules carefully to avoid bending pins
- Ensure proper alignment when connecting modules to prevent damage
- The built-in voltage divider in the module prevents component damage
- Keep the Lonely Binary UNO R3 and shield in a stable position during operation
- Do not apply voltages higher than 5V to analog inputs
- Avoid exposing the sensor to temperatures beyond its specified range
---
**Lab Completion Checklist:**
- [ ] TinkerBlock shield properly seated on Lonely Binary UNO R3
- [ ] TK12 NTC Thermistor Sensor module connected to shield (A1)
- [ ] Code uploaded successfully to Lonely Binary UNO R3
- [ ] Temperature sensor responds to temperature changes
- [ ] Raw values range from 0-1023
- [ ] Mapped values range from 0-100%
- [ ] Voltage calculation shows 0.00-5.00V
- [ ] Temperature calculation in Celsius works correctly
- [ ] Temperature level categorization works correctly
- [ ] Serial Monitor displays all values correctly
- [ ] Values change smoothly with temperature changes
- [ ] Troubleshooting completed (if needed)
- [ ] Experiment variations tried
- [ ] Questions answered