Skip to content
XeveAbout code and problems

Using a TI LM35 temperature sensor with Arduino Mega

March 18, 2013 0 comments Article Uncategorized nspo

This is some code I wrote for fun to read the temperature from a TI LM35 temperature sensor and output the result with a speaker as morse code.

Note: Fig. 7 from the LM35 datasheet seems so have a different number in the current version of the datasheet

/*
 * Code to monitor temperature as measured by an LM35 sensor
 * Connect as shown in Fig. 7 of datasheet (+Vs to 5V, GROUND to GND, Vout+ to pOut, Vout- to pVGND)
 * 
 * I found one 1N4148 diode to be enough (-> raises GND by about 0.49V, so good until -49°C)
 * 
 * I used a 10 kOhm resistor instead of a 18 kOhm one
 * 
 * Outputs values via Serial and morses them with a speaker connected to a resistor -> pin pSpeaker and GND
 * 
 * Author: Nicolai Spohrer <nicolai@xeve.de>
 * License: GPL v3 <http://www.gnu.org/licenses/gpl-3.0.html>
 */
#include <Tone.h>

Tone tone1;
int freqs[] = {NOTE_A4, NOTE_A5};

int DOT_LENGTH = 75;  // morse dot length in ms


int pOut = 2; // pin to V_OUT of LM35
int pVGND = 1; // pin to GND of LM35 (to measure raise of ground voltage by connected diodes)
float REFERENCE_VOLTAGE = 2.56; // either 5.0 or 2.56 (Mega only)

int pSpeaker = 13;


void setup()
{
  tone1.begin(pSpeaker);
  Serial.begin(9600);
  if(REFERENCE_VOLTAGE == 2.56) {
    analogReference(INTERNAL2V56); // now one ADC step is 2.56V/1024=2.5mV^=0.25°C
  }
}

void loop(){ 
  readAndPrint(); 
  delay(5000);
  }

void readTemp(float &vOut, float &vVGND, float &vTemp, float &temp, float &roundTemp) {
  /*
   * vOut is output voltage of LM35 relative to Arduino ground
   * vVGND is "virtual" ground voltage (raised by diode) of LM35 relative to Arduino ground
   * vTemp is voltage difference between vVGND and vOut, ergo the actually important voltage
   * temp is temperature as float
   * roundTemp is temperature rounded to nearest 0.5
   * (remember the LM35 has only 0.5°C guaranteed accuracy at +25°C)
   */
   
   // 1024.0 because of 10 bit ADC resolution
   vOut = analogRead(pOut) * REFERENCE_VOLTAGE / 1024.0; // Vout+ in datasheet
   vVGND = analogRead(pVGND) * REFERENCE_VOLTAGE / 1024.0; //Vout- in datasheet
   vTemp = vOut - vVGND; //Vout in datasheet
  
   temp = vTemp * 100;
   roundTemp = round(temp * 2.0) / 2.0; // round to nearest 0.5
}

void readAndPrint() {
  float vOut, vVGND, vTemp, temp, roundTemp;
  
  readTemp(vOut, vVGND, vTemp, temp, roundTemp);
  
  Serial.print("vOut | vVGND | vTemp | temp | roundTemp : ");
  Serial.print(vOut); Serial.print(" | ");
  Serial.print(vVGND); Serial.print(" | ");
  Serial.print(vTemp); Serial.print(" | ");
  Serial.print(temp); Serial.print(" | ");
  Serial.println(roundTemp);
    
  if(roundTemp < 0) { 
    /*
     * If temperature is negative, morse a minus sign and continue with |temperature|
     */
    morse('-'); 
    roundTemp = -roundTemp;
  }

  /*
   * Extract the digits from the temperature reading
   */
  byte dec1 = ((int)(roundTemp*100))%10; //5 in 123.45
  byte dec0 = ((int)(roundTemp*10))%10; //4 in 123.45
  byte ten0 = ((int)roundTemp % 10); // 3 in 123.45
  byte ten1 = ((int)roundTemp % 100 / 10); // 2 in 123.45
  byte ten2 = ((int)roundTemp/100); // alternatively, ten2 = ((int) roundTemp % 1000 / 100), but roundTemp < 1000 anyway

  /*
   * +48 to convert from byte to char
   */
  if(ten2 != 0) { morse(ten2+48); }
  if(ten1 != 0) { morse(ten1+48); }
    
  morse(ten0+48); morse('.'); morse(dec0+48); morse(dec1+48); morseWordPause(); 
}

void morse(char chr) {
  switch(chr) {
    case '0':
      morseLong(5); morseCharacterPause();
      break;
    case '1':
      morseShort(1); morseLong(4); morseCharacterPause();
      break;
    case '2':
      morseShort(2); morseLong(3); morseCharacterPause();
      break;
    case '3':
      morseShort(3); morseLong(2); morseCharacterPause();
      break;
    case '4':
      morseShort(4); morseLong(1); morseCharacterPause();
      break;
    case '5':
      morseShort(5); morseCharacterPause();
      break;
    case '6':
      morseLong(1); morseShort(4); morseCharacterPause();
      break;
    case '7':
      morseLong(2); morseShort(3); morseCharacterPause();
      break;
    case '8':
      morseLong(3); morseShort(2); morseCharacterPause();
      break;
    case '9':
      morseLong(4); morseShort(1); morseCharacterPause();
      break;
    case '-':
      morseLong(1); morseShort(4); morseLong(1); morseCharacterPause();
      break;
    case '.':
      morseShort(1); morseLong(1); morseShort(1); morseLong(1); morseShort(1); morseLong(1); morseCharacterPause();
      break;
  }
}

void morseLong(int times) {
  for(int i=0; i<times; i++) {
      tone1.play(freqs[0], 3*DOT_LENGTH);
      delay(3*DOT_LENGTH + 1*DOT_LENGTH);
  }
}

void morseShort(int times) {
  for(int i=0; i<times; i++) {
      tone1.play(freqs[0], DOT_LENGTH);
      delay(DOT_LENGTH + 1*DOT_LENGTH);
  }
}

void morseWordPause() {
  delay(7*DOT_LENGTH);
}

void morseCharacterPause() {
  delay(3*DOT_LENGTH);
}

Leave a Reply Cancel reply

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

Calendar

March 2013
M T W T F S S
 123
45678910
11121314151617
18192021222324
25262728293031
    Sep »

Archives

  • January 2021
  • May 2020
  • April 2020
  • July 2018
  • May 2018
  • April 2018
  • March 2018
  • September 2015
  • August 2015
  • June 2015
  • March 2015
  • February 2015
  • September 2014
  • March 2013

Categories

  • Uncategorized

Copyright Xeve 2021 | Theme by ThemeinProgress | Proudly powered by WordPress