MAX31855 driver for Sonoff-Tasmota - Initial commit

This commit is contained in:
Markus Past 2018-12-30 11:45:21 +01:00
parent 5026cbd38d
commit 5737665a2f
5 changed files with 181 additions and 1 deletions

View File

@ -106,8 +106,10 @@
#define D_JSON_PRESSURE "Pressure"
#define D_JSON_PRESSUREATSEALEVEL "SeaPressure"
#define D_JSON_PRESSURE_UNIT "PressureUnit"
#define D_JSON_PROBETEMPERATURE "ProbeTemperature"
#define D_JSON_PROGRAMFLASHSIZE "ProgramFlashSize"
#define D_JSON_PROGRAMSIZE "ProgramSize"
#define D_JSON_REFERENCETEMPERATURE "ReferenceTemperature"
#define D_JSON_RESET "Reset"
#define D_JSON_RESTARTING "Restarting"
#define D_JSON_RESTARTREASON "RestartReason"

View File

@ -540,6 +540,9 @@
#define D_SENSOR_RF_SENSOR "RF Sensor"
#define D_SENSOR_AZ_RX "AZ Rx"
#define D_SENSOR_AZ_TX "AZ Tx"
#define D_SENSOR_MAX31855_CS "MAX31855 CS"
#define D_SENSOR_MAX31855_CLK "MAX31855 CLK"
#define D_SENSOR_MAX31855_DO "MAX31855 DO"
// Units
#define D_UNIT_AMPERE "A"

View File

@ -285,6 +285,9 @@
// #define W1_PARASITE_POWER // If using USE_DS18x20 then optimize for parasite powered sensors
// #define DS18B20_INTERNAL_PULLUP // Use INPUT_PULLUP internal pullup resistors for single DS18B20
// -- SPI sensors ----------------------------------
#define USE_MAX31855 // Enable MAX31855 K-Type thermocouple sensor
// -- I2C sensors ---------------------------------
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)

View File

@ -143,6 +143,9 @@ enum UserSelectablePins {
GPIO_RF_SENSOR, // Rf receiver with sensor decoding
GPIO_AZ_TXD, // AZ-Instrument 7798 Serial interface
GPIO_AZ_RXD, // AZ-Instrument 7798 Serial interface
GPIO_MAX31855CS, // MAX31855 Serial interface
GPIO_MAX31855CLK, // MAX31855 Serial interface
GPIO_MAX31855DO, // MAX31855 Serial interface
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality offset by user selectable GPIOs
@ -204,7 +207,8 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_MGC3130_XFER "|" D_SENSOR_MGC3130_RESET "|"
D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|"
D_SENSOR_RF_SENSOR "|"
D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX;
D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|"
D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO;
/********************************************************************************************/
@ -461,6 +465,11 @@ const uint8_t kGpioNiceList[] PROGMEM = {
GPIO_AZ_TXD, // AZ-Instrument 7798 CO2 datalogger Serial interface
GPIO_AZ_RXD // AZ-Instrument 7798 CO2 datalogger Serial interface
#endif
#ifdef USE_MAX31855
GPIO_MAX31855CS, // MAX31855 Serial interface
GPIO_MAX31855CLK, // MAX31855 Serial interface
GPIO_MAX31855DO, // MAX31855 Serial interface
#endif
};
const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = {

163
sonoff/xsns_39_max31855.ino Normal file
View File

@ -0,0 +1,163 @@
/*
xsns_39_max31855.ino - MAX31855 thermocouple sensor support for Sonoff-Tasmota
Copyright (C) 2018 Markus Past
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
//#define USE_MAX31855
#ifdef USE_MAX31855
#define XSNS_39 39
bool initialized = false;
struct MAX31855_ResultStruct{
uint8_t ErrorCode;
float ProbeTemperature;
float ReferenceTemperature;
} MAX31855_Result;
void MAX31855_Init(void){
if(initialized)
return;
pinMode(pin[GPIO_MAX31855CS], OUTPUT);
pinMode(pin[GPIO_MAX31855CLK], OUTPUT);
pinMode(pin[GPIO_MAX31855DO], INPUT);
digitalWrite(pin[GPIO_MAX31855CS], HIGH);
digitalWrite(pin[GPIO_MAX31855CLK], LOW);
initialized = true;
}
void MAX31855_GetResult(void){
int32_t RawData = MAX31855_ShiftIn(32);
uint8_t probeerror = RawData & 0x7;
MAX31855_Result.ErrorCode = probeerror;
MAX31855_Result.ReferenceTemperature = MAX31855_GetReferenceTemperature(RawData);
if(probeerror)
MAX31855_Result.ProbeTemperature = NAN;
else
MAX31855_Result.ProbeTemperature = MAX31855_GetProbeTemperature(RawData);
}
float MAX31855_GetProbeTemperature(int32_t RawData){
if(RawData & 0x80000000)
RawData = (RawData >> 18) | 0xFFFFC000;
else
RawData >>= 18;
float result = (RawData * 0.25);
return (Settings.flag.temperature_conversion) ? ConvertTemp(result) : result;
}
float MAX31855_GetReferenceTemperature(int32_t RawData){
if(RawData & 0x8000)
RawData = (RawData >> 4) | 0xFFFFF000;
else
RawData = (RawData >> 4) & 0x00000FFF;
float result = (RawData * 0.0625);
return (Settings.flag.temperature_conversion) ? ConvertTemp(result) : result;
}
int32_t MAX31855_ShiftIn(uint8_t Length){
int32_t dataIn = 0;
digitalWrite(pin[GPIO_MAX31855CS], LOW);
delayMicroseconds(1);
for(uint8_t i = 0; i < Length; i++)
{
digitalWrite(pin[GPIO_MAX31855CLK], LOW);
delayMicroseconds(1);
dataIn <<= 1;
if(digitalRead(pin[GPIO_MAX31855DO]))
dataIn |= 1;
digitalWrite(pin[GPIO_MAX31855CLK], HIGH);
delayMicroseconds(1);
}
digitalWrite(pin[GPIO_MAX31855CS], HIGH);
digitalWrite(pin[GPIO_MAX31855CLK], LOW);
return dataIn;
}
void MAX31855_Show(bool Json){
char probetemp[33];
char referencetemp[33];
dtostrfd(MAX31855_Result.ProbeTemperature, Settings.flag2.temperature_resolution, probetemp);
dtostrfd(MAX31855_Result.ReferenceTemperature, Settings.flag2.temperature_resolution, referencetemp);
if(Json){
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_PROBETEMPERATURE "\":%s,\"" D_JSON_REFERENCETEMPERATURE "\":%s,\"" D_JSON_ERROR "\":%d}"), \
mqtt_data, "MAX31855", probetemp, referencetemp, MAX31855_Result.ErrorCode);
} else {
#ifdef USE_WEBSERVER
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "MAX31855", probetemp, TempUnit());
#endif // USE_WEBSERVER
}
}
// void MAX31855_ShowDebug(void){
// char probetemp[33];
// char referencetemp[33];
// dtostrfd(MAX31855_Result.ProbeTemperature, Settings.flag2.temperature_resolution, probetemp);
// dtostrfd(MAX31855_Result.ReferenceTemperature, Settings.flag2.temperature_resolution, referencetemp);
// snprintf_P(mqtt_data, sizeof(mqtt_data), "%s %d %s %d %s %d %s %d %s %d %s %s %s %s %s %d", \
// "CS:", pin[GPIO_MAX31855CS], "CLK:", pin[GPIO_MAX31855CLK], "DO:", pin[GPIO_MAX31855DO], \
// "DO-State:", digitalRead(pin[GPIO_MAX31855DO]), \
// "RAW-Data:", MAX31855_ShiftIn(32), \
// "Probe-Temp:", probetemp, "Internal-Temp:", referencetemp, "Error:", MAX31855_Result.ErrorCode);
// }
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
boolean Xsns39(byte function)
{
boolean result = false;
if((pin[GPIO_MAX31855CS] < 99) && (pin[GPIO_MAX31855CLK] < 99) && (pin[GPIO_MAX31855DO] < 99)){
switch (function) {
case FUNC_INIT:
MAX31855_Init();
break;
case FUNC_EVERY_SECOND:
MAX31855_GetResult();
break;
case FUNC_JSON_APPEND:
//MAX31855_ShowDebug();
MAX31855_Show(true);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_APPEND:
MAX31855_Show(false);
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_MAX31855