如何修复我的i2c bit bang python库中的错误?

时间:2019-01-08 08:26:59

标签: python-3.x raspberry-pi bit i2c

我在树莓派零上的i2c库有问题。

我已经使用许多教程用python编写了代码,但是没有一个是完全足够的。在这段代码中,缺少time.sleep(),但是即使包含了它,问题仍然存在。它可以与设备通信但不正确。在设备BME280上进行了测试。

import RPi.GPIO as GPIO
import time

class SMBus(object):

    pin_SCL = 0
    pin_SDA = 0
    signal = []

    def __init__(self, bus=-1):
        GPIO.setmode(GPIO.BOARD)
        self.set_pin(13, 11)
        self.start()

    def set_pin(self, SCL, SDA):
        self.pin_SCL = SCL
        self.pin_SDA = SDA
        GPIO.setup(self.pin_SCL, GPIO.OUT)


    def start(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)

        GPIO.output(self.pin_SCL, GPIO.HIGH)
        GPIO.output(self.pin_SDA, GPIO.HIGH)

        GPIO.output(self.pin_SDA, GPIO.LOW)
        GPIO.output(self.pin_SCL, GPIO.LOW)

    def stop(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)

        GPIO.output(self.pin_SDA, GPIO.LOW)

        GPIO.output(self.pin_SDA, GPIO.HIGH)
        GPIO.output(self.pin_SCL, GPIO.HIGH)


    def send_byte(self, byte):
        GPIO.setup(self.pin_SDA, GPIO.OUT)

        for i in range(8):
            GPIO.output(self.pin_SDA, byte & 0b10000000)
            GPIO.output(self.pin_SCL, GPIO.HIGH)
            GPIO.output(self.pin_SCL, GPIO.LOW)
            byte = byte << 1


    def acknowledge_from_slave(self):
        GPIO.setup(self.pin_SDA, GPIO.IN)

        GPIO.output(self.pin_SCL, GPIO.HIGH)
        status = GPIO.input(self.pin_SDA)
        GPIO.output(self.pin_SCL, GPIO.LOW)

        if (status == GPIO.HIGH):
            print("BYTE NOT RECEIVED")


    def acknowledge_from_master(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)

        GPIO.output(self.pin_SCL, GPIO.HIGH)
        GPIO.output(self.pin_SDA, GPIO.LOW)
        GPIO.output(self.pin_SCL, GPIO.LOW)


    def receive_byte(self):
        byte = ''

        GPIO.setup(self.pin_SDA, GPIO.IN)

        for i in range(8):
            GPIO.output(self.pin_SCL, GPIO.HIGH)
            byte = byte + str(GPIO.input(self.pin_SDA))
            GPIO.output(self.pin_SCL, GPIO.LOW)

        byte = int(byte, 2)
        return byte

    def write_byte_data(self, DEVICE, address, byte):
        self.start()
        self.send_byte(DEVICE*2+0)
        self.acknowledge_from_slave()
        self.send_byte(address)
        self.acknowledge_from_slave()
        self.send_byte(byte)
        self.acknowledge_from_slave()

    def read_byte_data(self, DEVICE, address):
        self.start()
        self.send_byte(DEVICE*2+1)
        self.acknowledge_from_slave()
        self.send_byte(address)
        self.acknowledge_from_master()
        return self.receive_byte()

我希望从我的设备(BME280)获得合适的温度。

1 个答案:

答案 0 :(得分:0)

您非常亲密。这是有效的解决方案:

import RPi.GPIO as GPIO
import time

class SMBus(object):

    pin_SCL = 0
    pin_SDA = 0
    delay = 0.001


    def __init__(self, bus=-1):
        GPIO.setwarnings(False)
        GPIO.setmode(GPIO.BOARD)
        self.set_pin(11, 13)
        self.start()


    def set_pin(self, SDA, SCL):
        self.pin_SCL = SCL
        self.pin_SDA = SDA
        GPIO.setup(self.pin_SCL, GPIO.OUT)
        time.sleep(self.delay)


    def start(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)
        GPIO.output(self.pin_SDA, GPIO.HIGH)
        GPIO.output(self.pin_SCL, GPIO.HIGH)
        time.sleep(self.delay)
        GPIO.output(self.pin_SDA, GPIO.LOW)
        time.sleep(self.delay)


    def repeated_start(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)
        GPIO.output(self.pin_SCL, GPIO.LOW)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SDA, GPIO.HIGH)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SCL, GPIO.HIGH)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SDA, GPIO.LOW)
        time.sleep(self.delay)


    def stop(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)
        GPIO.output(self.pin_SCL, GPIO.LOW)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SDA, GPIO.LOW)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SCL, GPIO.HIGH)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SDA, GPIO.HIGH)
        time.sleep(self.delay)


    def send_ack(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)
        GPIO.output(self.pin_SCL, GPIO.LOW)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SDA, GPIO.LOW)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SCL, GPIO.HIGH)
        time.sleep(self.delay)


    def send_nack(self):
        GPIO.setup(self.pin_SDA, GPIO.OUT)
        GPIO.output(self.pin_SCL, GPIO.LOW)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SDA, GPIO.HIGH)
        time.sleep(self.delay/2)
        GPIO.output(self.pin_SCL, GPIO.HIGH)
        time.sleep(self.delay)


    def send_byte(self, byte):
        GPIO.setup(self.pin_SDA, GPIO.OUT)

        for i in range(8):
            GPIO.output(self.pin_SCL, GPIO.LOW)
            time.sleep(self.delay)
            GPIO.output(self.pin_SDA, byte & 0b10000000)
            time.sleep(self.delay/2)
            GPIO.output(self.pin_SCL, GPIO.HIGH)
            time.sleep(self.delay)
            byte = byte << 1

        self.send_ack()


    def receive_byte(self):
        byte = ''

        for i in range(8):
            GPIO.setup(self.pin_SDA, GPIO.OUT)
            GPIO.output(self.pin_SCL, GPIO.LOW)
            GPIO.output(self.pin_SDA, GPIO.HIGH)
            time.sleep(self.delay)
            GPIO.output(self.pin_SCL, GPIO.HIGH)
            time.sleep(self.delay/2)
            GPIO.setup(self.pin_SDA, GPIO.IN)
            byte = byte + str(GPIO.input(self.pin_SDA))
            time.sleep(self.delay)

        byte = int(byte, 2)
        return byte


    def write_byte_data(self, DEVICE, address, byte):
        self.start()
        self.send_byte(DEVICE*2+0)
        self.send_byte(address)
        self.send_byte(byte)
        self.stop()


    def read_byte_data(self, DEVICE, address):
        self.start()
        self.send_byte(DEVICE*2+0)
        self.send_byte(address)

        self.repeated_start()

        self.send_byte(DEVICE*2+1)
        byte = self.receive_byte()
        self.send_nack()
        self.stop()

        return byte