MOD-TC-MK2-31855 and Raspberry Pi

Started by defa, July 22, 2014, 01:01:51 PM

Previous topic - Next topic

defa

I need some help with using the MOD-TC-MK2-31855 on a Raspberry Pi. So far the the MOD-TC shows up on the I2C bus but I did not succeed in reading temperature values using the example software from https://github.com/OLIMEX/OLINUXINO/tree/master/SOFTWARE/A13/MOD-TC-MK2 - I had to path i2c.c to read from /dev/i2c-1 and changed the address of the I2C_Open/Send/Read commands in main.c from  0x48 to 0x23.

I connected the MOD-TC board to the Raspberry Pi Rev. B like this:

MOD-TC          Raspi
  1 --- 3.3 V --- 1
  2 ---  GND  --- 9
  5 ---  SCL  --- 5
  6 ---  SDA  --- 3


Inspecting the I2C bus with sudo i2cdetect -y 1 indicates that the MOD-TC is connected to address 0x23:


$ sudo i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --                         


Regarding the mod-tc-mk2 command compiled from the github repo (see link above), I not sure what kind of parameters I do have to pass. Executing the command to read the temperature results in the following error:


$ sudo ./mod-tc-mk2 -t 1
-1 of 3 bytes sended
Failed to send data: Input/output error


Looking at the source it seems that the open command does work but send fails with an I/O error.

Giving Python a try:

import smbus
import time
bus = smbus.SMBus(1)
address = 0x23

bus.write_byte(address, 0x01)
bus.write_byte(address, 0x00)
bus.write_byte(address, 0x21)


results in the following error (indicating that the first write seems to work):

$ sudo python i2c_mod_tc.py
Traceback (most recent call last):
  File "i2c_mod_tc.py", line 7, in <module>
    bus.write_byte(address, 0x00)
IOError: [Errno 5] Input/output error


There is a related thread on this form: https://www.olimex.com/forum/index.php?topic=2446 which claims that using the board with the Raspberry Pi is possible.

Any ideas what I'm doing wrong?

Thanks in advance, Stefan

martinayotte

#1
According to the piece of python code you provided, it seems that you try to send 3 differents I2C messages instead of a single one :
bus.write_byte(address, 0x01)
bus.write_byte(address, 0x00)
bus.write_byte(address, 0x21)

Although I'm not familiar with the MOD-TC-MK2, looking at the C code of the link, it should be a single message :
I2C_Send(&fd, in_buffer, 3);
I2C_Read(&fd, out_buffer, 4);

According to this older link https://www.olimex.com/Products/Modules/Sensors/MOD-TC-MK2-31855/resources/MOD-TC-MK2_firmware_OLinuXino_v2.zip, it is mentionned that the GET_TEMP can be retrieve at command line with "./i2c-tool -w 0 0x48 3 0x02 0xA0 0x21"
So, this will be translate in Python with similar to the following code :
bus.write_i2c_block_data(address, 0x02, [0xA0, 0x21])
# or if we keep original values :
# bus.write_i2c_block_data(address, 0x01, [0x00, 0x21])
results = bus.read_i2c_block_data(address, 0x00, 4)

But looking at the newer version https://www.olimex.com/Products/Modules/Sensors/MOD-TC-MK2-31855/resources/MOD-TC-MK2_firmware_OLinuXino_v3.zip, it seems that code should be a bit different :
bus.write_i2c_data(address, 0x00, 0x21)
results = bus.read_i2c_block_data(address, 0x00, 4)

Since I'm not sure about MOD-TC-MK2 registers mapping, maybe the register 0x00 is not needed, in such case, the request would be even simpler :
bus.write_i2c_data(address, 0x21)
results = bus.read_i2c_block_data(address, 0x00, 4)


In summary, don't try to send multiple I2C Writes, since the sensor getting confused. It must be a single message to send the GET_TEMP command, followed by the I2C Read.

Maybe you should try all examples above.

Hoping this help,




defa

#2
Thanks, martinayotte for the fast reply!

I'm not sure but I think those three bus.write_byte commands are equivalent to one bus.write_i2c_block_data with three bytes of data. I have tried what you suggested but it does not work:

import smbus
import time
bus = smbus.SMBus(1)
address = 0x23

bus.write_i2c_block_data(address, 0x01, [0x0a, 0x21])


$ sudo python i2c_mod_tc.py
Traceback (most recent call last):
  File "i2c_mod_tc.py", line 6, in <module>
    bus.write_i2c_block_data(address, 0x02, [0x0a, 0x21])
IOError: [Errno 5] Input/output error


I also compiled the i2c-tool and tried sending commands as you and the Olimex docu suggested, does not work either:


$ sudo ./i2c-tool -w 1 0x23 3 0x01 0x0A 0x21
SLAVE ADDRESS: 0x23
NUMBER OF BYTES TO WRITE: 3
MEMORY ALLOCATED AT ADDRESS: 0x1EC6008
/dev/i2c-1 OPENDED!
Failed writing to the I2C-bus: Input/output error


However I derived some Olimex's code available on Github [1] to use the wiringPi library and this seems to work. At least I don't get any I/O errors but the readings are a litte strange:


$ sudo ./mod-tc-read-temp
raw data (4 bytes): D0 9D B8 81
INTERNAL TEMPERATURE: -98.1875 C
EXTERNAL TEMPERATURE: -2020.50 C


This should be equivalent to:


sudo ./i2c-tool -w 1 0x23 3 0x01 0x01 0x21


My derived code can be found here: https://github.com/kreutter/MOD-TC-MK2-31855-RasPi

I will consult the firmware zip files for more information...

[1] https://github.com/OLIMEX/OLINUXINO/tree/master/SOFTWARE/A13/MOD-TC-MK2

martinayotte

Hi again Defa,

In your trials, you seems to have done some typo : you've changed the 0xA0 to 0x0A.
(In your original example, this byte was 0x00, which you also changed it to 0x01 in your last sources, and commented as "// what is the second parameter for?")

According to https://www.olimex.com/Products/Modules/Sensors/MOD-TC-MK2-31855/resources/MOD-TC-MK2_firmware_OLinuXino_v2.zip, this value seems to be some kind of sub-address used by Olimex in case there are 2 MOD board on the same I2C. Here is the notice from the README.pdf :

QuoteIMPORTANT NOTE: By default the address of the board is 0xA0. If this is the only device - you
could set new address without the use of the PROG jumper. If there are multiple devices on same
address put the jumper and reset the board. This will set the address to 0xF0. After that set the new
address and remove the jumper

You should probably continue trying with i2c-tool because clarifying any other code.

So, in the same section of README.pdf, it is said :

Quote
Address 0 – the address of all Olimex I2C devices - 0x48
Address 1 – the address of all MOD-TC-MK2 devices – 0x01
Address 2 – the individual address of specific MOD-TC-MK2 device.

If you want to read temperature use the following commands:
# ./i2c-tool -w 0 0x48 3 0x02 0xA0 0x21
# ./i2c-tool -r 4

BTW, in the above quote, I2C address seems to be 0x48 in their example, but yours is 0x23. I don't know why it is not the same, maybe they changed something between v2 and v3 firmware ...

For Python SMBus API, be careful : bus.write_byte() is to send only 1 byte, useful sometime when the devices only require 1 bytes. But for multiple bytes message, it is not equivalent to bus.write_i2c_block_data(), since multiple single byte messages with multiple acknowledges will be transfer for each bytes instead of only 1 multi-bytes message + 1 acknowledge.



BAStumm

#4
Default address is 0x48 for v2 firmware and 0x23 for v3 firmware.

To the original poster... our projects sound quite similar would you perhaps be interested in comparing notes? I have my system *mostly* working using a raspberry pi as the i2c master and the mod-tc-mk2 as i2c slave. My system has multiple zones of heat control.