Отображение температуры с датчика PT100 на дисплее OLED прошу помощи

Добрый день! Впервые тут, в общем то по работе возникла необходимость в датчике температуры PT100. Купил датчик, MAX31865, ARDUINO UNO, OLED дисплей 128Х64.
Залил скетч:

#include <Wire.h> //Arduino Uno; SDA = A4, SCL = A5
#include <SPI.h>
//CS => CS //Arduino 10
//MISO => SDO //Arduino 12
//MOSI => SDI //Arduino 11
//SCK => SCK //Arduino 13

//Variables for the PT100 boards
double resistance;
uint8_t reg1, reg2; //reg1 holds MSB, reg2 holds LSB for RTD
uint16_t fullreg; //fullreg holds the combined reg1 and reg2
double temperature;
//Variables and parameters for the R - T conversion
double Z1, Z2, Z3, Z4, Rt;
double RTDa = 3.9083e-3;
double RTDb = -5.775e-7;
double rpoly = 0;

//--Display---------------------------------------------
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin 
Adafruit_SSD1306 display(OLED_RESET);

const int chipSelectPin = 10;

void setup()
{
  SPI.begin();
  Serial.begin(115200); //Start serial

  pinMode(chipSelectPin, OUTPUT); //because CS is manually switched  

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextSize(3);
  display.setTextColor(SSD1306_WHITE);
}

void loop()
{
  readRegister();
  convertToTemperature();
  printDisplay();
}

void printDisplay()
{
  display.clearDisplay();     // Clear display
  display.setCursor(0, 0);    // Start at top-left corner
  display.print(temperature);
  display.display();
}

void convertToTemperature()
{
  Rt = resistance;
  Rt /= 32768;
  Rt *= 430; //This is now the real resistance in Ohms

  Z1 = -RTDa;
  Z2 = RTDa * RTDa - (4 * RTDb);
  Z3 = (4 * RTDb) / 100;
  Z4 = 2 * RTDb;

  temperature = Z2 + (Z3 * Rt);
  temperature = (sqrt(temperature) + Z1) / Z4;

  if (temperature >= 0)
  {
    Serial.print("Temperature: ");
    Serial.println(temperature); //Temperature in Celsius degrees
    return; //exit
  }
  else
  {
    Rt /= 100;
    Rt *= 100; // normalize to 100 ohm

    rpoly = Rt;

    temperature = -242.02;
    temperature += 2.2228 * rpoly;
    rpoly *= Rt; // square
    temperature += 2.5859e-3 * rpoly;
    rpoly *= Rt; // ^3
    temperature -= 4.8260e-6 * rpoly;
    rpoly *= Rt; // ^4
    temperature -= 2.8183e-8 * rpoly;
    rpoly *= Rt; // ^5
    temperature += 1.5243e-10 * rpoly;

    Serial.print("Temperature: ");
    Serial.println(temperature); //Temperature in Celsius degrees
  }
  //Note: all formulas can be found in the AN-709 application note from Analog Devices
}


void readRegister()
{
  SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE1));
  digitalWrite(chipSelectPin, LOW);

  SPI.transfer(0x80); //80h = 128 - config register
  SPI.transfer(0xB0); //B0h = 176 - 10110000: bias ON, 1-shot, start 1-shot, 3-wire, rest are 0
  digitalWrite(chipSelectPin, HIGH);

  digitalWrite(chipSelectPin, LOW);
  SPI.transfer(1);
  reg1 = SPI.transfer(0xFF);
  reg2 = SPI.transfer(0xFF);
  digitalWrite(chipSelectPin, HIGH);

  fullreg = reg1; //read MSB
  fullreg <<= 8;  //Shift to the MSB part
  fullreg |= reg2; //read LSB and combine it with MSB
  fullreg >>= 1; //Shift D0 out.
  resistance = fullreg; //pass the value to the resistance variable
  //note: this is not yet the resistance of the RTD!

  digitalWrite(chipSelectPin, LOW);

  SPI.transfer(0x80); //80h = 128
  SPI.transfer(144); //144 = 10010000
  SPI.endTransaction();
  digitalWrite(chipSelectPin, HIGH);

  Serial.print("Resistance: ");
  Serial.println(resistance);
}

И показывает он погоду на марсе. Я пробовал и другие скетчи, но некоторые зависают через некоторое время, какие-то вообще ничего не выводят на дисплей. Подскажите пожалуйста в чем ошибка в этом скетче. На данный момент при температуре 27 градусов он показывает 754.

попробуйте вывести это значение, будет оно в диапазоне 100 - 130 Ом, грубо в этих пределах.

(Точнее можете посмотреть, найдя в интернете таблицу Платиновый датчик температуры, там Омы - Температура. хотя сейчас дело не в этом, конечно)

Может АЦП неправильно измеряет (что-то не так подключено) и тп. При измерении на датчике должно быть небольшое напряжение.

Пробовал. Что-то тут вообще не то, если поднести паяльник к датчику он вообще до определенного значения греет. И это не 754+350. Пробовал другие скетчи, показывал один правильно, но зависал постоянно.

Отлаживать надо…
Берется даташыт, подключается резистор 100 или там 110 Ом, выводится значение АЦП, смотрим сколько должно быть (считаем в Экселе).
Потом отлаживаем расчеты: Омы, Градусы.

Почему-то значение АЦП в скетче при выводе в порт обозвано “резистенсе”: (а надо было написать ADC= )

resistance = fullreg; //pass the value to the resistance variable
  //note: this is not yet the resistance of the RTD!

  digitalWrite(chipSelectPin, LOW);

  SPI.transfer(0x80); //80h = 128
  SPI.transfer(144); //144 = 10010000
  SPI.endTransaction();
  digitalWrite(chipSelectPin, HIGH);

  Serial.print("Resistance: ");
  Serial.println(resistance);

Поэтому скетч не вызывает доверия, видимо писал какой-то заграничный лох ))

Если АЦП не то выдает, то смотрим:

  1. Подключения, величина опорного резистора.
  2. коды, выдаваемые в АЦП в соотв с даташытом.

Дело нудное, но куда деваться?

Rref на модуле какой распаян? Он звонится правильно?
тк АЦП выдает значение относительно этого сопротивления. Может скетч рассчитан на другое значение этого резистора.

На картинке я вижу обозначение на резисторе: 431 - то есть 430 Ом, распаяно в этом модуле. Есть где-то на какой Rref расчитан сей скетч?..

Скетч я брал тут. MAX31865 - Pt100 RTD module — Curious Scientist
Там все как и у меня, подключение резистор впаян на 430 Ом, У него показывает температуру, у меня температуру на марсе. Меряется он верно, 429 ом, ну с погрешностью допустимо.

Сам Pt100 какое сопротивление имеет? Попробуйте вместо него 100-130 Ом, например. Это хотя бы быстро.

…на модуле надо замкнуть крайние и между ними резистор, как я понял
1-2 -резистор- 3-4

После этих действий у вас Rt всегда будет ноль.

У того чертилы ТРЕХПРОВОДКА! в этом видимо суть. Соедините как я нарисовал и наверное пойдет. У вас из датчика сколько проводков торчит?
(для трехпроводки надо замкнуть неиспользуемую клемму чтобы ток бежал через резистор)

//Серьезные парни юзают 4х проводку. ))

Если Rt float то не факт.

Я не серьезный парень. ))) 2 провода, брал с али чисто из-за того что проводка термозащищенная сразу приварена. В целом он показывает очень точно, и на 225 чип уже снимается, косик предыдущего скетча был в зависании, приходилось несколько раз выключать и включать ардуино. На датчике при температуре окружающей среды 28 111ом, и это норма. Тут явно проблема со скетчем. Сейчас пробую другой скетч и он показывает нормальное значение ±.

В соединении 100% нет проблем. Тут я покурил даташиты на все. В этом я разбираюсь. Впервые с Ардуино.

Покажите, как к модулю подключаете.
(расчет в скетче выглядит нормальным)

#include <Adafruit_MAX31865.h>
#include "U8glib.h"


// Use software SPI: CS, DI, DO, CLK
//Adafruit_MAX31865 max = Adafruit_MAX31865(10, 11, 12, 13);
// use hardware SPI, just pass in the CS pin
Adafruit_MAX31865 max = Adafruit_MAX31865(10);

// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000
#define RREF      430.0
// The 'nominal' 0-degrees-C resistance of the sensor
// 100.0 for PT100, 1000.0 for PT1000
#define RNOMINAL  100.0

//U8GLIB_SSD1306_128X64 u8g(13, 11, 10, 9);	// SW SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_SSD1306_128X64 u8g(4, 5, 6, 7);	// SW SPI Com: SCK = 4, MOSI = 5, CS = 6, A0 = 7 (new white HalTec OLED)
//U8GLIB_SSD1306_128X64 u8g(10, 9);		// HW SPI Com: CS = 10, A0 = 9 (Hardware Pins are  SCK = 13 and MOSI = 11)
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);	// I2C / TWI 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST);	// Fast I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);	// Display which does not send AC


void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.setPrintPos(5, 35);
  u8g.print("Temp.: ");
  u8g.print(max.temperature(RNOMINAL, RREF));
}


void setup() {
//  Serial.begin(115200);
//  Serial.println("Adafruit MAX31865 PT100 Sensor Test!");

  max.begin(MAX31865_2WIRE);  // set to 2WIRE or 4WIRE as necessary


  // flip screen, if required
  // u8g.setRot180();
  
  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
  
  pinMode(8, OUTPUT);
}



void loop() {
  uint16_t rtd = max.readRTD();

//  Serial.print("RTD value: "); Serial.println(rtd);
  float ratio = rtd;
  ratio /= 32768;
//  Serial.print("Ratio = "); Serial.println(ratio,8);
//  Serial.print("Resistance = "); Serial.println(RREF*ratio,8);
//  Serial.print("Temperature = "); Serial.println(max.temperature(RNOMINAL, RREF));

  // Check and print any faults
  uint8_t fault = max.readFault();
  if (fault) {
    Serial.print("Fault 0x"); Serial.println(fault, HEX);
    if (fault & MAX31865_FAULT_HIGHTHRESH) {
      Serial.println("RTD High Threshold"); 
    }
    if (fault & MAX31865_FAULT_LOWTHRESH) {
      Serial.println("RTD Low Threshold"); 
    }
    if (fault & MAX31865_FAULT_REFINLOW) {
      Serial.println("REFIN- > 0.85 x Bias"); 
    }
    if (fault & MAX31865_FAULT_REFINHIGH) {
      Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_RTDINLOW) {
      Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); 
    }
    if (fault & MAX31865_FAULT_OVUV) {
      Serial.println("Under/Over voltage"); 
    }
    max.clearFault();
  }
 // Serial.println();


  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  //delay(50);
  
  delay(50);
}

Залил этот, все кажет нормально. Но с этим U8glib проблема с отображением.

Тогда наверное команды чтения с АЦП не так идут. Может библиотека этого SPI какая-то другая и тп. Сам скетч выглядит разумно в общем.

Выше указанный скетч работает. Но там с подключением дисплея беда. Он явно работает не на свои 100% возможностей.

Можно взять измерительную часть, а дисплейную от другого скетча… Или разобраться почему первый неправильно с АЦП работает. Или искать еще какой скетч. Но странно что у первого мужика глючный скетч.

Я даже его видео пересмотрел 10 раз, сравнивал скетч и тот что в видео. У него показывает у меня нет. )))