Wednesday, January 12, 2011

Temperature and Humidity Sensor on Arduino

I already posted about connecting a temperature sensor to the Arduino, but I wanted to use the opportunity to introduce a small combo board. The SHT15 mini board from sparkfun. They made a convenient mini board to easily access the SHT15 sensor from sensirion, which is well documented. After soldering on a connector for the breadboard, I found a blog post which provided a good working source code to access the data. I changed it only slightly because it already provided the access methods to get the data from the sensor.

The setup is trivial but here it is anyway:



All of the credits for the source go to Maurice Ribble:
int gTempCmd  = 0b00000011;
int gHumidCmd = 0b00000101;
int theDataPin  = 10;
int theClockPin = 11;
int temperatureVal;
int currentTemperatureInF;
int currentTemperatureInC;
int humidityVal;
int currentHumidityInPercent;
int ack;
 
int shiftIn(int dataPin, int clockPin, int numBits)
{
   int ret = 0;
   int i;

   for (i=0; i<numBits; ++i)
   {
      digitalWrite(clockPin, HIGH);
      delay(10);  // I don't know why I need this, but without it I don't get my 8 lsb of temp
      ret = ret*2 + digitalRead(dataPin);
      digitalWrite(clockPin, LOW);
   }

   return(ret);
}

void sendCommandSHT(int command, int dataPin, int clockPin)
{
  // Transmission Start
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, LOW);
          
  // The command (3 msb are address and must be 000, and last 5 bits are command)
  shiftOut(dataPin, clockPin, MSBFIRST, command);

  // Verify we get the correct ack
  digitalWrite(clockPin, HIGH);
  pinMode(dataPin, INPUT);
  ack = digitalRead(dataPin);
  if (ack != LOW)
    Serial.println("Ack Error 0");
  digitalWrite(clockPin, LOW);
  ack = digitalRead(dataPin);
  if (ack != HIGH)
     Serial.println("Ack Error 1");
}

void waitForResultSHT(int dataPin)
{
  int i;
 
  pinMode(dataPin, INPUT);
 
  for(i= 0; i < 100; ++i)
  {
    delay(10);
    ack = digitalRead(dataPin);

    if (ack == LOW)
      break;
  }
 
  if (ack == HIGH)
    Serial.println("Ack Error 2");
}

int getData16SHT(int dataPin, int clockPin)
{
  int val;
 
  // Get the most significant bits
  pinMode(dataPin, INPUT);
  pinMode(clockPin, OUTPUT);
  val = shiftIn(dataPin, clockPin, 8);
  val *= 256;

  // Send the required ack
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  digitalWrite(dataPin, LOW);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
          
  // Get the least significant bits
  pinMode(dataPin, INPUT);
  val |= shiftIn(dataPin, clockPin, 8);

  return val;
}

void skipCrcSHT(int dataPin, int clockPin)
{
  // Skip acknowledge to end trans (no CRC)
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  digitalWrite(dataPin, HIGH);
  digitalWrite(clockPin, HIGH);
  digitalWrite(clockPin, LOW);
}

void setup()
{
   Serial.begin(9600); // open serial
}

void loop()
{
  sendCommandSHT(gTempCmd, theDataPin, theClockPin);
  waitForResultSHT(theDataPin);
  temperatureVal = getData16SHT(theDataPin, theClockPin);
  skipCrcSHT(theDataPin, theClockPin);
  Serial.print("Temperature in F:");
  currentTemperatureInF = -40.2 + 0.018 * (float)temperatureVal;
  Serial.println(currentTemperatureInF, DEC);
  Serial.print("Temperature in C:");
  currentTemperatureInC = -40.1 + 0.01 * (float)temperatureVal;
  Serial.println(currentTemperatureInC, DEC); 
 
  sendCommandSHT(gHumidCmd, theDataPin, theClockPin);
  waitForResultSHT(theDataPin);
  humidityVal = getData16SHT(theDataPin, theClockPin);
  skipCrcSHT(theDataPin, theClockPin);
  Serial.print("Humidity in percent:");
  currentHumidityInPercent = -4.0 + 0.0405 * humidityVal + -0.0000028 * humidityVal * humidityVal;
  Serial.println(currentHumidityInPercent, DEC);
  Serial.println("");
}
Here is a small demonstration:

video

No comments:

Post a Comment