29.03.2024, Пятница, 10:10
22.09.2013 в 00:32
DIY цифровой термометр
На макетной плате с Ардуино Нано цифровой датчик DS18B20 передаёт значение температуры на терминал компьютера и 3-разрядный семисегментный индикатор с общим анодом.
Схема индикатора:



Листинг программы на Wiring (Arduino IDE 1.5.3):

Код

#include <OneWire.h>
//http://arduino.net.ua/Arduino_articles/Arduino_proekty/Podkljuchaem%20datchik%20temperatury%20DS18S20%20ili%20DS18B20%20k%20Arduino/

OneWire ds (12); // on pin 12 - приём данны с датчика
  static byte celsy, desyata;

void setup (void) {
  Serial.begin (9600);
  pinMode(2, OUTPUT); //0 разряд
  pinMode(3, OUTPUT); // 1 разряд
  pinMode(4, OUTPUT); // 2 разряд
  pinMode(5, OUTPUT);// сегмент F
  pinMode(6, OUTPUT);// сегмент A
  pinMode(7, OUTPUT);// сегмент E
  pinMode(8, OUTPUT);// сегмент B
  pinMode(9, OUTPUT);// сегмент D
  pinMode(10, OUTPUT);// сегмент C
  pinMode(11, OUTPUT);// сегмент G  
  pinMode(13, OUTPUT);// сегмент dp  
}

void digit (byte cifra) {
  // сначала всё обесточиваем
  for (byte j=5; j<12; j++)
  {
  digitalWrite(j, HIGH);  
  }
  digitalWrite(13, HIGH);  
  switch (cifra)
  {
  case 0:  
  {
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);  
  digitalWrite(7, LOW);  
  digitalWrite(8, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(10, LOW);  
  break;  
  }  
  case 1:  
  {
  digitalWrite(8, LOW);  
  digitalWrite(10, LOW);  
  break;
  }
  case 2:  
  {
  digitalWrite(6, LOW);  
  digitalWrite(7, LOW);  
  digitalWrite(8, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(11, LOW);
  break;
  }
  case 3:  
  {
  digitalWrite(6, LOW);
  digitalWrite(8, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(10, LOW);  
  digitalWrite(11, LOW);  
  break;
  }
  case 4:  
  {
  digitalWrite(5, LOW);
  digitalWrite(8, LOW);  
  digitalWrite(10, LOW);  
  digitalWrite(11, LOW);  
  break;
  }
  case 5:  
  {
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(10, LOW);  
  digitalWrite(11, LOW);  
  break;
  }
  case 6:  
  {
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);  
  digitalWrite(7, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(10, LOW);  
  digitalWrite(11, LOW);  
  break;
  }
  case 7:  
  {
  digitalWrite(6, LOW);
  digitalWrite(8, LOW);  
  digitalWrite(10, LOW);  
  break;  
  }  
  case 8:  
  {
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);  
  digitalWrite(7, LOW);  
  digitalWrite(8, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(10, LOW);  
  digitalWrite(11, LOW);  
  break;  
  }  
  case 9:  
  {
  digitalWrite(5, LOW);
  digitalWrite(6, LOW);  
  digitalWrite(8, LOW);  
  digitalWrite(9, LOW);  
  digitalWrite(10, LOW);  
  digitalWrite(11, LOW);  
  break;  
  }  
  default: ;
  }
}  

void loop (void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
   
  if (! ds.search (addr)) {
  ds.reset_search ();
  for (byte i=0;i<20;i++)
  {
  digit(celsy/10);  
  digitalWrite(4, HIGH);  
  delay (5);  
  digitalWrite(4, LOW);  
  digit(celsy%10);
  digitalWrite(13, LOW);  
  digitalWrite(3, HIGH);  
  delay (5);  
  digitalWrite(3, LOW);  
  digit(desyata%10);
  digitalWrite(2, HIGH);  
  delay (5);  
  digitalWrite(2, LOW);  
  }
  //delay (250);
  return;
  }
   
  ds.reset ();
  ds.select (addr);
  ds.write (0x44,1); // start conversion, with parasite power on at the end

// delay (1000); // maybe 750ms is enough, maybe not
  // we might do a ds.depower () here, but the reset will take care of it.
   
  present = ds.reset ();
  ds.select (addr);  
  ds.write (0xBE); // Read Scratchpad
   
  for (i = 0; i < 9; i++) { // we need 9 bytes
  data[i] = ds.read ();
  }

  // convert the data to actual temperature
  unsigned int raw = (data[1] << 8) | data[0];
  if (type_s) {
  raw = raw << 3; // 9 bit resolution default
  if (data[7] == 0x10) {
  // count remain gives full 12 bit resolution
  raw = (raw & 0xFFF0) + 12 - data[6];
  }
  } else {
  byte cfg = (data[4] & 0x60);
  if (cfg == 0x00) raw = raw << 3; // 9 bit resolution, 93.75 ms
  else if (cfg == 0x20) raw = raw << 2; // 10 bit res, 187.5 ms
  else if (cfg == 0x40) raw = raw << 1; // 11 bit res, 375 ms
  // default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print ("Temperature =");
  Serial.print (celsius);
  Serial.print (" C,");
  Serial.print (fahrenheit);
  Serial.println (" F");

  if (celsius<70)
  {
  celsy=celsius;
  desyata=celsius*10;
  for (byte i=0;i<50;i++)
  {  
  digit(celsy/10);  
  digitalWrite(4, HIGH);  
  delay (5);  
  digitalWrite(4, LOW);  
  digit(celsy%10);
  digitalWrite(13, LOW);  
  digitalWrite(3, HIGH);  
  delay (5);  
  digitalWrite(3, LOW);  
  digit(desyata%10);
  digitalWrite(2, HIGH);  
  delay (5);  
  digitalWrite(2, LOW);  
  }
  }
}  


Результат работы программы - вывод на терминал (через USB):



Грел пальцами датчик для демонстрации его чувствительности и скорости реакции.

И вывод на семисегментник (100% DIY-участок)):



В случае использования для длительной работы требуется включение резисторов по паре сотен Ом в анодные цепи (так их меньше надо)

PS: хотел сделать схему в Fritzing, но столкнулся с отсутствием там как DS18B20, так и 3-разрядных семисегментников, в общем, решил не мучаться), там (в схеме) главное - в принципе разобраться по подключению от цифровых выводов к катодам сегментов (выводы D5-D11, точка - на D13) и к анодам разрядов (выводы D2-D4). Данные от датчика идут на D12. Для зажигания сегмента нужно подать LOW уровень на сегмент и HIGH - на разряд.
Ардуино Нано не имеет стандартного разъёма для DC 5 вольт, но можно подключить эти 5 вольт откуда угодно к нижнему правому выводу (Vin) и землю - к выводу чуть левее (Gnd) .
Количество просмотров: 4775.
dth="100%" cellspacing="0" cellpadding="0" class="commTable">
Имя *: Email:
Подписка:1 Код *: