Arduino:Примеры/DS18x20 Temperature

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Чтение данных с температурного датчика[1]

Этот пример демонстрирует, как при помощи библиотеки OneWire считывать данные с температурных датчиков типа 1-Wire. Поддерживаются модели DS18S20, DS18B20 и DS1822.

Код

  1 #include <OneWire.h>
  2 
  3 // Чтение данных с температурных датчиков типа 1-Wire: DS18S20, DS18B20, DS1822
  4 //
  5 // http://www.pjrc.com/teensy/td_libs_OneWire.html
  6 //
  7 // Библиотека DallasTemperature может сделать это все за вас!
  8 // http://milesburton.com/Dallas_Temperature_Control_Library
  9 
 10 OneWire  ds(10);  // на 10-ом контакте (если необходимо, подключите резистор на 4,7 кОм)
 11 
 12 void setup(void) {
 13   Serial.begin(9600);
 14 }
 15 
 16 void loop(void) {
 17   byte i;
 18   byte present = 0;
 19   byte type_s;
 20   byte data[12];
 21   byte addr[8];
 22   float celsius, fahrenheit;
 23   
 24   if ( !ds.search(addr)) {
 25     Serial.println("No more addresses.");  //  "Адресов больше нет."
 26     Serial.println();
 27     ds.reset_search();
 28     delay(250);
 29     return;
 30   }
 31   
 32   Serial.print("ROM =");
 33   for( i = 0; i < 8; i++) {
 34     Serial.write(' ');
 35     Serial.print(addr[i], HEX);
 36   }
 37 
 38   if (OneWire::crc8(addr, 7) != addr[7]) {
 39       Serial.println("CRC is not valid!");  //  "CRC не корректен!"
 40       return;
 41   }
 42   Serial.println();
 43  
 44   // первый ROM-байт, определяет, с каким чипом мы имеем дело:
 45   switch (addr[0]) {
 46     case 0x10:
 47       Serial.println("  Chip = DS18S20");  //  "  Чип – DS18S20" или старый DS1820
 48       type_s = 1;
 49       break;
 50     case 0x28:
 51       Serial.println("  Chip = DS18B20");  //  "  Чип – DS18B20"
 52       type_s = 0;
 53       break;
 54     case 0x22:
 55       Serial.println("  Chip = DS1822");  //  "  Чип – DS1822"
 56       type_s = 0;
 57       break;
 58     default:
 59       Serial.println("Device is not a DS18x20 family device.");  //  "Устройство не принадлежит семейству DS18x20."
 60       return;
 61   } 
 62 
 63   ds.reset();
 64   ds.select(addr);
 65   ds.write(0x44, 1);        // запускаем конверсию и включаем паразитное питание
 66   
 67   delay(1000);     // 750 миллисекунд может хватить, а может и нет;
 68                    // здесь можно использовать ds.depower(), 
 69                    // но об этом позаботится сброс 
 70   
 71   present = ds.reset();
 72   ds.select(addr);    
 73   ds.write(0xBE);         // считываем scratchpad-память
 74 
 75   Serial.print("  Data = ");  //  "  Данные = "
 76   Serial.print(present, HEX);
 77   Serial.print(" ");
 78   for ( i = 0; i < 9; i++) {           // нам нужно 9 байтов
 79     data[i] = ds.read();
 80     Serial.print(data[i], HEX);
 81     Serial.print(" ");
 82   }
 83   Serial.print(" CRC=");
 84   Serial.print(OneWire::crc8(data, 8), HEX);
 85   Serial.println();
 86 
 87   // конвертируем данные в температуру; поскольку результат - это
 88   // 16-битное целое знаковое число, оно должно быть записано в типе 
 89   // данных "int16_t", который всегда будет 16-битным – даже если
 90   // данные скомпилированы на 32-битном процессоре.
 91   int16_t raw = (data[1] << 8) | data[0];
 92   if (type_s) {
 93     raw = raw << 3; // разрешение по умолчанию – 9 бит
 94     if (data[7] == 0x10) {
 95       // регистр "count remain" дает полное 12-битное разрешение
 96       raw = (raw & 0xFFF0) + 12 - data[6];
 97     }
 98   } else {
 99     byte cfg = (data[4] & 0x60);
100     // при низком разрешении младшие биты не определяются, поэтому обнуляем их:
101     if (cfg == 0x00) raw = raw & ~7;  // 9-битное разрешение (93,75 миллисекунд)
102     else if (cfg == 0x20) raw = raw & ~3;  // 10-битное разрешение (187,5 миллисекунд)
103     else if (cfg == 0x40) raw = raw & ~1;  // 11-битное разрешение (375 миллисекунд)
104 
105     //// по умолчанию стоит 12-битное разрешение; время конверсии – 750 миллисекунд
106   }
107   celsius = (float)raw / 16.0;
108   fahrenheit = celsius * 1.8 + 32.0;
109   Serial.print("  Temperature = ");  //  "Температура = "
110   Serial.print(celsius);
111   Serial.print(" Celsius, ");  //  " по Цельсию, "
112   Serial.print(fahrenheit);
113   Serial.println(" Fahrenheit");  //  " по Фаренгейту"
114 }

См.также

Внешние ссылки