Hi, this isn’t so much a question as a report on the changes I needed to make to the existing Python library in order to use a pair of Inventor HAT Mini (AKA IHM) boards on a robot, where I needed support for four motors. Below also are two “bugs” or issues I found when using the HAT.
I’d first like to compliment Pimoroni for what is a quite impressive software library. It was much more than I had expected. Lots of great features for the motor controller in particular.
Given the IHM is based on the IO Expander (Nuvoton MS51) it seemed strange to me that the Motor, PID, Encoder and Servo implementations were in the ioexpander
library rather than in the inventorhatmini
. But that’s a side issue, I’m assuming there was some good reason for this (access to IOE internals?)
I made three changes to inventorhatmini/__init__.py
. We need to declare the variable so that even if undefined it exists (this avoids an exception when calling __del__()
):
self.ioe = None
Secondly, in order to change the I2C address of the second IHM, we need to expose the underlying IO Expander with the addition of this method to __init__py:
def get_ioe(self):
return self.ioe
Third, running multiple IHMs puts two GPIO pins in conflict. We’ll disable them on all but the default address with the change of these lines to the __init__()
method:
if ( address == self.IOE_ADDRESS ): # only if using default address, for use with multiple HATs
# Setup user button
self._pin_user_sw = gpiodevice.get_pin(self.PI_USER_SW_PIN, "IHM-SW", INPD)
# Setup amplifier enable. This mutes the audio by default
self._pin_amp_en = gpiodevice.get_pin(self.PI_AMP_EN_PIN, "IHM-AMP-En", OUTL if start_muted else OUTH)
with one final change to avoid an exception:
def __del__(self):
if self.ioe:
self.ioe.reset()
Then I modified an existing Pimoroni script and executed:
from inventorhatmini import InventorHATMini
board = InventorHATMini(init_leds=False) # default address: 0x17
_ioe = board.get_ioe()
_i2c_addr = 0x16 # new I2C address
_ioe.set_i2c_addr(_i2c_addr)
print('complete: changed I2C address of IO Expander to 0x{:02X}.'.format(_i2c_addr))
This changes the IHM attached at 0x17
to 0x16
. Now two IHMs can coexist.
Now I have an Inventor HAT Mini at both 0x16
and 0x17
. The user button and sound only operate on the latter. This is unavoidable if both are plugged directly into the Pi’s GPIO header.
I’d like to suggest to Pimoroni that they incorporate these small changes into the library so that people can operate multiple boards without needing to make these changes to their installed libraries.
Incompatibility with Pololu N20 Motors
The simplicity of connecting an Inventor HAT Mini directly to a Pimoroni N20 motor with encoders (e.g., Pololu #5197) is being able to use 6 pin JST SH connectors. Unfortunately, I immediately found out that the pinouts for the IHM and the Pololu motors are actually reversed. There are two solutions for this: purchase cables that are “opposite” or “reversed” (available on AliExpress); or use a needle or sharp object to de-pin the connector at one end and reverse the wires. Perhaps Pimoroni could sell some compatible cables, or at least document this on the product page. I initially couldn’t figure out why the motors weren’t working.
Plasma Bug?
I do have an additional issue that probably should be its own Topic, which is that the Plasma library doesn’t seem to work unless one executes under sudo:
RuntimeError: Failed to initialise the RGB LEDs because higher privileges are needed to control the necessary hardware of the Raspberry Pi.
I’m avoiding that issue by calling the constructor with “init_leds=False”. This does seem like a bug. This may be due to me using a global installation rather than venv
, which for various reasons I cannot use.