{"id":16,"date":"2012-05-14T11:41:50","date_gmt":"2012-05-14T10:41:50","guid":{"rendered":"http:\/\/mskvorc.com\/blog\/?p=16"},"modified":"2013-11-13T23:44:58","modified_gmt":"2013-11-13T22:44:58","slug":"arduino-temperature-sensor-box","status":"publish","type":"post","link":"http:\/\/mskvorc.com\/blog\/?p=16","title":{"rendered":"Arduino temperature sensor box"},"content":{"rendered":"<p>Several months ago I&#8217;ve uploaded a video on YouTube showing my new Arduino project &#8211; reading temperature from DS18B20 sensor and showing the result on a 7-segment display. In the mean time I received several questions about schematics and source code. I finally put all peaces together so here are all details.<\/p>\n<p><iframe loading=\"lazy\" src=\"http:\/\/www.youtube.com\/embed\/MLqxgcqnzU0\" height=\"315\" width=\"560\" frameborder=\"0\"><\/iframe><\/p>\n<p><!--more--><\/p>\n<p>List of components:<\/p>\n<ul>\n<li>1x Arduino board<\/li>\n<li>1x Protoboard and a bunch of jumper wires<\/li>\n<li>4x 10k resistors<\/li>\n<li>4x DS18B20 temperature sensors<\/li>\n<li>4x 4digit 7-segment displays<\/li>\n<li>5x 8-bit shift register (I used four M74HC59581 and one CD74HCT4094E)<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>Arduino sketch<\/p>\n<pre>\r\n[java]\r\n\/*\r\n\r\nDisplay temperatures from four DS18B20 sensors\r\non four 7 segment displays.\r\n\r\nDetailed description can be found at http:\/\/www.mskvorc.com\r\n\r\nAuthor: Marko \u0160kvorc (marko.skvorc@gmail.com)\r\nLast changed: 24.02.2013.\r\n\r\n*\/\r\n#include <SPI.h>\r\n#include <OneWire.h>\r\n\r\n\/\/ 7 Segment display\r\n\/\/ ----------------------------------------------------------\r\n\/\/Pin connected to ST_CP of 74HC595\r\nint latchPin = 7;\r\n\/\/\/\/Pin connected to DS of 74HC595\r\nint dataPin = 8;\r\n\/\/Pin connected to SH_CP of 74HC595\r\nint clockPin = 9;\r\n\r\nbyte seven_seg_digits[12] = { \r\n     B00101000 ,  \/\/ = 0\r\n     B11101011 ,  \/\/ = 1\r\n     B00110010 ,  \/\/ = 2\r\n     B10100010 ,  \/\/ = 3\r\n     B11100001 ,  \/\/ = 4\r\n     B10100100 ,  \/\/ = 5\r\n     B00100100 ,  \/\/ = 6\r\n     B11101010 ,  \/\/ = 7\r\n     B00100000 ,  \/\/ = 8\r\n     B10100000 ,  \/\/ = 9\r\n     B11110111 ,  \/\/ = -\r\n     B11111111    \/\/ = all off\r\n};\r\n\r\nbyte dot = B00100000;\r\nbyte digits[] = {B10000000, B01000000, B00100000, B00010000};\r\n\r\nint nextDisplay = 1;\r\nint numDisplay = 4;\r\nint nextSensor = 0;\r\n\/\/ ----------------------------------------------------------\r\n\r\n\/\/ Temperatures\r\n\/\/ ----------------------------------------------------------\r\nint tempPins[4] = {2, 3, 4, 5};\r\n\r\nint temps[4] = {0, 0, 0, 0};\r\nint tempDigits[4][4] = {{0, 0, 0, 11}, {0, 0, 0, 11}, {0, 0, 0, 11}, {0, 0, 0, 11}};\r\n\r\nint tempReadingStep = 0;\r\n\r\nvoid OneWireReset(int Pin);\r\nvoid OneWireOutByte(int Pin, byte d);\r\nbyte OneWireInByte(int Pin);\r\n\/\/ ----------------------------------------------------------\r\n\r\n\r\n\/\/ ----------------------------------------------------------\r\nint delayTime = 2000;\r\nint currentDelayTime = 0;\r\n\r\nint sensorTime = 1000; \/\/ read temp every 1 sec\r\n\r\nint readSensorCount = sensorTime \/ (delayTime \/ 1000);\r\n\r\nint counter = 0;\r\n\/\/ ----------------------------------------------------------\r\n\r\n\r\nvoid setup() { \r\n  pinMode(latchPin, OUTPUT);\r\n  pinMode(clockPin, OUTPUT);\r\n  pinMode(dataPin, OUTPUT);\r\n\r\n  for (int i = 0; i < 4; i++){\r\n    digitalWrite(tempPins[i], LOW);\r\n    pinMode(tempPins[i], INPUT);      \/\/ sets the digital pin as input (logic 1)\r\n  }\r\n}\r\n\r\nbyte isDot(){\r\n  if (nextDisplay == 2)\r\n    return dot;\r\n  else\r\n    return B0;\r\n}\r\n\r\nvoid refreshDisplay(){\r\n    digitalWrite(latchPin, LOW);\r\n    \/\/ shift out the bits:\r\n    \r\n    \/\/ turn on display\r\n    shiftOut(dataPin, clockPin, LSBFIRST , digits[nextDisplay - 1]);\r\n    \r\n    \/\/ show digits\r\n    shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[tempDigits[0][nextDisplay - 1]] - isDot());\r\n    shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[tempDigits[1][nextDisplay - 1]] - isDot());\r\n    shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[tempDigits[2][nextDisplay - 1]] - isDot());\r\n    shiftOut(dataPin, clockPin, LSBFIRST, seven_seg_digits[tempDigits[3][nextDisplay - 1]] - isDot());\r\n\r\n    \/\/take the latch pin high so the LEDs will light up:\r\n    digitalWrite(latchPin, HIGH);\r\n    \r\n    nextDisplay = nextDisplay + 1;\r\n    if (nextDisplay > numDisplay){\r\n      nextDisplay = 1;\r\n    }\r\n}\r\n\r\nvoid loop() {\r\n  \r\n  refreshDisplay();\r\n\r\n  \/\/ read sensor\r\n  if (counter == readSensorCount){\r\n    temps[nextSensor] = readSensor(tempPins[nextSensor], tempReadingStep);\r\n    tempReadingStep++;\r\n    \r\n    if (temps[nextSensor] != 0){\r\n      tempDigits[nextSensor][2] = (abs(temps[nextSensor]) \/ 100) \/ 10;\r\n      tempDigits[nextSensor][1] = (abs(temps[nextSensor]) \/ 100) % 10;\r\n      tempDigits[nextSensor][0] = (abs(temps[nextSensor]) % 100) \/ 10;\r\n\r\n      if (temps[nextSensor] < 0){\r\n        tempDigits[nextSensor][3] = 10;\r\n      } else {\r\n        tempDigits[nextSensor][3] = 11;\r\n      }\r\n      nextSensor++;\r\n      if (nextSensor == 4){\r\n        nextSensor = 0;\r\n      }\r\n      counter = 0;\r\n      tempReadingStep = 0;\r\n    }\r\n  } else {\r\n    counter++;\r\n  }\r\n\r\n  int additionalDelay = delayTime - currentDelayTime;\r\n  delayMicroseconds(additionalDelay);\r\n\r\n  currentDelayTime = 0;\r\n}\r\n\r\nint readSensor(int pin, int tempReadingStep){\r\n  int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;\r\n\r\n  switch(tempReadingStep){\r\n    case 1:\r\n      OneWireReset(pin);\r\n      break;\r\n    case 2:\r\n      OneWireOutByte(pin, 0xcc);\r\n      OneWireOutByte(pin, 0x44); \/\/ perform temperature conversion, strong pullup for one sec\r\n      break;\r\n    case 3:\r\n      OneWireReset(pin);\r\n      break;\r\n    case 4:\r\n      OneWireOutByte(pin, 0xcc);\r\n      OneWireOutByte(pin, 0xbe);\r\n\r\n      LowByte = OneWireInByte(pin);\r\n      HighByte = OneWireInByte(pin);\r\n      TReading = (HighByte << 8) + LowByte;\r\n      SignBit = TReading &#038; 0x8000;  \/\/ test most sig bit\r\n      if (SignBit) \/\/ negative\r\n      {\r\n        TReading = (TReading ^ 0xffff) + 1; \/\/ 2's comp\r\n      }\r\n      Tc_100 = (6 * TReading) + TReading \/ 4;    \/\/ multiply by (100 * 0.0625) or 6.25\r\n      if (SignBit){\r\n        Tc_100 = -Tc_100;\r\n      }\r\n      break;\r\n    default:\r\n      break;\r\n  }\r\n\r\n  return Tc_100;\r\n}\r\n\r\nvoid OneWireOutByte(int Pin, byte d) \/\/ output byte d (least sig bit first).\r\n{\r\n   byte n;\r\n\r\n   for(n=8; n!=0; n--)\r\n   {\r\n      if ((d &#038; 0x01) == 1)  \/\/ test least sig bit\r\n      {\r\n         digitalWrite(Pin, LOW);\r\n         pinMode(Pin, OUTPUT);\r\n         delayMicroseconds(5);\r\n         currentDelayTime = currentDelayTime + 5;\r\n         pinMode(Pin, INPUT);\r\n         delayMicroseconds(60);\r\n         currentDelayTime = currentDelayTime + 60;\r\n      }\r\n      else\r\n      {\r\n         digitalWrite(Pin, LOW);\r\n         pinMode(Pin, OUTPUT);\r\n         delayMicroseconds(60);\r\n         currentDelayTime = currentDelayTime + 60;\r\n         pinMode(Pin, INPUT);\r\n      }\r\n\r\n      d=d>>1; \/\/ now the next bit is in the least sig bit position.\r\n   }\r\n   \r\n}\r\n\r\nbyte OneWireInByte(int Pin) \/\/ read byte, least sig byte first\r\n{\r\n    byte d, n, b;\r\n\r\n    for (n=0; n<8; n++)\r\n    {\r\n        digitalWrite(Pin, LOW);\r\n        pinMode(Pin, OUTPUT);\r\n        delayMicroseconds(5);\r\n        currentDelayTime = currentDelayTime + 5;\r\n        pinMode(Pin, INPUT);\r\n        delayMicroseconds(5);\r\n        currentDelayTime = currentDelayTime + 5;\r\n        b = digitalRead(Pin);\r\n        delayMicroseconds(50);\r\n        currentDelayTime = currentDelayTime + 50;\r\n        d = (d >> 1) | (b<<7); \/\/ shift d to right and insert b in most sig bit position\r\n    }\r\n    return(d);\r\n}\r\n\r\nvoid OneWireReset(int Pin) \/\/ reset.  Should improve to act as a presence pulse\r\n{\r\n     digitalWrite(Pin, LOW);\r\n     pinMode(Pin, OUTPUT); \/\/ bring low for 500 us\r\n     delayMicroseconds(500);\r\n     currentDelayTime = currentDelayTime + 500;\r\n     pinMode(Pin, INPUT);\r\n     delayMicroseconds(500);\r\n     currentDelayTime = currentDelayTime + 500;\r\n}\r\n[\/java]\r\n<\/pre>\n<p>The final product looks like this:<\/p>\n<p><a href=\"http:\/\/mskvorc.com\/blog\/wp-content\/uploads\/2012\/05\/7segmentBox.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"aligncenter size-medium wp-image-26\" title=\"7segmentBox\" alt=\"\" src=\"http:\/\/mskvorc.com\/blog\/wp-content\/uploads\/2012\/05\/7segmentBox-268x300.jpg\" width=\"268\" height=\"300\" srcset=\"http:\/\/mskvorc.com\/blog\/wp-content\/uploads\/2012\/05\/7segmentBox-268x300.jpg 268w, http:\/\/mskvorc.com\/blog\/wp-content\/uploads\/2012\/05\/7segmentBox.jpg 716w\" sizes=\"(max-width: 268px) 100vw, 268px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Several months ago I&#8217;ve uploaded a video on YouTube showing my new Arduino project &#8211; reading temperature from DS18B20 sensor and showing the result on a 7-segment display. In the mean time I received several questions about schematics and source &hellip; <a href=\"http:\/\/mskvorc.com\/blog\/?p=16\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,4],"tags":[],"_links":{"self":[{"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/16"}],"collection":[{"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":11,"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions"}],"predecessor-version":[{"id":37,"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/16\/revisions\/37"}],"wp:attachment":[{"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=16"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/mskvorc.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}