c++ - 具有pigpio SPI功能的Raspberry Pi上的MAX31865 C++类
问题描述
我正在寻找一些关于将 MAX31865 板集成到我的带有 Qt 前端的 Raspberry Pi 项目中的指导。该板包含 4 个带有独立 CS 引脚的 MAX31865 芯片。我已经确认芯片/RTD 在 Arduino 和 STM32 板上都能正常工作,但由于某种原因,我无法从 Raspberry Pi 获得相同的输出。我想知道不正确的输出是否与 pigpio spiWrite / spiRead / spiXfer 函数使用 (char *) 用于 rx / tx 缓冲区而不是像大多数其他库一样的 uint8_t 。例如,我会在连接了 RTD 的芯片上得到 92.5(大约 92.406),在没有连接 RTD 的芯片上得到 -403.636。无论如何,我在传感器上根本没有得到电阻变化。
我正在尝试将我用于 STM32 芯片组的一些代码改编为 C++ 类,它看起来不错,但如果可能的话,我会喜欢第二(或更多)双眼睛。
这是我的 max31865.cpp 文件(为简单起见,我在此处包含了 #defines 而不是 .h 文件)
#include "math.h"
#include "rpigpio.h"
#define MAX31865_CONFIG_REG 0x00
#define MAX31865_CONFIG_BIAS 0x80
#define MAX31865_CONFIG_MODEAUTO 0x40
#define MAX31865_CONFIG_MODEOFF 0x00
#define MAX31865_CONFIG_1SHOT 0x20
#define MAX31865_CONFIG_3WIRE 0x10
#define MAX31865_CONFIG_24WIRE 0x00
#define MAX31865_CONFIG_FAULTSTAT 0x02
#define MAX31865_CONFIG_FILT50HZ 0x01
#define MAX31865_CONFIG_FILT60HZ 0x00
#define MAX31865_RTDMSB_REG 0x01
#define MAX31865_RTDLSB_REG 0x02
#define MAX31865_HFAULTMSB_REG 0x03
#define MAX31865_HFAULTLSB_REG 0x04
#define MAX31865_LFAULTMSB_REG 0x05
#define MAX31865_LFAULTLSB_REG 0x06
#define MAX31865_FAULTSTAT_REG 0x07
#define MAX31865_FAULT_HIGHTHRESH 0x80
#define MAX31865_FAULT_LOWTHRESH 0x40
#define MAX31865_FAULT_REFINLOW 0x20
#define MAX31865_FAULT_REFINHIGH 0x10
#define MAX31865_FAULT_RTDINLOW 0x08
#define MAX31865_FAULT_OVUV 0x04
#define MAX31865_FAULT_NONE 0x00
#define RTD_A 3.9083e-3
#define RTD_B -5.775e-7
#define _MAX31865_RREF 402.0f
#define _MAX31865_RNOMINAL 100.0f
#define MAX31865_WIRES 3
#define MAX31865_FILTERHZ 50
MAX31865::MAX31865(uint8_t spiHandle, uint8_t cs_pin)
{
this->_spiHandle = spiHandle;
this->_cs_pin = cs_pin;
gpioSetMode(this->_cs_pin, PI_OUTPUT);
gpioWrite(this->_cs_pin, PI_HIGH);
MAX31865_setWires(MAX31865_WIRES);
MAX31865_enableBias(false);
MAX31865_autoConvert(false);
MAX31865_clearFault();
MAX31865_setFilter(MAX31865_FILTERHZ);
}
void MAX31865::MAX31865_readRegisterN(uint8_t address, uint8_t *buffer, uint8_t n) {
uint8_t tmp = 0xFF;
address &= 0x7F;
gpioWrite(this->_cs_pin, PI_LOW);
spiWrite(this->_spiHandle, (char *) &address, 1);
while (n--) {
spiXfer(this->_spiHandle, (char*) &tmp, (char *) buffer, 1);
buffer++;
}
gpioWrite(this->_cs_pin, PI_HIGH);
}
uint8_t MAX31865::MAX31865_readRegister8(uint8_t address) {
uint8_t ret = 0;
MAX31865_readRegisterN(address, &ret, 1);
return ret;
}
uint16_t MAX31865::MAX31865_readRegister16(uint8_t address) {
uint8_t buffer[2] = {0, 0};
MAX31865_readRegisterN(address, buffer, 2);
uint16_t ret = buffer[0];
ret <<= 8;
ret |= buffer[1];
return ret;
}
void MAX31865::MAX31865_writeRegister8(uint8_t address, uint8_t data) {
gpioWrite(this->_cs_pin, PI_LOW);
address |= 0x80;
spiWrite(this->_spiHandle, (char*) &address, 1);
spiWrite(this->_spiHandle, (char*) &data, 1);
gpioWrite(this->_cs_pin, PI_HIGH);
}
void MAX31865::MAX31865_readFault(){
this->_fault = MAX31865_readRegister8(MAX31865_FAULTSTAT_REG);
}
void MAX31865::MAX31865_clearFault() {
uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
t &= ~0x2C;
t |= MAX31865_CONFIG_FAULTSTAT;
MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}
void MAX31865::MAX31865_enableBias(bool enable) {
uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
if (enable) {
t |= MAX31865_CONFIG_BIAS;
}
else {
t &= ~MAX31865_CONFIG_BIAS;
}
MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}
void MAX31865::MAX31865_autoConvert(bool enable) {
uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
if (enable) {
t |= MAX31865_CONFIG_MODEAUTO;
}
else {
t &= ~MAX31865_CONFIG_MODEAUTO;
}
MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}
void MAX31865::MAX31865_setWires(uint8_t numWires) {
uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
if (numWires == 3) {
t |= MAX31865_CONFIG_3WIRE;
}
else {
t &= ~MAX31865_CONFIG_3WIRE;
}
MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}
void MAX31865::MAX31865_setFilter(uint8_t filterHz) {
uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
if (filterHz == 50) {
t |= MAX31865_CONFIG_FILT50HZ;
}
else {
t &= ~MAX31865_CONFIG_FILT50HZ;
}
MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
}
uint16_t MAX31865::MAX31865_readRTD() {
MAX31865_clearFault();
MAX31865_enableBias(true);
std::this_thread::sleep_for (std::chrono::milliseconds(10));
uint8_t t = MAX31865_readRegister8(MAX31865_CONFIG_REG);
t |= MAX31865_CONFIG_1SHOT;
MAX31865_writeRegister8(MAX31865_CONFIG_REG, t);
std::this_thread::sleep_for (std::chrono::milliseconds(10));
uint16_t rtd = MAX31865_readRegister16(MAX31865_RTDMSB_REG);
MAX31865_enableBias(false);
rtd >>= 1;
return rtd;
}
void MAX31865::MAX31865_readTemp() {
float Z1, Z2, Z3, Z4, Rt, temp;
Rt = MAX31865_readRTD();
Rt /= 32768;
Rt *= _MAX31865_RREF;
Z1 = -RTD_A;
Z2 = RTD_A * RTD_A - (4 * RTD_B);
Z3 = (4 * RTD_B) / _MAX31865_RNOMINAL;
Z4 = 2 * RTD_B;
temp = Z2 + (Z3 * Rt);
temp = (sqrtf(temp) + Z1) / Z4;
if (temp >= 0) {
MAX31865_readFault();
MAX31865_compareFault();
// Assume the temperature is correct
this->_MAX31865_tempC = temp;
this->_MAX31865_tempF = (this->_MAX31865_tempC * 9.0f / 5.0f) + 32.0f;
}
else {
Rt /= _MAX31865_RNOMINAL;
Rt *= 100;
float rpoly = Rt;
temp = -242.02;
temp += 2.2228 * rpoly;
rpoly *= Rt; // square
temp += 2.5859e-3 * rpoly;
rpoly *= Rt; // ^3
temp -= 4.8260e-6 * rpoly;
rpoly *= Rt; // ^4
temp -= 2.8183e-8 * rpoly;
rpoly *= Rt; // ^5
temp += 1.5243e-10 * rpoly;
MAX31865_readFault();
MAX31865_compareFault();
this->_MAX31865_tempC = temp;
this->_MAX31865_tempF = (this->_MAX31865_tempC * 9.0f / 5.0f) + 32.0f;
}
}
void MAX31865::MAX31865_compareFault() {
this->_faultText = "Unknown error has occured. Refer to the MAX31865 datasheet.";
if (this->_fault == MAX31865_FAULT_NONE)
this->_faultText = "No errors detected";
if (this->_fault == MAX31865_FAULT_HIGHTHRESH)
this->_faultText = "Measured resistance greater than High Fault Threshold value.";
if (this->_fault == MAX31865_FAULT_LOWTHRESH)
this->_faultText = "Measured resistance less than Low Fault Threshold value.";
if (this->_fault == MAX31865_FAULT_REFINLOW)
this->_faultText = "vREFIN > 0.85 x vBIAS.";
if (this->_fault == MAX31865_FAULT_REFINHIGH)
this->_faultText = "vRERFIN < 0.85 X vBIAS (FORCE - open).";
if (this->_fault == MAX31865_FAULT_RTDINLOW)
this->_faultText = "vRTRIN- < 0.85 X vBIAS (FORCE - open).";
if (this->_fault == MAX31865_FAULT_OVUV)
this->_faultText = "Any protected input voltage > vDD or < GND1.";
}
这是初始化代码和温度读取功能
int spiHandle = 0;
spiHandle = spiOpen(SPI_CHANNEL, SPI_SPEED, 0);
qDebug() << "[DEBUG] SPI Handle Open. Handle: " << spiHandle;
MAX31865 MAX31865_1(spiHandle, MAX31865_1_GPIO);
qDebug() << "[DEBUG] MAX31865 Initialized.";
volatile float _temp1_F = 0.0f;
MAX31865_1.MAX31865_readTemp();
qDebug() << "[DEBUG] 1 Temp F: " << MAX31865_1.read_MAX31865TempF();
_temp1_F = MAX31865_1.read_MAX31865TempF();
qDebug() << "[DEBUG] 1 Fault: " << MAX31865_1.read_MAX31865FaultText();
RPIDataStructure->set_tempMAX_1(_temp1_F);
非常感谢对这个项目的任何和所有帮助。谢谢你。
解决方案
推荐阅读
- python - 未找到模块错误:没有名为“chart_studio”的模块
- git - OPAM 无法发布包 - 说 git 无法获取
- azure-data-factory - Azure 数据流(将一个数据流的输出传递到管道中的另一个数据流)
- machine-learning - Keras ROC 与 Scikit ROC 不同?
- swift - replaceOccurrences 在 Playground 中工作,在编译的 macOS 应用程序中失败
- postgresql - 使用大/长子查询的 PostgreSQL 删除语句挂起/失败
- python - 在 PyQt 中使用 while-loop 时 time.sleep() 使程序崩溃
- java - 添加到arraylist列表
- jquery - 如何使用带有参数的jquery重定向到另一个页面
- matlab - Octave GUI 中的变量编辑器是什么