Arduino to Squirrel

I bought an RTD breakout board but the only examples they have are Arduino based. Any pointers would be awesome!

`/***************************************************************************

  • File Name: serial_MAX31865.h
  • Processor/Platform: Arduino Uno R3 (tested)
  • Development Environment: Arduino 1.0.5
  • Designed for use with with Playing With Fusion MAX31865 Resistance
  • Temperature Device (RTD) breakout board: SEN-30201 (PT100 or PT1000)
  • —> http://playingwithfusion.com/productview.php?pdid=25
  • —> http://playingwithfusion.com/productview.php?pdid=26
  • Copyright © 2014 Playing With Fusion, Inc.
  • SOFTWARE LICENSE AGREEMENT: This code is released under the MIT License.
  • Permission is hereby granted, free of charge, to any person obtaining a
  • copy of this software and associated documentation files (the “Software”),
  • to deal in the Software without restriction, including without limitation
  • the rights to use, copy, modify, merge, publish, distribute, sublicense,
  • and/or sell copies of the Software, and to permit persons to whom the
  • Software is furnished to do so, subject to the following conditions:
  • The above copyright notice and this permission notice shall be included in
  • all copies or substantial portions of the Software.
  • THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  • AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  • LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  • DEALINGS IN THE SOFTWARE.

  • REVISION HISTORY:
  • Author Date Comments
  • J. Steinlage 2014Jan25 Original version
  • Playing With Fusion, Inc. invests time and resources developing open-source
  • code. Please support Playing With Fusion and continued open-source
  • development by buying products from Playing With Fusion!

  • ADDITIONAL NOTES:
  • This file configures then runs a program on an Arduino Uno to read a
  • MAX31865 RTD-to-digital converter breakout board and print results to
  • a serial port. Communication is via SPI built-in library.
    • Configure Arduino Uno
    • Configure and read resistances and statuses from MAX31865 IC
  •  - Write config registers (MAX31865 starts up in a low-power state)
    
  •  - RTD resistance register
    
  •  - High and low status thresholds 
    
  •  - Fault statuses
    
    • Write formatted information to serial port
  • Circuit:
  • Arduino Uno --> SEN-30201
  • CS: pin 10 --> CS
  • MOSI: pin 11 --> SDI (must not be changed for hardware SPI)
  • MISO: pin 12 --> SDO (must not be changed for hardware SPI)
  • SCK: pin 13 --> SCLK (must not be changed for hardware SPI)
  • GND --> GND
  • 5V --> Vin (supply with same voltage as Arduino I/O, 5V)
    ***************************************************************************/

// the sensor communicates using SPI, so include the hardware SPI library:
#include <SPI.h>
// include Playing With Fusion MAX31865 libraries
#include <PlayingWithFusion_MAX31865.h> // core library
#include <PlayingWithFusion_MAX31865_STRUCT.h> // struct library

//Sensor addresses:
const byte CONFIG_REG_W = 0x80; // Config register write addr
const byte CONFIG_VALUE = 0xC3; // Config register value (Vbias+Auto+FaultClear+50Hz, see pg 12 of datasheet)
const byte ADC_WORD_MSB = 0x01; // Addr of first byte of data (start reading at RTD MSB)
const byte ADC_FAULT_REG = 0x07; // Addr of the fault reg

// CS pin used for the connection with the sensor
// other connections are controlled by the SPI library)
const int CS_PIN = 10;

PWFusion_MAX31865_RTD rtd_ch0(CS_PIN);

void setup() {
Serial.begin(9600);

// setup for the the SPI library:
SPI.begin(); // begin SPI
SPI.setDataMode(SPI_MODE3); // MAX31865 is a Mode 3 device

// initalize the chip select pin
pinMode(CS_PIN, OUTPUT);
rtd_ch0.MAX31865_config();

// give the sensor time to set up
delay(100);
}

void loop()
{
delay(500); // 500ms delay… can be much faster

static struct var_max31865 RTD_CH0;
double tmp;

RTD_CH0.RTD_type = 1; // un-comment for PT100 RTD
// RTD_CH0.RTD_type = 2; // un-comment for PT1000 RTD

struct var_max31865 *rtd_ptr;
rtd_ptr = &RTD_CH0;

rtd_ch0.MAX31865_full_read(rtd_ptr); // Update MAX31855 readings

// Print information to serial port
Serial.println(“RTD Sensor 0:”); // Print RTD0 header

if(0 == RTD_CH0.status) // no fault, print info to serial port
{
if(1 == RTD_CH0.RTD_type) // handle values for PT100
{
// calculate RTD resistance
tmp = (double)RTD_CH0.rtd_res_raw * 400 / 32768;
Serial.print("Rrtd = "); // print RTD resistance heading
Serial.print(tmp); // print RTD resistance
}
else if(2 == RTD_CH0.RTD_type) // handle values for PT1000
{
// calculate RTD resistance
tmp = (double)RTD_CH0.rtd_res_raw * 4000 / 32768;
Serial.print(“Rrtd = “); // print RTD resistance heading
Serial.print(tmp); // print RTD resistance
}
Serial.println(” ohm”);
// calculate RTD temperature (simple calc, +/- 2 deg C from -100C to 100C)
// more accurate curve can be used outside that range
tmp = ((double)RTD_CH0.rtd_res_raw / 32) - 256;
Serial.print(“Trtd = “); // print RTD temperature heading
Serial.print(tmp); // print RTD resistance
Serial.println(” deg C”); // print RTD temperature heading
} // end of no-fault handling
else
{
Serial.print("RTD Fault, register: ");
Serial.print(RTD_CH0.status);
if(0x80 & RTD_CH0.status)
{
Serial.println(“RTD High Threshold Met”); // RTD high threshold fault
}
else if(0x40 & RTD_CH0.status)
{
Serial.println(“RTD Low Threshold Met”); // RTD low threshold fault
}
else if(0x20 & RTD_CH0.status)
{
Serial.println(“REFin- > 0.85 x Vbias”); // REFin- > 0.85 x Vbias
}
else if(0x10 & RTD_CH0.status)
{
Serial.println(“FORCE- open”); // REFin- < 0.85 x Vbias, FORCE- open
}
else if(0x08 & RTD_CH0.status)
{
Serial.println(“FORCE- open”); // RTDin- < 0.85 x Vbias, FORCE- open
}
else if(0x04 & RTD_CH0.status)
{
Serial.println(“Over/Under voltage fault”); // overvoltage/undervoltage fault
}
else
{
Serial.println(“Unknown fault, check connection”); // print RTD temperature heading
}
} // end of fault handling
}

`

I’d be willing to bet that it reads pretty similarly to the MAX31855… I’d start with that. There is reference code on the Electric Imp GitHub page, or the tutorial in mine.

Is there an easy way to just log the output data? I don’t think the unit is responding properly to my setup. I don’t see any LED lights going off so I suspect my soldering skills are not good.

I am guessing this output is not hopeful:

2014-05-27 15:09:14 UTC-4 [Device] AAAAAA==
2014-05-27 15:09:24 UTC-4 [Device] AAAAAA==
2014-05-27 15:09:34 UTC-4 [Device] AAAAAA==
2014-05-27 15:09:44 UTC-4 [Device] AAAAAA==

OK I think my main issue is this library that initializes the board. Is this typical for some breakouts?

`
PWFusion_MAX31865_RTD::PWFusion_MAX31865_RTD(int8_t CSx)
{
// Function to initialize thermocouple channel, load private variables
_cs = CSx;

// immediately pull CS pin high to avoid conflicts on SPI bus
digitalWrite(_cs, HIGH);
}

// function to configure MAX31865 configuration register
void PWFusion_MAX31865_RTD::MAX31865_config(void)
{
// take the chip select low to select the device:
digitalWrite(_cs, LOW);

// Write config to MAX31865 chip
SPI.transfer(0x80); // Send config register location to chip
// 0x8x to specify ‘write register value’
// 0xx0 to specify 'configuration register’
SPI.transfer(0xC2); // Write config to IC
// bit 7: Vbias -> 1 (ON)
// bit 6: conversion mode -> 1 (AUTO)
// bit 5: 1-shot -> 0 (off)
// bit 4: 3-wire select -> 0 (2/4 wire config)
// bit 3-2: fault detection cycle -> 0 (none)
// bit 1: fault status clear -> 1 (clear any fault)
// bit 0: 50/60 Hz filter select -> 0 (60 Hz)

// take the chip select high to de-select, finish config write
digitalWrite(_cs, HIGH);

// code if you need to configure High and Low fault threshold registers (4 total registers)
// // take the chip select low to select the device:
// digitalWrite(_cs, LOW);
// SPI.transfer(0x83); // write cmd, start at HFT MSB reg (0x83)
// SPI.transfer(0xFF); // write cmd, start at HFT MSB reg (0x83)
// SPI.transfer(0xFF); // write cmd, start at HFT MSB reg (0x83)
// SPI.transfer(0x00); // write cmd, start at HFT MSB reg (0x83)
// SPI.transfer(0x00); // write cmd, start at HFT MSB reg (0x83)
// // take the chip select high to de-select, finish config write
// digitalWrite(_cs, HIGH);
}

void PWFusion_MAX31865_RTD::MAX31865_full_read(struct var_max31865 *rtd_ptr)
{
// Function to unpack and store MAX31865 data
int16_t _temp_i16, _rtd_res;
uint32_t _temp_u32;

digitalWrite(_cs, LOW); // must set CS low to start operation

// Write command telling IC that we want to ‘read’ and start at register 0
SPI.transfer(0x00); // plan to start read at the config register

// read registers in order:
// configuration
// RTD MSBs
// RTD LSBs
// High Fault Threshold MSB
// High Fault Threshold LSB
// Low Fault Threshold MSB
// Low Fault Threshold LSB
// Fault Status

rtd_ptr->conf_reg = SPI.transfer(0x00); // read 1st 8 bits

_rtd_res = SPI.transfer(0x00); // read 2nd 8 bits
_rtd_res <<= 8; // shift data 8 bits left
_rtd_res |= SPI.transfer(0x00); // read 3rd 8 bits
rtd_ptr->rtd_res_raw = _rtd_res >> 1; // store data after 1-bit right shift

_temp_i16 = SPI.transfer(0x00); // read 4th 8 bits
_temp_i16 <<= 8; // shift data 8 bits left
_temp_i16 |= SPI.transfer(0x00); // read 5th 8 bits
rtd_ptr->HFT_val = _temp_i16 >> 1; // store data after 1-bit right shift

_temp_i16 = SPI.transfer(0x00); // read 6th 8 bits
_temp_i16 <<= 8; // shift data 8 bits left
_temp_i16 |= SPI.transfer(0x00); // read 7th 8 bits
rtd_ptr->LFT_val = _temp_i16; // store data after 1-bit right shift

rtd_ptr->status = SPI.transfer(0x00); // read 8th 8 bits

digitalWrite(_cs, HIGH); // set CS high to finish read

// re-write config if no valid read or a fault present
// keep in mind some faults re-set immediately (HFT/LFT)
if((0 == _rtd_res) || (0 != rtd_ptr->status))
{
MAX31865_config(); // call config function
}
}
`

It won’t address this case specifically, folks, but I am currently working on a guide to porting Arduino code to Squirrel. As usual, I’ll post a note in the forum when it’s live.

@smittytone How would you interpret this Arduino code?

`rtd_ptr->conf_reg = SPI.transfer(0x00); // read 1st 8 bits

_rtd_res = SPI.transfer(0x00); // read 2nd 8 bits
_rtd_res <<= 8; // shift data 8 bits left
_rtd_res |= SPI.transfer(0x00); // read 3rd 8 bits
rtd_ptr->rtd_res_raw = _rtd_res >> 1; // store data after 1-bit right shift

_temp_i16 = SPI.transfer(0x00); // read 4th 8 bits
_temp_i16 <<= 8; // shift data 8 bits left
_temp_i16 |= SPI.transfer(0x00); // read 5th 8 bits
rtd_ptr->HFT_val = _temp_i16 >> 1; // store data after 1-bit right shift

_temp_i16 = SPI.transfer(0x00); // read 6th 8 bits
_temp_i16 <<= 8; // shift data 8 bits left
_temp_i16 |= SPI.transfer(0x00); // read 7th 8 bits
rtd_ptr->LFT_val = _temp_i16; // store data after 1-bit right shift

rtd_ptr->status = SPI.transfer(0x00); // read 8th 8 bits`

At a rough guess, something like this, @theorem:

`SPI <- hardware.spi257;
CS <- hardware.pin8;

SPI.configure((CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 100); // Mode 3
CS.configure(DIGITAL_OUT);
CS.write(1); // Set CS pin high

. . .

CS.write(0); // CS pin low to signal transaction

SPI.write("\x00"); // Write start register address to bus

local data = SPI.readblob(8); // Read in eight bytes into blob data

CS.write(1); // CS pin high to end transaction

conf_reg = data[0];
_rtd_res = (data[1] << 8) + data[2];
rtd_res_raw = _rtd_res >> 1;
_temp_i16 = (data[3] << 8) + data[4];
HFT_val = _temp_i16 >> 1;
_temp_i16 = (data[5] << 8) + data[6];
LFT_val = _temp_i16 >> 1;
status = data[7];`

The write() and readblob() methods automatically handle the reading and writing of dummy characters (the 0x00 in SPI.transfer(0x00)). This fragment also assumes that the peripheral device set-up is done elsewhere; I’ve included imp set-up for clarity.

@smittytone That helped a ton thanks! At this stage, I cannot seem to get it to take the configuration. The config bit returns 255. Anything look broken to anyone?

`// Read data from MAX31865 chip on Playing with Fusion breakout boards
// Code developed by Electric Imp Forum members rivers,
// mjkuwp94, Brown, as well as Hugo, peter, Joel Wehr, and others.
// Modified for use by David Peterson.
// pins:
// imp 1 CLK
// imp 2 CS
// imp 5 UNASSIGNED
// imp 7 UNASSIGNED
// imp 8 UNASSIGNED
// imp 9 DO
// Constants
const a_therm = 3.90830;
const b_therm = -5.77500;

//Configure Pins
hardware.spi189.configure(( CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 100);
hardware.pinA.configure(DIGITAL_OUT); //chip select

// define variables
conf_reg <- 0;
data <- 0;
_rtd_res <- 0;
rtd_res_raw <- 0;
_temp_i16 <- 0;
rtd_prt <- 0;
HFT_val <- 0;
LFT_val <- 0;
temptest <- 0;
farenheit <- 0;
celcius <- 0;
R_therm <- 0;
R2 <- 400;
//Define functions
function readChip189()
{
// hardware.pinA.write(1); //clear spurious data
//Get SPI data
hardware.pinA.write(0); //pull CS low to start the transmission of temp data
hardware.spi189.write("\x80"); //initialize the board
hardware.spi189.write("\xD3"); //Send Configuration
// hardware.spi189.write("\x01"); // Finish transaction
imp.sleep(0.2); // let the board initialize
hardware.pinA.write(1);
imp.sleep(0.2);
hardware.pinA.write(0);
imp.sleep(0.5);
hardware.spi189.write("\x00"); // Write to register to read
local data=hardware.spi189.readblob(8);//SPI read is totally completed here
hardware.pinA.write(1); // pull CS high to end transaction

conf_reg = data[0]; //Start bit shifting
_rtd_res = (data[1] << 8) + data[2];     
rtd_res_raw = _rtd_res >> 1;
_temp_i16 = (data[3] << 8) + data[4];
HFT_val = _temp_i16 >> 1;
_temp_i16 = (data[5] << 8) + data[6];
LFT_val = _temp_i16 >> 1;
local status = data[7];
rtd_prt = _rtd_res | 

	server.log(rtd_res_raw);
	server.log(conf_reg);
	server.log(status);
    
    imp.wakeup(2, readChip189); //Wakeup every 2 second and read data.
}

//Begin executing program
hardware.pinA.write(1); //Set the Chip Select pin to HIGH prior to SPI read
readChip189(); //Read SPI data`

OK I decided to follow your code and add in the functions I believe are needed for the config. Here is what I currently have:

`SPI <- hardware.spi189;
CS <- hardware.pinA;
status <- 0;
conf_reg <- 0;
rtd_res_raw <- 0;
SPI.configure((CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 100); // Mode 3
CS.configure(DIGITAL_OUT);
CS.write(1); // Set CS pin high

function readmash()
{
CS.write(0); // CS pin low to signal transaction
SPI.write("\x80"); //initialize the board
SPI.write("\xD3"); //Send Configuration
SPI.write("\x01");
imp.sleep(0.5);
SPI.write("\x00"); // Write start register address to bus

local data = SPI.readblob(8); // Read in eight bytes into blob data

CS.write(1); // CS pin high to end transaction

local conf_reg = data[0];
local _rtd_res = (data[1] << 8) + data[2];
rtd_res_raw = _rtd_res >> 1;
local _temp_i16 = (data[3] << 8) + data[4];
local HFT_val = _temp_i16 >> 1;
local _temp_i16 = (data[5] << 8) + data[6];
local LFT_val = _temp_i16 >> 1;
status = data[7];

server.log(rtd_res_raw + “resistance”);
}

readmash();`

From looking at the code and a brief glance at the datasheet, init should be CS.write(0), write the two bytes (address then data), then CS.write(1) - to complete the transaction. Right now you’re not doing that so it’s not interpreting the 0x00 as an address pointer write which means you’re likely not reading much useful.

Then you can wait your 0.5s, then you need to write CS low once more (to indicate a new transaction start), write the address (\x00) and read your 8 data registers.

@Hugo thanks for that! Would you say I probably don’t need to add the SPI.write("\\x01");? I think I took that out of context from an example.

@Hugo This seems to be working. However, I think I have the SPI bus settings wrong. The resistance numbers I am getting are all over the place.

`SPI <- hardware.spi189;
CS <- hardware.pinA;
status <- 0;
conf_reg <- 0;
rtd_res_raw <- 0;
mash_resis <- 0;
mash_C <- 0;
SPI.configure((CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 100); // Mode 3
CS.configure(DIGITAL_OUT);
CS.write(1); // Set CS pin high

function readmash()
{
CS.write(0); // CS pin low to signal transaction
imp.sleep(0.2);
SPI.write("\x80"); //initialize the board
SPI.write("\xC2"); //Send Configuration
SPI.write("\x01");

imp.sleep(0.5);
SPI.write("\x00"); // Write start register address to bus

local data = SPI.readblob(8); // Read in eight bytes into blob data

CS.write(1); // CS pin high to end transaction

local conf_reg = data[0];
local _rtd_res = (data[1] << 8) + data[2];
rtd_res_raw = _rtd_res >> 1;
local _temp_i16 = (data[3] << 8) + data[4];
local HFT_val = _temp_i16 >> 1;
local _temp_i16 = (data[5] << 8) + data[6];
local LFT_val = _temp_i16 >> 1;
status = data[7];
mash_resis = (rtd_res_raw * 400) / 32768;

mash_C = (rtd_res_raw / 32) - 256;
server.log(mash_resis + " resistance");
server.log(rtd_res_raw + " raw resis");
server.log(mash_C);
imp.wakeup(10, readmash);
}

readmash();
`

You’re not actually doing what I recommended there. See below:

`SPI <- hardware.spi189;
CS <- hardware.pinA;
status <- 0;
conf_reg <- 0;
rtd_res_raw <- 0;
mash_resis <- 0;
mash_C <- 0;
SPI.configure((CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 100); // Mode 3
CS.configure(DIGITAL_OUT);
CS.write(1); // Set CS pin high

function readmash()
{
CS.write(0); // CS pin low to signal transaction
SPI.write("\x80"); //initialize the board
SPI.write("\xC2"); //Send Configuration
CS.write(1); // end transaction

imp.sleep(0.5);

CS.write(0);
SPI.write("\x00"); // Write start register address to bus
local data = SPI.readblob(8); // Read in eight bytes into blob data
CS.write(1); // CS pin high to end transaction

local conf_reg = data[0];
local _rtd_res = (data[1] << 8) + data[2];
rtd_res_raw = _rtd_res >> 1;
local _temp_i16 = (data[3] << 8) + data[4];
local HFT_val = _temp_i16 >> 1;
local _temp_i16 = (data[5] << 8) + data[6];
local LFT_val = _temp_i16 >> 1;
status = data[7];
mash_resis = (rtd_res_raw * 400) / 32768;

mash_C = (rtd_res_raw / 32) - 256;
server.log(mash_resis + " resistance");
server.log(rtd_res_raw + " raw resis");
server.log(mash_C);
imp.wakeup(10, readmash);
}

readmash();`

…see if that works any better?

@Hugo thanks, I had actually stumbled across a similar config and it does seem to be working. Right now, I am trying to figure out why the readings are all over the place.

Here is what I am using:

You will notice the clock difference. From the manufacturer, the readings will be all over the place if the clock on the Imp is not exactly in sync with the breakout clock.

`SPI <- hardware.spi189;
CS <- hardware.pinA;
status <- 0;
conf_reg <- 0;
rtd_res_raw <- 0;
mash_resis <- 0;
mash_C <- 0;
SPI.configure((CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 1000); // Mode 3
CS.configure(DIGITAL_OUT);
CS.write(1); // Set CS pin high

function readmash()
{
CS.write(0); // CS pin low to signal transaction
SPI.write("\x80"); //initialize the board
SPI.write("\xD2"); //Send Configuration
SPI.write("\x01");
CS.write(1);
imp.sleep(0.5);
CS.write(0);
imp.sleep(0.2);
SPI.write("\x00"); // Write start register address to bus

local data = SPI.readblob(8); // Read in eight bytes into blob data

CS.write(1); // CS pin high to end transaction

local conf_reg = data[0];
local _rtd_res = (data[1] << 8) + data[2];
rtd_res_raw = _rtd_res >> 1;
local _temp_i16 = (data[3] << 8) + data[4];
local HFT_val = _temp_i16 >> 1;
local _temp_i16 = (data[5] << 8) + data[6];
local LFT_val = _temp_i16 >> 1;
status = data[7];
mash_resis = (rtd_res_raw * 400) / 32768;

mash_C = (rtd_res_raw / 32) - 256;
server.log(mash_resis + " resistance");
server.log(rtd_res_raw + " raw resis");
server.log(mash_C);
imp.wakeup(5, readmash);
}

readmash();
`

OK so apparently I am still a bit at square 1. The configuration does not appear to being accepted or sent to the breakout. The “readings” I was seeing were coming from the DRDY which is just a signaling pin. If you set the device to “1 shot” mode, that pin signals when a reading is ready.

It appears I need to figure out why the serial write is not being stored.

OK I am finally getting somewhere! The chip is a dual breakout with an additional slave built on board. When I am reading one serial bus I have to ensure that the other is pin high so they don’t conflict. In addition, the SD1 is actually SDI (MOSI) and SD0 is SDO (MISO). So once I put the wires in the proper spots communication actually commenced and I am getting some feedback from the configuration bit with actual data. (As opposed to 0 or 255). However, it is moving from one value to another so something in my code must be wrong. I have to initialize the config and then read, so I split it into 2 functions. I must have something wrong as its moving around and it should be \xd2 or 210 on my read. Formatting issue maybe?

`SPI <- hardware.spi189;
CS1 <- hardware.pinA;
CS2 <- hardware.pinB;
status <- 0;
conf_reg <- 0;
rtd_res_raw <- 0;
mash_resis <- 0;
mash_C <- 0;
SPI.configure((CLOCK_IDLE_HIGH | CLOCK_2ND_EDGE), 100); // Mode 3
CS1.configure(DIGITAL_OUT);
CS2.configure(DIGITAL_OUT);

function startread()
{
CS1.write(0); // CS1 pin low to signal transaction
imp.sleep(0.5);
SPI.write("\x80"); //initialize the board
SPI.write("\xD2");
//SPI.write("\x01");
CS1.write(1);
}
function readmash()
{
// startread();
CS2.write(1);
CS1.write(0);
imp.sleep(0.2);
//SPI.write("\x00"); // Write start register address to bus

local data = SPI.readblob(8); // Read in eight bytes into blob data

CS1.write(1); // CS1 pin high to end transaction

local conf_reg = data[0];
local _rtd_res = (data[1] << 8) + data[2];
rtd_res_raw = _rtd_res >> 1;
local _temp_i16 = (data[3] << 8) + data[4];
local HFT_val = _temp_i16 >> 1;
local _temp_i16 = (data[5] << 8) + data[6];
local LFT_val = _temp_i16 >> 1;
status = data[7];
mash_resis = (rtd_res_raw * 400) / 32768;

mash_C = (rtd_res_raw / 32) - 256;
server.log(mash_resis + " resistance");
server.log(rtd_res_raw + " raw resis");
server.log(conf_reg);
imp.wakeup(5, readmash);
}
CS1.write(1); // Set CS1 pin high
CS2.write(1); //Set CS2 pin high
startread();
readmash();
`

Why do you have imp.sleep calls between enabling chip-select and starting to write data? None of the Arduino code you posted does that.

Peter

…and why have you got two CS pins? The MAX31855 only has one…

@peter the core code shows some delays added in while reading the bus. I will post the code after this.

@hugo the version I bought is the dual max31865 breakout. http://www.playingwithfusion.com/productview.php?pdid=29&catid=1001

Here is the core procedure as written in Arduino. (I absolutely know I could be misreading this.)

`/***************************************************************************

  • File Name: serial_MAX31865.h
  • Processor/Platform: Arduino Uno R3 (tested)
  • Development Environment: Arduino 1.0.5
  • Designed for use with with Playing With Fusion MAX31865 Resistance
  • Temperature Device (RTD) breakout board: SEN-30201 (PT100 or PT1000)
  • —> http://playingwithfusion.com/productview.php?pdid=25
  • —> http://playingwithfusion.com/productview.php?pdid=26
  • Copyright © 2014 Playing With Fusion, Inc.
  • SOFTWARE LICENSE AGREEMENT: This code is released under the MIT License.
  • Permission is hereby granted, free of charge, to any person obtaining a
  • copy of this software and associated documentation files (the “Software”),
  • to deal in the Software without restriction, including without limitation
  • the rights to use, copy, modify, merge, publish, distribute, sublicense,
  • and/or sell copies of the Software, and to permit persons to whom the
  • Software is furnished to do so, subject to the following conditions:
  • The above copyright notice and this permission notice shall be included in
  • all copies or substantial portions of the Software.
  • THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  • AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  • LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  • FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  • DEALINGS IN THE SOFTWARE.

  • REVISION HISTORY:
  • Author Date Comments
  • J. Steinlage 2014Jan25 Original version
  • Playing With Fusion, Inc. invests time and resources developing open-source
  • code. Please support Playing With Fusion and continued open-source
  • development by buying products from Playing With Fusion!

  • ADDITIONAL NOTES:
  • This file configures then runs a program on an Arduino Uno to read a
  • MAX31865 RTD-to-digital converter breakout board and print results to
  • a serial port. Communication is via SPI built-in library.
    • Configure Arduino Uno
    • Configure and read resistances and statuses from MAX31865 IC
  •  - Write config registers (MAX31865 starts up in a low-power state)
    
  •  - RTD resistance register
    
  •  - High and low status thresholds 
    
  •  - Fault statuses
    
    • Write formatted information to serial port
  • Circuit:
  • Arduino Uno --> SEN-30201
  • CS: pin 10 --> CS
  • MOSI: pin 11 --> SDI (must not be changed for hardware SPI)
  • MISO: pin 12 --> SDO (must not be changed for hardware SPI)
  • SCK: pin 13 --> SCLK (must not be changed for hardware SPI)
  • GND --> GND
  • 5V --> Vin (supply with same voltage as Arduino I/O, 5V)
    ***************************************************************************/

// the sensor communicates using SPI, so include the hardware SPI library:
#include <SPI.h>
// include Playing With Fusion MAX31865 libraries
#include <PlayingWithFusion_MAX31865.h> // core library
#include <PlayingWithFusion_MAX31865_STRUCT.h> // struct library

//Sensor addresses:
const byte CONFIG_REG_W = 0x80; // Config register write addr
const byte CONFIG_VALUE = 0xC3; // Config register value (Vbias+Auto+FaultClear+50Hz, see pg 12 of datasheet)
const byte ADC_WORD_MSB = 0x01; // Addr of first byte of data (start reading at RTD MSB)
const byte ADC_FAULT_REG = 0x07; // Addr of the fault reg

// CS pin used for the connection with the sensor
// other connections are controlled by the SPI library)
const int CS_PIN = 10;

PWFusion_MAX31865_RTD rtd_ch0(CS_PIN);

void setup() {
Serial.begin(9600);

// setup for the the SPI library:
SPI.begin(); // begin SPI
SPI.setDataMode(SPI_MODE3); // MAX31865 is a Mode 3 device

// initalize the chip select pin
pinMode(CS_PIN, OUTPUT);
rtd_ch0.MAX31865_config();

// give the sensor time to set up
delay(100);
}

void loop()
{
delay(500); // 500ms delay… can be much faster

static struct var_max31865 RTD_CH0;
double tmp;

RTD_CH0.RTD_type = 1; // un-comment for PT100 RTD
// RTD_CH0.RTD_type = 2; // un-comment for PT1000 RTD

struct var_max31865 *rtd_ptr;
rtd_ptr = &RTD_CH0;

rtd_ch0.MAX31865_full_read(rtd_ptr); // Update MAX31855 readings

// Print information to serial port
Serial.println(“RTD Sensor 0:”); // Print RTD0 header

if(0 == RTD_CH0.status) // no fault, print info to serial port
{
if(1 == RTD_CH0.RTD_type) // handle values for PT100
{
// calculate RTD resistance
tmp = (double)RTD_CH0.rtd_res_raw * 400 / 32768;
Serial.print("Rrtd = "); // print RTD resistance heading
Serial.print(tmp); // print RTD resistance
}
else if(2 == RTD_CH0.RTD_type) // handle values for PT1000
{
// calculate RTD resistance
tmp = (double)RTD_CH0.rtd_res_raw * 4000 / 32768;
Serial.print(“Rrtd = “); // print RTD resistance heading
Serial.print(tmp); // print RTD resistance
}
Serial.println(” ohm”);
// calculate RTD temperature (simple calc, +/- 2 deg C from -100C to 100C)
// more accurate curve can be used outside that range
tmp = ((double)RTD_CH0.rtd_res_raw / 32) - 256;
Serial.print(“Trtd = “); // print RTD temperature heading
Serial.print(tmp); // print RTD resistance
Serial.println(” deg C”); // print RTD temperature heading
} // end of no-fault handling
else
{
Serial.print("RTD Fault, register: ");
Serial.print(RTD_CH0.status);
if(0x80 & RTD_CH0.status)
{
Serial.println(“RTD High Threshold Met”); // RTD high threshold fault
}
else if(0x40 & RTD_CH0.status)
{
Serial.println(“RTD Low Threshold Met”); // RTD low threshold fault
}
else if(0x20 & RTD_CH0.status)
{
Serial.println(“REFin- > 0.85 x Vbias”); // REFin- > 0.85 x Vbias
}
else if(0x10 & RTD_CH0.status)
{
Serial.println(“FORCE- open”); // REFin- < 0.85 x Vbias, FORCE- open
}
else if(0x08 & RTD_CH0.status)
{
Serial.println(“FORCE- open”); // RTDin- < 0.85 x Vbias, FORCE- open
}
else if(0x04 & RTD_CH0.status)
{
Serial.println(“Over/Under voltage fault”); // overvoltage/undervoltage fault
}
else
{
Serial.println(“Unknown fault, check connection”); // print RTD temperature heading
}
} // end of fault handling
}

`