Как исправить ошибки в моей библиотеке Python i2c bit bang? - PullRequest
0 голосов
/ 08 января 2019

У меня проблема с моей библиотекой i2c на Raspberry Pi ноль.

Я написал свой код на 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 голосов
/ 08 марта 2019

Вы были очень близки. Вот рабочее решение:

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
...