interfacing a MCP9701

Posted on
  • In my past projects I have successfully used a MCP9701. Atlas-scientific has created a wonderful waterproof and food friendly product that incorporates the MCP9701. I emailed the manufacturer for more info about their product. They responded that their product uses a "MCP9701 and other stuff" in the past I had to modify their arduino example code to work with the mbed platform with success. Now, I would like to port/modify the arduinos example code to work on the Espruino platform. I stumbled across http://www.espruino.com/Thermistors. I am not sure of the mcp chip that I am using will work when using the Espruino thermistors example. The example page asked to check the resistance then use a matching resistor. I have never used a resistor with my past projects using a arduino and mbed because the datasheet of the temp probe https://www.atlas-scientific.com/_files/­_datasheets/_sensor/ENV-TEMP_1.4.pdf never asked to use one. maybe the resister is already part of the atlas-scientific temp probe? I'm looking for guidance to port the code over to Espruino, any help is greatly appreciated.

  • You should not use a resistor like the thermistor tutorial suggests. Instead you connect the output pin (white on the Atlas device) on the MCP9701 directly to an ADC pin on the Espruino. The voltage you read is proportional to the temperature. Use the calculations described in the atlas datasheet to get the actual temperature. Just remember that Espruino analogRead returns a resolution-independent number between 0 and 1, and the Aref voltage is 3.3V.

  • Hi... It looks from the MCP9701 info like the MCP9701 is an 'active' thermistor and outputs a voltage (rather than resistance) so you don't need a resistor at all. Not only that but it's linear.

    The datasheet gives you the formula you need - I don't have one here to test but your code should look something like:

    var vOut = E.getAnalogVRef() * analogRead(A0); // if you attached VOUT to Ao
    var vZero = 0.4;
    var tCoeff =  19.5 / 1000;
    var temp = (vOut - vZero) / tCoeff;
    console.log(temp);
    
  • Thank you. Hook up was simple :-)

  • Gordon, your example worked. I echoes out, for example, 24.91330565947488295819 I was able to convert C to F by this:

    var tempinc = (vOut - vZero) / tCoeff;
      var tempinf = tempinc * (9 / 5) + 32;
    

    Is there anyway to change the decimal place to just two digits after the decimal?

  • try tempinf.toFixed(2)

  • That worked. Thank you.

  • I am now attempting to get a more accurate result by finding the average of multiple temp results. The issue I am having is, when I find the average I am getting undefined and NaN from the output of the variable that I supposedly saved the average to. The issue I think is stemming from the way I am saving the temp value. Also, besides taking the average results, is there another way I could achieve a more accurate temperature?

    My code:

    function getResTempValue(x) {
        var temp;
        var avgTemp;
    
        for (var i=0;i<x;i++)
        {
          var vOut = E.getAnalogVRef() * analogRead(A0); // if you attached VOUT to Ao
          var vZero = 0.4;
          var tCoeff =  19.5 / 1000;
          var tempinc = (vOut - vZero) / tCoeff;
          var tempinf = tempinc * (9 / 5) + 32;
    
          temp = temp + tempinc;
          console.log(temp);
          if (i==x) {
            avgTemp = temp / x;
            temp = temp / x;
          }
          console.log(i);
        }
    
        console.log("Temp: " + temp + " Avg temp: " + avgTemp);
        return temp.toFixed(2);
      }
    //IE getResTemp(5);
    
  • Try setting temp and avgTemp to 0 first:

        var temp=0;
        var avgTemp=0;
    

    In JavaScript, values default to undefined, and undefined + 0.0 == NaN.

  • Hi Gordon. Setting both the variables to 0 worked. I am now receiving a negative temp reading. It has to be my math that is the issue.

    Code:

    function getResTempValue(x) {
        var temp=0;
        var avgTemp=0;
    
        for (var i=0;i<x;i++)
        {
          var vOut = E.getAnalogVRef() * analogRead(A0); // if you attached VOUT to Ao
          var vZero = 0.4;
          var tCoeff =  19.5 / 1000;
          var tempinc = (vOut - vZero) / tCoeff;
          var tempinf = tempinc * (9 / 5) + 32;
    
          temp = temp + tempinc;
          console.log(temp);
          if (i==x) {
            //avgTemp = temp / x;
            //temp = temp / x;
          }
          console.log(i);
        }
    
        temp = temp / x;
    
        console.log("Temp: " + temp + "Avg temp: " + avgTemp);
        return temp.toFixed(2);
      }
    
  • Around -20C by any chance? (in other words, tempinc=(-0.4)*tCooef, so Vout=0 because of a wiring issue or something like that)

  • DrAzzy, yes the temp is averaging around -20C. I don't think it is a wiring issue. I was getting positive readings before I attempting to implement some kind of averaging temp reading. Well, I just made a liar out of myself. I went back to my original code without the averaging stuff and I am still receiving negative readings.

    Original code:

    function onInit() {
      var phValue="";
    
      Serial4.setup(38400);
    
      Serial4.onData(function (e) {
        phValue+=e.data;
    
        if (e.data == "\r") {
          console.log(phValue);
          phValue="";
        }
      });
    
      function getResTempValue() {
        var vOut = E.getAnalogVRef() * analogRead(A0); // if you attached VOUT to Ao
        var vZero = 0.4;
        var tCoeff = 19.5 / 1000;
        var temp = (vOut - vZero) / tCoeff;
        console.log(temp);
    
        return temp.toFixed(2);
      }
    
      function getPhValue() {
        var rescomp="";
        var pfloat="";
        //on = !on;
        //digitalWrite(LED1, on);
        rescomp = getResTempValue();
        pfloat = parseFloat(rescomp);
        console.log("Temp: " + pfloat);
        Serial4.print(rescomp+"\r");
        //Serial4.print("r\r");
      }
    
      function phCalibrate4() {
      }
    
      function phCalibrate7() {
      }
    
      function phCalibrate10() {
      }
    
      var interval = setInterval(getPhValue, 5000);
    }
    
    onInit();
    
  • Oh, I just found your problem!

    E.getAnalogVRef() returns something that's nearly 0 on V53 of Espruino firmware.

    
     _____                 _ 
    |   __|___ ___ ___ _ _|_|___ ___ 
    |   __|_ -| . |  _| | | |   | . |
    |_____|___|  _|_| |___|_|_|_|___|
              |_| http://espruino.com
     1v53 Copyright 2014 G.Williams
    >>
    =undefined
    >E.getAnalogVRef();
    =0.000050167224080267551
    
    
  • DrAzzy, I'm at a loss to what that means. What should I do to fix this issue?

    UPDATE
    I downgraded the firmware from 1v54 to 1v52 and I am no longer getting negative values. I guess this is a bug?

  • Yes, sorry about this. I'll try and fix this tomorrow.

  • Thanks, I'm looking forward to the fix :-)

  • Ok, it's fixed (1v55). The next time you try it, it should prompt you to update.

  • Gordon, thank you! All is working as expected :)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

interfacing a MCP9701

Posted by Avatar for d0773d @d0773d

Actions