OpenMV3 and PCA9685 module communication errors
main.py: from pyb import I2C import time from servoctrl import ServoCtrl i2c = I2C(2, I2C.MASTER) # The i2c bus must always be 2. servos = ServoCtrl(i2c) servos.position(0,90) time.sleep(1000) servos.position(0,0) time.sleep(1000) servos.position(0,90) time.sleep(1000) servos.position(0,0)
import ustruct import time class PCA9685: def __init__(self, i2c, address=0x40): self.i2c = i2c self.address = address self.reset() def _write(self, address, value): self.i2c.mem_write(bytearray([value]), self.address, address ) def _read(self, address): return self.i2c.mem_read(1, self.address, address) def reset(self): self._write(0x00, 0x00) # Mode1 def freq(self, freq=None): if freq is None: return int(25000000.0 / 4096 / (self._read(0xfe) - 0.5)) prescale = int(25000000.0 / 4096.0 / freq + 0.5) old_mode = self._read(0x00) # Mode 1 self._write(0x00, (old_mode & 0x7F) | 0x10) # Mode 1, sleep self._write(0xfe, prescale) # Prescale self._write(0x00, old_mode) # Mode 1 time.sleep(1) self._write(0x00, old_mode | 0xa1) # Mode 1, autoincrement on def pwm(self, index, on=None, off=None): if on is None or off is None: data = self.i2c.mem_read(self.address, 0x06 + 4 * index, 4) return ustruct.unpack('<HH', data) data = ustruct.pack('<HH', on, off) self.i2c.mem_write(data, self.address, 0x06 + 4 * index) def duty(self, index, value=None, invert=False): if value is None: pwm = self.pwm(index) if pwm == (0, 4096): value = 0 elif pwm == (4096, 0): value = 4095 value = pwm if invert: value = 4095 - value return if not 0 <= value <= 4095: return ValueError("Out of range") if invert: value = 4095 - value if value == 0: self.pwm(index, 0, 4096) elif value == 4095: self.pwm(index, 4096, 0) else: self.pwm(index, 0, value)
from pca9685 import PCA9685 import math class ServoCtrl( PCA9685 ): """ Servo Controleur - Allow you to control the servo 0 to 15 on the PCA9685 PWM Driver """ def __init__(self, i2c, address=0x80, freq=50, min_us=600, max_us=2400, degrees=180): PCA9685.__init__( self, i2c=i2c, address=address) self.period = 1000000 / freq self.min_duty = self._us2duty(min_us) self.max_duty = self._us2duty(max_us) self.degrees = degrees # Init the freq on PCA9685 self.freq(freq) def _us2duty(self, value): return int(4095 * value / self.period) def position(self, index, degrees=None, radians=None, us=None, duty=None): span = self.max_duty - self.min_duty if degrees is not None: duty = self.min_duty + span * degrees / self.degrees elif radians is not None: duty = self.min_duty + span * radians / math.radians(self.degrees) elif us is not None: duty = self._us2duty(us) elif duty is not None: pass else: return self.duty(index) duty = min(self.max_duty, max(self.min_duty, int(duty))) self.duty(index, duty) def release(self, index): self.duty(index, 0)
Is there an error in the I2C communication program call?
So, not trying to be mean here. But if you want an answer to your problems on the forums you need to structure your question in such a way that I can answer it. You just gave me a lot of code dump with no context.
Can you please try to narrow down the exact line of code that has the issue and then ask me questions about that? This way I can actually answer your question.
Also, maybe give me some pictures of your setup, details about what you are trying to do, etc. Holding back info just makes it harder to help you.
Please use the
tag on your code so I can read it.
That code looks a lot like my library for the PCA9685 chip available here: GitHub - adafruit/micropython-adafruit-pca9685: Micropython driver for 16-channel, 12-bit PWM chip the pca9685 but some things are changed. I’m using that library with my servo shield, and it works fine, so if it doesn’t work for you, perhaps it’s because of the changes you made?
Ah, I see the problem. You are using i2c from pyb, while this library expects i2c from the machine module, which has a different API.
Sorry, I am learning how to use the forum.
Hi, can you edit your post and re-post your code using the
tags? That way the formatting will not be removed.
Thank you very much, I think I’ve learned.
Hi, I have solved this problem. How do I delete posts?
No need. Just try to keep your questions to one post for a particular issue.
I fixed the code format for you, next time please use the code tags.
Looking at your “schematic” I can also see that you don’t have pull-up resistors on the I2C lines. You need those for I2C communication to work – perhaps you should read more about the I2C protocol.