10
10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 1/10 10,118,810 members (52,152 online) Sign in home quick answers discussions features community help Search for articles, questions, tips Articles » Desktop Development » Desktop Gadgets » General Article Browse Code Stats Revisions (23) Alternatives Comments & Discussions (83) About Article Hardware interfacing through serial port using C# Type Article Licence CPOL First Posted 28 Jul 2009 Views 216,038 Downloads 4,258 Bookmarked 202 times WinXP Win2003 Vista C#1.0 C#2.0 C#3.0 , + Top News Tim Cook slams Android, citing low usage Get the Insider News free each morning. Related Videos Related Articles Matrix Multiplication in C# Creating animations with Dundas Chart for ASP.NET Smarter Data Labels with Dundas Chart SmartLabels Understanding Chart Areas with Dundas Chart for .NET A Formatted Text Box Using screensavers inside the Windows Media Player Making Sense of Geographic Data with Dundas Map and AJAX Next Sign Up to vote Digital Thermometer Using C# and ATmega16 Microcontroller By HiteshSharma, 1 Jul 2013 Download source - 260 KB Introduction We all have thermometers in our homes but what when it comes to seeing it digitally on your computer or to keep a record of it in your computer, it is very difficult. To provide such an ease, I have created a piece of hardware to detect temperature and to interface it with the computer so that the temperature can be shown or recorded there. Note: This application requires some hardware to send relevant data to the application through a serial port. Without such a device, it won't work. Contents Procedural Steps Hardware Details Software Details Configuring Serial Port Receiving Data Sampling Data Creating Graphics Displaying Data Procedural Steps Temperature Sensor ----> Atmega16 microcontroller ------> computer Serial Port 4.90 (81 votes) Like 43 0 Tweet 6 articles

Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

Embed Size (px)

DESCRIPTION

DB18B20

Citation preview

Page 1: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 1/10

10,118,810 members (52,152 online)

Sign in

home quick answers discussions features community help Search for articles, questions, tips

Articles » Desktop Development » Desktop Gadgets » General

Article

Browse Code

Stats

Revisions (23)

Alternatives

Comments &Discussions (83)

About Article

Hardware interfacingthrough serial port using C#

Type Article

Licence CPOL

First Posted 28 Jul 2009

Views 216,038

Downloads 4,258

Bookmarked 202 times

WinXP Win2003 Vista

C#1.0 C#2.0 C#3.0 , +

Top News

Tim Cook slams Android,

citing low usage

Get the Insider News free eachmorning.

Related Videos

Related Articles

Matrix Multiplication in C#

Creating animations withDundas Chart for ASP.NET

Smarter Data Labels withDundas Chart SmartLabels

Understanding Chart Areas withDundas Chart for .NET

A Formatted Text Box

Using screensavers inside theWindows Media Player

Making Sense of GeographicData with Dundas Map andAJAX

Next

Sign Up to vote

Digital Thermometer Using C# and ATmega16

MicrocontrollerBy HiteshSharma, 1 Jul 2013

Download source - 260 KB

Introduction

We all have thermometers in our homes but what when it comes to seeing it digitally on your computer or to keep a

record of it in your computer, it is very difficult. To provide such an ease, I have created a piece of hardware to detect

temperature and to interface it with the computer so that the temperature can be shown or recorded there.

Note: This application requires some hardware to send relevant data to the application through a serial port. Without

such a device, it won't work.

Contents

Procedural Steps

Hardware Details

Software Details

Configuring Serial Port

Receiving Data

Sampling Data

Creating Graphics

Displaying Data

Procedural Steps

Temperature Sensor ----> Atmega16 microcontroller ------> computer Serial Port

4.90 (81 votes) Like 43 0 Tweet 6

articles

Page 2: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 2/10

Handling connectionnotification between a desktopmachine and Windows CEbased devices

Create data-driven applicationswith the Hera ApplicationFramework

Towards the self-documentingdatabase: extended properties

Accessibility audit vs.accessibility testing

Digital Signatures and PDFDocuments

Color Scale Filter

WMP Power Hour APP

Merge Landscape and PortraitPDFs using ASP.NET

How to conduct an SMS surveyusing a cell phone connectedSMS gateway and MS Access

Using Barcodes in Documents –Best Practices

How to Retrieve EMC CenteraCluster/Pool Capabilities

Embedding IronPython in WPFUsing C#

"Hey! Is That My Car? How toSharpen a QuickBird SatelliteImage Using DotImage"

Integrate your SharePointenvironment into the openstandards-based WebSpherePortal platform using the VisualStudio IDE

(LM35) (sender) (receiver)

Here what I try to explain is that a temperature sensor LM35 detects the temperature and passes a corresponding

scaled voltage to the microcontroller which converts it into digital data.

This digital data is our temperature reading which is then transmitted to our application via serial port on our

computer, using Asynchronous Serial Transmission between the microcontroller and the computer.

This is the temperature sensor.

This is our atmega16 microcontroller which creates a digital temperature reading and transfers it to the computer. It's

an 8-bit microcontroller with a 16KB flash memory enough for long programs. For programming my microcontroller, I

used the AVR Studio 4 platform and the C language.

The code for the microcontroller just includes reading the sensor continuously and transmitting that data to our C#

application through a serial port.

The code for the microcontroller is as follows:

Collapse | Copy Code

#include<avr/io.h>#include<avr/interrupt.h>#define FOSC 12000000// Clock Speed#define F_CPU 12000000ul#define BAUD 9600#define MYUBRR (FOSC/16)/BAUD -1//#include<util/delay.h>

//initialise USARTvoid USART_Init( unsigned int ubrr){//Set baud rate UBRRH = (unsigned char)(ubrr>>8);UBRRL = (unsigned char)ubrr;//Enable receiver and transmitter UCSRB = (1<<RXEN)|(1<<TXEN);//Set frame format: 8data, 2stop bit, NO parityUCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);}

//Initialise A to D convertervoid ADC_Init(){

Page 3: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 3/10

//enable adc

ADCSRA |= (1<<ADEN);

//enable interrupts

ADCSRA |= (1<<ADIE);

//set reference selection to Vcc;//left adjust result//set voltage selection to bit 7 of portA

ADMUX |= (1<<REFS0) | (1<<ADLAR) | (1<<MUX2) | (1<<MUX1) | (1<<MUX0);

//set prescalar to 128

ADCSRA |= (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);// | (1<<ADATE);}

//Transmit Datavoid USART_Transmit( unsigned char data ){/* Wait for empty transmit buffer */while ( !( UCSRA & (1<<UDRE)) );/* Put data into buffer, sends the data */UDR = data;}

//Interrupt A to D converter readingISR(ADC_vect){unsigned char c;

//variable c stores data from ADCH register

c=ADCH;

USART_Transmit(c);//next statement starts a new ADC conversion

ADCSRA |= (1<<ADSC);}

int main( void ){USART_Init ( MYUBRR );ADC_Init();sei();

//start an adc conversion

ADCSRA |= (1<<ADSC);while(1);}

Monitoring More Than One Sensor at a Time

Note: If you are new to microcontrollers and this is one of your first projects, then I suggest you to implement the

above code only and work with one sensor. If you think you can, then nothing's better than that and go ahead.

This thing was demanded by a person (I guess Mr. Joel), that's why I am adding it here.

This shows how you can monitor up to 8 temperature sensors and pass their data to your computer.

In the ADMUX register of the Atmega16 microcontroller, bits MUX4.....MUX0 (5 bits) control data from which pin of

PORT A (out of 8 pins) will be used for digital conversion so that it could be transmitted to the computer.

Here our basic idea is that after each conversion, we will keep on changing the pin from which the reading is to be

taken. This way we will read through PIN0 to PIN7 (all 8 one by one) and then again back to PIN0.

Below I show what value of MUX4....MUX0 bits in the ADMUX register selects the channel (PIN of PORT A).

MUX4....MUX0PORTA PIN which will be

read

00000 PIN 0

00001 PIN 1

00010 PIN 2

00011 PIN 3

00100 PIN 4

00101 PIN 5

00110 PIN 6

00111 PIN 7

Page 4: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 4/10

Now to implement it properly in code, we have the idea that as soon as a conversion completes and Interrupt Service

Routine (ISR) is called, we will change the PIN for the next conversion. Here is how to do this:

Collapse | Copy Code

ISR(ADC_Vect){ //code for reading and transmitting conversion ( shown above as well)unsigned char c;c=ADCH; USART_Transmit(c);

//Now read the value of MUX4,MUX3, MUX2, MUX1 & MUX0 bits of ADMUX register//and increment it by one if less than 8 else make it 0.

unsigned char d;

d = ADMUX & 0x1F;

if(d < 7) { d = d + 1; ADMUX |= d;}else{ ADMUX |= 0;}

//Now start a new conversion which will read the next PIN now ADCSRA |= (1<<ADSC); }

Schematic

The temperature sensor is connected to the microcontroller only.

Many people out here demanded for a schematic, so here I am adding the connection diagrams. Hope this serves the

purpose.

Below is the connection diagram of the Atmega16 microcontroller with sensor LM35 (on the right). To the left in the

image is the Crystal Oscillator required in case someone wants a higher operating frequency than the internal 1MHz of

the microcontroller (it serves the purpose). In case you are satisfied with internal frequency, then don't add this Crystal

oscillator.

Now comes the point of how to connect the hardware to the computer through a serial port. For this, you should

know that the computer serial port adds at around 10v whereas a microcontroller operates at around 5v. So for

effective communication, we need a level converter (which may convert the ongoing voltages as per the devices on

both sides). IC MAX232 serves this purpose, it's a general purpose cheaply available IC with just a simple connection as

shown below:

Page 5: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 5/10

So this was the hardware detailing. Now I will discuss some software part.

Software Details

In this section, I will discuss the code of my application which is used to get temperature readings from the serial port

and display it. By now, the data is available on our computer's Serial Port, all we now need is an application to retrieve

it, which is done here.

Configuring the Serial Port

Now what comes first is configuring the Serial Port, i.e., fix the Baud Rate, set Parity, number of Data Bits to be received

in a single packet of data, and number of Stop Bits to be used.

First of all, we create a global System.IO.Ports.SerialPort object port in our class definition, which is then

initialized in the Load event of the Form.

And also a few variables which hold the values to be set for the properties of the port object.

portname holds the name of the serial port. In my computer, it was COM4.

voltage holds the reference voltage, which is actually the Vcc voltage of the microcontroller board and is set

manually in this application. 4.65 volts here.

parity holds the type of parity to be used in serial communication between the computer and the

microcontroller, i.e., Even Parity, Odd Parity, or No Parity. I have not used any parity.

BaudRate holds the value of Baud Rate of the serial communication. I settled for a Baud Rate of 9600 bps.

StopBits holds the number of stop bits to be used. The possible values are 1, 2, or none. I have used 2 stop

bits.

And finally the databits variable which defines how many data bits are to be received during communication.

It's always a good choice to use 8 data bits, as it's a standard byte size, so it becomes easier to manipulate it.

Collapse | Copy Code

public partial class Thermometer : Form{ public Thermometer() { InitializeComponent(); } System.IO.Ports.SerialPort port; static public double voltage; static public string portname; static public Parity parity; static public int BaudRate; static public StopBits stopbits; public int databits; private void Form1_Load(object sender, EventArgs e) { portname = "COM4"; parity = Parity.None; BaudRate = 9600; stopbits = StopBits.Two; databits = 8;

port = new System.IO.Ports.SerialPort(portname); port.Parity = parity; port.BaudRate = BaudRate; port.StopBits = stopbits; port.DataBits = databits;

Page 6: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 6/10

port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived); port.Open(); }

These were the serial port settings. The same communication settings are used in the microcontroller so that

communication can take place effectively.

Receiving Data

After the Serial Port is opened by calling the port.open() method, the serial port is ready for receiving the data

arriving at it.

DataReceived: To receive data at the application, we need to handle the DataReceived event of the

SerialPort class.

port.Read method reads data from the COM4 serial port and writes it into a single variable byte array bt.

Collapse | Copy Code

void port_DataReceived(object sender, SerialDataReceivedEventArgs e){ // read one byte data into bt port.Read(bt,0,1); // all the code to sample data}

Sampling Data

The basic idea behind sampling data is that as the readings are received continuously, we take 100 values and calculate

their average value so that a much fairer temperature reading is available. This gives us a single temperature reading to

display.

To carry out this calculation, a global double variable sum and an int variable count are created.

sum adds up subsequent temperature readings and count counts up the number of readings to see whether they

have reached 100 or not.

This code comes under the DataReceived event only ahead of the above code:

Collapse | Copy Code

// the calculation on the right hand side calculates// the temperature from the read valuesum += Convert.ToDouble(bt[0]) *voltage*100/255; //this counts to 100count++;

Now as soon as the count reaches 100, the calculated sum value is averaged by dividing it by 100. This sampled value

is then stored in a double temp variable, sum and count are again set to 0 value.

Collapse | Copy Code

// single temperature readingtemp = sum / 100;sum = 0;count = 0;

Now that we have a temperature reading with us, the next task is to calculate the angle of the arm so that the

calculated temp could be displayed on the round meter image.

The angle will be stored in a variable angle. Now before calculating angle, simply have a look at the round meter. The

angle between certain values doesn't vary uniformly, that is between 20 - 30, the angle is less as compared to between

30 - 40 and 40 - 50 (see the above image).

So before calculating the angle, this needs to be taken care of.

By some analysis, I found some angles beginning from the 50 value on the meter as being a 0 degree value.

Creating Graphics

Basically creating graphics like this means that whenever a temperature value is obtained, the arm should not just get

set to that reading on the meter but it should move there by subsequent rotation (as in some analog meter where the

arm moves from an initial value to an final value).

To achieve this a method named Animate is created which animates the arm from an initial reading to a final reading.

The method takes Currentangle and FinalAngle as arguments.

This method increases the value of the variable Currentangle by 1 in each step and keeps on calling itself recursively

until the value reaches the FinalAngle value. At each step, the form1.Paint event is raised through code to render

the value onto screen.

Collapse | Copy Code

private void Animate(double Currentangle, double FinalAngle)

Page 7: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 7/10

{ // if Final angle is negative then make it positive if (FinalAngle < 0) FinalAngle += 360;

// if final angle is greater than 360 degree then reduce it if (Currentangle >= 360) { Currentangle = Currentangle - 360; }

// if current angle is not within +0.5 and -0.5 of // the final angle value then execute if block if (!(Currentangle > FinalAngle-0.5 && Currentangle < FinalAngle + 0.5)) { if (Currentangle > FinalAngle) { //decrement Currentangle Currentangle -= 1; } else { //else Increment Current angle Currentangle += 1; } Form1_Paint(this, new PaintEventArgs(surface, DrawingRectangle)); Animate(Currentangle, FinalAngle); }}

Now with this, our code to create animations is over. Next comes creating graphics on the screen.

Displaying Data

For creating a meter on the screen, it is necessary that there should be no flickering of the screen as the graphics are

created, so ensure that we use Buffered Graphics.

For this, a BufferedGraphics object buff is created and is initialized in the Load event of the form. Also a

System.Drawing.Graphics object surface is created which just represents the graphics surface at which the

images are drawn.

Collapse | Copy Code

// create buffered graphics object for area of the form by using this.Bounds

buff = BufferedGraphicsManager.Current.Allocate(this.CreateGraphics(),this.Bounds); surface = buff.Graphics;

//ensure high quality graphics to users

surface.PixelOffsetMode = PixelOffsetMode.HighQuality;surface.SmoothingMode = SmoothingMode.HighQuality;

Now moving onto the final Paint event of the form. Here first of all, we hold the images of the round meter and the

meter arm in the Image class objects img and hand.

After this, the meter is drawn on the Form. The arm is rotated to the calculated angle and is drawn on the screen. The

temperature is drawn on the screen by calling the DrawString method.

All of the code is written in a try - catch block and an InvalidOperationException is caught which ensures

that if in some case graphics fails to render on the screen, then nothing causes the application to crash.

Collapse | Copy Code

private void Form1_Paint(object sender, PaintEventArgs e){ try { Image img = new Bitmap(Properties.Resources.speedometer, this.Size); Image hand = new Bitmap(Properties.Resources.MinuteHand) surface.DrawImageUnscaled(img, new Point(0, 0)); surface.TranslateTransform(this.Width / 2f, this.Height / 2f); surface.RotateTransform((float)CurrentAngle); surface.DrawImage(hand, new Point(-10, -this.Height / 2 + 40)); string stringtemp = displaytemp.ToString(); stringtemp = stringtemp.Length > 5 ? stringtemp.Remove(5, stringtemp.Length - 5) : stringtemp; Font fnt = new Font("Arial", 20); SizeF siz = surface.MeasureString(stringtemp, fnt); surface.ResetTransform(); LinearGradientBrush gd = new LinearGradientBrush(new Point(0,(int)siz.Height + 20), new Point((int)siz.Width,0), Color.Red, Color.Lavender); surface.DrawString(stringtemp, fnt, gd, new PointF(DrawingRectangle.Width / 2 - siz.Width / 2, 70));

surface.DrawEllipse(Pens.LightGray, DrawingRectangle);

surface.Save(); buff.Render();

Page 8: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 8/10

HiteshSharma

India

I am a siebel developer by profession and a C#, ASP.Net, Javascript, C, C++ developer by Hobby. I

code mostly for fun and usually code to create utilities and applications to enhance, improve and

ease out my work while working on my computer. I try to make my computer a better place to

code. I work on electronics as well and like to create hardware which may integrate with my

computer. Now a days i code mostly for web and spend more and more of my time on javascript.

visit my blog at: http://msphitesh.blogspot.in

Follow on Google

Article Top

Search this forum Go

} catch(InvalidOperationException) { //code to handle exception }}

This finishes the coding part of the application.

Another interesting project which I have is to switch 230 - 250 volt A.C. home appliances from computer through a C#

application.

A pure software application which I also plan to write here is the Isolated Storage. Copy or cut your files and folders

and paste it in the GUI provided by this application, and then just delete them from your computer. It will store your

data in the Isolated Storage area on the hard disk and it will be visible to you through this application only. Copy it

from this application and paste it back to your file system. No data will be lost. I plan to write it here as well soon....

Conclusion

With this, I have provided the idea for hardware interfacing through serial port using C# applications. Anyone like me

who likes developing hardware for personal use would have enjoyed reading this article. This is the second time I am

writing this article as it wasn't liked much earlier due to lack of explanation. I hope things are better this time up.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Comments and Discussions

You must Sign In to use this message board.

Profile popups Spacing Relaxed Noise Very High Layout Normal Per page 10 Update

Page 9: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 9/10

Permalink | Advertise | Privacy | Mobile Web01 | 2.6.1309030.1 | Last Updated 1 Jul 2013

Article Copyright 2009 by HiteshSharmaEverything else Copyright © CodeProject, 1999-2013

Terms of Use

Layout: fixed | fluid

First Prev Next

patodi 16-Jul-13 23:14

HiteshSharma 22-Aug-13 20:34

dpalash 1-Jul-13 0:44

Member 8807328 10-Apr-12 6:53

Abinash Bishoyi 30-Mar-12 1:38

P1119r1m 5-Nov-11 7:23

unbeliever1 24-Aug-11 0:58

benbas 24-Jul-11 6:25

JF2015 20-Jan-11 2:03

thatraja 9-Dec-10 19:27

Last Visit: 31-Dec-99 18:00 Last Update: 1-Oct-13 16:11 Refresh 1 2 3 4 5 6 7 8 9 Next »

General News Suggestion Question Bug Answer Joke Rant Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

error while running...

Re: error while running...

My vote of 5

Nice one

My vote of 5

My vote of 5

negative thermometer [modified]

compliments sir

My vote of 5

My vote of 5

Page 10: Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

10/2/13 Digital Thermometer Using C# and ATmega16 Microcontroller - CodeProject

www.codeproject.com/Articles/38459/Digital-Thermometer-Using-Csharp-and-ATmega16 10/10