Temperature module - cjus/hydra-cluster GitHub Wiki

The cluster includes a module consisting of an LCD display, temperature sensor and micro-controller used to display uptime and temperature within the enclosure.

Monitoring is performed using an Arduino Mini Nano micro-controller which is connected to a Raspberry pi 3. In addition to sampling temperature the module also sends collected data to the connected Raspberry Pi via the connected USB cable.

completed

Special thanks to Alex Pena for donating a DS18B20 thermal sensor and tips on its use!

Prototyping

The project began on the drawing board using Fritzing to prototype the design.

prototype-wiring

After some online research it was time to create a physical prototype. This not only validates the wiring but also the code required to read the temperature sensor and drive the display.

The photo below shows the sensor sitting in a glass filled with ice.

prototype

Cutting the PCB

Once the layout of the components were determined it was time to cut the PCB board. I used a Dremel with an attached cutting wheel.

Note on the top left of the photo below there's a filter mask. Not shown are the protective goggles. Make sure to use both!

I used painters tape to ensure that I had both a straight edge and to keep the board from potentially splinting.

dremel

By making multiple passes along the edge I was able to snap the board. splitpcb

Next it was time to stand the rough edge. I attached a sanding wheel on to the Dremel.

cutpcb

Testing the wiring

As I connected wires I was able to spot check the circuit using a digital multimeter. The Multimeter shown is a $16 model - it proved to be an indispensable tool.

multimeter

Wiring work

Soldering tiny wires on a circuit board is an exercise in patience. The circuit board holder shown below made the work less painful.

solderwork

Completed module

The completed project resulted in a compact module ready for mounting. The temperature sensor is the silver colored tube at the bottom of the photo. The sensor was mounted in the front of the display because it was easier than mounting it on the back. However, the latter may have been more effective.

The display shows days using two digits on the left. Hours, minutes and seconds are shown next followed by the current temperature in fahrenheit.

completed

Source code

#include <OneWire.h>
#include <Wire.h>
#include <LiquidCrystal.h>

#define LCD_WIDTH 16
#define LCD_HEIGHT 2

OneWire ds(11);  // on pin 11
LiquidCrystal lcd(12, 2, 4, 5, 6, 7);

void setup() {
  Serial.begin(9600);
  lcd.begin(LCD_WIDTH, LCD_HEIGHT);
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("HYDRA  CLUSTER");
}

void loop() {
  displayUptime();
  displayTemperature();
  delay(1000);
}

void displayUptime() {
  char buf[LCD_WIDTH];
  unsigned int days = 0;
  unsigned int hours = 0;
  unsigned int mins = 0;
  unsigned int secs = 0;

  secs = millis() / 1000;

  mins = secs / 60;
  hours = mins / 60;
  days = hours / 24;

  secs = secs - (mins * 60);
  mins = mins - (hours * 60);
  hours = hours - (days * 24);

  sprintf(buf, "%02d %02d:%02d:%02d", days, hours, mins, secs);
  lcd.setCursor(0, 1);
  lcd.print(buf);
  Serial.write(buf);
  Serial.write('|');
}

void displayTemperature() {
  int HighByte, LowByte, TReading, SignBit, Tc_100, Tf_100, Whole, Fract;
  char buf[LCD_WIDTH];

  byte i, sensor;
  byte present = 0;
  byte data[12];
  byte addr[8];

  ds.reset_search();
  if (!ds.search(addr)) {
    lcd.setCursor(0,0);
    lcd.print("No more addr.");
    ds.reset_search();
    delay(250);
    return;
  }

  if (OneWire::crc8(addr, 7) != addr[7]) {
    lcd.setCursor(0,0);
    lcd.print("CRC not valid");
    return;
  }

  if (addr[0] != 0x28) {
    lcd.setCursor(0,0);
    lcd.print("Not a DS18B20.");
    return;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);         // start conversion, with parasite power on at the end

//  delay(2000);     // 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++) {
    data[i] = ds.read();
  }

  LowByte = data[0];
  HighByte = data[1];
  TReading = (HighByte << 8) + LowByte;
  SignBit = TReading & 0x8000;  // test most sig bit
  if (SignBit) { // negative
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25
  Tf_100 = ((Tc_100 * 9.0) / 5.0  + 32 * 100) / 100;
  //TODO: use this instead: fahrenheit = (cel * 1.8) + 32;

  //sprintf(buf, "%d\337", Tf_100);
  sprintf(buf, "%dF", Tf_100);
  int pos = LCD_WIDTH - strlen(buf);
  lcd.setCursor(pos, 1);
  lcd.print(buf);
  Serial.write(buf);
  Serial.write('\n');
}

Parts list

Count Part
1 Arduino Mini Nano
1 40 Pin Header
1 1602 LCD display
1 DS18B20 thermal sensor
1 4.7K Ohm resister
1 10K Ohm Potentiometer
1 PCB w/Power Rails
x Small wires

Resources

LCD control

DS18B20+ Temp sensor tutorials

Because the Nano I used is a cheap clone I had to download the CH43x serial driver for use with the Arduino IDE.

⚠️ **GitHub.com Fallback** ⚠️