Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Thermocouple interface with PIC

Status
Not open for further replies.
Oops wrong data sheet. Input current is only 150ua, so you may be able to get away with just a cap for stability there. Minimum ref is also 2.0V. However, vref+ minimum is AVDD - 2.5, so if you can power it from 4.5V instead of 5.0 and that would solve your issue with that. Putting a diode in series with the supply will drop the voltage accordingly. Make sure if any periphrials are communicating with your PIC, that they don't put more than VDD at the pins.

Per datasheet: https://www.electro-tech-online.com/custompdfs/2010/09/39598e.pdf
 
Code:
char short_result = result << 4; //get whichever 32 step it corresponds to

Shouldn't that be "char short_result = result >> 5;" to divide by 32?

Code:
char result_diff = result - short_result; //how much larger than the 32 is it.

I think there's something wrong here too but I'm not quite sure what.

Also, shouldn't all the Chars be Ints? I thought a char was only 1 byte?
 
Way ahead of you, I already changed that one, lol.

with the second piece, yes you are right, should be
Code:
char result_diff = result - (short_result << 5);
I just used chars to save memory wear appropriate. For example, the maximum result_diff can be is 32, so it fits in 8 bits, same with short_result.

As is quite apparent, this code has not been checked and debugged, I am just trying to illustrate the concept, which by pointing out the errors, it seems you understand.
 
And on that idea with the chars, if you want to save program space, you could save 32 bytes by storing the TEMP_TABLE as offsets from -200 instead of the absolute temperatures since the whole span is less then 256 so.

Code:
unsigned char TEMP_TABLE[32] = {0,offset1,offset2,etc..};

Of course, all you would need for a complete table of each of the 1024 ADC results with two decimal places is 16 Kbits. What does a 16Kbit eeprom cost these days? 30 cents?
 
...Here...

hi,
Relooking at you project I would suggest that you left justify the adc value, so that you get 0 thru 255 counts [the 0 to 250 will be a Table address]
Dont go lower than 2.5V for the Vref, it MAY work at 2.0V or so, but its outside of the adc spec.
You can buy low cost 2.5Vref TO92 style references.
 
Thank you both for your help and advice so far. I'm having problems getting anything to work at the moment so it may be a while before I can try these things out.
 
Ok I've got things working again and implemented the lookup table. I just need to correct the code that CafeLogic gave to accompany the lookup table.
 
Ok, I've wrote my own interpolation code that I have tested in C++ for windows. I have yet to test it with the PIC as I can't fit it into ROM (floats take up lots of space :/) Does anyone have anytips I can use to save ROM?
 
Use fixed point instead. That proc is not the best option for floating point. Another option is to use a different MCU. Maybe something from the PIC18 series might be a better fit?
 
I'm using the Mikro C compiler and it doesn't appear to offer fixed-precision decimals. Is it somehting I would have to implement myself?
 
It is not part of the C standard and I have never seen a compiler that offers native support for it (although that would be great). Basically the idea is to represent each number with integer values with extra digits attached to represent decimal places. You could represent -200 through 50 with two decimals as 16 bit integers. For example, 35.24 would be the integer 3524. You can add numbers normally but when you go to multiply or divide, you need to be careful. 3524 * 5 results in the correct fixed point representation but 3524 * 500 creates a number represented by 4 decimal places instead of 2. So basically, you need to chop 2 off before or after the operation. When dividing, you need to add decimal places before or after (before for better accuracy, after to avoid 32 bit integers).

After that comes the PIA of formatting the numbers for LCD display. One method would be to use itoa to convert the number to a string, then put the decimal in the correct location. like this:

Code:
 #include <string.h>
 
 /* reverse:  reverse string s in place */
 void reverse(char s[])
 {
     int i, j;
     char c;
 
     for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
         c = s[i];
         s[i] = s[j];
         s[j] = c;
     }
 }

 /* itoa:  convert n to characters in s */
 void itoa(int n, char s[])
 {
     int i, sign;
 
     if ((sign = n) < 0)  /* record sign */
         n = -n;          /* make n positive */
     i = 0;
     do {       /* generate digits in reverse order */
         s[i++] = n % 10 + '0';   /* get next digit */
     } while ((n /= 10) > 0);     /* delete it */
     if (sign < 0)
         s[i++] = '-';
     s[i] = '\0';
     reverse(s);
 }

void insertDecimal(char place, char s[])
{
    char length = strlen(s);
    char i;
    for (i = (length - 1); i--; i >= 0)
    {
       s[i + 1] = s[i];
       if (i == place)
       {
          s[i] = '.';
          break;
       }
    }
}
itoa and reverse were taken from the second edition of K&R C. insertDecimal is my own, was composed in this post, and has not been checked.

Personally, I find the whole fixed point thing contributes bugs and adds a lot of time. Call me lazy, but I usually just prefer to upgrade to an MCU that is comfortable with floating point and then I don't have to write my own stuff. I usually only end up using fixed point if I am really pressed for BOM.
 
Last edited:
Thanks again for your wealth of information. I have read about fixed-point and have decided to stick with floating-point for the moment. I managed to cram everything in by using a bit of EEPROM for something. I need to test it but that will wait to tomorrow.

Cya.
 
Just to update you. I have everything working on a breadboard including the interpolation in firmware. Soon I will check it's conistency against a known good instrument.

Thank you both CafeLogic and ericgibbs for all your help so far :)
 
It passed the ice water and boiling water tests yesterday :) Now I am going to make the PCB and get it tested with some cryogenics.
 
Quick question. My circuit draws 100mA max from a 7805 regulator. I am supplying the regulator with 12v from my benchtop PSU. Using ((Vin - Vout) * Iload) gives: (12 - 5) * 0.1 = 0.7w. The regulator runs at 65c. Does that sound correct?

Thanks.
 
Yeah. With ambient at 25c that is about 65c/W. That is a very typical dissipation rate for TO-220 to ambient. There are many off the shelf heat sinks designed to fit TO-220 that you can use if you afraid it will compromise measurements.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top