Добрый день! Впервые тут, в общем то по работе возникла необходимость в датчике температуры 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.
Пробовал. Что-то тут вообще не то, если поднести паяльник к датчику он вообще до определенного значения греет. И это не 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);
Поэтому скетч не вызывает доверия, видимо писал какой-то заграничный лох ))
Rref на модуле какой распаян? Он звонится правильно?
тк АЦП выдает значение относительно этого сопротивления. Может скетч рассчитан на другое значение этого резистора.
На картинке я вижу обозначение на резисторе: 431 - то есть 430 Ом, распаяно в этом модуле. Есть где-то на какой Rref расчитан сей скетч?..
Скетч я брал тут. MAX31865 - Pt100 RTD module — Curious Scientist
Там все как и у меня, подключение резистор впаян на 430 Ом, У него показывает температуру, у меня температуру на марсе. Меряется он верно, 429 ом, ну с погрешностью допустимо.
У того чертилы ТРЕХПРОВОДКА! в этом видимо суть. Соедините как я нарисовал и наверное пойдет. У вас из датчика сколько проводков торчит?
(для трехпроводки надо замкнуть неиспользуемую клемму чтобы ток бежал через резистор)
Я не серьезный парень. ))) 2 провода, брал с али чисто из-за того что проводка термозащищенная сразу приварена. В целом он показывает очень точно, и на 225 чип уже снимается, косик предыдущего скетча был в зависании, приходилось несколько раз выключать и включать ардуино. На датчике при температуре окружающей среды 28 111ом, и это норма. Тут явно проблема со скетчем. Сейчас пробую другой скетч и он показывает нормальное значение ±.
Можно взять измерительную часть, а дисплейную от другого скетча… Или разобраться почему первый неправильно с АЦП работает. Или искать еще какой скетч. Но странно что у первого мужика глючный скетч.