/*
NTC Thermistor demo using Embedded C
Assumes a 10K@25℃ NTC thermistor connected in series with a 10K resistor.
This is a practice sketch to become better aquanted with ADC control
using an ATTiny85 and Embedded C
*/
#define F_CPU 8000000UL // 8 MHz internal oscillator
#include <avr/io.h>
#include <util/delay.h>
#include <TinyDebug.h>
const float BETA = 3950; // should match the Beta Coefficient of the thermistor
// Pin Definitions
#define POT_PIN PB2 // ADC1
#define GREEN_LED PB1
#define YELLOW_LED PB0
#define RED_LED PB3
void adc_init(void) {
// ADMUX – ADC Multiplexer Selection Register
// Set the ADC reference to Vcc (5V) and select ADC1 (PB2) as input
// Table 17-3. Voltage Reference Selections for ADC
// REFS2:X REFS1:0 REFS0:0 VCC used as Voltage Reference, disconnected from PB0 (AREF).
// (REFS bits default to Vcc in ATtiny85, so we don’t set them explicitly)
ADMUX = (1 << MUX0); // MUX0 = 1 selects ADC1 (PB2)
// ADCSRA – ADC Control and Status Register A
// Enable the ADC, set prescaler to 64 for 125 kHz ADC clock (8,000,000 / 64 = 125,000)
// Ideal ADC clock range is 50–200 kHz for good resolution
ADCSRA = (1 << ADEN) // Bit 7 – ADEN: ADC Enable
| (1 << ADPS2) | (1 << ADPS1); // Prescaler = 64
// DIDR0 – Digital Input Disable Register 0
// Disable digital input buffer on ADC1 (PB2) to reduce power/noise
// Strongly recommended for better ADC readings
DIDR0 = (1 << ADC1D);
}
uint16_t adc_read(void) {
// Bit 6 – ADSC: ADC Start Conversion
// In Single Conversion mode, write this bit to one to start each conversion.
ADCSRA |= (1 << ADSC); // Start conversion
while (ADCSRA & (1 << ADSC)); // Wait for conversion to finish
return ADC; // Return combined ADCL/ADCH value (10-bit), ADCL (low byte) and ADCH (high byte)
}
int main(void) {
Debug.begin();
DDRB |= (1 << GREEN_LED) | (1 << YELLOW_LED) | (1 << RED_LED); // Set LED pins as output
adc_init(); // Initialize the ADC
while(1) {
uint16_t analogValue = adc_read(); // Read analog value (0–1023)
Debug.print("analogValue:"); Debug.println(analogValue);
float celsius = 1 / (log(1 / (1023. / analogValue - 1)) / BETA + 1.0 / 298.15) - 273.15;
float fahrenheit = (celsius * 9.0 / 5.0) + 32.0;
Debug.print("Temperature C: "); Debug.println(celsius);
Debug.print("Temperature F: "); Debug.println(fahrenheit);
if (fahrenheit <= 60.0) {
PORTB |= (1 << GREEN_LED); // Turn GREEN_LED on
PORTB &= ~(1 << YELLOW_LED) & ~(1 << RED_LED); // Turn YELLOW_LED and RED_LED off
}
else if (fahrenheit > 60.0 && fahrenheit < 80.0) {
PORTB |= (1 << YELLOW_LED); // Turn YELLOW_LED on
PORTB &= ~(1 << GREEN_LED) & ~(1 << RED_LED); // Turn GREEN_LED and RED_LED off
}
else {
PORTB |= (1 << RED_LED); // Turn RED_LED on
PORTB &= ~(1 << GREEN_LED) & ~(1 << YELLOW_LED); // Turn GREEN_LED and YELLOW_LED off
}
_delay_ms(200);
}
return 0;
}