Menu

Understanding the MAX6675

Help
Chris S
2022-05-24
2022-05-30
  • Chris S

    Chris S - 2022-05-24

    I dont need help getting code to work, but I am having a hard time visualizing how this works. I almost thought of drawing it out with blocks to get an idea but I have no one else to check my knowledge. So I'll ask here:

    I have in hand, one of those MAX6675 modules. My code works! Yay, and it reports room temp and then close to boiling water (91C, but it was in a mug). My question is this:

    1) When doing an SPI transfer, is the MSB transfer first? So then if I put that in a byte, or upper byte of a word, the MSB's, would match, correct?

    Dim L_byte as Byte
    Dim Temperature as Word
    
      SPI_CS=0
      SPITransfer 0,Temperature
      Temperature=FnLSL(Temperature, 8) ;shift left 8 bits
      SPITransfer 0, L_byte
      Temperature = Temperature or L_byte
      Temperature = FnLSR(Temperature, 5)
      SPI_CS=1
    

    So this was a snippet of code I found around here. Now the MAX6675 has 3 lower bits that are ignored. If we are shifting 8 bits to the left, and then 5 bits to the right, wouldnt the upper 3 bits of the var "Temperature" be unknown? This is where Im getting stuck. It doesnt seem like we are right justifying the bits for correct temperature (But The code does work and report back correctly!) Maybe I'll draw it out..

     
    • Anobium

      Anobium - 2022-05-24

      It seems to me that you are shifting a value in Temperature from the low byte to the high bytes, then, loading the low byte then shifting the whole word to the left. Is this what you wanted to do? At the top three bits of the high byte of the word will get lost,

       
      • Chris S

        Chris S - 2022-05-24

        This is the thread I found where I got the snippet from
        https://sourceforge.net/p/gcbasic/discussion/projects%26guides/thread/f0a238743b/

        Really, I need to get rid of the 3 lower bits (0,1,2) but I still want to emphasize that the code above does work, I just am trying to understand how.

        It seems that the arduino library does the following, which also works:

          SPI_CS=0
          SPITransfer 0,Temperature
          Temperature=FnLSL(Temperature, 8) ;shift left 8 bits
          SPITransfer 0, L_byte
          Temperature = Temperature or L_byte
          SPI_CS=1
        
          Temperature = FnLSR(Temperature, 3)
          Temperature=Temperature/4
        

        Adapted from:https://github.com/adafruit/MAX6675-library/blob/master/max6675.cpp

         

        Last edit: Chris S 2022-05-24
        • Anobium

          Anobium - 2022-05-29

          I am home now.. back online.

          Your code analysed.

          Get the byte value with the result being loaded in Temperature variable
          SPITransfer 0,Temperature

          Put the low byte of the word variable into the high byte of the word variable
          Temperature=FnLSL(Temperature, 8) ;shift left 8 bits

          Get the byte value with the result being loaded in L_byte variable
          SPITransfer 0, L_byte

          'OR' the L_byte variable with Temperature variable to fully populate the word variable. Now the word variable is as per mmotte post - see https://sourceforge.net/p/gcbasic/discussion/579126/thread/7038dd6b3d/?limit=25#8068
          Temperature = Temperature or L_byte

          Remove the variable top 3 bits by shifting left
          Temperature = FnLSR(Temperature, 3)

          Shift the variable right by 2 bits by divide by 4
          Temperature=Temperature/4


          So, to be honest I do not know how this works in the reality. Assume the process has load the max value into the word variable, so, bits 5 thru 14 are all set - this equates to 32736 ignoring all the other bits for now. So, to get to 1023 the real value this would required a shift right 5 times - variable >> 5 = 32736 >> 5 =1023.

          Using the shifts in the method would be 32736 << 3 >> 2 = 16320

          Really, puzzled how this works....

           
          • Chris S

            Chris S - 2022-05-29

            So I actually amended the code a bit, to show step by step via UART what was getting received. It makes sense when you look at it that way. Here is my full code:

            Note: the 1 second delay is for the chip itself. It actually needs 300mS or so to sense the temperature. Realistically, in practice (like control loops), 1 second is more than enough.

            #chip PIC18F13K22, 8
            #define USART_BAUD_RATE 9600
            #define SPI_HardwareSPI
            #include "gcbversionnumber.cnt"
            
            
            #define SPI_CS PORTC.2
            #define SPI_DI PORTB.4
            #define SPI_SCK PORTB.6
            dir SPI_CS    out
            dir SPI_DI    In
            dir SPI_SCK   Out
            SPIMode MasterSlow
            
            Dim L_byte as Byte
            Dim Temperature as Word
            dim timercount as Word
              dim versionString as string * 40
              versionString = "Build"+GCBBuildStr
              versionString = versionString + "@"+GCBBuildTimeStr
            
            timercount=0
            
            Dim SPIstring as string
            
            set SPI_CS ON
            
            HSerSend 13
            HSerSend 10
            HSerPrint versionString
            HSerSend 13
            HSerSend 10
            
            do
            
              SPI_CS=0
              SPITransfer 0,Temperature
              Temperature=FnLSL(Temperature, 8) ;shift left 8 bits
              SPITransfer 0, L_byte
              Temperature = Temperature or L_byte
              SPI_CS=1
            
            //Temperature = FnLSR(Temperature, 3)
            //Temperature=Temperature/4
              SPIstring=Wordtobin(Temperature)
              HSerPrint "raw: "
              HSerPrint SPIstring
              HSerSend 13
              HSerSend 10
            Temperature = FnLSR(Temperature, 5)
             SPIstring=Wordtobin(Temperature)
              HSerPrint "shf: "
              HSerPrint SPIstring
              HSerSend 13
              HSerSend 10
            
            //Temperature=Temperature/4
             SPIstring=Wordtobin(Temperature)
              HSerPrint "tem: "
              HSerPrint SPIstring
              HSerSend 13
              HSerSend 10
            
            
            
              HSerPrint "Current Temperature: "
              HSerPrint Temperature
              HSerSend 13
              HSerSend 10
            '  HSerPrint "Current Timer Count: "
            '  HSerPrint timercount
            '  HSerSend 13
            '  HSerSend 10
            
            wait 1 s
            timercount++
            
            if timercount >=1023 then
              timercount=0
            end if
            
            loop
            
            
            
            end
            
             
            • Chris S

              Chris S - 2022-05-29

              As you can see, I amended the code and commented stuff out. Using shift 3, and then dividing by 4 (or shifting by 2) gives the same result. I ran the experiment twice and got the same result.

              Edit: There might be some duplicate code here:

              Temperature = FnLSR(Temperature, 5)
               SPIstring=Wordtobin(Temperature)
                HSerPrint "shf: "
                HSerPrint SPIstring
                HSerSend 13
                HSerSend 10
              
              //Temperature=Temperature/4
               SPIstring=Wordtobin(Temperature)
                HSerPrint "tem: "
                HSerPrint SPIstring
                HSerSend 13
                HSerSend 10
              

              Not that it will cause issues or anything. But its left over from the divide by 4.

               

              Last edit: Chris S 2022-05-29
    • Anobium

      Anobium - 2022-05-24

      It seems to me that you are shifting a value in Temperature from the low byte to the high bytes, then, loading the low byte then shifting the whole word to the left. Is this what you wanted to do? At the top three bits of the high byte of the word will get lost,

       
  • mmotte

    mmotte - 2022-05-24

    The range on the max6675 is 0 to 1024 deg C with .25 deg resolution.
    so the Msb 10 bits are the whole degs
    bits 0 tristate
    bit 1 is ID
    bit 2 is open thermocouple
    bit 3 and 4 are the 0.25 deg C increments
    bits 5 thru 14 are the whole degC
    bit 15 is 0

    Shifting right 5 throws away the .25 deg resolution and the lower flags

     
  • Anobium

    Anobium - 2022-05-30

    I understand now. Looks good.

     
  • Anobium

    Anobium - 2022-05-30

    I did make this test program to ensure it worked. :-)

    I set the Temperature and L_byte to the values that should represent 1023.... and, the result is correct. :-)

    Dim L_byte as Byte
    Dim Temperature as Word
    
      Temperature = 127
        HserPrintCRLF 2
        HserPrint "1: "
        HserPrint Temperature
        HserPrintCRLF
    
      Temperature=FnLSL(Temperature, 8) ;shift left 8 bits
        HserPrint "2: "
        HserPrint Temperature
        HserPrintCRLF
    
      L_byte = 224
      Temperature = Temperature or L_byte
        HserPrint "3: "
        HserPrint Temperature
        HserPrintCRLF
    
    
      Temperature = FnLSR(Temperature, 5)
        HserPrint "4: "
        HserPrint Temperature
        HserPrintCRLF
    
     

Log in to post a comment.