-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I use a generic I2C sensor? #782
Comments
The ev3dev-lang-python classes are for LEGO-specific devices. The best way to use generic device is to put the port in |
Thanks very much for your help. I don't (yet) have meaningful data coming back from the sensor, but there's many possible reasons for that. Do you have a good reference / examples for smbus? There seem to be several similarly named libraries, and I'm not sure that I'm looking at the right documentation! |
I think there might be a few examples in some of the issues at https://github.com/ev3dev/ev3dev/issues I don't think there are proper docs for the library, but is is basically a Python wrapper around https://www.kernel.org/doc/html/latest/i2c/smbus-protocol.html |
Thanks for the assistance. I had some hardware issues, that are now resolved, but I now get the following error.
Relevant section of code:
WIthout going too deep into I2C protocol, I belive this is because the slave (Wii Motion Plus) doesn't acknowledge the first I2C transaction, and the SMBus library concludes there's nothing there. Is there a way to either tell SMBus to ignore this, or a lower-level way to just push bytes onto the I2C bus? I found https://www.kernel.org/doc/html/latest/i2c/i2c-protocol.html which looks like it might do it, but I don't know if there's a way to access it from Python. I also don't know what it means by 'setting these flags for I2C messages'. |
Do you have docs on what the wii motion plus expects? For most devices I've worked with, the |
Official docs? No, I doubt Nintendo released them. There's reverse-engineered stuff online, though: The odd thing about the WMP is that (according to everything I've read) you need to do an initial write of 0xFE 0x04 to I2C address 0xA6 (or 0x53, depending on how you like your I2C addresses shifted) but all subsequent accesses are to I2C address 0xA4 (/0x52) I do have a working NXT setup, which I dug out and had a look at with an oscilloscope. I was surprised at what I saw. The NXT code was supposed to do what I've described above, but the scope showed that the initial write to 0x53 was terminated when the address was NACK'd, so the bytes 0xFE, 0x04 never make it onto the bus. Despite this, the WMP responds to the subsequent accesses to I2C address 0x52, and sends back valid data. The EV3, for comparison, does the same write to 0x53, also NACK'd, and aborted, but the driver error stops the code continuing. One more thing perhaps worth mentioning is that if I run my code with nothing plugged in to the sensor port, it runs happily, just returning 0x00 for all data bytes. The difference is, presumably, that with nothing plugged in, there's no pullup on SDA, and the I2C controller/driver sees SDA 'low' as an ACK, and so carries on. I realise that failure to ACK the 0x53 write is the WMPs fault, but it seems as though if I could just persaude the driver to ignore this, I might be able to get it to work. Apologies for the long post, but does anyone know how to get lower-level access to the I2C, to persuade it to ignore the NACK? |
So for the first command, wouldn't it be this? bus.write_byte_data(address, 0xFE, 0x04) |
Yes, it would. Sorry, that was the first thing I tried, I then went through lots of different variations, but they all do the same thing, i.e. fail with |
If I'm reading right, it looks like the NXT just writes the 0x53 without the 0xFE, 0x04 data. If that is the case, perhaps the quick write method could be used to just send the 0x53 address. |
You are reading correctly. (Though to be clear, the NXT code is supposed to be writing the 0xFE, 0x04. I assume the write is terminated because of the NACK) Yes, I've tried using the quick write method. Same result, |
Does the data still go over the bus though? You can catch this error and ignore it and then try the next commands at the second address. |
Apologies for the extremely slow response. I eventually gave up on this, so I'm not really asking for any more help, but thought I should perhaps describe what I tried. I used the try-except as suggested, so my code looked like this:
This worked, in that it kept running, and kept putting data on the bus, but I nerver saw a response from the WMP. There are some scope captures below, As far as I can tell, it looks like it should. I eventually managed to break my NXT interface too, so maybe it was always the hardware interface all along. |
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii micropython-ev 2.1.0 all Python language bindings for ev3d
ii python3-ev3dev 1.2.0 all Python language bindings for ev3d
ii python3-ev3dev 2.1.0 all Python language bindings for ev3d
I'm trying to use a generic I2C sensor with my EV3, specifically, a Nintendo Wii Motion Plus (https://en.wikipedia.org/wiki/Wii_MotionPlus) I used this sensor with my NXT a couple of years ago, so I think my hardware interface should be OK.
What is the best way to do 'raw' i2c writes and reads?
I tried using the Sensor class, but it can't seem to find my sensor.
Code:
Output:
The text was updated successfully, but these errors were encountered: