From 55c1fe8d012714438c532fdb98cafa60ea5be180 Mon Sep 17 00:00:00 2001 From: Henrik Ekblad Date: Sun, 7 Dec 2014 10:23:41 +0100 Subject: [PATCH] MAX6875 Temp Sensor example --- libraries/MAX6675/MAX6675.cpp | 109 ++++++++++++++++++ libraries/MAX6675/MAX6675.h | 30 +++++ libraries/MAX6675/README.markdown | 28 +++++ .../MAX6675/examples/read_temp/read_temp.pde | 47 ++++++++ libraries/MAX6675/keywords.txt | 16 +++ .../MAX6875TemperatureSensor.ino | 62 ++++++++++ 6 files changed, 292 insertions(+) create mode 100644 libraries/MAX6675/MAX6675.cpp create mode 100644 libraries/MAX6675/MAX6675.h create mode 100644 libraries/MAX6675/README.markdown create mode 100644 libraries/MAX6675/examples/read_temp/read_temp.pde create mode 100644 libraries/MAX6675/keywords.txt create mode 100644 libraries/MySensors/examples/MAX6875TemperatureSensor/MAX6875TemperatureSensor.ino diff --git a/libraries/MAX6675/MAX6675.cpp b/libraries/MAX6675/MAX6675.cpp new file mode 100644 index 0000000..d918de2 --- /dev/null +++ b/libraries/MAX6675/MAX6675.cpp @@ -0,0 +1,109 @@ +/* + MAX6675.cpp - Library for reading temperature from a MAX6675. + + This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. + http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +#include + +MAX6675::MAX6675(uint8_t CS_pin, uint8_t SO_pin, uint8_t SCK_pin, uint8_t units) +{ + pinMode(CS_pin, OUTPUT); + pinMode(SO_pin, INPUT); + pinMode(SCK_pin, OUTPUT); + + digitalWrite(CS_pin, HIGH); + + _CS_pin = CS_pin; + _SO_pin = SO_pin; + _SCK_pin = SCK_pin; + _units = units; +} + +float MAX6675::read_temp() +{ + uint16_t value = 0; + uint8_t error_tc = 0; + float temp = 0.0; + + /* + Initiate a temperature conversion. According to MAX's tech notes FAQ's + for the chip, Line going high initiates a conversion, which means, we + need to clock the chip low to high to initiate the conversion, then wait + for the conversion to be complete before trying to read the data from + the chip. + */ + digitalWrite(_CS_pin,LOW); + delay(2); + digitalWrite(_CS_pin,HIGH); + delay(220); + + /* Read the chip and return the raw temperature value */ + + /* + Bring CS pin low to allow us to read the data from + the conversion process + */ + digitalWrite(_CS_pin,LOW); + + /* Cycle the clock for dummy bit 15 */ + digitalWrite(_SCK_pin,HIGH); + delay(1); + digitalWrite(_SCK_pin,LOW); + + /* + Read bits 14-3 from MAX6675 for the Temp. Loop for each bit reading + the value and storing the final value in 'temp' + */ + for (int i=11; i>=0; i--) { + digitalWrite(_SCK_pin,HIGH); + value += digitalRead(_SO_pin) << i; + digitalWrite(_SCK_pin,LOW); + } + + /* Read the TC Input inp to check for TC Errors */ + digitalWrite(_SCK_pin,HIGH); + error_tc = digitalRead(_SO_pin); + digitalWrite(_SCK_pin,LOW); + + /* + Read the last two bits from the chip, faliure to do so will result + in erratic readings from the chip. + */ + for (int i=1; i>=0; i--) { + digitalWrite(_SCK_pin,HIGH); + delay(1); + digitalWrite(_SCK_pin,LOW); + } + + // Disable Device + digitalWrite(_CS_pin, HIGH); + + /* + Keep in mind that the temp that was just read is on the digital scale + from 0˚C to 1023.75˚C at a resolution of 2^12. We now need to convert + to an actual readable temperature (this drove me nuts until I figured + this out!). Now multiply by 0.25. I tried to avoid float math but + it is tough to do a good conversion to ˚F. THe final value is converted + to an int and returned at x10 power. + + 2 = temp in deg F + 1 = temp in deg C + 0 = raw chip value 0-4095 + */ + if(_units == 2) { + temp = (value*0.25) * 9.0/5.0 + 32.0; + } else if(_units == 1) { + temp = (value*0.25); + } else { + temp = value; + } + + /* Output negative of CS_pin if there is a TC error, otherwise return 'temp' */ + if(error_tc != 0) { + return -_CS_pin; + } else { + return temp; + } +} diff --git a/libraries/MAX6675/MAX6675.h b/libraries/MAX6675/MAX6675.h new file mode 100644 index 0000000..e80d8d0 --- /dev/null +++ b/libraries/MAX6675/MAX6675.h @@ -0,0 +1,30 @@ +/* + MAX6675.h - Library for reading temperature from a MAX6675. + + This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. + http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +#ifndef MAX6675_h +#define MAX6675_h + +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +class MAX6675 +{ + public: + MAX6675(uint8_t CS_pin, uint8_t SO_pin, uint8_t SCK_pin, uint8_t units); + float read_temp(); + private: + uint8_t _CS_pin; + uint8_t _SO_pin; + uint8_t _SCK_pin; + uint8_t _units; + uint8_t chip_read(uint8_t CS_pin, uint8_t &error_tc); +}; + +#endif diff --git a/libraries/MAX6675/README.markdown b/libraries/MAX6675/README.markdown new file mode 100644 index 0000000..54af7d3 --- /dev/null +++ b/libraries/MAX6675/README.markdown @@ -0,0 +1,28 @@ +MAX6675 Arduino Library +======================= +Version: **2.0.1** + +This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. + + +Summary +------- + +The primary use of the library is to easily interface with a MAX6675 chip via it's SPI interface. Use the following code to initialize the library. V2 also greatly improves performance and timing of the chip for more accurate reads. Thanks Ed! + + MAX6675 temp0(CS,SO,SCK,units); + +Variables: + +* CS is chip select pin of chip +* SO is data out of the chip +* SCK is the clock pin of the chip +* units is one of the following: + * 0 = raw 0-4095 value + * 1 = temp in ˚C + * 2 = temp in ˚F + +Following this you can use the _read_temp()_ function to return the temperature as a float. + + temperature = temp0.read_temp(); + diff --git a/libraries/MAX6675/examples/read_temp/read_temp.pde b/libraries/MAX6675/examples/read_temp/read_temp.pde new file mode 100644 index 0000000..3a9dbda --- /dev/null +++ b/libraries/MAX6675/examples/read_temp/read_temp.pde @@ -0,0 +1,47 @@ +/* + Single_Temp.pde - Example using the MAX6675 Library. + Created by Ryan McLaughlin + + This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License. + http://creativecommons.org/licenses/by-sa/3.0/ +*/ + +#include + +int LED1 = 9; // Status LED Pin +int CS = 10; // CS pin on MAX6675 +int SO = 12; // SO pin of MAX6675 +int SCK = 13; // SCK pin of MAX6675 +int units = 2; // Units to readout temp (0 = raw, 1 = ˚C, 2 = ˚F) +float temperature = 0.0; // Temperature output variable + + +// Initialize the MAX6675 Library for our chip +MAX6675 temp(CS,SO,SCK,units); + + +// Setup Serial output and LED Pin +// MAX6675 Library already sets pin modes for MAX6675 chip! +void setup() { + Serial.begin(9600); + pinMode(LED1, OUTPUT); +} + +void loop() { + // Read the temp from the MAX6675 + temperature = temp.read_temp(); + + if(temperature < 0) { + // If there is an error with the TC, temperature will be < 0 + Serial.print("Thermocouple Error on CS"); + Serial.println( temperature ); + digitalWrite(LED1, HIGH); + } else { + Serial.print("Current Temperature: "); + Serial.println( temperature ); + digitalWrite(LED1, LOW); + } + + // Wait one second before reading again + delay(1000); +} diff --git a/libraries/MAX6675/keywords.txt b/libraries/MAX6675/keywords.txt new file mode 100644 index 0000000..f2c1136 --- /dev/null +++ b/libraries/MAX6675/keywords.txt @@ -0,0 +1,16 @@ +####################################### +# Syntax Coloring Map For MAX6675 +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +MAX6675 KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +read_temp KEYWORD2 + diff --git a/libraries/MySensors/examples/MAX6875TemperatureSensor/MAX6875TemperatureSensor.ino b/libraries/MySensors/examples/MAX6875TemperatureSensor/MAX6875TemperatureSensor.ino new file mode 100644 index 0000000..553b840 --- /dev/null +++ b/libraries/MySensors/examples/MAX6875TemperatureSensor/MAX6875TemperatureSensor.ino @@ -0,0 +1,62 @@ +// MAX6875 Hight temperature sensor with range: -200 degC - +1300 degC +// Contribution by MrLynx +// http://forum.mysensors.org/topic/641/max6675 +// +// Connect: +// MAX6675 - Arduino +// CS0 - 4 +// SO - 3 +// SCLK - 5 +// VCC - 5V +// GND - GND + +#include +#include +#include +uint8_t CS0 = 4; // CS pin on MAX6675 +uint8_t SO = 3; // SO pin of MAX6675 +uint8_t SCLK = 5; // SCK pin of MAX6675 +uint8_t units = 1; // Units to readout temp (0 = ˚F, 1 = ˚C) +float temperature = 0.0; // Temperature output variable +float lastTemperature; +unsigned long SLEEP_TIME = 30000; +boolean metric = true; +MySensor gw; + +MyMessage msg(0, V_TEMP); + +// Initialize the MAX6675 Library for our chip + +MAX6675 temp0(CS0, SO, SCLK, units); + +void setup() +{ + // Startup and initialize MySensors library. Set callback for incoming messages. + gw.begin(); + + // Send the sketch version information to the gateway and Controller + gw.sendSketchInfo("Max6675 Temp Sensor", "1.0"); + + // Present all sensors to controller + gw.present(0, S_TEMP); +} + +void loop() +{ + // Process incoming messages (like config from server) + gw.process(); + + temperature = temp0.read_temp(); // Read the temp + + if (temperature < 0) { // If there is an error with the TC, temperature will be < 0 + Serial.println("Thermocouple Error!!"); // There is a thermocouple error + } else { + Serial.print("Current Temperature: "); + Serial.println( temperature ); // Print the temperature to Serial + if (temperature != lastTemperature) + gw.send(msg.setSensor(0).set(temperature, 1)); + lastTemperature = temperature; + } + + gw.sleep(SLEEP_TIME); +}