Miceuz / PlantWateringAlarm

A soil humidity level sensor based on ATTINY44. Uses capacitive sensing.
345 stars 84 forks source link

Problem Interfacing with Raspberry Pi Over I2C #6

Closed dpassarella closed 7 years ago

dpassarella commented 7 years ago

Hi, I am having trouble getting anything useful from the Chirp! over I2C.

I am having trouble interfacing with it on both the raspberry pi and arduino. I soldered on some headers and tried to connect it to the raspberry pi. I did the following steps

Chirp! -> PI VCC -> 3.3V GND -> GND SDA -> SDA1 SCK -> SCK1 Pin 1 -> Left unwired Pin 5 - Left unwired

I am using the following code from your github readme

import smbus, time, sys

class Chirp: def init(self, bus=1, address=0x20): self.bus_num = bus self.bus = smbus.SMBus(bus) self.address = address

def get_reg(self, reg):
    # read 2 bytes from register
    val = self.bus.read_word_data(self.address, reg)
    # return swapped bytes (they come in wrong order)
    return (val >> 8) + ((val & 0xFF) << 8)

def reset(self):
    # To reset the sensor, write 6 to the device I2C address
    self.bus.write_byte(self.address, 6)

def set_addr(self, new_addr):
    # To change the I2C address of the sensor, write a new address
    # (one byte [1..127]) to register 1; the new address will take effect after reset
    self.bus.write_byte_data(self.address, 1, new_addr)
    self.reset()
    self.address = new_addr

def moist(self):
    # To read soil moisture, read 2 bytes from register 0
    return self.get_reg(0)

def temp(self):
    # To read temperature, read 2 bytes from register 5
    return self.get_reg(5)

def light(self):
    # To read light level, start measurement by writing 3 to the
    # device I2C address, wait for 3 seconds, read 2 bytes from register 4
    self.bus.write_byte(self.address, 3)
    time.sleep(1.5)
    return self.get_reg(4)

def __repr__(self):
    return "<Chirp sensor on bus %d, addr %d>" % (self.bus_num, self.address)

if name == "main": addr = 0x20 if len(sys.argv) == 2: if sys.argv[1].startswith("0x"): addr = int(sys.argv[1], 16) else: addr = int(sys.argv[1]) chirp = Chirp(1, addr)

print chirp
print "Moisture\tTemperature\tBrightness"
while True:
    print "%d\t%d\t%d" % (chirp.moist(), chirp.temp(), chirp.light())
    time.sleep(1)

At first, I would get:

<Chirp sensor on bus 1, addr 32> Moisture Temperature Brightness Traceback (most recent call last): File "chirp.py", line 57, in print "%d\t%d\t%d" % (chirp.moist(), chirp.temp(), chirp.light()) File "chirp.py", line 29, in moist return self.get_reg(0) File "chirp.py", line 12, in get_reg val = self.bus.read_word_data(self.address, reg) IOError: [Errno 121] Remote I/O error

Then, I hit the button on the chirp right before I ran the code and started getting this

pi@raspberrypi:~ $ python chirp.py <Chirp sensor on bus 1, addr 32> Moisture Temperature Brightness 65535 65535 65535 65535 65535 65535

I have checked the reviews and the open issues on the Arduino library from Apollon77 and I even tried adding a 10K pullup on both i2c lines and still get similar results. The only time it seems to work is the first time it runs on arduno code, but then goes back to 65535 readings.

Do you think this is a hardware issue? Do you have any guidance? I have tried this with 2 Chirp!'s and still the same thing.

Miceuz commented 7 years ago

You have to control the reset line of the Chirp - reset it, then send any I2C command to it so it stays in sensor mode. Look this Arduino example for reference: https://gist.github.com/Miceuz/8ace1cde27671e8e161d

Also you have to slow down the raspi i2c clock speed drastically. It's due to raspi not dealing with i2c clock stretching properly.