Max31855x8 Help a noob out?

I received my Arduino for christmas and so far have blazed through several Arduino books.
"Getting started with Arduino" (Massimo Banzi)
"Programming Arduino" (Simon Monk)
"30 Arduino projects for the Evil Genius" (Simon Monk)
"Make: Sensors" (Tero Karvinen, Kimmo Karvinen, & Ville Valtokari"

All of which were given to me with the Arduino Uno Starter kit.
Now I have learned a lot and have been working with it often.
my primary project is this...

My shop has solar panels on the roof which feed lines in the floor, temperature controlled with solar heated water.
Currently the Valves are manual valves and the pump is set to turn on when the Thermocouple on the roof with the panels reaches a certain degree.
There are 6 Thermocouples in the floor on the lines to measure temp of areas of the floor, however they are not hooked up at all.
In my idea this is what I want to happen:
Thermo on roof reaches set temp >>>> Pump turns on
Thermo 1+2 which are on the same line is below a set temp >>>> open valve 1 for that area of floor.
Thermo 3+4 which are on the same line is below a set temp >>>> open valve 2
Thermo 5+6 same as the others.
There are a total of 3 valves that I want to operate based on what I determine to be the appropriate temp range.
I can use as little as 4 thermos (1 on the roof and 1 on each line) since they put two thermos on each line.
However my issue comes in the form of this....
Max31855x8 a board I bought from Http;//Whizoo.com it is a multiplex for thermocouples.
I can serial print each thermo individually however I dont know how to extract a single thermo out to make it operate a relay based on temperature.
if anyone can help me out I would appreciate it greatly.
Here is my code:
I have been using the library and code that I found at Github to run the board but am having an issue isolating a single thermo to use its temp to activate a relay.

_4Relaywith8Thermo.ino (4.93 KB)

I don't have your device or any thermocouples.

Your sample code appears to print out 8 different thermocouples (0 through 7).

Does that code function properly?

    // Right here is where I think the line of code should go to turn on and off Relay_1
    // which is the relay I want to activate when Thermocouple0 is above 70 degrees F
    // the other three relays I waant to try to make work with the other 6 thermocouples...
    // these thermos will activate the relay/s when the temperature gets lower than a set point
    if (????? >= 70){
       digitalWrite(RELAY_1, RELAY_ON);
       }
    else (????? >= 71); {
       digitalWrite(RELAY_1, RELAY_OFF);
      }
    }
  Serial.println();

The "?????" would be "therm" and therm is in a for loop going from 0 to 7...

The code you attached would not compile for me but I don't have your library...

Does whizoo have a forum? They should be able to answer your question, no?

So have you tried this...

    printTemperature(temperature);
    // Right here is where I think the line of code should go to turn on and off Relay_1
    if (temperature <= 70){
       digitalWrite(RELAY_1, RELAY_ON);
       }
    else (temperature >= 71); {
       digitalWrite(RELAY_1, RELAY_OFF);
      }

*Note I reversed the first >= to <=

Hmm, that's probably not your real problem. If you're able to do the book examples then I don't see why you are having difficulty with an if() statement.

Moving on...

It looks like you will need to create several MAX31855 objects in your code to be able to read the multiple thermocouples:

MAX31855 temp0 = MAX31855(MISO, T0, SCK);
MAX31855 temp1 = MAX31855(MISO, T1, SCK);
MAX31855 temp2 = MAX31855(MISO, T2, SCK);
MAX31855 temp3 = MAX31855(MISO, T3, SCK);

This is a little unfortunate as then it's more work to read them in a loop. I would personally try to give them distinct names, like RoofTop, FloorHallway etc... But your code tries to read them in a loop, so that's probably important to you?

  1. You've said there are 6 thermocouples
  2. The board you've bought seems to only have 4 MAX31855s
  3. The code has $defines for T0-T3 (4 thermocouples) and one extra CS
  4. Your loop goes from 0 to 7 (8 readings)

How can you get 8 readings from 4 thermocouples?

OK, so reading these 4-8 thermocouples in a loop. How is it done? There's two methods that immediately spring to mind for me. The first way is more 'modern' in that it uses object-oriented principles. The second way is more practical and easier for me to understand how it works.

So have you read about arrays? It's possible to have an array containing any fixed-size object in memory. It's more common to have arrays of simple variables like int[] but you can have an array of objects:

#define NumThermos 2 //Two for testing
MAX31855 thermos[] = {MAX31855(MISO, T0, SCK), MAX31855(MISO, T1, SCK)}; //put all thermocouple initialisation here
float temperatures[NumThermos];
//...
for(byte i = 0; i<NumThermos; i++) {
  temperatures[i] = thermos[i].readThermocouple(FAHRENHEIT);
}

*Note I have not tested this - there may be a significant error
A variation of this method would be to create the 4-8 objects and then have an array hold pointers to those objects.

Personally, I would understand it better if I wrapped all the thermocouple code into a function and then called that function from wherever I wanted. This can be useful because you can attach different types of temperature sensor. In this example, I use the internal sensor of one of the MAX31855s as temperature "zero" and the external thermocouples as the other temperatures.

MAX31855 temp0 = MAX31855(MISO, T0, SCK);
MAX31855 temp1 = MAX31855(MISO, T1, SCK);
MAX31855 temp2 = MAX31855(MISO, T2, SCK);
MAX31855 temp3 = MAX31855(MISO, T3, SCK);

float TeadTemp(byte i) {
  //read the nominated temperature sensor 0-4
  switch(i) {
    case 0:
      //the internal sensor of the first MAX31855
      return temp0.readJunction(FAHRENHEIT);
    break;
    case 1:
      //first thermocouple - roof
      return temp0.readThermocouple(FAHRENHEIT); 
    break;
    case 2:
      //thermocouple - floor 1
      return temp1.readThermocouple(FAHRENHEIT); 
    break;
    case 3:
      //thermocouple - floor 2
      return temp2.readThermocouple(FAHRENHEIT); 
    break;
    case 4:
      //thermocouple - floor 3
      return temp3.readThermocouple(FAHRENHEIT); 
    break;
    default:
      //error: return Not-A-Number
      return NAN;
  }
} //end TempRead
//...
void loop() {
  //...
  //read all thermometers in one loop:
  for(byte i = 0; i <=4; i++) {
     temperatures[i] = TempRead(i);
  }

How do you have this wired? You do understand why you have to use thermocouple wire?

Thank you everyone.

Carl, yes the code I uploaded works. The library was at guthub. And whizoo only directed me to this forum, which guthub also did.

Morgan, It does seem that the hardware is the issue. There are 8 connections on the board for thermocouples but only able to read the 4 you mentioned. On my loop that prints 8 therm readings, well it prints 8 when it doesn't read them as open. Anyway thank you, I will try using the advice you have given and the examples. I have it wired as per the wiring diagram whizoo provided. And I have to use thermocouple type k, because the are embedded in the concrete next to water lines, the only one I could change is the roof one. Anyway, thank you for the advice, I will work with my code and see what I can get done.

So I have looked and studied my the Max31855x8 board that I bought from Whizoo.com.
It appears that it has a single Max31855 chip and a multiplexer 74HC4051 on it.
So I am going to have to tell it what bit to read.

I think it will be something like this :
000 = Therm0
001 = Therm1
010 = Therm2
011 = Therm3
100 = Therm4
101 = Therm5
110 = Therm6
111 = Therm7
the code runs in the loop, defining
(Therm=0; Therm <8 ; Therm++)
Do I have to name a therm Therm1?
Or do I have to call it up on address?

so my biggest issue will be defining and reading individual bits from the multiplexer.
if anyone has any help or code that may help that would be really awesome as I am definately still a novice.
Thank you everyone.

I am starting to work with the Max31855x8 currently. After reading your post, and playing with the code myself, I decided to post a follow up for anyone else that stumbles on the thread, the solutions given here were much more complicated than they needed to be in my opinion.

For my code, I have one sensor hooked up to the board currently, but I will be adding three more. To read only that sensor, I just changed the range of the for loop to therm = 0; therm <1. To read four, I would use therm = 0; therm < 5

// Display the temperatures of the 8 thermocouples
 for (int therm=0; therm<1; therm++) {

if you want to read the thermocouple outside of the for loop without messing with bits use what was already given by the creator, and just add the thermocouple number into the code:

   digitalWrite(T0, x & 1? HIGH: LOW); //<<<x represents the thermocouple you want to read
   digitalWrite(T1, x & 2? HIGH: LOW);
   digitalWrite(T2, x & 4? HIGH: LOW);

   // The MAX31855 takes 100ms to sample the thermocouple.
   // Wait a bit longer to be safe.  We'll wait 0.125 seconds
   delay(125);
   
   temperature = temp.readThermocouple(CELSIUS);
   if (temperature == FAULT_OPEN)
       continue;
   Serial.print(" T");
   Serial.print(x); //again, x is the thermocouple you want to read
   Serial.print("=");
   printTemperature(temperature);

While it is in the for loop, you can extract a specific thermocouple's reading by using an a series of if/then statements and match the current thermocouple up to whatever relay you want to control, or just pass the reading to a global or local variable (using variable = printTemperature(temperature)) to use later in your code.

example:

....
printTemperature(temperature);

if (therm == 0) {
   if (temperature <= 70){
       digitalWrite(RELAY_0, RELAY_ON);
       }
    else (temperature >= 71); { 
       digitalWrite(RELAY_0, RELAY_OFF);
      }
}
else if (therm == 1) { ...... etc

It has been over a month since you posted your questions, so would I assume you probably solved the problem. If not, I hope this helps.