kizniche / Mycodo

An environmental monitoring and regulation system
http://kylegabriel.com/projects/
GNU General Public License v3.0
2.97k stars 495 forks source link

AM2315 I2C Multiplexer #465

Closed RynFlutsch closed 6 years ago

RynFlutsch commented 6 years ago

Hello Updated from 5.7.3 to 6.0.x Now my Am2315 is not working. Wired directly to Raspi 3 without any Multiplexer. scl and sda 0 I2c detect shows no device. How to add multiple Sensors with static adress now?

kizniche commented 6 years ago

Please provide your specific version

kizniche commented 6 years ago

This is probably a duplicate of #459 that was already fixed

kizniche commented 6 years ago

Actually, if i2c-detect doesn't see it, it's not a Mycodo issue

kizniche commented 6 years ago

You'll need to figure out why it's not being detected. Ensure I2C is enabled and it's wired properly. If it's an OS issue, try reinstalling Raspbian.

RynFlutsch commented 6 years ago

Hey Kyle, 6.0.9. Deleted the Data-input and created new one, working. What is with multiple Sensors with static address ?

kizniche commented 6 years ago

Good to hear. What do you mean by multiple sensors with static address?

RynFlutsch commented 6 years ago

Can i add now 3x am2315 without multiplexer to my pi3? I thought these sensors have all the same address and that is a problem. Static, i can‘t change them?

kizniche commented 6 years ago

The I2C address of the AM2315 can't be changed, so if you want to use more than one at the same time, you'll need an I2C multiplexer.

kizniche commented 6 years ago

See the I2C Multiplexers section of the manual for how to set up the multiplexers in version 6.x

RynFlutsch commented 6 years ago

Ok great

Theoi-Meteoroi commented 6 years ago

@RynFlutsch Let me know if you need assistance with using the mux overlay I created. You can get a small breakout board from several sources on ebay and elsewhere for the pca9548. Be sure to use 3.3v and not 5V for the chip supply.

kizniche commented 6 years ago

@Theoi-Meteoroi Do you have any idea about the issue in #489?

Also, I've been trying to port the arduino I2C code to read the K30, to python3, without success. Are you familiar enough to take a glance and see if there are any glaring issues with my code?

Arduino code: http://www.co2meters.com/Documentation/AppNotes/AN102-K30-Sensor-Arduino-I2C.pdf

My Code:

# coding=utf-8
# From http://www.co2meters.com/Documentation/AppNotes/AN102-K30-Sensor-Arduino-I2C.pdf
# Port to python3 attempt
import logging
import time

import smbus

logger = logging.getLogger("k30")

i2c_address = 0x68
i2c_bus = 1
i2c = smbus.SMBus(i2c_bus)

# Write bytes
i2c.write_byte(i2c_address, 0x22)
i2c.write_byte(i2c_address, 0x00)
i2c.write_byte(i2c_address, 0x08)
i2c.write_byte(i2c_address, 0x2A)
time.sleep(0.01)
# Read 4 bytes
buf = []
for i in range(4):
    buf[i] = i2c.read_byte(i2c_address)

logger.error("TEST00: {}".format(buf))

# Calculate co2
co2 = 0
co2 |= buf[1] & 0xFF
co2 = co2 << 8
co2 |= buf[2] & 0xFF

logger.error("TEST01: {}".format(co2))

# Calculate checksum
sum = buf[0] + buf[1] + buf[2]
if sum == buf[3]:
    logger.error("TEST02: Checksum good")
else:
    logger.error("TEST02: Checksum bad: {}, {}".format(sum, buf[3]))

if co2 > 0:
    logger.error("TEST03: Checksum good")
else:
    logger.error("TEST03: Checksum bad: co2: {}".format(co2))

logger.error("TEST04: co2: {}".format(co2))

The errors I'm getting are either:

Traceback (most recent call last):
  File "./test_k30_i2c.py", line 14, in <module>
    i2c.write_byte(i2c_address, 0x22)
OSError: [Errno 121] Remote I/O error

or:

Traceback (most recent call last):
  File "./test_k30_i2c.py", line 24, in <module>
    buf[i] = i2c.read_byte(i2c_address)
OSError: [Errno 121] Remote I/O error

Just thought I'd ask since you've helped debug some sensor issues in the past. The sensor is detected with i2cdetect, BTW.

kizniche commented 6 years ago

Just for reference, the K30 literature is at https://www.co2meter.com/collections/0-1-co2/products/k-30-co2-sensor-module and the I2C comm guide is at http://co2meters.com/Documentation/Other/SenseAirCommGuide.zip

Don't take this as me being pushy, just sharing what I've been rooting through to try to figure this out.

Theoi-Meteoroi commented 6 years ago

Howdy @kizniche I'll take a look and see if I can help. The K30 was one I looked at but never obtained a sample to test. I found the manufacturer WINSEN was eager to help and interact and I could get the pricing in small quantaties of their NDIR sensors at about half or less of the typical sources. I just looked to see what a K30 would cost. Like the reverend said. Still too damned high. But I like the challlenge of getting something working :).

I'm looking at the published protocol specs and notice a possible first problem. Default I2C address is 0x68, which happens to collide with most Pi RTC hardware. From your error code, the first write fails ( the command code ) and so the second error is expected (empty buffer). I have yet to reconcile the example code you show with the specs from the mfgr. There is some mention about EEPROM where defaults can be changed, but that is some other thread.

I'm starting with this:
Reading-CO2-K30.pdf

It sorta looks like the command string is not quite correct. They seem to indicate the first byte is a function code and it isn't 0x22. The truth is the document is very sketchy about the protocol, so I'll have to look elsewhere in their docs.

Nope. Not pushy. You are a pleasure to work with.

Theoi-Meteoroi commented 6 years ago

I've been thinking about creating a Pi HAT with the muxes built in with some other supporting hardware to make building a Mycodo less about struggling with getting reliable wiring. With the newest Pi, power quality is becomming an issue and the platform itself uses more power so the 2 amp @5v wall wart widely used is not enough when you start integrating numerous sensors. Something tells me I could end up regretting the idea if it became too popular. Users can be brutal when expectations have a gap. And power supplies are always the last consideration (usually form factor concerns) hence the usual "run hot, die young" of many designs.

If I end up doing this - it would probably just be two muxes with some jumpers and perhaps terminal blocks for direct wiring. One mux for hardware I2C and the other for some selectable GPIO pins for SW I2C. I think it would simplfy many of the hardware design issues Mycodo users have in mind for their projects. The code to integrate is freely available.

Theoi-Meteoroi commented 6 years ago

Ok, here is the beef:
I2C comm guide 2_15.pdf

Page 14 has the encoding of the bytes.

It seems your example code tries to read 2 bytes from RAM. Their example in the previous doc seems to be reading from EEPROM. Then there is this note -

6.1. Important notice: Sensor’s I2C communication is not implemented as a hardware block but it is implemented in software instead. It imposes its limitations on the performance and compliance with I2C general specification. Limitations include:

  1. There is a deadtime in communication when sensor performs measurement.
  2. Communication with sensors networked on the same I2C bus may be complicated by the fact that there is no hardware detection of the address. The consequence is the response of all sensors on the first byte with address by ACK bit. Read more about ACK bit in chapter Acknowledge.
  3. Moreover if one of networked on the same I2C bus sensors is measuring, it will keep SCL line low until measurement finish. See chapter Use of the clock synchronizing mechanism as a handshake for more detailed description.

Oh. Swell. I think I'm remembering why I went with WINSEN.

kizniche commented 6 years ago

I like the HAT idea, especially if each multiplexer operates at either 3.3v or 5v, so any I2C device can be used regardless of the voltage. This has been an issue of mine.

I have reliable sensing using UART for the K30, and I haven't attempted to wire it to an arduino to test the I2C code, so I just wanted to see if I could add another communication protocol for Mycodo. So, what you're saying is it appears there will be difficulties using the K30 with I2C?

Theoi-Meteoroi commented 6 years ago

I think it may require SW I2C since it is more like SMBus than I2C in the interface implementation. And that solves the RTC address clash on bus 1 as a side effect.

I think having the mux setup solved and documented makes this as close to plug and play as you can get - for say the folks in the UK that want to build their own.

On Jun 6, 2018, at 2:56 PM, Kyle Gabriel notifications@github.com wrote:

I like the HAT idea, especially if each multiplexer operates at either 3.3v or 5v, so any I2C device can be used regardless of the voltage. This has been an issue of mine.

I have reliable sensing using UART for the K30, and I haven't attempted to wire it to an arduino to test the I2C code, so I just wanted to see if I could add another communication protocol for Mycodo. So, what you're saying is it appears there will be difficulties using the K30 with I2C?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kizniche/Mycodo/issues/465#issuecomment-395226927, or mute the thread https://github.com/notifications/unsubscribe-auth/APsXKtg8wRJ0DANgk7TW6IWdc4xVYyZXks5t6FADgaJpZM4TtoqQ.

Gossen1 commented 6 years ago

@Theoi-Meteoroi I checked out your overlay and I think it is exactly what I need. I have a tca9548a hooked up to the standard arm i2c bus with 3 am2315 sensors connected to the multiplexer. Works ok, except for the times it won't because of the BCM2835 clock stretching. My thought was that I connect the multiplexer to the sw i2c. Well, this didn't work. Now I think I understand why (the standard overlay i2c-mux looks for the arm i2c bus only) Sorry, for the long intro. Just to explain my situation and for other readers.

So, to add your overlay:

I saw that you mentioned to hook up the chip to 3.3v instead of 5v. Why is that? GPIO runs on 3.3v? Does this has any influence on the length of the cable you use to connect the am2315? Just curious. Thanks anyway for your time and effort.

Edit: added info about pull up resistors.

Theoi-Meteoroi commented 6 years ago

Yes, you should use 3.3v because that is the GPIO level. You can mix and match 3.3v and 5v devices on the mux ports. Be sure to add some sort of pull-up to the supply voltage of the device.

I tend to use 5v with the AM2315 - partly because of cable length. The device shuts off between measurements to mitigate self heating. The limitation with cables is the capacitance. 400pF max otherwise the rise time of the clock edge is too slow to operate anywhere near 100khz. If you slow the clock rate down and a device starts to work, excessive parasitic capacitance is a likely problem. I2C usually doesn't leave the circuit board or enclosure in robust applications. There are repeaters and some devices that can extend the distance however there are still problems with ground reference shifting in those devices, details of which are buried in the datasheets.

I'm happy you found the overlay useful. :)

Gossen1 commented 6 years ago

@Theoi-Meteoroi Thanks for the reply. If I can mix and match 3.3v and 5v devices on the mux ports does the multiplexer act as a level shifter? In that case I can power the mux with 3.3v and the am2315 with 5v and have a 'stronger' signal and I can use longer cables. Probably to good to be true :)

Gossen1 commented 6 years ago

Here is a little update on the i2c overlay with 3 am2315 sensors connected to 12 meters of cable each. In one word: perfect. Literally. If haven't got a single CRC error (the 'All measurements returned failed CRC' error) I implemented @Theoi-Meteoroi 's overlay the 25th of June and Mycodo is running beautifully since then.

I used s-ftp (shielded and foil) CAT6 network cable to counter EMI and 4.7k pullup to decrease the raise time to counter bus capacitance.

Thanks again for the help.

Theoi-Meteoroi commented 6 years ago

@Gossen1 That is great to hear! The SMbus clock speed requirements ( 100khz or less ) seem to really help with cable length issues. With a 400khz clock, the pull-up has to be such a low value to maintain rise time that it can be a problem for the open-drain outputs creating a valid 'low' voltage on the wire to be reliably recognized because of the voltage drop across the open-drain junction - leading to that ground reference shift I mentioned. Using 5v supply on the probe provides more margin on the logic trigger levels than what you have with 3.3v logic levels.

I really like the am2315. The cost/performance is excellent and the probe design makes the mechanical integration easy to create a professional appearance ( for those who are otherwise mystified why you are spending time on this stuff ). Mycodo is probably one of the most rewarding projects you can build on a Pi if you invest the time.