Best guess is that it wasn't spending long enough integrating the thermocouples. There were a couple of useless delay(1) statements in readThermocouple, so it was taking 64ms of the 100ms just to read the data. Altogether, it was only spending about 28ms integrating per sensor.
I adjusted the timing, and got rid of the delays in readThermocouple. It now spends the full 100ms integrating.
Here's the sketch. I added the two sections of code you posted.
And I fixed that. D'oh!! If I had a nickle for every time I've done that...wilheldp wrote:one little fix (if (channel == instead of if (channel = in the main loop).
Tip: whenever I'm testing against a constant value, I usually put the constant on the left side of the operator. That way, the compiler will flag an error whenever I'm dumb enough to use "=" instead of "==".
Code: Select all
if (0 == channel) //if we finished all 8 conversions,
Code: Select all
// TCMux shield demo by Ocean Controls
// Sends the data to a serial terminal
// Type @NS1<cr> (don't type <cr> it's the carriage return character, just hit enter) to set the number of sensor to 1
// Type @NS8<cr> to set the number of sensors to 8
// Type @UD1<cr> to set the update delay to 1 second
// Type @SV<cr> to save the number of sensors and update delay variables to eeprom
#include "SD.h"
#include <string.h> //Use the string Library
#include <ctype.h>
#include <EEPROM.h>
//#define SHOWMEYOURBITS // Display the raw 32bit binary data from the MAX31855
#define PINEN 7 //Mux Enable pin
#define PINA0 4 //Mux Address 0 pin
#define PINA1 5 //Mux Address 1 pin
#define PINA2 6 //Mux Address 2 pin
#define PINSO 12 //TCAmp Slave Out pin (MISO)
#define PINSC 13 //TCAmp Serial Clock (SCK)
#define PINCS 9 //TCAmp Chip Select Change this to match the position of the Chip Select Link
int Temp[8], SensorFail[8];
float floatTemp, floatInternalTemp;
char failMode[8];
int internalTemp, intTempFrac;
unsigned int Mask;
//char data[16];
char i, channel, NumSensors =1, UpdateDelay;
char Rxchar, Rxenable, Rxptr, Cmdcomplete, R;
char Rxbuf[32];
char adrbuf[3], cmdbuf[3], valbuf[12];
int val = 0, Param;
unsigned long conversionTime, intervalTime;
// The objects to talk to the SD card
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
File logfile; // The object that represents our datafile
const byte chipSelect = 10; // chip select pin for SD card, 10 for regular Arduino, 53 for Mega
//*****************************************************************************************
// Error handling loop, from the tutorials at ladyada.net listed above
// If there is a problem accessing the SD card, this loop gets called to display a cryptic
// error message.
void error(char *str)
{
Serial.print("Error:");
Serial.print(str);
while(1);
}
void selectThermocouple(int channel)
{
digitalWrite(PINCS, LOW); //Take SPI bus
switch (channel) //select channel
{
case 0:
digitalWrite(PINA0, LOW);
digitalWrite(PINA1, LOW);
digitalWrite(PINA2, LOW);
break;
case 1:
digitalWrite(PINA0, HIGH);
digitalWrite(PINA1, LOW);
digitalWrite(PINA2, LOW);
break;
case 2:
digitalWrite(PINA0, LOW);
digitalWrite(PINA1, HIGH);
digitalWrite(PINA2, LOW);
break;
case 3:
digitalWrite(PINA0, HIGH);
digitalWrite(PINA1, HIGH);
digitalWrite(PINA2, LOW);
break;
case 4:
digitalWrite(PINA0, LOW);
digitalWrite(PINA1, LOW);
digitalWrite(PINA2, HIGH);
break;
case 5:
digitalWrite(PINA0, HIGH);
digitalWrite(PINA1, LOW);
digitalWrite(PINA2, HIGH);
break;
case 6:
digitalWrite(PINA0, LOW);
digitalWrite(PINA1, HIGH);
digitalWrite(PINA2, HIGH);
break;
case 7:
digitalWrite(PINA0, HIGH);
digitalWrite(PINA1, HIGH);
digitalWrite(PINA2, HIGH);
break;
default:
Serial.print("invalid thermocouple channel: "); Serial.println(channel);
break;
}
delay(5); //allow for leisurely digestion
digitalWrite(PINCS, HIGH); //Release SPI bus; Begin conversion
}
float convertTemperature(int channel)
{
Serial.print("#");
Serial.print(channel+1,DEC);
Serial.print(": ");
if (SensorFail[channel] == 1)
{
Serial.print("FAIL");
if ((failMode[channel] & 0b0100) == 0b0100)
{
Serial.print(" SHORT TO VCC");
}
if ((failMode[channel] & 0b0010) == 0b0010)
{
Serial.print(" SHORT TO GND");
}
if ((failMode[channel] & 0b0001) == 0b0001)
{
Serial.print(" OPEN CIRCUIT");
}
}
else
{
floatTemp = (float)Temp[channel] * 0.25;
Serial.print(floatTemp,2);
//This bit doesn't work for neg temps
/*Serial.print(Temp[channel]>>2,DEC);
Serial.print(".");
if ((Temp[channel] & 0b11) == 0b00)
{
Serial.print("00");
}
if ((Temp[channel] & 0b11) == 0b01)
{
Serial.print("25");
}
if ((Temp[channel] & 0b11) == 0b10)
{
Serial.print("50");
}
if ((Temp[channel] & 0b11) == 0b11)
{
Serial.print("75");
}
*/
Serial.print(" degC");
//}
//delay(1000);
}//end reading sensors
//Serial.println("");
Serial.print(" Int: ");
floatInternalTemp = (float)internalTemp * 0.0625;
Serial.print(floatInternalTemp,4);
//This doesn't work for negative values
/*
Serial.print(internalTemp>>4);
Serial.print(".");
intTempFrac = (internalTemp & 0x0F)*625;
Serial.print(intTempFrac/1000);
intTempFrac = intTempFrac%1000;
Serial.print(intTempFrac/100);
intTempFrac = intTempFrac%100;
Serial.print(intTempFrac/10);
intTempFrac = intTempFrac%10;
Serial.print(intTempFrac/1);
*/
Serial.print(" degC");
Serial.println("");
return floatTemp;
}
float readThermocouple(int channel)
{
Temp[channel] = 0;
failMode[channel] = 0;
SensorFail[channel] = 0;
internalTemp = 0;
digitalWrite(PINCS, LOW); //Take SPI bus, stop conversion
for (i=31;i>=0;i--)
{
digitalWrite(PINSC, HIGH);
// delay(1);
//print out bits
#ifdef SHOWMEYOURBITS
if (digitalRead(PINSO)==1)
{
Serial.print("1");
}
else
{
Serial.print("0");
}
#endif
if ((i<=31) && (i>=18))
{
// these 14 bits are the thermocouple temperature data
// bit 31 sign
// bit 30 MSB = 2^10
// bit 18 LSB = 2^-2 (0.25 degC)
Mask = 1<<(i-18);
if (digitalRead(PINSO)==1)
{
if (i == 31)
{
Temp[channel] += (0b11<<14);//pad the temp with the bit 31 value so we can read negative values correctly
}
Temp[channel] += Mask;
//Serial.print("1");
}
else
{
// Serial.print("0");
}
}
//bit 17 is reserved
//bit 16 is sensor fault
if (i==16)
{
SensorFail[channel] = digitalRead(PINSO);
}
if ((i<=15) && (i>=4))
{
//these 12 bits are the internal temp of the chip
//bit 15 sign
//bit 14 MSB = 2^6
//bit 4 LSB = 2^-4 (0.0625 degC)
Mask = 1<<(i-4);
if (digitalRead(PINSO)==1)
{
if (i == 15)
{
internalTemp += (0b1111<<12);//pad the temp with the bit 31 value so we can read negative values correctly
}
internalTemp += Mask;//should probably pad the temp with the bit 15 value so we can read negative values correctly
//Serial.print("1");
}
else
{
// Serial.print("0");
}
}
//bit 3 is reserved
if (i==2)
{
failMode[channel] += digitalRead(PINSO)<<2;//bit 2 is set if shorted to VCC
}
if (i==1)
{
failMode[channel] += digitalRead(PINSO)<<1;//bit 1 is set if shorted to GND
}
if (i==0)
{
failMode[channel] += digitalRead(PINSO)<<0;//bit 0 is set if open circuit
}
digitalWrite(PINSC, LOW);
// delay(1);
//delay(1);
}
digitalWrite(PINCS, HIGH); //Release SPI bus
return convertTemperature(channel);
}
#define CONVERSION_TIME 100 /* number of milliseconds per conversion */
#define CONVERSION_PERIOD 1000 /* start a new set of 8 conversions once every second */
#define CONVERSION_INTERVAL (CONVERSION_PERIOD - (CONVERSION_TIME * 8)) /*interval between the end of a conversion cycle and the start of the next */
void setup()
{
Serial.begin(9600);
Serial.println("TCMUXV3");
//initialize the SD card
if (!SD.begin(chipSelect)) {
error("SD Card failedor not present");
}
if (!card.init()) error("card.init, Reformat card");
Serial.print("SD Card Initialized");
delay(1500);
// create a new file
char name[] = "TEMPS00.CSV"; //File names will follow this format, and increment automatically
for (uint8_t x = 0; x < 100; x++) {
name[5] = x/10 + '0';
name[6] = x%10 + '0';
if (! SD.exists(name)) {
logfile = SD.open(name, FILE_WRITE);
break;
}
}
if (! logfile) {
error(" Could not create a file.");
}
//Write the output file header row to our file so that we can identify the data later
logfile.println("date,time,Ch1,Ch2,Ch3,Ch4,Ch5,Ch6,Ch7,Ch8");
logfile.flush();
delay(350);
if (EEPROM.read(511)==1)
{
NumSensors = EEPROM.read(0);
UpdateDelay = EEPROM.read(1);
}
pinMode(PINEN, OUTPUT);
pinMode(PINA0, OUTPUT);
pinMode(PINA1, OUTPUT);
pinMode(PINA2, OUTPUT);
pinMode(PINSO, INPUT);
pinMode(PINCS, OUTPUT);
pinMode(PINSC, OUTPUT);
digitalWrite(PINEN, HIGH); // enable on
digitalWrite(PINA0, LOW); // low, low, low = channel 1
digitalWrite(PINA1, LOW);
digitalWrite(PINA2, LOW);
digitalWrite(PINSC, LOW); //put clock in low
channel = 0;
selectThermocouple(channel); //start the first conversion
conversionTime = millis(); //timestamp start of first conversion
intervalTime = conversionTime - CONVERSION_INTERVAL; //back-date the start of the first conversion interval
}
void loop()
{
if (millis() > (intervalTime + CONVERSION_INTERVAL)) //start a new set of 8 conversions every CONVERSION_INTERVAL milliseconds
{
if (millis() > (conversionTime + CONVERSION_TIME)) //every CONVERSION_TIME milliseconds
{
readThermocouple(channel); //stop conversion and read the current thermocouple
channel = (channel + 1) % 8; //get the next channel number
selectThermocouple(channel); //select the next thermocouple and begin conversion
conversionTime = millis(); //reset conversion time-out
if (0 == channel) //if we finished all 8 conversions,
intervalTime = conversionTime; // reset the conversion interval time-out.
} //end CONVERSION_TIME
} //end CONVERSION _INTERVAL
if (Serial.available() > 0) // Is a character waiting in the buffer?
{
Rxchar = Serial.read(); // Get the waiting character
if (Rxchar == '@') // Can start recording after @ symbol
{
if (Cmdcomplete != 1)
{
Rxenable = 1;
Rxptr = 1;
}//end cmdcomplete
}//end rxchar
if (Rxenable == 1) // its enabled so record the characters
{
if ((Rxchar != 32) && (Rxchar != '@')) //dont save the spaces or @ symbol
{
Rxbuf[Rxptr] = Rxchar;
//Serial.println(Rxchar);
Rxptr++;
if (Rxptr > 13)
{
Rxenable = 0;
}//end rxptr
}//end rxchar
if (Rxchar == 13)
{
Rxenable = 0;
Cmdcomplete = 1;
}//end rxchar
}//end rxenable
}// end serial available
if (Cmdcomplete == 1)
{
Cmdcomplete = 0;
cmdbuf[0] = toupper(Rxbuf[1]); //copy and convert to upper case
cmdbuf[1] = toupper(Rxbuf[2]); //copy and convert to upper case
cmdbuf[2] = 0; //null terminate Command = Chr(rxbuf(3)) + Chr(rxbuf(4))
// Command = Ucase(command)
//Serial.println(cmdbuf);
valbuf[0] = Rxbuf[3]; // Mystr = Chr(rxbuf(5))
R = Rxptr - 1;
for (i = 4 ; i <= R ; i++)//For I = 6 To R
{
valbuf[i-3] = Rxbuf[i]; //Mystr = Mystr + Chr(rxbuf(i))
}
valbuf[R+1] = 0; //null terminate
Param = atoi(valbuf);// Param = Val(mystr)
//Serial.println(Param); // 'Print "Parameter: " ; Param
if (strcmp(cmdbuf,"NS")==0) //NumSensors
{
//'Print "command was ON"
if ((Param <= 8) && (Param > 0))
{
NumSensors = Param;
}
}
if (strcmp(cmdbuf,"UD")==0) //UpdateDelay
{
//'Print "command was ON"
if ((Param <= 60) && (Param >= 0))
{
UpdateDelay = Param;
}
}
if (strcmp(cmdbuf,"SV")==0) //Save
{
EEPROM.write(0,NumSensors);
EEPROM.write(1,UpdateDelay);
EEPROM.write(511,1);
}
}
}