Can not open MCP9600 with AnyI2C

I downloaded AnyI2C from github, it shows an update for the MCP9600, but it does not appear on AnyI2C selection window.

I found the XML file and copied it over, it then showed the MCP9600 on the selector, I clicked on the GUI, but it could not find the .dll for the MCP9600.

I could not find the .dll file on github either.

Thanks.

 

 

Target Product: 
MCP9600
Topics: 
R

Ok, I have sent this to our software developer for AnyI2C, we should have an update ready by tomorrow.

Please let me know if you have more questions.

Thanks,

Ryan

C

Thanks

R

Please let me know what interface you are using with the AnyI2C software.  It has come to my attention the MCP9600 does not operate at standard speeds (we have been unable to get the chip to respond at 100KHz operating speed, but it works fine at 50KHz or below), it is necessary to slow down communications for interface to this device.  Not all interface boards support slower speeds at this time, but if you are using the BridgeX5, I do have a solution for you.

Thanks,

Ryan

T

Hi,

I do have working code for Photon that monitors the temperature from a K-Type thermocouple using the MCP9600 if you would like for me to share that.  I am working on an application project using it so I have not shared the code yet but I do have it.  Please let me know if you would like me to share.

C

Travis that would be a big help, I am using the photon or electron most of the time. I should be able to convert to Python if I need to use the Raspberry Pi.

Thanks

T

Hi,

Here is what I have so far:

https://github.com/ControlEverythingCom/MCP9600-K-Type-Thermocouple

The MCP9600 is a bit of an odd duck.  It took some experimenting to find that the default I²C clock speed had to be lowered down to 75khz in order to function reliably.  This is the absolute fastest speed I could get it to work reliably.  At 80khz it failed.  The library takes care of setting the I²C clock speed in the init function which should always be called before using the object but keep in mind this must be done.  It will only set the I²C clock speed if Wire.begin has not yet been called in the application or by another library.  It would be a good idea to call the init function of this library before any other I²C communications in other libraries.

C

Thanks Travis, I will give it a try if my internet will behave (it is super slow today, Comcast will not here until tommorrow)..

C

It works good Travis, thanks for the code. I will go back and play with it some more.

T

Great!  Like I said that MCP9600 is a bit of an odd duck but in my testing after I got the I²C clock speed down to 75khz it worked like a champ.  Let me know if you need anything else.

Andy Hernandez's picture

Travis:

Let me know if you can share some code that will work with Windows 10 IOT, using C#, for this board I just bought?

T

Hi Andy,

I do not have any experience working with Windows 10 IOT.  However I can tell you it will work as previous customers have used our products with Windows 10 IOT.  What are you using as the computer running the Windows 10 IOT OS?

Thank you,

Travis Elliott

Andy Hernandez's picture

Travis:

This is my current Setup:
Raspberry Pi 3
Windows 10 IOT Version 14393.448
Visual Studio 2015 Community 
CSharp language C#

 

Can you try to get some sample code and post it here?

T

Hi Andy,

I checked around with a couple of other developers here and we do not have any code samples applicable to your setup.  We will look into putting some together in the future.  In the mean time if you develop any sample code please feel free to share it with the community.

kandy's picture

Hi Travis,

 

I just got the MCP9600 sensor from CE. Reading this blog I found out that you have written some code for the MCP9600. Did you do it in Python? Checking the Internet I did not find a line of Python code for the MCP9600. As I am not fluent in coding a sensor in Python I would appreciate any help.

 

 

Regards

Hans

T

Hi Hans,

I will try to put together a simple python script today for reading temperature on the MCP9600.  I will post here as soon as it is complete.

T

Hi Hans,

Just an update on the Python code on a Pi reading the MCP9600.  This Python code will print out the temperature of the sensor:

https://github.com/ControlEverythingCom/MCP9600-Python/blob/master/MCP9600.py

However there is an issue.  The default i2c clock speed on the Pi needs to be adjusted to 75000 in order to work with the MCP9600.  I have not been able to get this to work thus far.  If you google 'change I2C clock speed on Pi' you will see adjusting this with a line in boot/config.txt  then reboot.  I tried that but still have not gotten it to work.  You can give this a try and see what you find.

kandy's picture

Hi Travis,

Thanks a lot for your effort on writing a code for the MCP9600. I'll also try to get this timing problem under control.

Hans

 

 

T

Hey Hans,

So I finally have the MCP9600 working with the Pi and a Python script.  See latest Python script here which has updated since my last post(Now using bus.read_i2c_block_data properly):

https://github.com/ControlEverythingCom/MCP9600-Python/blob/master/MCP9600.py

I was also finally able to update the I2C buad rate on the Pi.  To do this:

Open terminal and enter:

sudo modprobe i2c_bcm2708 baudrate=75000

Then reboot the Pi.  

After reboot check the speed by entering in the terminal:

sudo cat /sys/module/i2c_bcm2708/parameters/baudrate

It should print out 75000.  If so then just run the Python script and you should get a temperature reading printed to the terminal.

Let me know what you find.

kandy's picture

Hi Travis,Thanks again for your help. The changing of RPI's baudrate works well. If you do not want to reboot after the modprobe line 

just enter ' $ sudo modprobe -r i2c_bcm2708' first to unload the kernel and then enter the new baudrate .

I checked the Python code for the MCP9600 and it worked so far. It outputs a constant temp of 60.8°F... even if you expose the thermocouple to higher temps.

Did not find a solution yet to the problem

Hans

 

T

Hi Hans,

Yes, I had that same issue initially.  Have you pulled in my latest code from GitHub which uses the bus read block function rather than reading twice individually?  That latest Python code corrects that issue.

kandy's picture

Hi Travis,

I downloaded this code from github..

 

 

import smbus 
import time 
 
address = 0x64 
  
bus = smbus.SMBus(1) 
 
bus.write_byte_data(address, 0xC0, 0x00) 

# time.sleep(0.5) 

data = bytearray() 

bus.write_byte(address, 0xC1) 
# time.sleep(0.5) 
 
data = bus.read_i2c_block_data(address, 2) 

# print data[0] 
# print data[1] 
 
if((data[0] & 0x80) == 0x80): 
   data[0] = data[0] &0x7F 
   temp = 1024 - (data[0] * 16 + data[1]/16) 
   temp = (temp * 1.8)+32
   print temp 
else: 
   temp = data[0] * 16 + data[1] / 16 
   temp = (temp * 1.8)+32 
   print temp 

 

.... and I still get this 60.8°F number and nothing else. The baudrate is set at 75000. Do I have the right code?

Sorry for bothering you with this problem

Hans

 

 

T

Hi Hans,

Yes, that is the correct code.  Not sure why you are getting that.  You might try rebooting the Pi, not sure what would be causing that.  I do know that you are not getting the second byte back from the controller but not sure why.  If you uncomment out print data[0] and print data[1]  you will more than likely see both bytes printed out as 1.  If you heat the sensor up sufficiently(I held it in my mouth) it will bump up so both bytes are 2 but the second byte should be changing more, it is not because the second byte is not being received by the Pi.

kandy's picture

Hi Travis,

I played with the MCP9600, calling register data and changing register data. This works pretty well. A part of the code is attached, see below. Whether I did everything right, I don't know. 

Had the following results with the Hot Temp Register:

The Temperature jumped between 16C and 24C depending on the time.sleep value (changed it between 0 and 1.1)

Calling the MPC9600 ADC register's 3 bytes gives a lot of information... they also , of course, contain the Hot Junction Temp bytes (your data[0] and data[1]. Always about 24C

Changed the baudrate 100'000, 75'000 and 50'000. No success.

I honestly dont know what I could do to make it work...

 

Hans

 

import smbus
import time 

# MCP9600 Bus address
address = 0x64 

bus = smbus.SMBus(1)

# Write to Thermocouple Sensor Configuration Register 05h , 00h
# Type K / Filter Coefficient  = 0
bus.write_byte_data(address, 0x05 , 0x00) 

# Write to Device Configuration Register 06h , C0h (11000000b 192d )
# Ambient Sensor Resolution 0.25C / ADC Resolution 14-bit / 1 Sample / ShutDown Mode Normal
bus.write_byte_data(address, 0x06 , 0xC0)  

# Read Device Configuration Register
Dev_Reg = bus.read_byte_data(address,0x06)

# time.sleep(0.5) 

# Write to Thermocouple Hot-Junction Register 00h 
bus.write_byte(address, 0x00)

# Read Thermocouple Hot-Junction Register
data = bus.read_i2c_block_data(address,2)

# Write to Raw ADC Data Register 04h 
bus.write_byte(address, 0x04)

# Read Raw ADC Data Register 04h
d = bus.read_i2c_block_data(address,3)
print d

# print Dev_Reg
print data[0] 
print data[1]
# print data

if ((data[0] & 0x80) == 0x80):    # Temp T < 0 C
   data[0] = data[0] &0x7F 
   temp = 1024 - (data[0] * 16 + data[1]/16) 
   print "Temperature : %.2f C" %temp 
else: 
   temp = data[0] * 16 + data[1] / 16 
   print "Temperature : %.2f C" %temp import smbus

 

 

   

T

That is so strange that it's working here for me and not for you.  What Linux image are you running on the Pi?  I am running Raspbian.  I do not know if that could have something to do with it.  How about your I2C cable length between the Pi and the sensor, is it really long?  In my testing I was using a short 3" cable.

kandy's picture

Hi Travis,

I am also running Raspian with Python 2.7.9. The cable length is 3"...

Did you try the code snipplet I just sent to you and it worked?

 

T

Hi Hans,

No, I did not try the snippet you sent over.  I can tomorrow if you would like.  I just used the origional code I posted earlier.  It is working here no problem.

Do you have I2C tools installed?  If not you might install that and try i2cdetect to see if the MCP9600 shows up correctly.  You can also use it to manually read registers from I2C devices.

I did a short video series on using I2C devices with RPi which includes setting up and using i2ctools here:

https://www.youtube.com/playlist?list=PLGoyJ253LT0LbVgzKDyi9AB0jDmRW4BNZ

Let me know what you find.

kandy's picture

Hi Travis,

I checked the board with the i2c tools. It shows up at 0x64 and I also can read/write using i2c tools. I looked up all your videos, fine stuff.

As I have no docs about the i2c tools commands I could not read out both bytes of the Hot Junction Thermocouple at register 0x00. The first byte read shows 1.

Perhaps you could run my snippet and see whether it works. Would be a great assurance for me whether I understood the programming or not...

It's just an idea which surfaced lately: Could the board or the thermocouple be flawed? Honestly I don't think so...

Hans

 

 

kandy's picture

Hi Travis,

A night's work passed... 

I couldn't let go and here is a code snippet which finally works for me.  I used the command 'bus.read_word_data' which calls the Hot Junction Temperature register.

The rest is splitting the 16-bit word into 2 bytes (MSByte and LSByte). Checking it out with ice water gave 0°C. When I check the Cold Junction Temp it  gives - 1021. 3 counts off from the 1024 value used in the negative temp calc in the code. Negative temps are yet to be checked with the code.

What I do not understand is the fact that you get no fractions of the temp. Do you have an idea?

Here is the working code snippet. Please check it 

Thanks 

Hans


import smbus
import time

# MCP9600 Bus address
address = 0x64 

bus = smbus.SMBus(1)


# Write to Thermocouple Sensor Configuration Register 05h , 00h
# Type K / Filter Coefficient  = 0
bus.write_byte_data(address, 0x05 , 0x00) 

# Write to Device Configuration Register 06h , C0h (11000000b 192d )
# Ambient Sensor Resolution 0.25C / ADC Resolution 14-bit / 1 Sample / ShutDown Mode Normal
# bus.write_byte_data(address, 0x06 , 0xC0)  

# Write to Device Configuration Register 06h , C0h (11000000b 192d )
# Ambient Sensor Resolution 0.0625C / ADC Resolution 16-bit / 1 Sample / ShutDown Mode Normal
bus.write_byte_data(address, 0x06 , 0x20) 

# Read Device Configuration Register
# Dev_Reg = bus.read_byte_data(address,0x06)

# Read Thermocouple Hot-Junction Register
data = bus.read_word_data(address,0x00)

LSByte = data & 65280
LSByte = LSByte/256
MSByte = data & 255

if ((MSByte & 0x80) == 0x80):    # Temp T < 0 deg
   MSByte = MSByte &0x7F 
   temp = 1021 - (MSByte * 16 + LSByte/16)
   print "Temperature : %.2f C" %temp
else: 
   temp = MSByte * 16 + LSByte/16 
   print "Temperature : %.2f C" %temp

T

Hi Hans,

Great news!  I'm glad you have it mostly working.  I will take a look and test your code this afternoon to see why you are not getting fractions on your readings.

kandy's picture

Hi Travi

 

Unfortunately I found out that the code does not work for negative temps. At the moment I have no idea why not.

Checking the MSByte at negative temps it reads always 255d ...

Hans

T

Hi Hans,

Now that the sensor is somewhat functional have you tried going back and using the code I posted before to see if perhaps it works now?  Just thought that might be worth a try.

Sorry I have not been able to check the code recently.  Work has really picked up around here.

kandy's picture

Hi Travis,

I'll give the original code a try at subzero conditions. Let you know asap.

Travis, are you interested in setting foot on the European continent to sell your excellent products? The shop where I buy my other stuff (located in Zurich) would be very interested in selling your merchandise in Switzerland. The owner Ralf Lohse tried to contact you via email, but didn't get a response. If you were interested you can check his shops under the following URL's: maker-shop.ch and pi-shop.ch. His personal address is Ralf.Lohse@totonic.ch.    

Hans

T

Hi Hans,

Yes, we are most definitely interested in having a distributor in Europe, mainly to help fight the high shipping charges we have to pass onto the customer.  We are revamping our site now by moving over to a new online cart provider.  During this move we hope to further optimize our offering to allow for sales through distributors.  As it currently stands there is little to no markup that would allow for reselling through distributors.  Unfortunately this will raise our sale price a bit but there really is no choise if we hope to sell product through distributors.

kandy's picture

Hi Travis,

That sounds beautifully and I would be happy to help you establishing a base here in Switzerland. So please contact Ralf Lohse via the mentioned email address. He would be happy to hear from you.

Maybe we can establish contact via skype or phone

This is my contact:

 

Hans Kandlbauer

CEO AeroScience

Augwilerstrasse 64

CH-8426 LUFINGEN

Switzerland

Phone: +41 44 8131001

Mobile: +41 76 3345463

email: kandy@aeroscience.ch

skype: aeroscience

Best regards

Hans

T

Thanks Hans.  When we get a bit closer to being ready I will reach out to both of you about this.

kandy's picture

Hi Travis,

Your code, downloaded from github, now works with me as well. I just made minor changes. You can check it below. But when I check the sensor in below- zero-conditions I get the same odd numbers as my code delivers. The temperature (measured and) displayed is about  -1080 C when it should read -4C... Your data[0] byte reads 255d or FFh and so does my MSByte. For sure this data[0] value is not correct. 

 

import smbus
import time

address = 0x64

bus = smbus.SMBus(1)

bus.write_byte_data(address, 0xC0, 0xA0)

data = bytearray()

#time.sleep(0.5)

#for x in range (1,50):
bus.write_byte(address, 0x00)
data = bus.read_i2c_block_data(address, 0x00)
#    print (data)
print (data[0])
print (data[1])
#time.sleep(0.5)
if((data[0] & 0x80) == 0x80):
    data[0] = data[0] &0x7F
    temp = 1024 - (data[0] * 16 + data[1]/16)
#    temp = (temp * 1.8)+32
    print (temp)
else:
    temp = data[0] * 16 + data[1] / 16
#    temp = (temp * 1.8)+32
    print (temp)

 

Best Regards

Hans

 

T

Hi Hans,

I will have to come up with some sort of test setup that will allow me to put the sensor into a negative temperature environment.  Currently I do not have a good way of doing that so the code has not been tested for negative temperatures.

I will have another look at the datasheet for the sensor to see if there are alterations needed to the equasion.  This code was actually pulled from another source and modified for Python so I did not origionally write the equasion to calculate temperature.

Thank you Hans

kandy's picture

Hi Travis

After an odyssey through the MCP9600 logic I finally came up with a code which I checked for temperatures as low as -23°C . To my understanding this codes holds true down to -32°C. For lower temps another "if"-block has to be inserted.

Would you be so kind to check the code snippet if it really worked... thank you.

I came across a problem with the i2C outward facing shield for my RPi 3. Connecting a cable to the shield sometimes produces a loose contact. The shield receptacle seems to be a bit to large for the cable connector. You can move the  connector in the receptacle from side to side... Maybe it is only my shield...

Hans

Here is my code snippet:

 

import smbus
import time

address = 0x64
bus = smbus.SMBus(1)

# Write to Thermocouple Sensor Configuration Register 05h , 00h
# Type K / Filter Coefficient  = 0
#bus.write_byte_data(address, 0x05 , 0x00)

# Write to Device Configuration Register 06h , A0h (10100000b 160d )
# Ambient Sensor Resolution 0.25C / ADC Resolution 16-bit / 1 Sample / ShutDown Mode Normal
bus.write_byte_data(address, 0x06 , 0xA0) 

# Open a byte array for temperature bytes pulled from register 0x00
data = bytearray()

# Pointer to Temp Register
bus.write_byte(address, 0x00)
# Read data starting at register 0x00
data = bus.read_i2c_block_data(address, 0x00)

# Check, if Temp is above 0 °C

if(data[0] &0x80 != 0x80):                  
    temp = (data[0]*16 + data[1]/16)        # calc the positive temp
    print ("Temperature %.2f °C" %temp)     # Temperature in °C
#    temp = (temp * 1.8)+32                  # Temperature in °F         

# Temp is below 0°C

    if(data[0] == 0xFE):                        # Check, if  -32°C =< Temp <16 °C
        data[0] = ~data[0] +1
        data[0] = data[0] & 10
        temp = (-data[0]*16 + data[1]/16)
        print ("Temperature %.2f °C" %temp)     # Temperature in °C


    if(data[0] == 0xFF):                        # -16°C =< Temp < 0°C
        data[0] = ~data[0] +1
        data[0] = data[0] & 1
        temp = (-data[0]*16+data[1]/16)         # calc the negative temp
        print ("Temperature %.2f °C" %temp)     # Temperature in °C
#        temp = (temp * 1.8)+32                   # Temperature in °F    import smbus

 

 

T

Hi Hans,

Unfortunately I do not currently have a way of testing the sensor in a sub zero temperature environment.  I will however test your code here and see what I come up with.

I will forward your comment on the loose I2C cable connection to our design engineers.  Personally I have never seen this be an issue and I do not remember any reports of this in the past.  Perhaps it is just the I2C cable you have.  Using a needle you can press the small metal fingers for each wire in the female connector on the cable to pull them out, you can then use the needle or small plyers to crimp the wires on the metal end in a bit which should help with a better connection, then insert that metal sleeve back in the plastic housing.

C

Travis,

Chould you just put the rtd into a freezer (kitchen type), it would be below zero C. Mine is normally -2 F.

Or put the rtd in a plastic bag and put the bag into ice cubes with salt (think ice cream freezer).

I don't have my module with me or I would try it.

 

Chuck

T

Hi Chuck,

We do have a freezer here in the office.  Ill see if I can rig the sensor up inside there.  Thanks for the suggestion Chuck!

kandy's picture

Hi Chuck, hi Travis,

I put the sensor first in icewater to see if the measured temp was at the expected 0 C (32 F). And it was. So the accuracy is fine. Thereafter I put the thermocouple into my freezer and compared the indicated temp with a second thermometer placed together in the freezer. Worked fine. I also checked the temp drop from positve to negative temps down to -23 C. Especially the changeovers from 0 C to negative temps and from -15.9 to below -16 C. There were no discontinuities in the indicated temps.

Hans