kplindegaard / smbus2 Goto Github PK
View Code? Open in Web Editor NEWA drop-in replacement for smbus-cffi/smbus-python in pure Python
License: MIT License
A drop-in replacement for smbus-cffi/smbus-python in pure Python
License: MIT License
Hey there,
Looking forward to using this library. I ran the pip install and run one the basic examples to read a byte.
I get the following error:
Traceback (most recent call last):
File "test.py", line 6, in <module>
b = bus.read_byte_data(80,0)
File "/home/david/.local/lib/python3.7/site-packages/smbus2/smbus2.py", line 412, in read_byte_data
ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 6] No such device or address
which I believe is permission related as i2cdetect -l
returns:
sudo i2cdetect -l
i2c-3 smbus SMBus PIIX4 adapter port 3 at 0b00 SMBus adapter
i2c-10 i2c NVIDIA i2c adapter 7 at 41:00.0 I2C adapter
i2c-1 smbus SMBus PIIX4 adapter port 0 at 0b00 SMBus adapter
i2c-8 i2c NVIDIA i2c adapter 5 at 41:00.0 I2C adapter
i2c-6 i2c NVIDIA i2c adapter 1 at 41:00.0 I2C adapter
i2c-4 smbus SMBus PIIX4 adapter port 4 at 0b00 SMBus adapter
i2c-11 i2c NVIDIA i2c adapter 8 at 41:00.0 I2C adapter
i2c-2 smbus SMBus PIIX4 adapter port 2 at 0b00 SMBus adapter
i2c-0 i2c Synopsys DesignWare I2C adapter I2C adapter
i2c-9 i2c NVIDIA i2c adapter 6 at 41:00.0 I2C adapter
i2c-7 i2c NVIDIA i2c adapter 3 at 41:00.0 I2C adapter
i2c-5 smbus SMBus PIIX4 adapter port 1 at 0b20 SMBus adapter
I took it out of virtualenv but still get an error. Any suggestions?
i just did
sudo python3 setup.py install
then when i try :
from smbus2 import SMBus, ic_msg
it give me an error like that..
`ImportError Traceback (most recent call last)
in
----> 1 from smbus2 import SMBus, ic_msg
2 import pydoc
ImportError: cannot import name 'ic_msg'`
Hello! Please tell me, I don't understand.
how to read/write devices with 10-bit address.
is it possible to do with this project?
Hello,
This is more of a thank you than an actual issue. I could not get the Motor Bridge Cape to work with the other i2c python3 installs and I figured out how to make it work with your library.
So, thank you.
Seth
P.S. I am making a couple of posts about it in case it helps anyone else. You can find them at https://www.hackster.io/functt/small-bots-motor-s-and-the-motor-bridge-cape-w-bbgw-f90acf and https://github.com/silver2row/MotorBridge/blob/master/MotorBridgeI.py. Thank you, again. Oh and the second link is a work in progress right now.
I think it's OK to use C + + language? , how can I use it? Do you have a reference code?
Hi,
I am just wondering why you have added the SMBusWrapper class instead of extending the SmBus class itself by enter/exit handlers?
For me it looks rather unnecessary but maybe I just don't get it.
P.S. Great python library! It just works ... and the only working i2c_rdwr implementation I've found.
How to change i2c baudrate to 50khz on rasberry pi 3B?
I try https://gist.github.com/ribasco/c22ab6b791e681800df47dd0a46c7c3a
but Signal always display 100khz
Hello,
First I would like to thank Karl-Petter for a great I2C driver. With it I was able to read the block data from my sensor. No other code worked. Again KUDOs.
For my sensor I need to read signed bytes and words. Also I need to be able to specify endianness. I could (or at least think I can) modify your code to add signed reads/writes. I would, however prefer not to modify your code for my application. If there is a way for me to modify the Git hub code, I would not as my coding capability is marginal. Is there any plan to add signed functions?
Thanks
BR
JohnRobert
BTW I could not find how to identify the entry as a request, not a bug.....sorry.
Hi,
I have a question about creating several instances of an SMBus
object.
I have a system that uses several sensors that communicate over I2C.
I noticed that the library for each of them creates its own instance of SMBus
in __init__
.
Example:
class Sensor1:
def __init__(self):
self.bus = SMBus(1)
class Sensor2:
def __init__(self):
self.bus = SMBus(1)
Can I have two SMBus
objects? They will not impact each other?
Additionally, I noticed that often the connection in such libraries is not closed (method close
in not invoked).
How might this affect the application?
Wouldn't it be a better idea to pass the SMBus
instance to the __init__
and manage it outside of a class?
class SmBusWrapper:
def __init__(self):
self.bus = SMBus(1)
def __del__(self):
self.bus.close()
class Sensor1:
def __init__(self, smbus: SMBus):
self.bus = smbus
class Sensor2:
def __init__(self, smbus: SMBus):
self.bus = smbus
Thanks for answers :) !
I need help understanding a response I'm getting from read_i2c_block_data(). I'm using I2C bus on RPI.
When I block read certain offset from the device, read_i2c_block_data() gets the following content of msg.data.contents.block:
0f 0d 05 50 00 36 00 34 00 03 80 00 01 00 03 c5 00
^length ^PEC
The smbus2 library cuts the first byte, and gives my python code 13 bytes, as this is the size my script requested. So my script receives:
0d 05 50 00 36 00 34 00 03 80 00 01 00
In other word, I don't receive the last byte of data (03
), and instead I receive the size byte (0d
).
In order to receive the whole message, I need to actually read 14 bytes, and remove the length from my script. Which is unnecessary, but not that bad until I get to 32-byte block. For 32-byte one, there is no way for me to retrieve the last byte.
So the smbus2 library effectively allows me to retrieve message of max 31 bytes.
Where is the issue? Is the library implementation flawed? or is it unexpected that the buffer contains the 0f
at start?
Hi, trying to install smbus2 on a rPi2, because something else I am trying to install(!) may have a dependency on it, but smbus2 install fails:
sudo python setup.py install
error in smbus2 setup command: 'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.
I had a look in setup.py and it says:
extras_require={
'docs': [
'sphinx >= 1.5.3'
],
'qa': [
'flake8'
],
'test': test_deps
}
But I have no idea how to fix it.
Please help.
Is it possible to read 4 bytes without defining the offset register?
Working example in Micropython:
from machine import Pin, I2C
i2c = I2C (scl=Pin (18), sda=Pin (19), freq=100000)
data = i2c.readfrom (slave_addr, 4)
Since 2018 PyPI has supported markdown format for long_description
. To enable this, you have to add
long_description_content_type="text/markdown"
to your setup function in setup.py
. This might allow you to keep only one copy of your README.
Dear @kplindegaard,
Thank you for all your effort and your very nice smbus2 interface for python, which will hopefully help me with my problem to interface a 3d magnetic field amr sensor. Unfortunately, I don't really know, whether it is possible to use your package to solve my problem. Is smbus2 using i2c_rdwr able to distinguish between first and repeated starts? Sorry, but I didn't really get this from your documentation / examples and I hope that you could just give me a hint, how I can get the sensor running. I already opened a discussion showing my C code I want to port to python on stack overflow:
I really would appreciate if someone could help me. Thank you in advance.
Kind regards!
I am writing a module for a Lidar device that uses the I2C interface. I wrote my module importing the 'smbus' module. But when I created a distributable package that included the 'smbus' module as a requirement, it failed to install 'smbus' with about twenty lines of serious looking red text that began: ERROR: Command errored out with exit status 1:
etc.
Intimidated by this message, I rewrote my module to use 'smbus2' instead. 'smbus2' installed without error, but when I tried to import 'smbus2' (or 'SMBus' from 'smbus2'), I got this:
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from smbus2 import SMBus
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Bud Ryerson\Desktop\package\myve\lib\site-packages\smbus2\__init__.py", line 23, in <module>
from .smbus2 import SMBus, i2c_msg, I2cFunc # noqa: F401
File "C:\Users\Bud Ryerson\Desktop\package\myve\lib\site-packages\smbus2\smbus2.py", line 25, in <module>
from fcntl import ioctl
ModuleNotFoundError: No module named 'fcntl'
It seems that 'smbus2' cannot find 'fcntl' or maybe 'ioctl'. Now it seems that I can't use 'smbus' and I can't use 'smbus2' either. This is very frustrating. Any advice would be appreciated.
Bud Ryerson
San Francisco
hi how can i list avaible i2c adresses in python code
Hi ๐, loving your package.
I'm a conda-forge user that relies upon smbus2, so I'm intending to create a conda-forge feedstock. This will allow users to consume smbus2 via anaconda cloud.
I want to invite you to become feedstock maintainers for smbus2 on conda-forge---just let me know. If you aren't interested I'm comfortable maintaining this feedstock myself.
https://github.com/conda-forge/smbus2-feedstock
https://anaconda.org/conda-forge/smbus2
I'm not entirely certain the reason for the I2C_SMBUS_BLOCK_MAX being 32 bytes and curious if I could investigate how to modify this. If you have suggestions of what requires this hard limit please let me know. I have some time to investigate. Currently trying to emulate an i2C touch screen that results in reads well over 32 bytes
thanks
Is there a way to gracefully handle this in a program?
This happens very rarely in my code, but when it does, it exits a long running test.
Traceback (most recent call last):
File "battery_test.py", line 89, in <module>
remaining = bus.read_byte_data(0x0b, 0x0d)
File "/usr/local/lib/python3.7/site-packages/smbus2/smbus2.py", line 355, in read_byte_data
ioctl(self.fd, I2C_SMBUS, msg)
OSError: [Errno 121] Remote I/O error
Would be nice to have online sphinx (api) documentation on readthedocs that can be linked to using intersphinx.
Good Morning,
I am trying to preform a function call, as described in the doc https://www.pozyx.io/Documentation/Datasheet/Interfaces but am not able to get it to work. I am using th PI platform, and had to turn on "combined" mode, by setting the file to Y sudo nano /sys/module/i2c_bcm2708/parameters/combined and that makes the reads work as expected. Do you have any tips how to make this function call using the library.
Thank you!
Peter
This is likely to be my problem that I need help with. I'm using this i2c joysticks:
http://www.grayhill.com/assets/1/7/67a_i2c_user_manual_1.2.pdf
It requires reading 2 bytes simultaniously; there is no register used. Python SMBus doesn't support this function, hence I'm trying your SMBus2. Of the four options I've tried, only the first works (a bit but only one byte), the rest either get exceptions or return all zeros. Any suggestions please?
` with SMBusWrapper(1) as bus:
bus.write_byte_data(0x40, 0x76, 2)
bus.write_byte_data(0x41, 0x76, 2)
while True:
time.sleep(0.5)
# data = bus.read_byte(0x40)
# data = bus.read_byte_data(0x40, 0)
# data = bus.read_word_data(0x40, 0)
data = list(i2c_msg.read(0x40, 2))
# data = bus.read_i2c_block_data(0x40, 0, 2)
assert (len(data) == 2), "Joystick 0 data len: %d" % len(data)
print "0x40: ",
print data,`
It would be nice to support named devices for USB-I2C adapters such as tiny-i2c-usb because their bus number will not be consistent between restarts. However, we can create symlinks using udev. Currently, I just symlink to /dev/i2c-my-bus1 and use "my-bus1" as bus id in smbus2. Works as a hack but it is probably not intended this way.
SMBus Quick Command
This sends a single bit to the device, at the place of the Rd/Wr bit.
A Addr Rd/Wr [A] P
Functionality flag: I2C_FUNC_SMBUS_QUICK
from https://www.kernel.org/doc/Documentation/i2c/smbus-protocol
Hi,
I've been using your library for a while on a Pi talking to four Arduino's over I2C.
Usually(โข) things go fine, but from time to time the whole bus seems to get messed up and no writes/reads are succeeding any more.
My program fires off a thread which basically has a while True
loop in which it reads/writes from/to i2c whenever instructed to. This often results in up to four read/write instructions per second during one hour.
How would you suggest to use SMBusWrapper in this scenario?
I am currently wrapping the with
statement inside the loop, but cold also run the loop inside the with
, I suppose. Then I don't open/close a the bus four times per second.
Would this make any difference, in your opinion?
Thanks a lot!
Here is a link do an image taken from spec of a device which uses SMBus communication (BQ series chip from TI).
o-gs/dji-firmware-tools#17 (comment)
Note that the use of specific function of the device (read firmware version) requires to write block_data with size=62.
(actual data is never sent, as the device responds with NACK on the size)
Currently, the smbus2 implementation will prevent sending such packet, making it impossible to use this functionality of the BQ series chips.
The restriction should be lifted, or another lower level API should be prepared.
Since KMD supports currently only SMBus 2.0, and the message length is restricted even more by length being included in the bytes limit, I had to implement SMBus using I2C commands.
Maybe smbus2 itself should include such implementation? There could be a selection option on whether messages should be constructed by kernel or by python. I'd call it 'engine' selection, or 'api' selection.. not sure what's the best name.
This would also allow support of other 'engines' in the future - for example, for USB-to-I2C bridges, which typically are visible as USB HID device, there is a library smbusb. That library can also be used on Windows.
I might work on Python bindings for it in the future.
So available 'engines' may depend on OS - the list should be dynamic.
I am trying to install smbus2-0.2.1 on a Pocketbeagle running Debian v9.5. While I do not have an internet connection, I've utilized WinSCP to get the appropriate wheels and tar files over to the beagle to install pip v18.1 and setuptools v40.6.3. However, upon trying to install smbus2-0.2.1, I get the following error:
debian@beaglebone:/var/lib/cloud9$ pip install smbus2-0.2.1.tar
Processing ./smbus2-0.2.1.tar
Complete output from command python setup.py egg_info:
error in smbus2 setup command: 'extras_require' must be a dictionary whose values are strings or lists of strings containing valid project/version requirement specifiers.
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-req-build-f0O3p9/
Per a previous bug report (#21 ), I tried untarring smbus2-0.2.1 and commenting out the "extras_require" lines. Upon running setup.py, I got the following:
debian@beaglebone:/var/lib/cloud9/smbus2-0.2.1$ python setup.py
Traceback (most recent call last):
File "setup.py", line 63, in <module>
"Programming Language :: Python :: 3.6"
File "/usr/lib/python2.7/distutils/core.py", line 111, in setup
_setup_distribution = dist = klass(attrs)
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/setuptools/dist.py", line 225, in __init__
_Distribution.__init__(self,attrs)
File "/usr/lib/python2.7/distutils/dist.py", line 287, in __init__
self.finalize_options()
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/setuptools/dist.py", line 257, in finalize_options
ep.require(installer=self.fetch_build_egg)
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/pkg_resources.py", line 2072, in require
working_set.resolve(self.dist.requires(self.extras),env,installer))
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/pkg_resources.py", line 2282, in requires
dm = self._dep_map
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/pkg_resources.py", line 2511, in _dep_map
self.__dep_map = self._compute_dependencies()
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/pkg_resources.py", line 2544, in _compute_dependencies
common = frozenset(reqs_for_extra(None))
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/pkg_resources.py", line 2541, in reqs_for_extra
if req.marker_fn(override={'extra':extra}):
File "/usr/local/lib/python2.7/dist-packages/distribute-0.6.45-py2.7.egg/_markerlib/markers.py", line 109, in marker_fn
return eval(compiled_marker, environment)
File "<environment marker>", line 1, in <module>
NameError: name 'sys_platform' is not defined
I'm not sure where to go at this point. Previous solutions were based on upgrading the version of setuptools that was available, but I have the most up-to-date version, so that's out. Any thoughts?
Hi!
I'm trying to do a simple read using i2c_rdwr
, In a Raspeberry pi 3 with Raspbian stretch but I get this error:
Traceback (most recent call last):
File "i2c_test.py", line 8, in <module>
i2cbus.i2c_rdwr(read)
File "/home/pi/.local/lib/python3.5/site-packages/smbus2/smbus2.py", line 658, in i2c_rdwr
ioctl(self.fd, I2C_RDWR, ioctl_data)
OSError: [Errno 5] Input/output error
I checked the I2C_FUNC_I2C
capabilities and they should be OK
This is a minmal example that reproduces the problem:
from smbus2 import SMBus, i2c_msg, I2cFunc
i2cbus = SMBus(1) # Create a new I2C bus
i2caddress = 0x40
if (i2cbus._get_funcs() & I2cFunc.I2C):
read = i2c_msg.read(i2caddress, 9)
i2cbus.i2c_rdwr(read)
data = list(read)
print(data)
else:
#from https://www.kernel.org/doc/html/latest/i2c/dev-interface.html#full-interface-description
print("The i2c adapter doesn't support RDWR")
Any ideas?
Thanks in advance
Trying to switch monitor inputs. I can accomplish this using ddccontrol
or ddcutil
on ubuntu linux.
For example: ddccontrol -r 0x60 -w 18 dev:/dev/i2c-4
This will change my monitor's input.
I have the following python code:
from smbus2 import SMBus, i2c_msg
with SMBus(4) as bus:
message = i2c_msg.write(0x60, [0x12])
bus.i2c_rdwr(message)
But I receive the following error:
Traceback (most recent call last):
File "/home/jjshoe/buttons!/switch.py", line 5, in <module>
bus.i2c_rdwr(message)
File "/usr/local/lib/python3.10/dist-packages/smbus2/smbus2.py", line 658, in i2c_rdwr
ioctl(self.fd, I2C_RDWR, ioctl_data)
OSError: [Errno 5] Input/output error
Thoughts on what I'm doing wrong?
Working on an Ubuntu system using the following
and encountered a weird error. When using SMBus or SMBusWrapper, for the first couple of reads, I get the following OSError exception:
[Errno 6] No such device or address
But after a half second or so, the reads begin to succeed. I've used the command-line python to try and reproduce but I am getting mixed results: some success, some failures.
Example code below (should reproduce it):
def main():
nowork = True
bust = smbus2.SMBus(8)
while(nowork):
try:
temperature = bust.read_word_data(0xb, 0x8)
nowork = False
except OSError as ex:
print("fail %s" % str(ex))
except:
print("fails")
if __name__ == "__main__":
main()
By sticking it in a retry loop until successful, I'm able to bypass it, but it doesn't feel like a clean solution to me. Any suggestions?
This is not a bug in smbus2, rather looking for some help figuring out how the I2C bus ordinal is mapped to physical I2C busses.
I have a Intel master device, the SEEDStudio Odyssey motherboard, it appears to have 8 busses according to sudo i2cdetect . Three of these are attached to a 'Synopsys DesignWare I2C adapter' and of these three, two are exposed on a 40 pin RPI compatible GPIO connector. The pins these two busses are attached to are fixed and defined.
However, on each boot, the I2C channel number used by smbus2 and other I2C api software seems to randomly change.
I am wondering if someone has found a way to drill down through Linux /sys or /dev or ??? and figure out what pins are mapped to what I2C channel?
I have seen similar behavior in Linux RAID drivers, where the /dev/mdmXXX device id number changes on boot based on how fast the drives come on line in each RAID unit.
The problem in this particular motherboard may be exacerbated by the fact the BIOS does not assign a unique 'name' to each of the I2C busses managed by the 'Synopsys DesignWare I2C adapter' , all three report they name as 'Synopsys DesignWare I2C adapter', it seems other implementations add some unique identifier into the name :
user@ODYSSEY-X86J4125:~$ sudo i2cdetect -l
i2c-3 smbus SMBus I801 adapter at f040 SMBus adapter
i2c-1 i2c Synopsys DesignWare I2C adapter I2C adapter
i2c-6 i2c i915 gmbus misc I2C adapter
i2c-4 i2c i915 gmbus dpb I2C adapter
i2c-2 i2c Synopsys DesignWare I2C adapter I2C adapter
i2c-0 i2c Synopsys DesignWare I2C adapter I2C adapter
i2c-7 i2c AUX C/port C I2C adapter
i2c-5 i2c i915 gmbus dpc I2C adapter
Thank you for your work on this project, very helpful. And any insight you might have on this question.
Will this work with python3.5? Many thanks
Hello :)
I would love to see FreeBSD support in smbus2 so Python i2c stuff would be easier in FreeBSD.
Before I do too much I wanted to ask if you are interested in accepting a PR for FreeBSD support (if I get that far)?
I've dug up https://github.com/freebsd/freebsd-src/blob/main/sys/dev/iicbus/iic.h which is used by https://github.com/freebsd/freebsd-src/blob/098dbd7ff7f3da9dda03802cdb2d8755f816eada/usr.sbin/i2c/i2c.c - the latter works well for communicating with i2c devices from the console. So I think the basics are in place.
I am not sure how to continue from here though, any pointers would be much appreciated! My ultimate goal is getting FreeBSD support in the Qwiic_py package for SparkFuns QWIIC ecosystem of sensors.
Thank you! ๐
I use i2c to connect rpi and arduino . I check the data i sent to arduino in Serial Monitor if i sent a array by write_block_data() function , arduino receive start register + length + array .
I want to know how to use read_block_data() to read the data returned by arduino .
I tried these days , rpi always receive a empty list and arduino Wire.write() only send back a byte data how can i combine these two function together.
The spec describes a send byte command. It is a single byte write with no register in the data. See
http://smbus.org/specs/SMBus_3_0_20141220.pdf, page 39, section 6.5.2
Hello,
I just cloned the repo today and I used the command "python setup.py install" and then it told me "traceback, file "setup.py" line 1 in from setuptools import setup ImportError: no module named setuptools".
I am new to using python and I am new to GitHub as well so it might be possible I just missed something. But I desperately need your nice i2c block write/read routines and I would be really glad if you could point me to the right direction.
Thanks in advance!
Kind regards
Susanne
Hi,
I'm trying to get a sensor to work with requires smbus2 but includes the line:
from smbus2 import SMBusWrapper, which I think not longer exists as a class in smbus2 (as far as I can tell). This short thread (above) suggests that it was removed and replaced by extension of SMBus. The section causing issues (in a script called sgp30.py) has the following line:
with SMBusWrapper(1) as bus:
Is there a simple change I can make to the scripts that call smbus2 and here that will allow reading of the i2c port on a grove HAT / sgp30 CO2 sensor.
thanks!
Hi! I'm trying to get the adapter capabilities, like stated in the README:
Thanks!
Hi can you help me how should I compose a write_i2c_block_data in order to execute a commands shown here:
https://ibb.co/GWZjSqq
The problem I find is the array of data I want to send. For example with high alert clear I wrote:
bus.write_i2c_block_data(0x44, 0x61,[0x16,0xC9,0x2D,0x93]) - that unfortunately throws an error:
IOError: [Errno 121] Remote I/O error
I based my code on https://github.com/ControlEverythingCommunity/SHT30/blob/master/Python/SHT30.py where command header for reading temerpature is "0x2C06" and the whole command looks like this: bus.write_i2c_block_data(0x44, 0x2C, [0x06])
But as shwn it does not work. The paper on the commands you fill find here: https://www.mouser.com/pdfDocs/Sensirion_Humidity_Sensors_SHT3x_Application_Note_Alert_Mode_DIS.pdf (table.2)
We use smbus2 in the Mission Pinball Framework (https://github.com/missionpinball/mpf/). However, MPF is an asyncio application and most operations will block for a while. It certainly works because I2C is fast but we would like to keep latency down in the app. I looked into non-blocking mode for the smbus interface and i2c on Linux in general but i looks like that either does not work or nobody uses it. So we can probably not use select (or epoll) via the asyncio loop. Let me know if you thing that this would work.
However, I would like to have an asyncio smbus implementation anyway. Would you be up to merge a change where all ioctls would happen in an executor (a separate thread in asyncio) which synchronizes via two queues? That way the asyncio app would not have to block when performing operations and the library would only require minimal changes. What do you think?
I am attempting to do the following with a Raspberry pi zero w:
start condition
address+write bit
write byte
start condition
address+read bit
read byte
read byte
read byte
stop condition
Can you suggest the right combination of calls using the smbus2 library?
I am successfully talking on the bus. I can see with my logic analyzer the device ACK. I have failed thus far to figure out how to do the write one byte, send another start then a read command then read the 3 bytes. I can do all kinds of other communication just fine using the smbus2 library. Thanks in advance for any help that could be provided.
SMBus spec 2.0:
5.5.7. Block write/read
[...] The byte count does not include the PEC byte. The byte count may not be 0. A Block Read or Write is allowed to transfer a maximum of 32 data bytes.
The Figure 5-17 below defines "Byte Count" separately from "Data Byte" fields - so count is not included in the limit.
Smbus spec 3.1:
6.5.7 Block Write/Read
[...] The byte count does not include the PEC byte. The byte count may be 0. A Block Read or Block Write is allowed to transfer a maximum of 255 data bytes.
The Figure 35 below defines "Byte Count" separately from "Data Byte" fields - so count is not included in the limit.
I2C spec rev. 6 - 4 April 2014:
I2C does not impose any restrictions on message length, other than stating that "I2C transmissions are sequences of 8-bit bytes".
Q: Is this library intended to meet SMBus 2.0 spec, or the latest one?
I'm trying to connect my energy measurement IC with Raspberry Pi 3B using the I2C protocol. I'm using sudo i2cdetect -y 1
to detect the connected devices and it is correctly showing the address(7-bits) of the connected IC. The IC contains various registers of 8,16,24 and 32-bits. The register addresses are 16-bits long and I'm using the following code to access a register 0x021C(24-bits)
and write registers 0xFE(8-bit) and 0x0120(16-bit)
.
Python Code
from smbus2 import SMBus
bus = SMBus(1)
address = 0x38
bus.write_byte_data(address,0xFE,0xAD) #Writing single byte of data
bus.write_i2c_block_data(address,0x120,[0x00,0x30]) #Writing multiple bytes of data to the register
block = bus.read_i2c_block_data(address,0x21C,3) #Reading multiple bytes of data from the register
print(block)
bus.close()
The output should be[0x8D,0xXX,0xXX]
but the code is producing output as [0,0,0]
Hi,
I can read from an EEPROM with following snippet successfully:
with SMBusWrapper(1) as bus:
bus.write_byte_data(0x55, 0x0, 0x0) # set address to beginning of eeprom
bus= i2c_msg.read(0x55, 4) # read 4 bytes
bus.i2c_rdwr(read)
but writing with i2c_msg doesn't work at all
with SMBusWrapper(1) as bus:
bus.write_byte_data(0x55, 0x0, 0x0) # set address to beginning of eeprom
write = i2c_msg.write(0x55, [0xff, 0x0, 0xff, 0x0])
bus.i2c_rdwr(write)
..writing bytes with this does work:
bus.write_i2c_block_data(0x55, 0x00, [0x00, 0xff, 0x0, 0xff, 0x0])
Thank you for developing smbus2
At the moment only the source tarball is published to PyPI but it would be nice if a wheel was also published.
I am reading data from a IST8308 IMU sensor with this script on a Linux Arm64 board:
import smbus2
i2c_bus = smbus2.SMBus(2)
i2c_magnetometer_register = 12
# initialize magnetometer
i2c_bus.write_byte_data(i2c_magnetometer_register, 32, 0) # action register
i2c_bus.write_byte_data(i2c_magnetometer_register, 50, 1) # control register 3
i2c_bus.write_byte_data(i2c_magnetometer_register, 49, 4) # control register 2
# read values
dataxl = i2c_bus.read_byte_data(i2c_magnetometer_register, 17)
dataxh = i2c_bus.read_byte_data(i2c_magnetometer_register, 18)
datax = uint_to_int((dataxh << 8) + dataxl)
# same for Y and Z
the read_byte_data()
function is very slow (in particular, the builtin ioctl()
call in read_byte_data()
). Is it a sensor problem, or a smbus2 problem?
This does not work properly in Python 3.x in version 0.2.2 and earlier
from smbus2 import i2c_msg
address = 80
msg1 = i2c_msg.write(address, 'ABC\xff') # Notice value 0xFF (255) as last value
msg2 = i2c_msg.write(address, [65, 66, 67, 255]) # Same same, just using list instead
msg1.len == msg2.len # False in Python 3.x !!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.