Рейтинг@Mail.ru

Как подключить MAX31865 и термодатчик PT100 к Arduino

автор:
3 comments Arduino
Print Friendly, PDF & Email
Научимся работать с конвертером MAX31865 аналогового сигнала датчика температуры P100/P1000 в цифровой сигнал.

Для проекта нам понадобится:

1Описание и характеристики конвертера MAX31865

Конвертер MAX31865 – это преобразователь сопротивления аналоговых датчиков температуры (RTD) в цифровой сигнал. Преобразователь MAX31865 оптимизирован для работы с датчиками температуры, наиболее широко применяемые из которых это платиновые датчики PT100 и PT1000. Преобразователь рассчитан на работу с 2-, 3- и 4-проводными датчиками. Подобные датчики выпускаются разными производителями и могут отличаться по форме, внешнему виду и т.д. Для примера в приложении к статье несколько технических описаний аналогичных датчиков.

Лучше всего покупать MAX31865 в составе готового модуля, как, например, на фотографии:

Внешний вид модуля преобразователя MAX31865
Внешний вид модуля преобразователя MAX31865

Назначение выводов приведённого модуля такое:

Назначение выводов MAX31865
ВыводНазначениеПримечание
CLKВход тактовой частоты SPI.Максимум до 5 МГц.
SDOВыход данных от MAX31865 к ведущему контроллеру.
SDIВход данных от контроллера к MAX31865.
CSВход выбора ведомого (MAX31865).Активный уровень – низкий.
VINВход питания 3,3…5,0 В.Имеется встроенный преобразователь напряжения, обеспечивающий необходимое питание чипа MAX31865.
3V3Выход 3,3 В.Можно питать внешние устройства, ток не более 100 мА.
DRDYИндикатор готовности данных.
GNDЗемля.
RTD+, RTD-Подключение температурного RTD датчика.Полярность не важна.
F+, F-Подключение дополнительных проводов термодатчика.В 3- и 4-проводном типах подключений.

Датчики PT100 и PT1000 имеют номинальное сопротивление 100 Ом и 1000 Ом при 0°C, соответственно. Эти датчики очень просты по принципу действия. По сути это обычный терморезистор, т.е. резистор, который изменяет сопротивление RTD при изменении температуры. Такие датчики могут быть изготовлены и из других металлов (никель, медь и др.). Датчики на основе платины отличаются широким температурным диапазоном, высокой точностью и относительно хорошей линейностью. Из рисунка видно, что отклонение от линейного закона для платинового термодатчика PT100 начинается при температурах свыше 200°C.

Зависимость сопротивления датчика PT100 от температуры
Зависимость сопротивления датчика PT100 от температуры

Обратите внимание на точку 0°C. При этой температуре термодатчик имеет своё номинальное сопротивление, в данном случае 100 Ом.

Датчики обычно выполняют в 2-, 3- и 4-проводном вариантах. Первый из них – самый простой, но при этом и самый грубый. Дело в том, что при большой длине провода (а датчик может находиться в десятках метрах от контроллера) сопротивление провода становится сопоставимым с сопротивлением самого датчика. И на провод также действует температура. Соответственно, он будет вносить некоторую (возможно, значительную) погрешность в измерения. Для компенсации этого эффекта придумали 4-проводную схему подключения, когда 2 дополнительных провода используются для компенсации температурной погрешности датчика. А трёхпроводный датчик – это компромисс между 2- и 4-проводными: он более точный, чем 2-проводный, но менее точный 4-проводного. Зато и проводов у него меньше, чем у 4-проводного.

Вкратце рассмотрим принцип работы чипа MAX31865 в 4-проводном режиме, используя следующую схему.

Схема измерений на чипе MAX31865
Схема измерений на чипе MAX31865

Терморезистор RTD подключен одной парой проводов к выводам RTDIN+ и RTDIN-, а второй парой проводов – к выводам FORCE+ и FORCE-. Для начала измерений с вывода BIAS микросхемы подаётся опорное напряжение. Возникает электрический ток, который проходит через опорное сопротивление RREF и дальше идёт по проводу через вывод FORCE+, через терморезистор RTD к выводу FORCE-. Зная напряжение на выходе BIAS и сопротивление опорного резистора, по закону Ома можно вычислить ток I, протекающий в этой цепи. Этот же ток протекает и через терморезистор. Далее чип MAX31865 измеряет напряжение U между выводами RTDIN+ и RTDIN-. По рассчитанному току I и измеренному напряжению U можно определить сопротивление на терморезисторе RRTD. А зная сопротивление терморезистора и закон изменения сопротивления от температуры, можно определить температуру датчика.

Есть тонкости по работе с датчиками с разным числом проводов: необходимо определённым образом распаять перемычки на модуле. Распайка перемычек показана на иллюстрации и обозначена зелёным цветом. Кроме того, для подключения 3-проводного датчика необходимо рассечь перемычку, которая по умолчанию имеется между контактными площадками, обзначенными "2" и "4"; на иллюстрации она обозначена красным цветом.

Распайка перемычек модуля MAX31865 под разные датчики
Распайка перемычек модуля MAX31865 под разные датчики

Для подключения 2-проводного датчика просто подключаем его два провода к клеммам RTD+ и RTD-.

Для подключения 4-проводного датчика необходимо определить, между какими из 4-х проводов находится терморезистор. Для этого достаточно померить сопротивление мультиметром или омметром. Оно должно быть около 100 Ом для датчика PT100 и около 1 кОм для датчика PT1000. Эти два провода подключаются к клеммам RTD+ и RTD-, оставшиеся два провода – к клеммам F+ и F-, не важно какой из них куда.

Для подключения 3-проводного датчика опять с помощью мультиметра определяем, какие 2 провода подключены через терморезистор, и подключаем их к клеммам RTD+ и RTD-. Третий провод необходимо подключить к клемме F+.

Модуль для датчика PT100 отличается от модуля для датчика PT1000 распаянным опорным сопротивлением (оно обведено на плате прямоугольником и обозначено Rref ). На модуле, который рассчитан на работу с PT100, стоит резистор Rref сопротивлением 430 Ом (обозначение на корпусе резистора 431 или 4300), а на модуле для датчика PT1000 резистор Rref=4300 Ом (обозначение на корпусе 432 или 4301). Обратите на это внимание при выборе датчика и модуля.

Сначала проверим работоспособность датчика с помощью Arduino и одной из популярных библиотек, а затем рассмотрим его более детально и научимся управлять чипом MAX31865 без сторонних библиотек.

2Подключение преобразователяMAX31865 к Arduino

Есть несколько популярных библиотек Arduino для работы с MAX31865. Но наиболее популярная и проверенная, вероятнее всего, библиотека от Adafruit. Скачаем и установим её.

Библиотеку от Adafruit можно также установить через менеджер библиотек Arduino IDE: Tools Manage Libraries… и в поле фильтра ввести MAX31865. Выбрать интересующую библиотеку, нажать кнопку Install и дождаться окончания установки.

Откроем из примеров библиотеки единственный скетч для MAX31865 и загрузим его в память Arduino.

Загрузка примера из библиотеки для MAX31865
Загрузка примера из библиотеки для MAX31865

Обратите внимание, что в функции setup() необходимо указать, по какой схеме вы подключаете датчик. По умолчанию стоит трёхпроводная схема, что указывается константой MAX31865_3WIRE. Для 2- и 4-проводных подключений датчика названия констант, соответственно, MAX31865_2WIRE и MAX31865_4WIRE. Также следует обратить внимание на константы в начале скетча RREF и RNOMINAL, которые определяют референсное (опорное) сопротивление и номинальное сопротивление термодатчика, соответственно.

Теперь подключим модуль с MAX31865 к Arduino по такой схеме (соответствие выводов можно поменять в скетче):

Схема подключения модуля MAX31865 к Arduino
Вывод модуляВывод Arduino
CLKD13
SDID11
SDOD12
CSD10
VIN3V3
GNDGND

Если запустить теперь монитор последовательного порта из Arduino IDE, то мы должны увидеть ежесекундно обновляющиеся показания термодатчика.

3Управление преобразователемMAX31865 по SPI

Конвертер MAX31865 управляется по интерфейсу SPI в режиме 1 (MODE1) или 3 (MODE3). Можно читать из и передавать в MAX31865 как по 1 байту, так и сразу по несколько.

Для управления необходимо знать карту его регистров. Регистров всего восемь:

Карта регистров преобразователя MAX31865
Карта регистров преобразователя MAX31865

Здесь POR – это состояние регистра после подачи питания или сброса.

В первом столбце названия регистров. Во втором их адреса для чтения, а в третьем – для записи. В четвёртом столбце приведены исходные состояния регистров после сброса. В последнем – можно ли записывать в регистр (R/W, read/write) или только читать из него (R, read). Рассмотрим кратко все регистры.

Регистр конфигурации MAX31865 (адрес 0x00)

Первый из регистров – регистр конфигурации. Он задаёт режим работы чипа MAX31865, в том числе, включает измерение температуры.

Регистр конфигурации преобразователя MAX31865
Регистр конфигурации преобразователя MAX31865
Назначение битов регистра конфигурации MAX31865
D7 (VBIAS)Подаёт ток на датчик температуры, без этого измерения невозможны.
D6Включает автоматический режим измерения температуры.
D5Управляет режимом измерений: если D6=0, то установка бита D5 приводит к однократному измерению температуры.
D4Задаёт схему подключения датчика (2-, 3-, 4-проводная).
D3, D2Определяют режим обнаружения неисправностей.
D1Позволяет очистить регистр статуса, если он показывает ошибки.
D0Управляет выбором режекторного фильтра, который отрезает 50- или 60-герцовые наводки. В процессе автоматических измерений менять тип фильтра нельзя!

Регистр статуса (или ошибок) MAX31865 (адрес 0x07)

В регистр статуса преобразователь MAX31865 выставляет следующие признаки (если они возникают):

Регистр статуса преобразователя MAX31865
Регистр статуса преобразователя MAX31865
Назначение битов регистра статуса MAX31865
D7Выше заданного верхнего порога температуры.
D6Ниже заданного нижнего порога температуры.
D5Напряжение на REFIN- слишком высокое (REFIN- – один из входов опорного напряжения на резисторе Rref).
D4Напряжение на REFIN- слишком низкое.
D3Напряжение на RTDIN- слишком низкое (RTDIN- – один из входов термодатчика RRTD).
D2Ошибка питания (напряжение превышено или слишком низкое).
D1, D0Не важны.

Сбросить значение регистра состояния можно указав лог. "1" в разряде D1 регистра конфигурации, рассмотренного выше.

Регистры данных с термодатчика MAX31865 (адреса 0x01, 0x02)

Сюда MAX31865 записывает измеренные значения с термодатчика. Эти регистры доступны только для чтения. Преобразование считанного значения в градусы Цельсия рассмотрим чуть позже.

Регистры установки порогов срабатывания оповещения термодатчика MAX31865 (адреса 0x03…0x06)

Можно настроить диапазон температуры, при выходе за который чип MAX31865 оповестит об этом событии (запишет в регистр статуса соответсвующий признак). По умолчанию используется весь доступный диапазон от 0x0000 до 0xFFFF.

Теперь, имея необходимую информацию о регистрах чипа, применим эти знания на практике. По традиции, сначала научимся работать с чипом MAX31865 посредством микросхемы FT2232 или аналогичной и программы SPI via FTDI.

Подключим модуль к порту A микросхемы FT2232 стандартным образом:

Вывод модуля MAX31865Вывод FT2232
CLKADBUS0
SDIADBUS1
SDOADBUS2
CSADBUS3
VINЛюбой из BDBUS0…BDBUS7 (GPIO0…GPIO7) или можно использовать внешний источник питания напряжением 3-5 В.
GNDGND

Должно быть как-то так. Правда, несмотря на то, что у меня 4-проводный датчик, в данном случае я подключил его по схеме 2-проводного. Т.е. 2 дополнительных провода на тех же клеммах, что и выводы терморезистора. Перемычки на модуле уже распаяны, и не было времени перепаивать их для 4-проводного режима. При таком подключении, конечно, теряется преимущество 4-проводного модуля, но для задачи тестирования и демонстрации принципов управления преобразователем это допустимо.

Модуль MAX31865 подключён к отладочной плате с FT2232
Модуль MAX31865 подключён к отладочной плате с FT2232

Теперь запустим программу SPI via FTDI. В меню «Устройство» выберем интерфейс SPI, если выбран не он. Программа произведёт поиск подключённых устройств FTDI и добавит их во вкладки. Нас будет интересовать порт A, который появится в первой вкладке. Нажмём на ней правой кнопкой мыши и нажмём «Подключить». Теперь зададим режим SPI: MODE1 (п.1 на рисунке). Остальные параметры здесь можно не трогать. В разделе записи поставим флажок «Команда» и введём команду 80 C6 (п.2 ). Нажмём кнопку «Записать», и программа отправит эту команду чипу MAX31865.

Настройка программы для работы с MAX31865
Настройка программы для работы с MAX31865

Почему команда 80 C6? Здесь 80 – это адрес для записи в регистр конфигурации, см. таблицу с картой регистров. А C6 – это значение регистра конфигурации. В двоичном виде 0xC6=1100_0110. Как было описано выше, здесь мы подаём ток на термодатчик, выставляем непрерывный режим измерения, указываем, что датчик подключён по 2-проводной схеме, что ошибки нужно обрабатывать автоматически, а также сбрасываем регистр статуса.

Физически на линиях данных интерфейса SPI во время отправки команды происходит вот что. Линия CS опускается в логический "0". На линии CLK генерируются 16 тактовых импульсов для передачи 2-х байт информации (16 бит). Мастер (в данном случае микросхема FT2232H) в это время на линию SDI выставляет данные (это и есть наша команда 0x80 0xC6).

Временная диаграмма записи по SPI в регистр конфигурации MAX31865
Временная диаграмма записи по SPI в регистр конфигурации MAX31865

После этого можно начать вычитывать данные температуры. Для этого в разделе чтения указываем команду 00 (п.3 ) (это адрес регистра, с которого начинаем читать), укажем размер вычитываемых данных 8 (п.4 ). Это количество регистров чипа MAX31865. Можно прочитать данные один раз, а можно в поле количества раз поставить 0 (п.5 ), что будет означать непрерывное чтение из MAX31865. Нажмём кнопку «Прочитать». Чтобы увидеть принимаемые данные, нажмём на кнопку с изображением таблицы, расположенную слева от кнопки чтения (п.6 ). Откроется окно с принимаемыми данными (п.7 ).

В данных нас в первую очередь интересуют байты по адресам 1 и 2. Это, собственно, и есть значение температуры в «попугаях», а точнее – в отсчётах АЦП. В данном случае 0x43FC. Байт 7, как мы помним, это значение регистра статуса. В примере он 0, а значит работа идёт без проблем и замечаний. Байты со 2 по 6 – это пороги температуры. Мы их не задавали, поэтому они имеют значения по умолчанию 0xFFFF и 0x0000.

Во время чтения физически на линиях: CS опускается в лог."0", на линии CLK генерируется столько тактовых импульсов, сколько байтов нужно прочитать и отправить, умноженное на 8. Например, в данном случае мы отправили однобайтовую команду 0x00, а затем запросили 8 байтов. Т.е. в сумме обмен состоит из 9-ти байтов. Значит, тактовых импульсов 9×8=72. Первый байт передаётся по линии SDI от ведущего (FT2232H) к ведомому, а следующие 8 уже от ведомого (MAX31865) к ведущему на линии SDO. И эти 8 байт как раз и есть содержимое 8-ми регистров MAX31865. На временной диаграмме это 0xC1 0x44 0x0E 0xFF 0xFF 0x00 0x00 0x00.

Временная диаграмма чтения по SPI всех регистров MAX31865, начиная с 0-го
Временная диаграмма чтения по SPI всех регистров MAX31865, начиная с 0-го

Теперь нужно перевести полученное значение в температуру. MAX31865 возвращает код напряжения, измеренного аналого-цифровым преобразователем на терморезисторе. Сначала необходимо посчитать сопротивление термодатчика по формуле:RRTD = (ADC_Code × RREF) / 215 / 2, где ADC_Code – прочитанное из регистров 1 и 2 значение, RREF – сопротивление опорного резистора, а 215 – диапазон 15-разрядного АЦП. В приведённом случае, например, получим:

    RRTD = 0x440E * 430 Ом / 32768 / 2 = 114,3 Ом.

Теперь, зная сопротивление термодатчика RTD, можно определить температуру. Обычно это делается по таблицам или рассчитывается по формулам. Но проще всего воспользоваться т.н. коэффициентом α. Это коэффициент, который показывает на сколько Ом изменяется сопротивление RTD при изменении температуры на 1°C. Обычно «альфа» равняется 0,385 или 0,392 (точное значение указывается в документации на датчик). В моём случае α=0,3851.

Указание коэффициента α на датчик PT100
Указание коэффициента α на датчик PT100

Использование α рекомендуется в диапазоне температур от 0 до 100°C.

Таким образом, чтобы вычислить температуру по коэффициенту α, необходимо: TRTD = (RRTD − 100) / α или

    TRTD = (114,3 - 100) / 0,3851 = 37,13°C.

4Управление преобразователем MAX31865c Arduino без библиотек

Итак, мы постигли основы работы с термодатчиком PT100 и преобразователем MAX31865. Наших знаний теперь хватит для того чтобы написать свою реализацию опроса резистивного температурного детектора. Подключим модуль с датчиком температуры к Arduino. Схема подключения была приведена выше в разделе 2.

Модуль с MAX31865 и термодатчиком PT100 подключены к Arduino Nano
Модуль с MAX31865 и термодатчиком PT100 подключены к Arduino Nano

Давайте немного разовьём идею. Один раз в секунду будем опрашивать температуру с MAX31865. Перед тем как возвращаеть измерение пользователю, будем смотреть вывод готовности данных DRDY и забирать данные только по готовности, а в случае неготовности данных оповещать об этом. Также добавим отключение датчика после каждого измерения до следующего.

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

Скетч будет такой.

Скетч чтения температуры с MAX31865 без библиотек (разворачивается)
#include <SPI.h>

#define RREF          430.0  // опорное сопротивление
#define RNOMINAL      100.0  // номинальное сопротивление термодатчика
#define ALPHA         0.3851 // коэффициент "альфа"
#define CFG_REG_READ  0x00   // адрес для чтения конфигурационного регистра
#define CFG_REG_WRITE 0x80   // адрес для записи конфигурационного регистра
#define DRDY          9      // пин готовности данных - D9

SPISettings spiSettings(1000000, MSBFIRST, SPI_MODE1); // настройки SPI 

void setup() {
  SPI.begin(); // инициализируем SPI
  Serial.begin(115200); // инициализируем UART
  Serial.println("Test MAX31865 and temperature detector PT100");
}

void loop() {
  start_conversion(); // запускаем процесс измерения температуры
  if (check_data_ready()) // проверяем готовность данных
  {
    int rtd = read_rtd(); // читаем показания термодатчика
    float temp = convert_to_temperature(rtd); // переводим показания в температуру
    Serial.println("T = " + (String)temp); // выводим температуру в консоль
  }
  else 
  {
    Serial.println("Data NOT ready"); // сообщаем о неготовности данных
  }
  stop_conversion(); // останавливаем измерения на 1 сек
  delay(1000);
}

// Запускает однократное измерение.
void start_conversion() {
  SPI.beginTransaction(spiSettings); // начинаем передачу по SPI
  digitalWrite(SS, LOW); // активируем вывод выбора ведомого
  SPI.transfer(CFG_REG_WRITE); // передаём адрес записи конфигурационного регистра
  SPI.transfer(0xA2); // передаём значение в регистр (сделать однокаратное измерение, 2- или 4-проводная схема)
  digitalWrite(SS, HIGH); // деактивируем вывод выбора ведомого
  SPI.endTransaction(); // заканчиваем передачу по SPI
}

// Останавливает измерения.
void stop_conversion() {
  SPI.beginTransaction(spiSettings);
  digitalWrite(SS, LOW);
  SPI.transfer(CFG_REG_WRITE); // передаём адрес записи конфигурационного регистра
  SPI.transfer(0x02); // передаём значение в регистр (выключить измерения, сброс регистра статуса)
  digitalWrite(SS, HIGH);
  SPI.endTransaction();
}

// Проверяет готовность данных.
bool check_data_ready() {
  int data_ready = 1; // признак готовности данных
  int cnt = 0; // счётчик для ограничения числа повторов, чтобы не войти в бесконечный цикл опроса
  while ((data_ready == 1) && (cnt < 10)) { // несколько раз опрашиваем MAX31865 на предмет готовности данных
    data_ready = digitalRead(DRDY); // когда данные готовы, MAX31865 выставляет DRDY в "0"
    delay(10);
    cnt += 1;
  }
  return (data_ready != 1); // если "0", то данные готовы, если "1" - не готовы
}

// Читает показания термодатчика PT100.
int read_rtd() {
  SPI.beginTransaction(spiSettings);
  digitalWrite(SS, LOW);
  SPI.transfer(CFG_REG_READ); // передаём адрес чтения конфигурационного регистра 
  int inByte[8]; // массив для хранения значений 8-ми регистров MAX31865
  for (int i=0; i<8; i++) { // читаем 8 байт из MAX31865
    inByte[i] = SPI.transfer(0x00);
    Serial.print(inByte[i], HEX); Serial.print(" "); // вывод содержимого регистров
  }
  Serial.println();
  digitalWrite(SS, HIGH);
  SPI.endTransaction();
  int rtd = word(inByte[1], inByte[2]); // собирает значение из 2-х байт
  Serial.print("RTD = "); Serial.println(rtd);
  return rtd;
}

// Преобразует показания с датчика PT100 в градусы Цельсия.
float convert_to_temperature(int rtd) {
  float rrtd = rtd * RREF / 32768 / 2; // сопротивление термодатчика
  Serial.println("RRTD = " + (String)rrtd);
  float temp = (rrtd - RNOMINAL) / ALPHA; // перевод в температуру с помощью коэф-та α
  return temp;
}

После загрузки данного скетча в Arduino запустим монитор последовательного порта. В нём ежесекундно будет выводиться содержимое 8-ми регистров MAX31865, «сырые» показания АЦП чипа, сопротивление датчика PT100 и температура датчика:

Вывод скетча со значениями температуры датчика PT100
Вывод скетча со значениями температуры датчика PT100

Конечно, весь вспомогательный вывод информации можно убрать из скетча, ведь нас интересует, по сути, только температура. Кроме того, в данный скетч можно добавить обработку ошибок из регистра статуса, управление настройками через конфигурационный регистр, выставление температурных порогов и т.д.

Last modified onВторник, 14 Сентябрь 2021 18:21 Read 2149 times
Ключевые слова: :

Поделиться

Print Friendly, PDF & Email

3 comments

  • Алексей
    Алексей Четверг, 28 Октябрь 2021 21:21 Ссылка на комментарий

    Добрый день.
    Скопировал код, подключил к arduino mega, данных нет. Код из примера библиотеки работает, Ваш нет.
    Как подключить 2 датчика Pt100?
    Есть ли у Вас код и подключение на данный датчик и ADS1015
    спасибо

  • Aave1
    Aave1 Пятница, 29 Октябрь 2021 18:00 Ссылка на комментарий

    Алексей, подключить 2 датчика через 2 преобразователя? Один датчик к одному преобразователю. Управление в протоколе SPI осуществляется ножкой выбора ведомого. Два датчика к одному преобразователю подключить нельзя.
    Почему у Вас не работает мой код надо разбираться. У меня на Arduino Nano всё работает. Возможно, у Меги выводы управления по-другому нумеруются, надо смотреть. Микросхемы ADS1015 у меня нет.

  • Алексей
    Алексей Пятница, 29 Октябрь 2021 18:27 Ссылка на комментарий

    Ну, первый код, при помощи библиотеки, работает. без нее, то есть второй код нет. Пишет данные не готовы, закомментировал строки по проверки готовности данных, все по нулям. Значит подключение верное.
    Могу ли я попросить у Вас совета с одной проблемой?
    Имею датчик Pt100 и ADS1015. Вывод температуры имеется. Так же имеется твердотельное реле (управляет двигателем) и обычное (управляет клапаном).
    При включении твердотельного, температура прыгает на +0.20 град. При включении обычного реле на клапан, показание температуры прыгает на +0.40 град. Без нагрузки все хорошо, сделал раздельное питание, не помогает, двигатель на расстоянии 30см, клапан на 60см. Не пойму где проседает, или что влияет.

Leave a comment