Using a TI LM35 temperature sensor with Arduino Mega
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);
}
Recent Posts
- Vorabpauschale: Theoretische zu versteuernde Rendite seit 1987
- Untersuchung der Kosten der gesetzlichen Kranken- und Pflegeversicherung in Deutschland 1962 – 2026
- Spanish Juggling problem
- Changing the maximum upload file size with Nextcloud in a docker-compose setup
- Shrinking a QNAP Virtualization Station disk image
Recent Comments
- Vorabpauschale: Theoretische zu versteuernde Rendite seit 1987 - Xeve on Untersuchung der Kosten der gesetzlichen Kranken- und Pflegeversicherung in Deutschland 1962 – 2026
- Andreas on Shrinking a QNAP Virtualization Station disk image
- Arjun on Fix for Latex4CorelDraw with CorelDraw 2017
- Harald H on Automatically reboot TP-Link router WDR4300 / N750 with bash script
- Gene on Running multiple Django projects on one Apache instance with mod_wsgi
Leave a Reply