Hello,
I am trying to design a temperature probe circuit and display the results on an OLED screen, But I am having a problem with getting both the screen and probes working together, I have had them running well individually, but the probe is giving out weird readings when I introduce the screen into the mix, I'm guessing it could be a timing issue and / or library issue??
I am using the following items
Teensy 3.0
Type K probe
MAX31855K K-Type Thermocouple Sensor Breakout (4ch) - http://playingwithfusion.com/productview.php?pdid=20&catid=1001
1.3" 128x64 OLED Display Module SSD1306 - http://www.wide.hk/products.php?product=1.3"-128x64-OLED-Display-Module-SSD1306
I am using a customised library for both screen and Thermocouple, I am trying to use the hardware SPI instead of software
the OLED is from here https://www.adafruit.com/forums/viewtopic.php?f=47&t=29123
the Thermocouple is a modified version of https://github.com/rocketscream/MAX31855
THIS IS THE MODIFIED LIBRARY CODE
SO WHATS HAPPENING!!
So when I have the both items plugged in the splash screen shows as it should then goes blank, I then open the serial monitor to show the following results
If i comment out all of the screen related items the temperature returns to how it should
If i comment out all of the thermocouple related items and use a mock data (temperature = temperature + 2.5
for the temperature it returns to how it should on the screen.
So any ideas would be appreciated or anywhere can I look to find this answer would be good as well.
I am trying to design a temperature probe circuit and display the results on an OLED screen, But I am having a problem with getting both the screen and probes working together, I have had them running well individually, but the probe is giving out weird readings when I introduce the screen into the mix, I'm guessing it could be a timing issue and / or library issue??
I am using the following items
Teensy 3.0
Type K probe
MAX31855K K-Type Thermocouple Sensor Breakout (4ch) - http://playingwithfusion.com/productview.php?pdid=20&catid=1001
1.3" 128x64 OLED Display Module SSD1306 - http://www.wide.hk/products.php?product=1.3"-128x64-OLED-Display-Module-SSD1306
I am using a customised library for both screen and Thermocouple, I am trying to use the hardware SPI instead of software
the OLED is from here https://www.adafruit.com/forums/viewtopic.php?f=47&t=29123
the Thermocouple is a modified version of https://github.com/rocketscream/MAX31855
THIS IS THE MODIFIED LIBRARY CODE
Code:
/*******************************************************************************
* MAX31855 Library
* Version: 1.10
* Date: 24-07-2012
* Company: Rocket Scream Electronics
* Website: www.rocketscream.com
*
* This is a MAX31855 library for Arduino. Please check our wiki
* (www.rocketscream.com/wiki) for more information on using this piece of
* library.
*
* This library is licensed under Creative Commons Attribution-ShareAlike 3.0
* Unported License.
*
* Revision Description
* ======== ===========
* 1.10 Added negative temperature support for both junction & thermocouple.
* 1.00 Initial public release.
*
*******************************************************************************/
#include "MAX31855H.h"
#include "SPI.h"
MAX31855H::MAX31855H(unsigned char SS)
{
// MAX31855H chip select input pin
pinMode(SS, OUTPUT);
// MAX31855H clock input pin
pinMode(SCK, OUTPUT);
// MAX31855H clock input pin
//pinMode(MISO, INPUT);
// Default output pins state
digitalWrite(SS, HIGH);
digitalWrite(SCK, LOW);
//SPI.setClockDivider (SPI_CLOCK_DIV2);
SPI.begin();
}
/*******************************************************************************
* Name: readThermocouple
* Description: Read the thermocouple temperature either in Degree Celsius or
* Fahrenheit. Internally, the conversion takes place in the
* background within 100 ms. Values are updated only when the SS
* line is high.
*
* Argument Description
* ========= ===========
* 1. unit Unit of temperature required: CELSIUS or FAHRENHEIT
*
* Return Description
* ========= ===========
* temperature Temperature of the thermocouple either in Degree Celsius or
* Fahrenheit. If fault is detected, FAULT_OPEN, FAULT_SHORT_GND or
* FAULT_SHORT_VCC will be returned. These fault values are outside
* of the temperature range the MAX31855 is capable of.
*******************************************************************************/
double MAX31855H::readThermocouple(unit_t unit)
{
unsigned long dataSPI;
double temperature;
// Initialize temperature
temperature = 0;
// Shift in 32-bit of data from MAX31855
dataSPI = readData();
// If fault is detected
if (dataSPI & 0x00010000)
{
// Check for fault type (3 LSB)
switch (dataSPI & 0x00000007)
{
// Open circuit
case 0x01:
temperature = FAULT_OPEN;
Serial.println("FAULT_OPEN");
Serial.println(dataSPI, BIN);
break;
// Thermocouple short to GND
case 0x02:
temperature = FAULT_SHORT_GND;
Serial.println("FAULT_SHORT_GND");
break;
// Thermocouple short to VCC
case 0x04:
temperature = FAULT_SHORT_VCC;
Serial.println("FAULT_SHORT_VCC");
break;
}
}
// No fault detected
else
{
// Retrieve thermocouple temperature data and strip redundant data
dataSPI = dataSPI >> 18;
//Serial.print("postshift bin therm ");
//Serial.println(dataSPI, BIN);
// Bit-14 is the sign
temperature = (dataSPI & 0x00001FFF);
// Check for negative temperature
if (dataSPI & 0x00002000)
{
// 2's complement operation
// Invert
dataSPI = ~dataSPI;
// Ensure operation involves lower 13-bit only
temperature = dataSPI & 0x00001FFF;
// Add 1 to obtain the positive number
temperature += 1;
// Make temperature negative
temperature *= -1;
}
// Convert to Degree Celsius
temperature *= 0.25;
// If temperature unit in Fahrenheit is desired
if (unit == FAHRENHEIT)
{
// Convert Degree Celsius to Fahrenheit
temperature = (temperature * 9.0/5.0)+ 32;
}
}
return (temperature);
}
/*******************************************************************************
* Name: readJunction
* Description: Read the thermocouple temperature either in Degree Celsius or
* Fahrenheit. Internally, the conversion takes place in the
* background within 100 ms. Values are updated only when the SS
* line is high.
*
* Argument Description
* ========= ===========
* 1. unit Unit of temperature required: CELSIUS or FAHRENHEIT
*
* Return Description
* ========= ===========
* temperature Temperature of the cold junction either in Degree Celsius or
* Fahrenheit.
*
*******************************************************************************/
double MAX31855H::readJunction(unit_t unit)
{
double temperature;
unsigned long dataSPI;
// Shift in 32-bit of data from MAX31855
dataSPI = readData();
// Strip fault data bits & reserved bit
dataSPI = dataSPI >> 4;
//Serial.print("postshift bin junct ");
//Serial.println(dataSPI, BIN);
// Bit-12 is the sign
temperature = (dataSPI & 0x000007FF);
// Check for negative temperature
if (dataSPI & 0x00000800)
{
// 2's complement operation
// Invert
dataSPI = ~dataSPI;
// Ensure operation involves lower 11-bit only
temperature = dataSPI & 0x000007FF;
// Add 1 to obtain the positive number
temperature += 1;
// Make temperature negative
temperature *= -1;
}
// Convert to Degree Celsius
temperature *= 0.0625;
// If temperature unit in Fahrenheit is desired
if (unit == FAHRENHEIT)
{
// Convert Degree Celsius to Fahrenheit
temperature = (temperature * 9.0/5.0)+ 32;
}
// Return the temperature
return (temperature);
}
/*******************************************************************************
* Name: readData
* Description: Shift in 32-bit of data from MAX31855 chip. Minimum clock pulse
* width is 100 ns. No delay is required in this case.
*
* Argument Description
* ========= ===========
* 1. NIL
*
* Return Description
* ========= ===========
* data 32-bit of data acquired from the MAX31855 chip.
*
*******************************************************************************/
unsigned long MAX31855H::readData()
{
int bitCount;
unsigned long dataSPI;
// Clear data
dataSPI = 0;
// enable Slave Select
digitalWrite(SS, LOW); // CS is pin 10
// Shift in 32-bit of data
for (bitCount = 31; bitCount >= 0; bitCount--)
{
digitalWrite(SCK, HIGH);
// If data bit is high
if (digitalRead(MISO))
{
// Need to type cast data type to unsigned long, else compiler will
// truncate to 16-bit
dataSPI |= ((unsigned long)1 << bitCount);
}
digitalWrite(SCK, LOW);
}
// disable Slave Select
digitalWrite(SS, HIGH);
// turn SPI hardware off
SPI.end ();
//READ DEBUG
Serial.print("raw SPI bin ");
Serial.println(dataSPI, BIN);
return(dataSPI);
}
Code:
/*******************************************************************************
* Thermocouple to serial for MAX31855H example
*
*******************************************************************************/
// ***** INCLUDES *****
#include <MAX31855H.h> // hardware version
//#include <MAX31855.h> // original version
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306h.h>
// ***** PIN DEFINITIONS *****
//pins for hardware spi therm
//
const unsigned char thermocoupleSS = 10;
MAX31855H MAX31855H(thermocoupleSS);
//
////pins for original therm
/*
const unsigned char thermocoupleSO = 12;
const unsigned char thermocoupleCS = 10;
const unsigned char thermocoupleCLK = 13;
MAX31855 MAX31855(thermocoupleSO, thermocoupleCS, thermocoupleCLK);
*/
//pins for OLED Screen
#define OLED_DC 8
#define OLED_CS 9
#define OLED_CLK 13
#define OLED_MOSI 11
#define OLED_RESET 7
Adafruit_SSD1306h display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
void setup()
{
Serial.begin(57600);
// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
display.begin(SSD1306h_SWITCHCAPVCC);
display.display(); // show splashscreen
delay(2500);
display.clearDisplay(); // clears the screen and buffer
}
void loop()
{
//Screen display
display.display();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
// Display Title
display.setCursor(0,0);
display.println("OLED MENU SYSTEM");
//delay(500);
double temperature;
// Retrieve thermocouple temperature in Degree Celsius
temperature = MAX31855H.readThermocouple(CELSIUS); //Hardware Spi Therm
//temperature = MAX31855.readThermocouple(CELSIUS); //Original Therm
Serial.print("Thermocouple temperature: ");
Serial.print(temperature);
Serial.println(" Degree Celsius");
display.setCursor(0,10);
display.print("Probe 1: ");
display.print(temperature);
display.println("'C");
delay(250);
/*
// Retrieve cold junction temperature in Degree Celsius
temperature = MAX31855H.readJunction(CELSIUS);
Serial.print("Junction temperature: ");
Serial.print(temperature);
Serial.println(" Degree Celsius");
*/
delay(1000);
}
SO WHATS HAPPENING!!
So when I have the both items plugged in the splash screen shows as it should then goes blank, I then open the serial monitor to show the following results
which doesn't seem right i doubt its over 1000 degrees in here and the screen is still blankraw SPI bin 1000001101000000001100101000000
Thermocouple temperature: 1050.00 Degree Celsius
raw SPI bin 1101000000001100101000000
Thermocouple temperature: 26.00 Degree Celsius
raw SPI bin 1000001101001000001100101000000
Thermocouple temperature: 1050.25 Degree Celsius
raw SPI bin 1000001101000000001100101000000
Thermocouple temperature: 1050.00 Degree Celsius
raw SPI bin 1101000000001100101000000
Thermocouple temperature: 26.00 Degree Celsius
raw SPI bin 1100001101000000001100101000000
Thermocouple temperature: 1562.00 Degree Celsius
raw SPI bin 1101000000001100101000000
Thermocouple temperature: 26.00 Degree Celsius
raw SPI bin 1000001101001000001100101000000
Thermocouple temperature: 1050.25 Degree Celsius
If i comment out all of the screen related items the temperature returns to how it should
raw SPI bin 1101000000001100101110000
Thermocouple temperature: 26.00 Degree Celsius
raw SPI bin 1101001000001100101000000
Thermocouple temperature: 26.25 Degree Celsius
raw SPI bin 1101001000001100100100000
Thermocouple temperature: 26.25 Degree Celsius
raw SPI bin 1101001000001100100110000
Thermocouple temperature: 26.25 Degree Celsius
If i comment out all of the thermocouple related items and use a mock data (temperature = temperature + 2.5
So any ideas would be appreciated or anywhere can I look to find this answer would be good as well.