↑ Return to Projects

Print this Page

Temperature Central

The objective of this project was to build a little station to measure the temperature. To retrieve the temperature value, I used the LM35 sensor, wrote the value in 2 7-segment displays and sent it through the Serial port to Processing, in order for it to draw a graph of the temperature variation.

Project Status

Progress: 100%
Time Spent: 2h

Tools Needed

  • Arduino + USB Cable
  • IC LM35
  • IC 74HC595
  • 2 7-segment display’s
  • 220Ω resitors
  • Breadboards
  • Wires
  • Computer

Step 1 – One 7-segment display

This was the first time I used the 7-segment displays. I decided to investigate and I found this page on Arduino website that explains how to wire 8 LEDs to the Arduino, using only 3 digital outputs. If you are asking why didn’t I wire the segments directly to the Outputs, here is why: I could do that if I just needed I display, but my intention was to use 2 displays, and Arduino doesn’t have 14 digital Outputs.

What is a 7-segment display?

Basically, it’s a set of LEDs (7 or 8), arranged in way like you see on the left picture. If all those LEDs are ON, they will represent the number 8, but if we make different combinations, we can create all the other numbers from 0 up to 9.

The majority of them already has a dot point to deal with decimal numbers when using more than 1 display.

In this step, I built a simple code that would allow me to do a count-down and turn on a high-brightness LED at the ond of the count-down. A very simple thing, just to get used to the code.

Step 2 – Instead of 1 display, 2 displays => 2 ICs

This intermediate step consisted in adding another 7-segment display. This meant also to add another chip and a turnaround in the code. This time I left the buttons alone and made a sequence of numbers: 00, 11, 22, … , 88, 99, 00, 11, …

At this time, it had no interaction with the user, but my intention was to know how to handle 2 display’s at the same time.

Step 3 – The LM35 temperature sensor

In this step, I introduced the analog input of the sensor and passed that value to the display’s. Nothing special…

Step 4 – Processing

Taking into account that I had never explored Processing before, this projecto also allowed me to evolve in that way too…

I had to analyse each part I needed for it to work sepparately. Firstly, I pass the value from the Arduino Serial to Processing. At the Processing side, I needed some code waiting for that value and build a graph based on the data it receives. I also found it interesting to have some statistics, such as the achieved minimum and maximum since the program started running.

Video

Arduino Code

/**
 * Temperature Central (Arduino Code)
 *  by Ricardo Dias (2009)
 *   http://ricardo-dias.com/
 */

int latchPin = 8; // Pin ST_CP (latch) of 74HC595
int clockPin = 12; // Pin SH_CP (clock) of 74HC595
int dataPin = 11; // Data Pin of 74HC595

// variables that hold the data being sent to ShiftOut()
byte dataEsq;
byte dataDir;
byte esq[10];
byte dir[10];

int sensorPin = 0; // Analog Pin 0
int tempc = 0;     // Temperature Variable
int samples[8];    // Variables for better precision
int i;

void setup() {
  pinMode(latchPin, OUTPUT);
  Serial.begin(9600);

  // The way we write in binary in Arduino is by placing 'B' just in the start
  // Here are the equivalent codes for 0 - 9 digits
  // NOTE that these codes should be adjusted, because they depend on the
  // wiring done from displays to the ICs.
  esq[0] = B11101110;
  esq[1] = B10000010;
  esq[2] = B11011100;
  esq[3] = B11010110;
  esq[4] = B10110010;
  esq[5] = B01110110;
  esq[6] = B01111110;
  esq[7] = B11100010;
  esq[8] = B11111110;
  esq[9] = B11110110;

  dir[0] = B11101110;
  dir[1] = B00101000;
  dir[2] = B11001101;
  dir[3] = B01101101;
  dir[4] = B00101011;
  dir[5] = B01100111;
  dir[6] = B11100111;
  dir[7] = B00101110;
  dir[8] = B11101111;
  dir[9] = B01101111;

}

void loop() {
  // Get 8 samples of temperature
  for(i = 0; i<=7; i++){
    samples[i] = ( 5.0 * analogRead(sensorPin) * 100.0) / 1024.0;
    tempc = tempc + samples[i];
    delay(50);
  }
  tempc = tempc/8.0; // Calcula-se a média

  // Send it right away to Processing
  Serial.print(tempc,DEC);
  
  // Calc left and right digits
  int num1 = 0;
  do{
    num1++;
    tempc = tempc - 10;
  }while(tempc >= 10);
  
  dataEsq = esq[num1];
  dataDir = dir[tempc];

  // Enquanto estivermos a transmitir, o pino "latch" tem de estar a LOW
  digitalWrite(latchPin, 0);

  // Send bytes
  shiftOut(dataPin, clockPin, dataDir);
  shiftOut(dataPin, clockPin, dataEsq);

  // Let the LATCH pin be HIGH again, so he is informed we stopped sending data
  digitalWrite(latchPin, 1);
}

// The shiftOut function
// More info about ShiftOut in: http://www.arduino.cc/en/Tutorial/ShiftOut
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  for (i=7; i>=0; i--)  {
    digitalWrite(myClockPin, 0);
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }
    digitalWrite(myDataPin, pinState);  
    digitalWrite(myClockPin, 1);
    digitalWrite(myDataPin, 0);
  }

  digitalWrite(myClockPin, 0);
}

Processing Code

/**
 * Temperature Central (Processing Code)
 *  by Ricardo Dias (2009)
 *   http://ricardo-dias.com/
 */

import processing.serial.*;

// Main Window Definitions
final int WIDTH = 400;
final int HEIGHT = 200;
final int winW = 200;
final int winH = 160;

Serial myPort;  // Object for Serial communication
int val = 20;   // Received data from Serial
int x = 1;
int valAnt = 21; // last value

String inString = "0";

PFont title;
PFont texto;

int first = 1;

int valMax = 0;
int valMin = 0;

void setup()
{
  size(WIDTH,HEIGHT);
  background(200);

  String portName = Serial.list()[4]; // change 4 to whatever id your port has
  myPort = new Serial(this, portName, 9600);
  myPort.buffer(2);
  while(myPort.available() == 0);
  clear();
  title = createFont("Verdana", 12);
  texto = createFont("Verdana", 10);
}

void draw()
{
  int val = 20;
  val = Integer.parseInt(inString) + 21;
  int valAbs = val - 21;

  if(first == 0){

    if(val != 0){
      stroke(100);
      fill(100);
      rect(x, 21, 10, winH-2);

      if(x > winW){
        rect(x - winW + 21, 21, 10, winH-2);
      }

      stroke(255);
      line(x , HEIGHT - valAnt, x+1 , HEIGHT - val);

      if(valAbs > valMax){ valMax = valAbs; }
      if(valAbs < valMin){ valMin = valAbs; }

    }
  }else{
    valAnt = val;
    valMin = valAbs;
    valMax = valAbs;
    first = 0;
  }

  x++;
  valAnt = val;
  delay(50);

  if(x == winW + 20)
  {
    x = 41;
    //clear();
  }

  showStats(val, valMax, valMin);
}

void serialEvent(Serial p) {
  inString = p.readString();
}

void clear(){
  stroke(0);
  background(200);
  x = 41;
  fill(100);
  rect(20, 20, 20+winW, winH);
}

void showStats(int val, int vMax, int vMin)
{
  // BOX Current Value
  stroke(0);
  fill(129,139,149);
  rect(60 + winW, 20, 120, 40);
  fill(189,199,209);
  textFont(title);
  text("Current Val",60 + winW, 25, 120, 40);
  textAlign(CENTER);

  fill(255,255,255);
  textFont(texto);
  text(inString , 60 + winW, 40, 120, 40);
  textAlign(CENTER);

  // BOX Max Value
  stroke(0);
  fill(129,139,149);
  rect(60 + winW, 80, 120, 40);
  fill(189,199,209);
  textFont(title);
  text("Max Value",60 + winW, 85, 120, 40);
  textAlign(CENTER);

  fill(255,255,255);
  textFont(texto);
  text(Integer.toString(vMax) ,60 + winW, 100, 120, 120);
  textAlign(CENTER);

  // BOX Min Value
  stroke(0);
  fill(129,139,149);
  rect(60 + winW, 140, 120, 40);
  fill(189,199,209);
  textFont(title);
  text("Min Value",60 + winW, 145, 120, 40);
  textAlign(CENTER);

  fill(255,255,255);
  textFont(texto);
  text(Integer.toString(vMin) ,60 + winW, 160, 120, 120);
  textAlign(CENTER);
}

Permanent link to this article: http://ricardo-dias.com/projects/temperature-central/

2 comments

  1. William Massano

    I am adding a LM35 family sensor to a project, but from my reading of the specs, what you call tempc is actually the temperature in Kelvin. The sheet says the voltage at 25C will be 2.982 (which is 298.2 K=25C!) Multiplying the analog read value by 500/1024 converts it to a voltage between 0 and 500 which corresponds to a temperature of 0 to 500K or -273 to 227C. Am I missing something???

  2. Ricardo

    Very nice website, and really nice and easy to follow tutorial, congrats.

Leave a Reply to William Massano Cancel reply

Your email address will not be published. Required fields are marked *