AdSense

Monday 20 May 2013

ATMega - Temperature measurement with the DS18S20

(Deutsche Version) To measure the temperature in my room, I use a DS18S20, this is a 3-pin temperature sensor (looks like a transistor) and an ATMega 8 to read the temperature digitally. The precision is ± 0.5 °C. The sensor has the following pins: Vcc(+5V), Gnd and the data pin. Further information about the communication is provided in the data sheet. In my application, PORTD0 is an output and PORTD2 is an input. Both pins are connected to the data pin of the sensor. Here is the code i use to read the temperature:

void on()
{
  PORTD |= (1 << PORTD0);
}

void off()
{
  PORTD &= ~ (1 << PORTD0);
}

void write(int hilow)
{
  if (hilow == 0)
  {
   off();
   _delay_us(80);
   on();
   _delay_us(20);
  }
  else
  {
   off();
   _delay_us(5);
   on();
   _delay_us(95);
  }
}

void read()
{
  off();
  _delay_us(2);
  on();
  _delay_us(98);
}

double read0()
{
  double retVal = 0;
  off();
  _delay_us(2);
  on();
  _delay_us(1);
  if (PIND & (1 << PIND2)) //HIGH
  {
    retVal = 1;
  }
  else
  {
    retVal = 0;
  }
  _delay_us(97);
  return retVal;
}


double measureTemp()
{
  double temp = 0;
  double fac = 0.5;
  double neg = 0;
  double value = 0;

  off();
  _delay_us(500);
  on();
  _delay_us(1000);

  write(0);
  write(0);
  write(1);
  write(1);
  write(0);
  write(0);
  write(1);
  write(1);

  _delay_us(100);
  //Start temperature conversion
  write(0);
  write(0);
  write(1);
  write(0);
  write(0);
  write(0);
  write(1);
  write(0);

  _delay_us(1000);

  off();
  _delay_us(500);
  on();
  _delay_us(1000);

  write(0);
  write(0);
  write(1);
  write(1);
  write(0);
  write(0);
  write(1);
  write(1);

  _delay_us(100);
  //read Temperature
  write(0);
  write(1);
  write(1);
  write(1);
  write(1);
  write(1);
  write(0);
  write(1);

  value = read0();

  temp += fac * value; fac = fac*2; 
  bits[0] = value;

  value = read0();
  temp += fac * value; fac = fac*2;
  bits[1] = value;

  value = read0();
  temp += fac * value; fac = fac*2;
  bits[2] = value;

  value = read0();
  temp += fac * value; fac = fac*2;
  bits[3] = value;

  value = read0();
  temp += fac * value; fac = fac*2;
  bits[4] = value;

  value = read0();
  temp += fac * value; fac = fac*2; 
  bits[5] = value;

  value = read0();
  temp += fac * value; fac = fac*2;
  bits[6] = value;

  value = read0(); 
  temp += fac * value;  bits[7] = value;
  //The last bit is irrelevant if count_remain is involved.

  neg = read0();
  read();
  read(); 
  read();
  read();
  read(); 
  read();
  read();

  //TH 
  read(); 
  read(); 
  read(); 
  read();
  read(); 
  read();
  read();
  read();

  //TL 
  read(); 
  read();
  read();
  read(); 
  read();
  read(); 
  read(); 
  read();

  //Reserved 
  read(); 
  read(); 
  read(); 
  read(); 
  read(); 
  read(); 
  read(); 
  read();

  //Reserved
  read();
  read(); 
  read(); 
  read(); 
  read(); 
  read(); 
  read(); 
  read();

  //COUNT REMAIN 
  count_remain[0] = read0(); 
  count_remain[1] = read0();
  count_remain[2] = read0();
  count_remain[3] = read0();
  count_remain[4] = read0(); 
  count_remain[5] = read0(); 
  count_remain[6] = read0(); 
  count_remain[7] = read0();

  //COUNT PER °C 
  count_per_c[0] = read0(); 
  count_per_c[1] = read0();
  count_per_c[2] = read0(); 
  count_per_c[3] = read0(); 
  count_per_c[4] = read0(); 
  count_per_c[5] = read0(); 
  count_per_c[6] = read0(); 
  count_per_c[7] = read0(); 

  //CRC 
  read(); 
  read();
  read();
  read();
  read(); 
  read(); 
  read(); 
  read();

  //You can increase the precision if you use count_remain

  return temp;

}


No comments:

Post a Comment