Monday, December 14, 2015

Using an ATTiny85 to control a relay based on an LM34 temperature reading

The following code uses an ATTiny85 to turn a relay on and off based on a temperature reading from the LM34 temperature sensor. I used this to turn a freezer on and off to help save energy and to prevent the freezer from actually freezing anything.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/*
 * LM34.c
 *
 * Created: 4/13/2015 10:35:05 PM
 *  Author: Jacob
 */


#include <avr/io.h>
#include <util/delay.h>

#define relay PB1 //The relay is connected to PB1 on the ATTiny85
#define led PB0 //The indicator LED is connect to PB0 on the ATTiny85

void ledAlert() //Function used to blink the LED at a fast pulse, used for alerting user if there is an error with the cooling system
{
 PORTB ^= (1 << led); //Toggle the LED
 _delay_ms(250); //LED state changes every 250 milliseconds
}

void initADC() {
 
 DDRB |= (1 << relay); //Sets the relay pin as an output
 DDRB |= (1 << led); //Sets the led pin as an output
 
 ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
 //Setting a 1 to "ADEN" enables the ADC feature
 //Setting a 1 to "ADPS2, ADPS1, ADPS0" sets the pre-scaler to divide the clock by 128
 ADMUX |= (0<<REFS0)|(0<<REFS1); //Reference = Vcc
 ADMUX |= (1<<ADLAR); //Left adjust ADC results
 ADMUX |= (1<<MUX1); //Select ADC3 (pin 2)
 ADMUX |= (1<<MUX0); //Select ADC3 (pin 2)
 ADCSRA |= (1 << ADATE); //Free running mode
 ADCSRB &= ~((1<<ADTS2)|(1<<ADTS1)|(1<<ADTS0)); //First three bits of ADCSRB needs to be 000 to select free running mode
 ADCSRA |= (1<<ADEN); //Completes the initialization of ADC
 ADCSRA |= (1<<ADSC); //Start ADC conversions
  
}

int main(void)
{
 initADC(); //Initialize the registers so the ATTiny85 can perform Analog to Digital Conversions
    while(1)
 {
  if(ADCH > 19) //(19/255) * 5 = 39.2 degrees //If the temperature is above 39 degrees, Turn the relay and led on
  {
   PORTB |= (1 << relay);
   PORTB |= (1 << led);
   while(ADCH > 18); //35.3 //While the temperature is greater than 35 degrees, stay here to temporarily lock it in place
  }
  else //If the temperature is below 39 degrees, turn the relay off so the beer doesn't freeze
  {
   PORTB &= (0 << relay); //Turn relay off if the temperature is acceptable (below 38 degrees)
   PORTB &= (0 << led); //Turn led off if the temperature is acceptable (below 38 degrees)
  }
    }
}
 
/*
8 bit value to degrees F
15 -> 29.4
16 -> 31.3
17 -> 33.3
18 -> 35.3
19 -> 37.2
20 -> 39.2
21 -> 41.1
22 -> 43.1
23 -> 45.1
*/


I don't have a wiring diagram or pictures to show as I no longer need this project. But this is a good example to show how to read an analog input into the ATTiny85 using the ADC.