Renewable Energy Innovation

  • Increase font size
  • Default font size
  • Decrease font size
Email Print

No image

This is a large visual temperature display which can be used as an alert if a temperature set-point is reached.

It was built for a friend who has a laser cutter and needed to keep an eye on the coolant temperature. The cutter was not meant to be run with coolant temperature above 25°C. If the temperature goes above 25°C then the unit will 'bleep'.

It uses the large 7-segment displays, a minimus AVR and a Dallas 1-wire temperature sensor, all within a mountable laser-cut plywood enclosure.

If you would like one for your laser cutter set-up then you can also buy one built and tested for £30.

The full build instructions are here, along with the software code used.

Overview

Here are some photos of the unit in action. It runs from 12V DC (provided in this case from an old plug-in power supply)

No image

No image

Set up with the laser cutter (a model from HPC lasers).

No image

Here is a video of it in action:

Here are some more photos of a unit added to the Nottingham Hackspace laser cutter.

No image

No image

No image

Buy it now

If you would like one, then I can also supply them ready-made and tested for £30 including p&p within the UK (afraid this does not including 12V power supply).

Options

(I'm also thinking about building a unit with a relay output to control a pump or chiller - let me know if you would be interested in a unit with that function.)

Hardware

The unit is based upon a minimus AVR microcontroller development board (see my blog post here for full details about getting it running). This reads a Dallas 1-wire DS18D20 temperature sensor (more info about that here) and outputs the data to two large 7-segment LED displays. There is also a 12V to 5 5V converter (using a standard 7805 regulator) and a piezoelectric buzzer for the output.

I have drawn the diagram here as a visual wiring diagram, rather than a circuit schematic. Hopefully it is obvious with regards to component orientation. As you can see, there is a small additional circuit done on strip board. I will hopefully change this to a PCB on which to mount the minimus AVR.

No image

 

Enclosure

The enclosure was designed using this method, using T-nut holders so it can be disassembled quite easily. The enclosure was built from 3mm ply-wood, with a 3mm acrylic diffuser for the 7-segment display. Here are .pdf images of the design, along with .dxf to download.

Download the .dxf file for the wooden parts (3mm plywood) here. The .dxf for the plastic parts (3mm acrylic) is here

Minimus AVR / Arduino software

The minimus AVR was programmed using Atmel Flip using code written within the Arduino IDE. Lots more details are in this post.

The Arudino code is quite simple and is shown here, and also for download to install into your sketch folder here. It is based mainly upon the OneWire Temperature example. The temperature set-point can be adjusted within code for other applications.

/********************************************************
/****** 7 Segment LED Temperature Sensorwith Minimus ****
/****** by Matt Little **********************************
/****** Date: 12/6/13 ***********************************
/****** This email address is being protected from spambots. You need JavaScript enabled to view it.
  ************************
/****** www.re-innovation.co.uk *************************
/********************************************************
This example uses the Serial Shift output to control a 7 segment LED display
Data is shifted out serially and only when all the shift registers are filled does the latch cause
the LED outputs to update.
The LED boards require 12V supply as they contain strings of 4 LEDs.
The wiring for each board is as follows (P1 and P2):
  Pin 1  ->  Serial LATCH -> PD0 on minimus (in this example)
  Pin 2  ->  Serial CLOCK -> PD1 on minimus (in this example)
  Pin 3  ->  Serial DATA  -> PD4 on minimus (in this example)  
  Pin 4  ->  GROUND       -> GND on Arduino
  Pin 5  ->  +5V          -> +5V on Arduino
  Pin 6  ->  GROUND       -> GND for LED supply
  Pin 7  ->  +12V         -> +12V for LED supply
Use a 0.1uF capacitor between Pin 1 (sLATCH) and Pin 4 (GND) to prevent flicker on the display.
In this example I have added a Dallas 1 wire temp sensor for pin PB0 on the minimus, this is pin 8 in Arduino IDE
see www.re-innovation.co.uk for more details
Modified:
19/6/13  Matt Little  Changed to give just one output temperature
19/6/13  Matt Little  Removed Farenheit conversion
19/6/13  Matt Little  Added Buzzer alarm
 
*/
#include 
// This is for the serial shifted output data
const int sLatch = 0;   //Pin connected to ST_CP of 74HC595
const int sClk =  1;    //Pin connected to SH_CP of 74HC595
const int sData = 4;    //Pin connected to DS of 74HC595
const int led = 6;      //LED of Minimus
const int buzzer = 18;  // There will be a buzzer on pin PC5 which is Arduino pin 18
OneWire  ds(8);  // on pin 10 (a 4.7K resistor is necessary)
float temperatureC;  
// This line defines a "Uart" object to access the serial port
HardwareSerial Uart = HardwareSerial();
// Variables for the serial shift output display:
// This includes an 2 value 7 segment display
int displayArray[2]; // An array to store the data to display
void setup()
{
  //Serial.begin(9600);    // Set up a serial output for data display and changing parameters
  Uart.begin(38400);
  //set pins to output so you can control the shift register
  pinMode(sLatch, OUTPUT);
  pinMode(sClk, OUTPUT);
  pinMode(sData, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(buzzer, OUTPUT);   
}
void loop()
{
  // Get the temperature from the 1-wire device
  getTemperature();
  Uart.print("Temperature is:");
  Uart.println(temperatureC);
  
  // Here we convert the temperature into data to display on the 7-segment display:
  // Data is a float, we need to convert into an int and then look at each digit, by dividing by 10
  // The numbers are then put into displayArray
  convertDisplay(temperatureC);    
   // take the latchPin low so the LEDs don't change while you're sending in bits:
  digitalWrite(sLatch, LOW);
  // shift out the bits:
  // Send data via 3 shift registers:
  shiftOut(sData, sClk, MSBFIRST, displayArray[0]);  
  shiftOut(sData, sClk, MSBFIRST, displayArray[1]); 
  //take the latch pin high so the LEDs will light up:
  digitalWrite(sLatch, HIGH);  
  // Sound an alarm if too hot
  if(temperatureC>25)
  {
         tone(buzzer, 420, 30);
         delay(30);
         tone(buzzer, 460, 30);
         delay(30);
         tone(buzzer, 700, 30);         
         delay(30);
  }
  
  // Blink the LED (tell us I'm alive)
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(200);   // Delay for a second
  digitalWrite(led, LOW);   // turn the LED on (HIGH is the voltage level)
  delay(200);
}
// This function returns the correct binary value to display the integer
int int7segment (int segmentData)
{
  int displayData;
  
  switch (segmentData)
  {
    case 0:
      displayData = B11111100;  // The number 0 in binary   
    break;
    case 1:
      displayData = B01100000;  // The number 1 in binary   
    break;
    case 2:
      displayData = B11011010;  // The number 2 in binary   
    break;
    case 3:
      displayData = B11110010;  // The number 3 in binary   
    break;
    case 4:
      displayData = B01100110;  // The number 4 in binary   
    break;
    case 5:
      displayData = B10110110;  // The number 5 in binary   
    break;
    case 6:
      displayData = B10111110;  // The number 6 in binary   
    break;
    case 7:
      displayData = B11100000;  // The number 7 in binary   
    break;
    case 8:
      displayData = B11111110;  // The number 8 in binary   
    break;
    case 9:
      displayData = B11110110;  // The number 9 in binary
    break; 
    case 10:
      displayData = B00000001;  // Decimal point ON  
    break;
      
  }
  return displayData;
}
// This function takes in a int (0-99)
// This number is converted into 2 pieces (the two numbers)
// The pieces are converted into 7 segment display code
// They are inserted into the display array
void convertDisplay (int data) {
 
  // First blank out any unused bits:
  if (data<10)
  {
    // This displays the correct values from 0-9
    // Want to blank the first two digits
    displayArray[1] = int7segment(data);
    displayArray[0] = B00000000;    
    // The last bit can be displayed 
    
  }
  else
  {
    // Ths displays the correct values from 10-99
    // Want to blank the first digit
    displayArray[1] = int7segment(data%10); 
    displayArray[0] = int7segment(data/10); 
  }
}
// This subroutine gets the temperature from a 1 wire temp sensor
float getTemperature()
{
  
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Uart.println("No more addresses.");
    Uart.println();
    ds.reset_search();
    delay(250);
    return(0);  // Here we return with the temperature
  }
  
  Uart.print("ROM =");
  for( i = 0; i < 8; i++) {
    Uart.write(' ');
    Uart.print(addr[i], HEX);
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
      Uart.println("CRC is not valid!");
      return(0);
  }
  Uart.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Uart.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Uart.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Uart.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Uart.println("Device is not a DS18x20 family device.");
      return(0);
  } 
  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
  Uart.print("  Data = ");
  Uart.print(present, HEX);
  Uart.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Uart.print(data[i], HEX);
    Uart.print(" ");
  }
  Uart.print(" CRC=");
  Uart.print(OneWire::crc8(data, 8), HEX);
  Uart.println();
    // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t 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);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 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;
  Uart.print("  Temperature = ");
  Uart.print(celsius);
  temperatureC = celsius;
  Uart.print(" Celsius, ");
  Uart.print(fahrenheit);
  Uart.println(" Fahrenheit");
  
}

 

Add comment