Digital Thermometer

140 downloads 0 Views 3MB Size Report
Jan 16, 2018 - For the scope of this project we used the Arduino UNO to control the MCP9808 digital temperature sensor, with a typical/maximum accuracy of.
Data Sheet

MartinosTEAM

16/01/2018

Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor Introduction The purpose of this project was to learn how to program a microcontroller and build pc software which communicates with the microcontroller. Send commands to the microcontroller and receive data from a sensor. As a platform for the microcontroller we used the Arduino UNO R3 development board which is the most popular and documented product of the whole Arduino family. The Arduino UNO is a microcontroller board based on the ATmega328P. It has 14 digital input/output pins, 6 analog inputs, a USB connection, a power jack and everything needed to support the microcontroller. For the scope of this project we used the Arduino UNO to control the MCP9808 digital temperature sensor, with a typical/maximum accuracy of ±0.25°C/±0.5°C over the sensor's -40°C to +125°C range. The MCP9808 comes from Adafruit as a breakout board PCB with a library for the Arduino, which makes it very easy to connect and get readings from the sensor. We used the Arduino IDE software to write the code for the microcontroller and uploaded it to the board. For the PC software we used the Visual Studio Community edition and wrote a windows form application in C# which communicates with the Arduino UNO via the COM port. Figure 1 shows the GUI for the PC software. We also, made an extension board "module" (see Figure 2) which connects to the Arduino Uno via pin headers. The circuit for the "module" was made on a PCB universal prototyping board 70X90mm. On the board we placed a 16X2 LCD character display which connects to the board via pin headers, the temperature sensor which is also connects to the board via pin headers, a Potentiometer to control the contrast of the LCD, a buzzer, 5 DIP switches, a LED and 7 resistors.

John Martinos

[email protected] http://www.researchgate.net/profile/J_Martinos LinkedIn: John Martinos

Themis Martinos

[email protected] http://www.researchgate.net/profile/Themis_Martinos LinkedIn: Themis Martinos

Figure 1. Graphical User Interface "GUI" for the PC software.

Following in the datasheet you will find the codes for the Microcontroller and the PC software. You can freely copy and modify those codes, in order to fit in your projects.

Page 2: Schematic and connection diagrams for the "module" Page 3: User guide for the "module" Page 4: User guide for the PC software Page 5: Code for the microcontroller Page 6: Code for the PC software Figure 2. Parts for the project.

[1]

Martinos TEAM 16/01/2018

Schematic and Connections Diagrams for the "Module" Published on Research Gate

8

11

1: Arduino Uno R3 2: LCD 16X2 Characters 3: MCP9808 Temp. Sensor 4: Buzzer 5V, 12mm 5: 220Ω Resistor 6: 220Ω Resistor 7: 4kΩ Potentiometer 8: LED 9: 10kΩ Resistor 10: 1kΩ Resistor 11: DIP Switch 5 Position

9

1 0 10 00 00

We used the Fritzing software to design the schematic diagram for the module (see Figure 3) which is connected to the Arduino UNO. Figure 4, shows the connections for the "module". Figure 5, shows the names for the pin headers of Arduino UNO.

5

6

7 4

3

Figure 3. Schematic diagram for the "module".

2 PIN9

RS

PIN10

E

PIN11

DB4

PIN12

DB5

PIN13

DB6

PIN14

DB7

PIN15

5V

PIN16

GND

Figure 4. Connections diagram for the "module". Martinos John and Martinos Themis

Connections DB7 DB6 DB5 DB4 E RS PIN9 PIN10 PIN11/SDA PIN12/SCL PIN13 PIN14 PIN15 PIN16

→ → → → → → → → → → → → → →

Digital Pin 2 Digital Pin 3 Digital Pin 4 Digital Pin 5 Digital Pin 12 Digital Pin 13 Digital Pin 6 Digital Pin 7 Analog Pin A4 Analog Pin A5 Digital Pin 8 Digital Pin 9 Digital Pin 10 Digital Pin 11

Figure 5. Arduino UNO R3.

[2]

Martinos TEAM 16/01/2018

User Guide for the "Module" Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

At the startup the UNO prints the message "Digital Thermometer" on the LCD display.

If the switch 3 is ON the reading speed is 2 sec.

If the switch 4 is ON the reading speed is 1 sec. After a delay of 1 sec the UNO search for the MCP9808 temperature sensor and check if the connection is correct. If the connection is correct, then it prints the message "Connection to MCP9808 Success" to the LCD.

If the switch 5 is ON the reading speed is 0.01 sec.

If the UNO cannot find the MCP9808 for some reason, then it prints the message "Connection to MCP9808 Failed" to the LCD.

If the switch 1 is ON the UNO waits for commands by the PC software.

After a delay of 1 sec the UNO checks whether the switch 1 is ON or OFF. If switch 1 is OFF then the UNO run as a standalone device and prints the readings from the MCP9808 to the LCD both for Celsius and Fahrenheit values. Also, in this case it is not allowed to the PC Software to connect with the UNO. The USB cable now it is used as a power supply for the UNO. Instead of USB cable you can use the 9V battery with the jack adapter to power the device. In this state the UNO reads the MCP9808 every 0.5 sec.

If we want to change the reading speed of the MCP9808, then we turn ON the switches 2, 3, 4 & 5. Every switch corresponds to different speed. If the switch 2 is ON the reading speed is 3 sec.

Switch 1

Switch 5 Switch 4 Switch 3 Switch 2

Martinos John and Martinos Themis

[3]

Martinos TEAM 16/01/2018

User Guide for the PC Software Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

Using Visual Studio Community edition we wrote a windows form application in C# which communicates with the UNO via the COM port. The figure below shows the GUI for the PC software at the startup. By default the program has preselected the Celsius and the reading speed at 50%.

As the "Connect" button is pressed, the software is searching all the available COM ports for the UNO. First the software gets all the available COM ports names. Then it sends a buffer with 3 bytes (4, 8 and 16) to each port until it receives the message "I'M ARDUINO". If the software cannot find the UNO then it prints to message line "Not connected". This will happen either because the UNO is not connected to the PC, or if it is connected the switch 1 on the "module" is OFF.

line represents the number of the loops. We control the delay for the loops via the track bar. The minimum value for the "Track Bar" is 1 (lowest speed) and the maximum value is 3000 (maximum speed). The current value of the temperature is printed on the right and above the graph. If we select the Fahrenheit ratio button, then the graph is cleared and the values now are on Fahrenheit.

When the ratio button Celsius is selected it appears the following menu on the LCD display.

When the ratio button Fahrenheit is selected it appears the following menu on the LCD display.

When the connection to the UNO is established, then the software prints in the message line the text "Connection Successful Connected to COM5". In our case it is COM5, but it can vary from PC to PC.

With the "Clear" button we can clear the current graph and start a new one. Finally, as long we control the UNO via the PC software, the control switches 2, 3, 4 & 5 on the "module" are not used and we can control the speed only with the "track bar".

The readings from the temperature sensor are printed on the graph as it shows the figure above. The vertical line of the graph represents the value of the temperature on Celsius or Fahrenheit. The horizontal line represents the number of the loops. The horizontal Martinos John and Martinos Themis

[4]

Martinos TEAM 16/01/2018

Code for the microcontroller Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

We used the Arduino IDE software to write the code for the microcontroller and uploaded it to the board. Following you can see the code. /* Project: Digital Thermometer Using Arduino and MCP9808 Digital Temperautre Sensor Team: John & Themis Martinos Date: 10/01/2018 We wrote the code for the Arduino in order to operate in two ways. When switch 1 is OFF, the Arduino run as a standalone device. In this case we can change the speed at which we get the readings from the sensor by controlling the switches 2, 3, 4 & 5. When switch 1 is ON, the Arduino wait for commands from the PC software. In this case the speed at which we get the readings from the sensor is controlled by the PC software. */ #include #include "Adafruit_MCP9808.h" // Create the MCP9808 temperature sensor object Adafruit_MCP9808 tempsensor = Adafruit_MCP9808(); // include the library code: #include // initialize the library by associating any needed LCD interface pin // with the arduino pin number it is connected to const int rs = 13, en = 12, d4 = 5, d5 = 4, d6 = 3, d7 = 2; LiquidCrystal lcd(rs, en, d4, d5, d6, d7); //Setup message bytes byte inputByte_0; byte inputByte_1; byte inputByte_2; const int buzzer = 7; // buzzer to arduino pin 9 int buzzerOnOff1 = true; int buzzerOnOff2 = true; int buzzerOnOff3 = true; int buzzerOnOff4 = true; int buzzerOnOff5 = true; int buzzerOnOff6 = true; int val = 0; int speed1 = true; int speed2 = true; int speed3 = true; byte usb1[] = { B01100, Martinos John and Martinos Themis

B01100, B01100, B01111, B00111, B00000, B00000, B00000 }; byte usb2[] = { B01111, B11111, B11111, B11111, B11111, B11111, B11111, B01111 }; byte usb3[] = { B00000, B11111, B11011, B11111, B11111, B11011, B11111, B00000 }; byte LoopSpeed1[] = { B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111 }; byte LoopSpeed2[] = { B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111 }; byte LoopSpeed3[] = {

[5]

Martinos TEAM 16/01/2018

Code for the microcontroller Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111 }; byte LoopSpeed4[] = { B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111 }; void setup() { lcd.createChar(1, usb1); lcd.createChar(2, usb2); lcd.createChar(3, usb3); lcd.createChar(4, LoopSpeed1); lcd.createChar(5, LoopSpeed2); lcd.createChar(6, LoopSpeed3); lcd.createChar(7, LoopSpeed4); pinMode(buzzer, OUTPUT); // Set buzzer - pin 9 as an output tone(buzzer, 3000); // Send 1KHz sound signal... delay(20); // ...for 0.02 sec noTone(buzzer); // Stop sound... pinMode(6, INPUT); pinMode(8, INPUT); pinMode(9, INPUT); // set up the LCD's number of columns and rows: lcd.begin(16, 2); Serial.begin(9600); analogReference(INTERNAL); Serial.println("MCP9808 module"); lcd.setCursor(0,0); lcd.print(" Digital "); lcd.setCursor(0,1); lcd.print(" Thermometer "); delay(1000); lcd.clear(); if (!tempsensor.begin()) { Serial.println("Couldn't find MCP9808!"); Martinos John and Martinos Themis

lcd.clear(); lcd.setCursor(0,0); lcd.print("Conection to"); lcd.setCursor(0,2); lcd.print("MCP9808 Failed"); while (1); } lcd.setCursor(0,0); lcd.print("Conection to"); lcd.setCursor(0,1); lcd.print("MCP9808 Success"); delay(1000); lcd.clear(); } void loop() { lcd.display(); float c = tempsensor.readTempC(); float f = c * 9.0 / 5.0 + 32; if (digitalRead(6)==true){ if (buzzerOnOff1==true){ tone(buzzer, 3000); delay(20); noTone(buzzer); buzzerOnOff1 = false; buzzerOnOff2 = true; lcd.clear(); lcd.setCursor(0,0); lcd.print("PC connection"); // lcd.setCursor(13,0); lcd.write(1); // write byte "1" to lcd lcd.setCursor(14,0); lcd.write(2); // write byte "2" to lcd lcd.setCursor(15,0); lcd.write(3); // write byte "3" to lcd // lcd.setCursor(0,1); lcd.print("Temp/ure"); lcd.setCursor(12,1); lcd.print("Wait"); } if (Serial.available()> 2) { inputByte_0 = Serial.read(); delay(10); inputByte_1 = Serial.read(); delay(10); inputByte_2 = Serial.read(); delay(10);

[6]

Martinos TEAM 16/01/2018 //Check for start of Message if(inputByte_0 == 4) { //Detect Command type switch (inputByte_1) { case 8: //Set PIN and value switch (inputByte_2) { case 16: Serial.print("I'M ARDUINO"); if (buzzerOnOff6==true){ tone(buzzer, 3000); delay(20); noTone(buzzer); buzzerOnOff6 = false; buzzerOnOff3 = false; buzzerOnOff4 = false; } break; { case 32: if (buzzerOnOff3==true){ tone(buzzer, 3000); delay(20); noTone(buzzer); buzzerOnOff3 = false; } buzzerOnOff4 = true; Serial.println(c); lcd.setCursor(10,1); lcd.print(c); lcd.setCursor(15,1); lcd.print("C"); break; } { case 64: if (buzzerOnOff4==true){ tone(buzzer, 3000); delay(20); noTone(buzzer); buzzerOnOff4 = false; } buzzerOnOff3 = true; Serial.println(f); lcd.setCursor(10,1); lcd.print(f); lcd.setCursor(15,1); lcd.print("F"); break; } { Martinos John and Martinos Themis

Code for the microcontroller Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor case 128: if (buzzerOnOff5==true){ tone(buzzer, 3000); delay(20); noTone(buzzer); buzzerOnOff5 = false; buzzerOnOff6 = true; } lcd.setCursor(10,1); lcd.print(" Wait"); break; } } } } //Clear Message bytes inputByte_0 = 0; inputByte_1 = 0; inputByte_2 = 0; buzzerOnOff5=true; } } else{ if (buzzerOnOff2==true){ tone(buzzer, 3000); delay(20); noTone(buzzer); buzzerOnOff2 = false; buzzerOnOff1 = true; lcd.clear(); lcd.setCursor(0,0); lcd.print("Temperature"); lcd.setCursor(5,1); lcd.print("C or"); lcd.setCursor(15,1); lcd.print("F"); } lcd.setCursor(0,1); lcd.print(c); lcd.setCursor(10,1); lcd.print(f); val=500; ////////////////////////////////////////////////// [ 1 ] if (digitalRead(11)==true){ val = 3000; lcd.setCursor(12,0); lcd.write(4); // write byte "4" to lcd } else{ if (speed1==true){ lcd.setCursor(12,0); lcd.print(" "); }

[7]

Martinos TEAM 16/01/2018 } ////////////////////////////////////////////////// [ 2 ] if (digitalRead(10)==true){ val = 2000; lcd.setCursor(12,0); lcd.write(4); // write byte "4" to lcd lcd.setCursor(13,0); lcd.write(5); // write byte "5" to lcd speed1 = false; } else{ if (speed2==true){ lcd.setCursor(13,0); lcd.print(" "); speed1 = true; } } ////////////////////////////////////////////////// [ 3 ] if (digitalRead(9)==true){ val = 1000; lcd.setCursor(12,0); lcd.write(4); // write byte "4" to lcd lcd.setCursor(13,0); lcd.write(5); // write byte "5" to lcd lcd.setCursor(14,0); lcd.write(6); // write byte "6" to lcd speed1 = false; speed2 = false; } else{ if (speed3==true){ lcd.setCursor(14,0); lcd.print(" "); speed2 = true; } } /////////////////////////////////////////////////// [ 4 ] if (digitalRead(8)==true){ val = 10; lcd.setCursor(12,0); lcd.write(4); // write byte "4" to lcd lcd.setCursor(13,0); lcd.write(5); // write byte "5" to lcd lcd.setCursor(14,0); lcd.write(6); // write byte "6" to lcd lcd.setCursor(15,0); lcd.write(7); // write byte "7" to lcd speed1 = false; speed2 = false; speed3 = false; } else{ lcd.setCursor(15,0); lcd.print(" "); Martinos John and Martinos Themis

Code for the microcontroller Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor speed3 = true; } ////////////////////////////////////////////////// delay(val); } }

[8]

Martinos TEAM 16/01/2018

Code for the PC software Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

We used the Visual Studio Community edition and wrote a windows form application in C# which communicates with the Arduino UNO via the COM port. This program consists of three main tabs. In the tab "Form1.cs" we have the main code (and main class) for the program. In the tab "Form1.cs [Design]" we have designed the graphical user interface "GUI" for the program. The part of the code which reads the COM ports and establishes the connection with the device, it is written in a second class. This part of the code it is written in the tab "Connector.cs". First step for the code is to get all the available COM port names. Then to each COM port name it sends a buffer and wait for a specific response. If the response is the message " I'M ARDUINO " then it saves the name of this port in a variable. On the next step it opens this port and sends a buffer. As a response it gets back the data from the sensor. The main code for "Form1.cs" tab using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; using System.Threading;

namespace WindowsFormsApp1 { public partial class Form1 : Form { Connector comport = new Connector(); bool TF; public Form1() { InitializeComponent(); chart2.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; Celsius.Checked = true; Fahrenheit.Checked = false; trackBar.Value = 1500; TimerPlot.Text = trackBar.Value + ""; } private void button1_Click(object sender, EventArgs e) { if (comport.connect(9600, "I'M ARDUINO", 4, 8, 16) & (button1.Text == "Connect")) { Status.Text = "Connection Successful - Connected to " + comport.port; timer1.Start(); button1.Text = "Disconnect"; TF = true; } else { Status.Text = "Not connected . . . "; timer1.Stop(); button1.Text = "Connect"; String TempMessage = comport.message(4, 8, 128); } } private void timer1_Tick(object sender, EventArgs e) { timer1.Interval = 3005 - trackBar.Value; TimerPlot.Text = trackBar.Value + ""; Martinos John and Martinos Themis

[9]

Martinos TEAM 16/01/2018

Code for the PC software Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

try { Status.Text = "Connection Successful - Connected to " + comport.port; if (Celsius.Checked==true) { if (TF == true) { chart2.Series[0].Points.Clear(); TF = false; Units.Text = "C"; } String TempMessage = comport.message(4, 8, 32); DataOut.Text = ""; DataOut.Text = TempMessage; chart2.Series[0].Points.AddY(TempMessage.Substring(0, 5)); } else { if (TF == false) { chart2.Series[0].Points.Clear(); TF = true; Units.Text = "F"; } String TempMessage = comport.message(4, 8, 64); DataOut.Text = ""; DataOut.Text = TempMessage; chart2.Series[0].Points.AddY(TempMessage.Substring(0, 5)); } } catch { Status.Text = ("Connection was lost - Searching . . ."); } } private void chart2_Click(object sender, EventArgs e) { } private void Form1_Load(object sender, EventArgs e) { } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { } private void DataOut_TextChanged(object sender, EventArgs e) { } private void Status_TextChanged(object sender, EventArgs e) { } private void Celsius_CheckedChanged(object sender, EventArgs e) { Units.Text = "C"; } private void Fahrenheit_CheckedChanged(object sender, EventArgs e) { Units.Text = "F"; } private void Units_Click(object sender, EventArgs e) { } Martinos John and Martinos Themis

[10]

Martinos TEAM 16/01/2018

Code for the PC software Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

private void Clear_Click(object sender, EventArgs e) { chart2.Series[0].Points.Clear(); DataOut.Text = ""; } private void trackBar_Scroll(object sender, EventArgs e) { TimerPlot.Text = trackBar.Value + ""; } private void panel1_Paint(object sender, PaintEventArgs e) { } private void TimerPlot_TextChanged(object sender, EventArgs e) { } } } The code for the "Connector.cs" tab using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO.Ports; using System.Threading; namespace WindowsFormsApp1 { class Connector { public string port = ""; static SerialPort currentPort; public Boolean connect(int baud, string recognizeText, byte paramone, byte paramtwo, byte paramthree) { try { byte[] buffer = new byte[3]; buffer[0] = Convert.ToByte(paramone); buffer[1] = Convert.ToByte(paramtwo); buffer[2] = Convert.ToByte(paramthree); int intReturnASCII = 0; char charReturnValue = (Char)intReturnASCII; string[] ports = SerialPort.GetPortNames(); foreach (string newport in ports) { currentPort = new SerialPort(newport, baud); currentPort.Open(); currentPort.Write(buffer, 0, 3); Thread.Sleep(200); int count = currentPort.BytesToRead; string returnMessage = ""; while (count > 0) { intReturnASCII = currentPort.ReadByte(); returnMessage = returnMessage + Convert.ToChar(intReturnASCII); count--; } currentPort.Close(); port = newport; if (returnMessage.Contains(recognizeText)) { Martinos John and Martinos Themis

[11]

Martinos TEAM 16/01/2018

Code for the PC software Digital Thermometer Using Arduino and MCP9808 Digital Temperature Sensor

return true; } } return false; } catch (Exception e) { return false; } } public string message(byte paramone, byte paramtwo, byte paramthree) { try { byte[] buffer = new byte[3]; buffer[0] = Convert.ToByte(paramone); buffer[1] = Convert.ToByte(paramtwo); buffer[2] = Convert.ToByte(paramthree); currentPort.Open(); currentPort.Write(buffer, 0, 3); int intReturnASCII = 0; char charReturnValue = (Char)intReturnASCII; Thread.Sleep(200); int count = currentPort.BytesToRead; string returnMessage = ""; while (count > 0) { intReturnASCII = currentPort.ReadByte(); returnMessage = returnMessage + Convert.ToChar(intReturnASCII); count--; } currentPort.Close(); return returnMessage; } catch (Exception e) { return ""; } } } }

Martinos John and Martinos Themis

[12]