Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

Измерване на температура и влажност чрез Arduino и SHT15

SHT15 е сензор за измерване на температура и влажност. Може да се намери запоен върху брейкаут борд, който го прави лесен за използване с бредборд. Комуникацията със сензора се осъщестява по две линии, но I2C протокола не може да се използва т.е. наличните Arduino библиотеки за комуникация не вършат работа.

Захранва се напрежение от 2.4 до 5.5V и е готов за работа 11ms след захранването му. Комуникацията започва след превключване на линиите DATA и SCK в следната последователност:

След започване на комуникацията, сензорът очаква команди 00000101 за измерване на влажност и 00000011 за температура. Потвърждава получаването на командата като след последния и бит, сваля линията DATA на LOW (ниско ниво) и очакваква SCK да премине от HIGH (високо ниво) на LOW, за да я върне на HIGH. С това започва измерването, което продължава докато DATA е HIGH. Когато DATA стане LOW, измерването e приключило и сензорът връща по нея два байта с данни.

Данните могат да се прочетат от микроконтролер, който трябва да променя SCK от HIGH на LOW за всеки бит и да свали DATA на LOW след първия прочетен байт. След прочитането и на втория байт, линията DATA трябва да се вдигне на HIGH, за да се продължи със следващо измерване.

Прочетените данни се разглеждат като двуично число, на което първата позиция отговаря на първия получен бит, втората на втория и т.н. Десетичната стойност на полученото число се използва за изчисляване на температурата и влажността в градуси и %RH.

Изчисляването на температура става по следната формула, в която SОт е стойността, прочетена от сензора, а d1 и d2 са коефиценти от даташийта на продукта.

За намиране на влажността се изчислява първо линейната и стойност. Ако стайната температура не е около 25 градуса за получената стойност се прилага температурна компенсация.

Пример

Даденият по-долу код, използва сензора за да измери едновременно температурата и влажността. Измерванията се повтарят през интервал от 2 секунди, за да се предотврати загряване на сензора. По подразбиране температурата се мери с резолюция 14 бита, а влажността с 12бита. Съответните коефиценти са въведени в програмата, която изчислява стойностите по дадените формули и ги показва в Serial Monitor.

Сензорът се свързва към Ардуино по следния начин:

Vcc  -> 5V
DATA -> pin8
SCK  -> pin9
GND  -> GND

                          източник: rzm-hamy-wsx.rz.uni-karlsruhe.de

Програмата, която трябва да се зареди на Arduino е следната:

/*

 Описание:
 * Осъществява комуникация с SHT15 по две линии
 * Чете данни от сензора и ги превръща в стойности
   за температура и влажност
 * Извежда информацията в Serial Monitor

 Свързване:
 * Vcc  -> 5V
 * DATA -> pin8
 * SCK  -> pin9
 * GND  -> GND

 * Tihomir Trifonov (08-2011)
 * email:tisho@inbox.com

 * с подкрепата на Robotev.com

*/

//// входно/изходни пинове за микроконтролера
int dataPin = 8; // DATA
int sckPin = 9;  // SCK

//// коефиценти за изчисляване на влажността
const float C1=-2.0468; // 12 Bit
const float C2= 0.0367; // 12 Bit
const float C3=-0.0000015955; // 12 Bit
const float T1=0.01; // 12 Bit
const float T2=0.00008; // 12 Bit

//// коефиценти за изчисляване на температурата
const float D1=-40.1; // 14 Bit @ 5V
const float D2=0.01;  // 14 Bit DEGC

//////////////////// стартира сензора

void startSHT(){

  pinMode(sckPin,OUTPUT);  // задава пиновете SCK и DATA
  pinMode(dataPin,OUTPUT); // като изходни за микроконтролера

  digitalWrite(dataPin,HIGH); // DATA HIGH
  digitalWrite(sckPin,HIGH);  // SCK HIGH
  digitalWrite(dataPin,LOW);  // DATA LOW
  digitalWrite(sckPin,LOW);   // SCK LOW
  digitalWrite(sckPin,HIGH);  // SCK HIGH
  digitalWrite(dataPin,HIGH); // DATA HIGH
  digitalWrite(sckPin,LOW);   // SCK LOW
} 

//////////////////// изпраща команда към сензора

void sendCommand(byte command) { 

  pinMode(sckPin,OUTPUT);  // SCK и DATA са изходни
  pinMode(dataPin,OUTPUT); // пинове за микроконтролера

  //// изпраща байта command бит по бит, като започва от най-левия                                           
  shiftOut(dataPin, sckPin, MSBFIRST, command); 

  pinMode(dataPin,INPUT); // DATA става входен пин

  //// изчаква SHT15 да потвърди получаването на байта (ACK bit)
  while(digitalRead(dataPin) == 1); // DATA LOW
  digitalWrite(sckPin,HIGH);        // SCK HIGH 
  digitalWrite(sckPin,LOW);         // SCK LOW 
  while(digitalRead(dataPin) == 0 );// DATA HIGH

  //// изчаква SHT15 да сигнализира че е готов с измерването
  while(digitalRead(dataPin) == 1 ); //DATA LOW
}

//////////////////// чете данни от сензора

int readData() {

  int readout = 0; // съхранява стойността от сензора
  unsigned int bitmask = 0x8000; // побитова маска
  int temp; // помощна променлива

  pinMode(dataPin,INPUT); // DATA е входен, а SCK изходен
  pinMode(sckPin,OUTPUT); // пин за микроконтролера

  for(int i = 0; i < 17; i++){ // прочита два байта от сензора

    if(i != 8){ // проверява за края на първия байт   

      digitalWrite(sckPin,HIGH);   // SCK HIGH
      temp = digitalRead(dataPin); // чете бит по бит
      readout += bitmask * temp;   // образува десетична стойност
      digitalWrite(sckPin,LOW);    // SCK LOW
      bitmask = bitmask/2; }       // променя маската за всеки бит 

    else { // потвърждава получаването на първия байт (ACK bit)

      pinMode(dataPin,OUTPUT);   // DATA става изходен пин
      digitalWrite(dataPin,LOW); // DATA LOW
      digitalWrite(sckPin,HIGH); // SCK HIGH
      digitalWrite(sckPin,LOW);  // SCK LOW
      pinMode(dataPin,INPUT); }  // DATA е отново входен пин   
  }

  digitalWrite(dataPin,HIGH); // DATA HIGH

  return readout; // връща данните от сензора
}

//////////////////// измерва температурата

int getTemp() {

  startSHT(); // стартира сензора
  sendCommand(B0000011); // изпраща команда 00011
  return readData(); // връща получената стойност
}

//////////////////// измерва влажността

int getHumidity() {

  startSHT(); // стартира сензора
  sendCommand(B00000101); // изпраща команда 00101
  return readData();// връща получената стойност
}

//////////////////// начални инициализации

void setup() { 

  pinMode(dataPin,OUTPUT); // SCK и DATA са изходни
  pinMode(sckPin,OUTPUT);  // пинове за микроконтролера

  Serial.begin(9600); // стартира серийна комуникация
}

//////////////////// програмен цикъл

void loop () { 

  Serial.println("Temperature/Humidity reading...");
  delay(2000); // изчаква 2 секунди

  // прочита данните за температурата
  int temp_raw = getTemp(); 
  // пресмята температурата в градуси
  float temp_degc = (temp_raw * D2) + D1;
  // извежда стойността и в Serial Monitor
  Serial.print("Temperature: "); 
  Serial.println(temp_degc);  

  // прочита данните за влажността 
  int rh_raw = getHumidity(); 
  // преобразува данните линейно 
  float rh_lin = C3*rh_raw*rh_raw+C2*rh_raw+C1; 
  // прилага температурна компенсация
  float rh_true = (temp_degc*(T1+T2*rh_raw)+rh_lin); 
  // извежда стойността в Serial Monitor
  Serial.print("Humidity: "); 
  Serial.println(rh_true);

  Serial.println(); // разделител         
}