urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Multiple SPI

Fri Mar 27, 2015 4:08 pm

Hi there...
I'm using MAX6675 with analogue temp sensor to read temperature. But i need at least 3 sensors working this way. The main agenda using MAX6675 is that we need height temp sensors which dallas (the easy way with Digital inputs) ca not deliver. T>200 degrees.

The question is is it possible to connect more than one SPI Read only device (in My case MAX6675) to one RP ? Using RP B+

Thanks for you input and help.

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Fri Mar 27, 2015 5:09 pm

Use a 74hc138 and 3 GPIO.

The chip select from the RPi will be one of the E line and use each Y to the corresponding max 6675 chip select.

When you want to read a specific sensor just set the GPio to select the correct sensor.

Strange thing, I just received my max6675 yesterday but it will be set to an arduino using nRF24L01 and then the data will be transfer to the Pi. This one will be attached to me pellet stove.

Daniel

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sat Mar 28, 2015 3:18 pm

Before I test my design with the Max6675 on the arduino, I hook the max6675 to a 74HC138 and made it work.


Image

I put my only Max6675 chip select on Y2 of the 74HC138

And this a demo python class to integrate the Max6675 and the 74HC138/139

The class also could be used without the 74HC138/139

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import spidev
import time
import RPi.GPIO as GPIO

class Max6675:

  VALID_DATA   = 0 
  ERROR_CHANNEL = 1
  ERROR_PROBE   = 2
  ERROR_DATA    = 3

  errorString  = [ 'Temperature is Valid' , 'Multiplex channel 74HC138/139 error' ,
                        'Probe is not connected' , 'Max6675 returned bad data']


  def __init__(self,spiPort=0, spiDevice=0,HC138A = None , HC138B = None, HC138C = None):

    self.spi = spidev.SpiDev()
    self.spi.open(spiPort,spiDevice)
    self.HC138A = HC138A
    self.HC138B = HC138B
    self.HC138C = HC138C
    self.HC138Valid = False
    
    if (self.HC138A != None) or (self.HC138B != None) or (self.HC138C != None):
       self.HC138Valid = True
       GPIO.setwarnings(False)
       GPIO.setmode(GPIO.BCM)
         

    if self.HC138A != None:
       GPIO.setup(self.HC138A,GPIO.OUT)

    if self.HC138A != None:
       GPIO.setup(self.HC138B,GPIO.OUT)

    if self.HC138A != None:
       GPIO.setup(self.HC138C,GPIO.OUT)

    


  ''' get(Channel)
    if Channel as to be None if no 74HC138 is used
    otherwisw Channel specify the Y0 output which the Max6675 is connected

    Return

    The return is [ temperature  , ErrorCode]

    Where ErrorCode is

    0 : Data is valid
    1 : Bad Channel (is the 74HC138 GPIO set ?)
    2 : Probe unconnected
    3 : Max6675 return bad data

  '''

  def get(self,Channel=None):
    # Deal with 74HC138/139 Multiplexer if we have one
    if ((Channel == None) and  (self.HC138Valid)) or ((Channel != None) and (not self.HC138Valid)):
       return [None , self.ERROR_CHANNEL]

    if Channel != None:
      if Channel > 7 :
         return [None , self.ERROR_CHANNEL]
      if self.HC138A!=None:
       GPIO.output(self.HC138A, Channel & 1)
      if self.HC138B!=None:
       GPIO.output(self.HC138B, Channel & 2)
      if self.HC138C!=None:
       GPIO.output(self.HC138C, Channel & 4)

    #Now let's read the sensor

    data= [0,0]
    data = self.spi.xfer2(data)
    
    #Is the sensor data Valid
    if (data[1] & 2) == 2:
      return [ None , self.ERROR_DATA ]

    #Is the Probe connected
    if (data[1] & 4) == 4:
      return [ None , self.ERROR_PROBE ]    
            
    wdata = data[0] << 8 | data[1]
    return [(wdata>>3)/4.0  , self.VALID_DATA]



if __name__ == "__main__":


   max6675 = Max6675(0,0,17,27,22)

  
   for Probe in range(8):

     probeOK=False
     temperature=0

     data = max6675.get(Probe)


     #let's check if the data is Valid
     if data[1] != max6675.VALID_DATA:
       print('Probe {}: {}'.format(Probe,max6675.errorString[data[1]]))
     else:
       print("Probe {}: Temperature : {:.1f}".format(Probe,data[0]))



I select GPIO 17,27 and 22 , in BCM mode, to select the channel.

and this is the output I got

Code: Select all

pi@BPlus ~ $ sudo python Max6675.py 
Probe 0: Max6675 returned bad data
Probe 1: Max6675 returned bad data
Probe 2: Temperature : 22.0
Probe 3: Max6675 returned bad data
Probe 4: Max6675 returned bad data
Probe 5: Max6675 returned bad data
Probe 6: Max6675 returned bad data
Probe 7: Max6675 returned bad data
B.T.W. I put the a 10K pull-up to force the code to detect when the max6675 is not connected.

Daniel

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sat Mar 28, 2015 6:10 pm

I added the degree celsius .

It wil work with python 2.7 or 3.2

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import sys
import spidev
import time
import RPi.GPIO as GPIO


#unicode  python 2.7  VS 3.2  
if sys.version < '3':
    import codecs
    def u(x):
        return codecs.unicode_escape_decode(x)[0]
else:
    def u(x):
        return x



class Max6675:

  VALID_DATA   = 0 
  ERROR_CHANNEL = 1
  ERROR_PROBE   = 2
  ERROR_DATA    = 3

  errorString  = [ 'Temperature is Valid' , 'Multiplex channel 74HC138/139 error' ,
                        'Probe is not connected' , 'Max6675 returned bad data']


  def __init__(self,spiPort=0, spiDevice=0,HC138A = None , HC138B = None, HC138C = None):

    self.spi = spidev.SpiDev()
    self.spi.open(spiPort,spiDevice)
    self.HC138A = HC138A
    self.HC138B = HC138B
    self.HC138C = HC138C
    self.HC138Valid = False
    
    if (self.HC138A != None) or (self.HC138B != None) or (self.HC138C != None):
       self.HC138Valid = True
       GPIO.setwarnings(False)
       GPIO.setmode(GPIO.BCM)
         

    if self.HC138A != None:
       GPIO.setup(self.HC138A,GPIO.OUT)

    if self.HC138A != None:
       GPIO.setup(self.HC138B,GPIO.OUT)

    if self.HC138A != None:
       GPIO.setup(self.HC138C,GPIO.OUT)

    


  ''' get(Channel)
    if Channel as to be None if no 74HC138 is used
    otherwisw Channel specify the Y0 output which the Max6675 is connected

    Return

    The return is [ temperature  , ErrorCode]

    Where ErrorCode is

    0 : Data is valid
    1 : Bad Channel (is the 74HC138 GPIO set ?)
    2 : Probe unconnected
    3 : Max6675 return bad data

  '''

  def get(self,Channel=None):
    # Deal with 74HC138/139 Multiplexer if we have one
    if ((Channel == None) and  (self.HC138Valid)) or ((Channel != None) and (not self.HC138Valid)):
       return [None , self.ERROR_CHANNEL]

    if Channel != None:
      if Channel > 7 :
         return [None , self.ERROR_CHANNEL]
      if self.HC138A!=None:
       GPIO.output(self.HC138A, Channel & 1)
      if self.HC138B!=None:
       GPIO.output(self.HC138B, Channel & 2)
      if self.HC138C!=None:
       GPIO.output(self.HC138C, Channel & 4)

    #Now let's read the sensor

    data= [0,0]
    data = self.spi.xfer2(data)
    
    #Is the sensor data Valid
    if (data[1] & 2) == 2:
      return [ None , self.ERROR_DATA ]

    #Is the Probe connected
    if (data[1] & 4) == 4:
      return [ None , self.ERROR_PROBE ]    
            
    wdata = data[0] << 8 | data[1]
    return [(wdata>>3)/4.0  , self.VALID_DATA]



if __name__ == "__main__":


   max6675 = Max6675(0,0,17,27,22)

  
   for Probe in range(8):

     probeOK=False
     temperature=0

     data = max6675.get(Probe)


     #let's check if the data is Valid
     if data[1] != max6675.VALID_DATA:
       print('Probe {}: {}'.format(Probe,max6675.errorString[data[1]]))
     else:
       if sys.version < '3':
         print('Probe {}: Temperature : {:.1f}'.format(Probe,data[0])),
         print(u('\u2103'))
       else:
         print('Probe {}: Temperature : {:.1f}{}'.format(Probe,data[0],'\u2103'))

This is a good thing that they put back the prefix 'u' in python 3.3

I also put the sensor into my pellet stove. We are at the end of march put the temperature are still cold. Today is -7 Celsius and my pellet stove is still running.

Code: Select all

pi@BPlus ~ $ sudo python Max6675.py 
Probe 0: Max6675 returned bad data
Probe 1: Max6675 returned bad data
Probe 2: Temperature : 238.8 ℃
Probe 3: Max6675 returned bad data
Probe 4: Max6675 returned bad data
Probe 5: Max6675 returned bad data
Probe 6: Max6675 returned bad data
Probe 7: Max6675 returned bad data

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sat Mar 28, 2015 6:11 pm

I added the degree celsius .

It will work with python 2.7 or 3.2

Code: Select all

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import sys
import spidev
import time
import RPi.GPIO as GPIO


#unicode  python 2.7  VS 3.2  
if sys.version < '3':
    import codecs
    def u(x):
        return codecs.unicode_escape_decode(x)[0]
else:
    def u(x):
        return x



class Max6675:

  VALID_DATA   = 0 
  ERROR_CHANNEL = 1
  ERROR_PROBE   = 2
  ERROR_DATA    = 3

  errorString  = [ 'Temperature is Valid' , 'Multiplex channel 74HC138/139 error' ,
                        'Probe is not connected' , 'Max6675 returned bad data']


  def __init__(self,spiPort=0, spiDevice=0,HC138A = None , HC138B = None, HC138C = None):

    self.spi = spidev.SpiDev()
    self.spi.open(spiPort,spiDevice)
    self.HC138A = HC138A
    self.HC138B = HC138B
    self.HC138C = HC138C
    self.HC138Valid = False
    
    if (self.HC138A != None) or (self.HC138B != None) or (self.HC138C != None):
       self.HC138Valid = True
       GPIO.setwarnings(False)
       GPIO.setmode(GPIO.BCM)
         

    if self.HC138A != None:
       GPIO.setup(self.HC138A,GPIO.OUT)

    if self.HC138A != None:
       GPIO.setup(self.HC138B,GPIO.OUT)

    if self.HC138A != None:
       GPIO.setup(self.HC138C,GPIO.OUT)

    


  ''' get(Channel)
    if Channel as to be None if no 74HC138 is used
    otherwisw Channel specify the Y0 output which the Max6675 is connected

    Return

    The return is [ temperature  , ErrorCode]

    Where ErrorCode is

    0 : Data is valid
    1 : Bad Channel (is the 74HC138 GPIO set ?)
    2 : Probe unconnected
    3 : Max6675 return bad data

  '''

  def get(self,Channel=None):
    # Deal with 74HC138/139 Multiplexer if we have one
    if ((Channel == None) and  (self.HC138Valid)) or ((Channel != None) and (not self.HC138Valid)):
       return [None , self.ERROR_CHANNEL]

    if Channel != None:
      if Channel > 7 :
         return [None , self.ERROR_CHANNEL]
      if self.HC138A!=None:
       GPIO.output(self.HC138A, Channel & 1)
      if self.HC138B!=None:
       GPIO.output(self.HC138B, Channel & 2)
      if self.HC138C!=None:
       GPIO.output(self.HC138C, Channel & 4)

    #Now let's read the sensor

    data= [0,0]
    data = self.spi.xfer2(data)
    
    #Is the sensor data Valid
    if (data[1] & 2) == 2:
      return [ None , self.ERROR_DATA ]

    #Is the Probe connected
    if (data[1] & 4) == 4:
      return [ None , self.ERROR_PROBE ]    
            
    wdata = data[0] << 8 | data[1]
    return [(wdata>>3)/4.0  , self.VALID_DATA]



if __name__ == "__main__":


   max6675 = Max6675(0,0,17,27,22)

  
   for Probe in range(8):

     probeOK=False
     temperature=0

     data = max6675.get(Probe)


     #let's check if the data is Valid
     if data[1] != max6675.VALID_DATA:
       print('Probe {}: {}'.format(Probe,max6675.errorString[data[1]]))
     else:
       print('Probe {}: Temperature : {:.1f}'.format(Probe,data[0])+u('\u2103'))

This is a good thing that they put back the prefix 'u' in python 3.3

I also put the sensor into my pellet stove. We are at the end of march put the temperature are still cold. Today is -7 Celsius and my pellet stove is still running.

Code: Select all

pi@BPlus ~ $ sudo python Max6675.py 
Probe 0: Max6675 returned bad data
Probe 1: Max6675 returned bad data
Probe 2: Temperature : 238.8 ℃
Probe 3: Max6675 returned bad data
Probe 4: Max6675 returned bad data
Probe 5: Max6675 returned bad data
Probe 6: Max6675 returned bad data
Probe 7: Max6675 returned bad data

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Sun Mar 29, 2015 6:14 am

Daniel, tahnk you so much for this post. Can i also ask you if you can provide a schematic view of connecting 3x Max6675 to RPi just to be sure and not mess something!
danjperron wrote:Before I test my design with the Max6675 on the arduino, I hook the max6675 to a 74HC138 and made it work.

Daniel

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sun Mar 29, 2015 3:31 pm

Image
Last edited by danjperron on Wed Oct 04, 2017 7:24 pm, edited 1 time in total.

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Mon Mar 30, 2015 7:54 am

Why do you use 5V pin and regulate it to 3.3V. Is there any obstacle not to use Pin1 which already has 3.3V ?

Regards... and again thank you very much !

scotty101
Posts: 3734
Joined: Fri Jun 08, 2012 6:03 pm

Re: Multiple SPI

Mon Mar 30, 2015 9:00 am

urosv wrote:Why do you use 5V pin and regulate it to 3.3V. Is there any obstacle not to use Pin1 which already has 3.3V ?
I imagine it is because you can only source a small amount of current from the 3.3V supply. Pulling to much from it can lead to brown-outs on the main processor.
Electronic and Computer Engineer
Pi Interests: Home Automation, IOT, Python and Tkinter

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Mon Mar 30, 2015 11:01 am

I imagine it is because you can only source a small amount of current from the 3.3V supply. Pulling to much from it can lead to brown-outs on the main processor.

1 - Yes there is a maximum of current you could draw from the PI.
2 - The Pi 3.3V is very noisy . Use an external linear regulator will provide a less noisy 3.3V.


P.S. The 74HC138 power as to be connected to the Pi 3.3V. It doesn't care about noise like the A/D in the max6675.

Also you should read the max6675 multiple times and averaging it to get a less jump in the result. You need to put a delay at least of 250ms between readings otherwise the max6675 won't do a new conversion.


Daniel

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Mon Mar 30, 2015 1:16 pm

B.T.W.

For try out you don't need the regulator, but I will suggest it for the final product. The specification for current on the max6675 is 1.5 ma.

Daniel

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Thu Apr 02, 2015 9:20 am

danjperron thank you very much for your help. We successfully created 3 sensor reading module with RPI !

The question popped out that in the future we would like to read even more of them. Is this even possible with this kind of approach or do we need something extra ?

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Thu Apr 02, 2015 11:14 am

A maximum of 10 devices could be in parallel. If you need more you will have to buffer the line.

You could use another approach which is cheaper. use multiplexer switch at the input of the max6675 instead.

Like the previous design , you could have height max6675, connected by the chip select, using the 74HC138.
Then you use a 74HC4052 in the input of the max6675 to connect four probes. This will give you 32 sensors.

N.B. The max6675 assume that the temperature of the connector it is the same that it reads. If the connector where the probe is connected is far away from the max6675, another device will have to read the max6675 and the connector temperature and do a calculated correction. This is a question of precision.

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Thu Apr 02, 2015 12:07 pm

While browsing the net a few solutions replacements for max6675 was found. Regarding your expertise on the problem do you think we are using the right approach to solving the problem or should we use different equipment.

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Thu Apr 02, 2015 1:36 pm

Problem ?

I don't see why because I don't have your specification. Everything is possible.

On the first post you specify height probes and you ask a schematic for three.

So what is your maximum of sensors?
What is your precision?
How far away each sensor are from the converter?
Are you building one of the kind or something else. If you are trying to make a product , hire an engineer!
And so many other question.

I can't answer that since I don't know why you want to do!

I gave you a design with a possibility of 8 sensors.

In My own opinion, I will use an Arduino instead of a pi and link the data to a PI or a PC.
But since you have already the PI working with the sensors, the questions stand .

Are you building only one unit and how many sensors ? and? and?
Daniel

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Thu Apr 02, 2015 6:04 pm

Thanks for your input :) .
My apologies since my communication in English may not be straight forward. The question was only due so many possible solutions to this problem nothing more. The bottom line is that we will use this on industrial compression unit. 2 ALU plates with heater to monitor temperature to 200 degrees and then shut down the heater. While doing this the temperatures will be send over network to main database for statistics for each product. The 3-rd temp sensor for measure the product. Tolerance +/- 1 degree. Speed 1 measurement per second. Nothing fancy...

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Sat Apr 18, 2015 9:58 am

Hi there... Something very strange happened today with this project and I was wondering if you have any idea on that...
The 3 sensors are/were working great.

Today i needed to test Temperature limit of sensors and strangely i noticed when I was heating them the software actually loweres the values, the more the heat the lower value. But strangest of all. In ambient temperature they are showing ~ 21-22 and i did not noticed this since temperature in the room is actually 21-22 ?

Any suggestions...

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sat Apr 18, 2015 12:12 pm

just swap the thermocouple wires. This is the normal behaviour if they are inverted.

On ambiant temperature the thermocouple signal is around 0V. There is no difference between the two junctions.

At no difference between the two junctions, the tip of the thermocouple and the connector were the two metals connect,
the temperature report will be the one measured at the MAX6675 I.C.

Daniel

urosv
Posts: 12
Joined: Mon Feb 16, 2015 12:12 pm

Re: Multiple SPI

Sun Nov 08, 2015 12:52 pm

Hi Danjperon. A while ago we discussed over forum regarding multiple SPI. In this matter i need help, and would be very much appreciated if you could take minute to look in the problem. Im also attaching the schema, which is from your template to the post. I'm using K type thermocupler.

Shema:
https://urosvl.tinytake.com/sf/MzcyNDQxXzIxMTIzOTA

The main problem is that this circuit is not working. The temperature from probes are actually temperature only from one probe displaying on both readings...
https://urosvl.tinytake.com/sf/MzcyNDQyXzIxMTI0MDE

removing one probe still 2 measurements persis
https://urosvl.tinytake.com/sf/MzcyNDQzXzIxMTI0MTI

removing one max
https://urosvl.tinytake.com/sf/MzcyNDQ0XzIxMTI0MjM

removing CS connections
https://urosvl.tinytake.com/sf/MzcyNDQ1XzIxMTI0MjQ

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sun Nov 08, 2015 2:31 pm

Please confirm that your 74HC138 pins 16 is at 3.3V and the pin 8 is at GND!

danjperron
Posts: 3403
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: Multiple SPI

Sun Nov 08, 2015 5:40 pm

I can not confirm that because the 74HC138 is not connected to 3.3 through + on pin 16 and GND pin 8 ? The + and - are on 5 and 6
Then it won't work.

You need to power up the 74HC138. it's like what you need to power any electronic device.
http://www.nxp.com/documents/data_sheet/74HC_HCT138.pdf

The pins 4 and 5 are inverted enable gate. The pin 6 are none inverted pin. This is to enable/disable the output signals. Nothing to do to power up the I.C.


ats1080
Posts: 44
Joined: Thu Sep 27, 2012 2:10 pm

Re: Multiple SPI

Wed Mar 23, 2016 11:50 pm

Well I got all the parts and got my perf board soldered up. I hooked it up the the pi and ran your script and it came back with:

pi@raspberrypi:~/Python $ python thermo.py
Probe 0: Temperature : 0.0℃
Probe 1: Temperature : 0.0℃
Probe 2: Temperature : 0.0℃
Probe 3: Temperature : 0.0℃
Probe 4: Temperature : 0.0℃
Probe 5: Temperature : 0.0℃
Probe 6: Temperature : 0.0℃
Probe 7: Temperature : 0.0℃

I'm not sure where I went wrong. This is my first adventure with SPI so I have no idea where to even begin. I did enable SPI.

ats1080
Posts: 44
Joined: Thu Sep 27, 2012 2:10 pm

Re: Multiple SPI

Thu Mar 24, 2016 12:41 am

So this is my problem:

Image

What is A, B, C, G1, G2A, and G2b???

Hopefully I did not try this chip, because I was thinking the image here was created with physical pin numbers in mind. Instead it seems that the numbers and placement have no real bearing on anything that I can put together. Even looking at the data sheet there is no mention of any of these labels.

ats1080
Posts: 44
Joined: Thu Sep 27, 2012 2:10 pm

Re: Multiple SPI

Thu Mar 24, 2016 1:16 am

After some serious trial and error (and luck that I didn't fry the chip in the process) I got it working! I'll post an explanation tomorrow of how I have it hooked up that is hopefully a little more clear for the simple people like me :lol:

Return to “Automation, sensing and robotics”