Need some help with this thermocouple project

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have spent many hours on this and it almost works :)

The problem I am having I think is the reading and sending of the received bits.

The max6675 is being read by a tiny45

16 bytes are read into an unsigned int with the code below

// Read the max6675 Chip. 2 bytes -----------------------------------------------------------
unsigned int get_temp_data()
 {
    unsigned char i;
    unsigned int buffer,mask;
    mask=0b1000000000000000;
    buffer=0;
    CS = 0;                     // Enable Chip Select CS low
     #asm("cli")
     delay_us(5);
     #asm("sei") 
    for(i=0;i<16;i++)
        {
            SCK=1;              // Clock high
     #asm("cli")
     delay_us(5);
     #asm("sei")    

            if(SO == 1)         // test bit high/low
            {
                buffer |= mask; // Store bit if 1
            }    
            mask >>=1;          // shift mask bit 
     SCK=0;              // Clock LOW 
     #asm("cli")
     delay_us(5);
     #asm("sei")            
        }      
        CS = 1;                 // Disable Chip
    return buffer;
 }

then the data is sent back to the master using 1 wire interface. I have tested sending hard coded bytes and the communication is fine however the following code to split the unsigned int to two unsigned chars and send them results in the High byte giving me a 0 when room temp, and heating it up it gives me a 128. Now there should be no bits set in the high byte as the a6 bit unsigned int is shifted 11 times so bits 11..14 should be in bits 0..3 and the 15th bit should be zero (bit 4 of the unsigned char) all upper bits should be zero correct?

      buffer = get_temp_data();
      byteread = (unsigned char)(buffer>>3);       // Low Byte  

      send_temp_data(byteread);  
      #asm("cli")
      delay_us(10);
      #asm("sei")  

      byteread = (unsigned char)(buffer>>11);    // High Byte 

     send_temp_data(byteread);      

Edit: I retested before I came to my real job with dummy variables and it seems the tiny45 1 wire algorithm I am using is not working correctly either in the tiny45 sending or the mega48 receiving. I suspect the mega48 as it also has interrupts running. I will fix that and then go back to trying to get data from the MAX , if that doesn't fix it then I will need some help I guess.

One question I do have on the output of the MAX6675 when a thermocouple is not connected. Do all the other bits except D2 get random data, all high or low? Anyone know?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here's how I'm reading the 6675. I tried all the spi modes. I settled on reading the 6675 using the spi with spi in mode 0x5c (flipped polarity) then flipping it back at the end of the routine. Shorted TC reads 0, open reads all 1s.

//----------SPI routines---------------
char readspi(void){
//return char from spi
char cnt,stat;

  cnt=0;
  do{
    stat=SPSR;
    cnt++;
    if(cnt==255){
      cprintf("spi rx ");
      break;
    }
  }while((stat & 0x80)==0);  //keep checking until done bit
  return(SPDR); //clears done flag
}

//--------------------------
void spiout8(char c){
//send c out spi
char cnt,stat;

  SPDR=c; //send data
  cnt=0;
  do{
    stat=SPSR;
	  cnt++;    
    if(cnt==255){
      cprintf("spi tx ");
      break;
    }
  }while((stat & 0x80)==0);
}

#define CSLO() PORTC &= ~0x40 //was 0x01 last rev
#define CSHI() PORTC |=  0x40
unsigned int raw; //raw bits from 6675 (1/4 degrees)
float fqdeg,fqdegsm;
//---------------------
void readmax6675(void){
//read max6675 thermocouple preamp     takes 220ms!  called every 250ms
//bit d2 lo means tc open
unsigned char dh,dl;
unsigned int qdeg; //quarter degrees

  INTR_OFF();
  SPCR=0x5c;    //0x58 -> 0x08 ->clk pol flipped + 0x04 data polarity
  CSLO();       //conv halt, output bit 0
  asm("nop");
  asm("nop");
  spiout8(0);   //send dummy byte, generates 8 clks
  dh=readspi(); //read hi byte 
  spiout8(0);   //send dummy byte, generates 8 clks
  dl=readspi(); //read lo byte
  CSHI();       //conv resume
  SPCR=0x50;    //fastest spi back on for needle  
  INTR_ON();
  
  raw=((unsigned int)dh << 8) + dl; //raw thermocouple reading 1/4 deg C x4? x8?
  tcopenerr=(raw & 0x0004) != 0;    //check tc open err bit d2
  qdeg=raw >> 3;   //12 bit unsigned integer number (4096 quarter degC->1024 degC)
  fqdeg=qdeg; 
  fqdegsm += 0.125*(fqdeg-fqdegsm); //
  degC=fqdegsm*0.25;    //cvt qdeg to degC  
  degF=degC*1.8 + 32.0; //cvt degC to degF 
}

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Bob, I almost was going to pack up my stuff and come over to your place, I started last night with the final soldering of the chip on my board it was 11:30pm then i said I better not hook it up or i will be debugging all night, well that lasted till 3:30am, somehow i woke at 7:45 am and started at it again till 12:00 noon then went to work to take a break from it (my real work) then back at 3:30 pm till 6:00 still going back and forth almost there, one more change. Actually jumping between the Pc harbor minigui code, the C code for both avr's and jumping in and out of avr studio programming the tiny45 on the dragon and the mega on the stk500 I finally said i need a really big pizza and a nice glass of cold beer.

Then, I came home looked at the receive code on the mega (my own 1 wire concoction) and realized, um er I was reading the bytes sent from lowest to highest. It should have dawned on me when I said in the previous post the high byte was jumping directly to 128 instead of 1 when I heated the thermocouple up.

Schazam, put some ice on the thermocouple and what do you know 0C 32F, boiling water now:)

I am going to post this whole project in completed projects when I am done at least the thermocouple tiny45 and mega48 code .. going to see how fast I can read it now.

Here is the 1 wire reading byte code.
i still have to add timeouts in the while loops but that's no problem. My Code posted above for reading the MAX works fine.

unsigned char  Get_Byte() 

{
unsigned char nbits;
unsigned char temp;

temp = 0;

nbits = 0b10000000;


while (nbits > 0) 
   {           
    while (xWire_Receive == 0)      // Wait for line to go high
    {
    }  

    while (xWire_Receive == 1)     // Wait for line to get pulled low 
    { 
    } 
    
  
    #asm("cli")           
    delay_us(60);
    #asm("sei") 
    DDRC.1 = 1; 
    if (xWire_Receive == 1)      // bit is 0
    {
        nbits>>=1;
    }
    else
    {     
    temp |= nbits;
    nbits>>=1;
    }
    #asm("cli")           
    delay_us(10);
    #asm("sei")       
    DDRC.1 = 0;   
 }

return temp;

}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wonder what the deal is with some thermocouples red wire being positive when most I have seen are red- white+
My neighbor has an injection molding machine and gave me one of his extra thermocouples, polarity is reversed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I wish my neighbor had an injection molding machine!