This Python module adds support to the Raspberry Pi for our range of mLink serial I2C modules. The module currently supports the following mLink products:
mLink 12 Bit port expander (SKU: HCMODU0180)
mLink DHT22 temperature and humidity sensor (SKU: HCMODU0181)
mLink 1 channel relay module (SKU: HCMODU0182)
mLink 2 channel relay module (SKU: HCMODU0183)
mLink 4 channel relay module (SKU: HCMODU0184)
mLink RGBW light controller (SKU: HCMODU0185)
mLink NTC temperature sensor (SKU: HCMODU0186)
mLink Matrix 4x4 keypad (SKU: HCMODU0188)
mLink 1602 & 2004 Character LCD (SKU: HCMODU0190A & HCMODU0190B)
mLink 6 Button Keypad (SKU: HCMODU0193)
mLink Home Sensor (SKU: HCMODU0198)
mLink NEC IR Transceiver (SKU: HCMODU0195)
mLink L9110 DC Motor Controller (SKU: HCMODU0199)
mLink TMP36 Temperature Sensor (HCMODU0187)
mLink WS2812 RGB LED controller (HCMODU0197)
Important
Please note that most of the mLink modules make use of an I2C feature called clock stretching. This feature is used by some I2C modules to tell the I2C master device that it needs more time to respond. Unfortunately the Raspberry Pi does not currently support this feature and expects I2C devices to respond instantly.
If you are experiencing random I2C communication errors with a module you can slow down the Pis I2C clock speed to allow time for the module to respond by following these steps:
On your Raspberry Pi open the /boot/config.txt file by typing the following in a terminal window:
- sudo nano /boot/config.txt
Find the following line:
- dtparam=i2c_arm=on
Add the following line below it to slow down the I2C clock to 10MHz:
- # Clock stretching
- dtparam=i2c_arm_baudrate=10000
Save the file and reboot your Pi
Installing the mLink module
To install the module you can either download it by clicking on the link below and then unzip it to your project folder….
V1.0.2 (latest): https://hobbycomponents.com/downloads/m ... V1_0_2.zip
…or if you have PIP installed you can just simply install it by typing the following command into a terminal window on your Raspberry Pi:
- pip install hc-mlink
Prerequisites:
Note that this module requires the smbus2 module to be installed. If you have installed the mLink module via pip then this will be installed automatically if you don’t already have it.
Using the module
Once you have installed the module using one of the above methods you can add the module to your Raspberry Pi Python script by adding the following lines to the top of the script:
- from mLink import mLink # Import the mLink module
- ml = mLink.mLink(1) # Create an instance using the Pis I2C port 1
You can then use any of the mLink modules functions by prefixing it with the modules instance name (ml). For example to print to an mLink LCD screen you can type the following:
- ml.CLCD_Print(0x56, “Hello World”) # Print to an mLink LCd at I2c address 0x56
List of module functions
Generic functions
reg = ml.read(I2C_add, reg_add) # Reads a single byte from an mLink register
reg = ml.readInt(I2C_add, reg_add) # Reads an integer from an mLink register(s)
state = ml.readBit(I2C_add, reg_add, bit_number) # Reads the state of a single bit (0 to 7) from an mLink register
ml.write(I2C_add, reg_add, data) # Writes a single byte to an mLink register
ml.writeInt(I2C_add, reg_add, data) # Writes an integer to an mLink register(s)
ml.writeBit(I2C_add, reg_add, bit_number, State) # Sets the state of a single bit in an mLink register
state = ml.Status(I2C_add) # Returns an mLink modules status register
state = ml.busy(I2C_add) # Returns the state of an mLink modules busy bit
ml.Change_Address(I2C_add, new_add) # Changes the I2C address of an mLink module
modType = ml.Get_Type(I2C_add) # Returns the modules type as a string
subType = ml.Get_Subtype(I2C_add) # Returns the modules sub type as a string
ver = ml.Get_SW_Ver(I2C_add) # Returns the modules software version
devList = Find_Devices() # Scans the I2C interface for mLink device and returns the result as a list containing the devices address in hex, module type, module subtype, and software version
Where
I2C_add = The I2C address of the module
Reg_add = The register address
Data = Is an 8 or 16 bit integer
Bit_number = Is the bit position of the required bit (0 = right most bit, 7= left most bit)
State = A boolean value (True / False)
mLink 12bit port expander functions
ml.DIO12_Port_Dir(I2C_add, Direction) # Sets the state of all 12 IO pins where setting a bit to a 0 sets the pin as an output and setting to a 1 sets it to an input.
ml.DIO12_Port_Write(I2C_add, data) # Sets the state of any pins configured to be an output where bit 0 = pin 0 and bit 11 = pin 11
value = ml.DIO12_Port_Read(I2C_add) # Read the state of all 12 pins and outputs it as an integer
ml.DIO12_Pin_Dir(I2C_add, Pin, Direction) # Sets the in/out direction for a single pin
ml.DIO12_Pin_Write(I2C_add, Pin, State) # Sets the state of a pin
pinState = ml.DIO12_Pin_Read(I2C_add, pin) # Reads the state of a single pin and returns it as a boolean value
I2C_add = The I2C address of the module
Pin = The required pin number (0 to 11)
Data = Is a 16 bit integer
Direction = The pin direction where 0 = output, 1 = input
State = A boolean value (True / False) where True = Pin high, False = pin low
mLink DHT22
ml.DHT22_Start(I2C_add) # Triggers the start of a new DHT22 measurement, use ml.busy(I2C_add) to test when measurement is complete
Temperature = ml.DHT22_Read_Temp(I2C_add) # Returns the temperature in oC as a floating point value to 1dp
Humidity = ml.DHT22_Read_Hum(I2C_add) # Returns the humidity in RH% as a floating point value to 1dp
Where
I2C_add = The I2C address of the module
mLink 1Ch, 2CH, & 4CH relays
ml.Relay_Set(I2C_add, Relay, State) # Sets the state of one of the relays
ml.Relay0_On(I2C_add) # Turns relay 0 on
ml.Relay0_Off(I2C_add) # Turns relay 0 off
ml.Relay1_On(I2C_add) # Turns relay 1 on
ml.Relay1_Off(I2C_add) # Turns relay 1 off
ml.Relay2_On(I2C_add) # Turns relay 2 on
ml.Relay2_Off(I2C_add) # Turns relay 2 off
ml.Relay3_On(I2C_add) # Turns relay 3 on
ml.Relay3_Off(I2C_add) # Turns relay 3 off
ml.Relay0_On_Time(I2C_add, Time) # Sets how many seconds relay 0 will stay on for when triggered. Setting it to 0 seconds will disable this feature
ml.Relay1_On_Time(I2C_add, Time) # Sets how many seconds relay 1 will stay on for when triggered. Setting it to 0 seconds will disable this feature
ml.Relay2_On_Time(I2C_add, Time) # Sets how many seconds relay 2 will stay on for when triggered. Setting it to 0 seconds will disable this feature
ml.Relay3_On_Time(I2C_add, Time) # Sets how many seconds relay 3 will stay on for when triggered. Setting it to 0 seconds will disable this feature
Where
I2C_add = The I2C address of the module
Relay = The relay number (0 to 3)
State = A boolean value (True / False) where True = Relay on, False = Relay off
Time = A 16 bit integer containing the relay on time in seconds. 0 = timer disabled, 65535 = max
mLink RGBW controller
ml.RGBW_Red_Level(I2C_add, Level) # Sets the level for the red channel
ml.RGBW_Green_Level(I2C_add, Level) # Sets the level for the green channel
ml.RGBW_Blue_Level(I2C_add, Level) # Sets the level for the blue channel
ml.RGBW_White_Level(I2C_add, Level) # Sets the level for the white/Aux channel
ml.RGBW_Brightness(I2C_add, Level) # Sets the master brightness of all channels
ml.RGBW_Pattern(I2C_add, Pattern) # Plays one of the predefined colour patterns
ml.RGBW_User_Pattern(I2C_add, PatternList) # Writes a user defined pattern to the module
ml.RGBW_Cycle_Steps(I2C_add, Steps) # Sets the amount of colour steps to insert between each RGB level of the user defined pattern
ml.RGBW_Cycle_Speed(I2C_add, Speed) # Sets the amount of time to wait in ms between each colour step
Where
I2C_add = The I2C address of the module
Level = Byte value containing the brightness level. 0 = off, 255 = max
Pattern = Byte value containing the predefined pattern number to play
PatternList = A list of R,G,B levels. Defining the user pattern to play. This must be in the following format [[R1, G1, B1], [R2, G2, B2], …..[Rn, Gn, Bn]]
Steps = A byte value containing the amount of additional steps to insert between each colour step
Speed = An integer value containing the amount of time in milliseconds to wait between each colour step
mLink NTC temperature sensor
Temperature = ml.NTC_Temp(I2C_add) # Returns a floating point value containing the current temperature
Where
I2C_add = The I2C address of the module
mLink 4x4 matrix keypad
keyState = ml.Keypad_4x4_Key_Down(I2C_add) # Returns True if a key is currently pressed, False if no key is pressed.
key = ml.Keypad_4X4_Read(I2C_add) # Returns a character value of the last key pressed, or '' if no new key has been pressed.
Where
I2C_add = The I2C address of the module
mLink 1602 & 2004 Character LCD
ml.CLCD_Cursor(I2C_add, Col, Row) # Sets the cursors column and row position
ml.CLCD_Print(I2C_add, Text) # Prints a string of text starting at the current cursor position
ml.CLCD_Clear(I2C_add) # Clears the display
ml.cLCD_on(I2C_add, State) # Turns the display on or off
ml.cLCD_cursDir(I2C_add, Direction) # Sets the direction the cursor will move after printing a character
ml.cLCD_dispType(I2C_add, Display) # Sets the display size
ml.cLCD_Backlight(I2C_add, bLevel) # Sets the backlight brightness level ml.cLCD_Contrast(I2C_add, Contrast) # Sets the contrast level
ml.cLCD_setCust0(I2C_add, Bitmap) # Writes a custom bitmap to custom character 0
ml.cLCD_setCust1(I2C_add, Bitmap) # Writes a custom bitmap to custom character 1
ml.cLCD_setCust2(I2C_add, Bitmap) # Writes a custom bitmap to custom character 2
ml.cLCD_setCust3(I2C_add, Bitmap) # Writes a custom bitmap to custom character 3
ml.cLCD_setCust4(I2C_add, Bitmap) # Writes a custom bitmap to custom character 4
ml.cLCD_setCust5(I2C_add, Bitmap) # Writes a custom bitmap to custom character 5
ml.cLCD_setCust6(I2C_add, Bitmap) # Writes a custom bitmap to custom character 6
ml.cLCD_setCust7(I2C_add, Bitmap) # Writes a custom bitmap to custom character 7
ml.cLCD_printCust(I2C_add, ccIndex) # Writes one of the 8 custom characters to the display
Where
I2C_add = The I2C address of the module
Col = Cursor column position where 0 = left most column and 15 (1602) or 19 (2004) is right most column
Row = Cursor row position where 0 = top row, 1 (1602) or 3 (2004) is the bottom row
Text = A string of text to print to the screen
State = Display on / off state where 0 = off and 1 = on
Direction = Cursor direction where direction = 0 is left to right and direction = 1 is right
Display = Display type where 0 = 16x2 line display and 1 = 20x4 line display
bLevel = Backlight level where 0 = off and 10 = max
Contrast = Contrast level where 0 = min, 255 = max
Bitmap = An array of 8 bytes containing the custom character bitmap to upload. See documentation for how to define a bitmap
ccIndex = The index (0 to 7) of the custom character to print
mLink 6 button pad
state = ml.bPad_Empty(I2C_add) # Returns the state of the buffer where True = buffer empty, False = buffer contains one or more keys
state = ml.bPad_New_Key(I2C_add) # Returns the state of the buffer where True = one or more keys present in the buffer, False = buffer empty
state = ml.bPad_Up_State(I2C_add) # Returns True if the Up key is currently pressed, False if not
state = ml.bPad_Left_State(I2C_add) # Returns True if the Left key is currently pressed, False if not
state = ml.bPad_Down_State(I2C_add) # Returns True if the Down key is currently pressed, False if not
state = ml.bPad_Right_State(I2C_add) # Returns True if the Right key is currently pressed, False if not
state = ml.bPad_Select_State(I2C_add) # Returns True if the Select key is currently pressed, False if not
state = ml.bPad_Back_State(I2C_add) # Returns True if the Back key is currently pressed, False if not
ml.bPad_Debounce(I2C_add, Debounce) # Sets the amount of debouncing
Where
I2C_add = The I2C address of the module
Debounce = The level of debouncing to apply to each keypress where 0 is none, 254 is max
mLink home sensor
ml.HSENS_Start(I2C_add) # Triggers the start of a new temperature/humidity, use ml.busy(I2C_add) to test when measurement is complete
ml.HSens_Temp(I2C_add) # Returns the temperature in oC as a floating point value to 1dp
ml.HSens_Hum(I2C_add) # Returns the humidity in RH% as a floating point value to 1dp
error = ml.HSens_DHT22_Error(I2C_add) # Returns true if the current measurement was read from the DHT22 was valid, false if there was an error
level = ml.HSens_LDR(I2C_add) # Returns a light level sensed by the LDR sensor where 0 = dark and 255 = maximum brightness
pir = ml.HSens_PIR(I2C_add) # Returns the current state of the PIR sensor where True = triggered, False = idle
triggers = ml.HSens_Trigs(I2C_add) # Returns a 16 bit integer containing the amount of times the PIR sensor has been triggered since last reset
ml.HSens_Clear_Trigs(I2C_add) # Resets the PIR trigger counter
mLink NEC IR Transceiver
ml.IR_Write_NEC(I2C_add, NECAdd, NECCom) # Writes an NEC address and command to the Tx buffer for transmitting
ml.IR_Send(I2C_add, txcount) # Triggers a transmit of the message stored in the Tx buffer
ml.IR_Write_Data(I2C_add, data) # Writes a 4 byte list to the Tx buffer
rxcount = ml.IR_Count(I2C_add) # Returns the amount of times an IR message (inc repeat codes) has been received
NECAdd = ml.IR_Read_NEC_Address(I2C_add) # Returns the NEC address byte from a received IR message
NECCom = ml.IR_Read_NEC_Command(I2C_add) # Returns the NEC command byte from a received IR message
data = ml.IR_Read(I2C_add) # Returns the last message received as a 4 byte list
valid = ml.IR_NEC_Valid(I2C_add) # Returns true if the last message received was a valid NEC message
ml.IR_Com_LED_Mode(I2C_add, mode) # Sets the mode of the COM led
Where
I2C_add = The I2C address of the module
NECAdd = NEC IR address byte
NECCom = NEC IR command byte
txcount = Amount of times to transmit the message including repeat codes. Valid values are:
If count = 1 then the message will be transmitted one
If count = 1 + n then the message will be transmitted once + n x repeat codes
If count = 255 then a single repeat code will be sent
data = a list of 4 bytes containing the IR message
mode = The required LED mode. Valid values are:
IR_COM_LED_I2C = LED will illuminate during I2C bus transfers
IR_COM_LED_IR = LED will illuminate whilst IR data is being received or transmitted
rxcount = The amount of times, including repeat codes, the IR message was received
valid = last received code was a valid NEC message
mLink L9110 DC Motor Controller
ml.L9110_M1_Speed(I2C_add, speed) # Sets the speed of motor M1
ml.L9110_M2_Speed(I2C_add, speed) # Sets the speed of motor M1
ml.L9110_M1_Dir(I2C_add, direction) # Sets the direction of motor M1
ml.L9110_M2_Dir(I2C_add, direction) # Sets the direction of motor M2
ml.L9110_M1_Stop(I2C_add) # Stops motor M1
ml.L9110_M2_Stop(I2C_add) # Stops motor M2
Where
I2C_add = The I2C address of the module
speed = A value between 0 and 255 that sets the speed of the motor
direction = Sets the direction of rotation. Valid values are:
REVERSE
FORWARD
mLink TMP36 Temperature Sensor
Temp = ml.TMP36_Temp(I2C_add)
Where
I2C_add = The I2C address of the module
Temp = The current temperature in oC to 1 decimal place
mLink WS2812 RGB LED Controller
ml.WS2812_Max(I2C_add, maxIndex)
ml.WS2812_Index(I2C_add, ledIndex)
ml.WS2812_Red(I2C_add, redLevel)
ml.WS2812_Green(I2C_add, greenLevel)
ml.WS2812_Blue(I2C_add, blueLevel)
ml.WS2812_Refresh(I2C_add)
ml.WS2812_Clear(I2C_add)
ml.WS2812_Brightness(I2C_add, bri)
ml.WS2812_On(I2C_add, onOff)
ml.WS2812_RGB(I2C_add, index, redLevel, greenLevel, blueLevel)
redLevel = ml.WS2812_Get_Red(I2C_add)
greenLevel = ml.WS2812_Get_Green(I2C_add)
blueLevel = ml.WS2812_Get_Blue(I2C_add)
bri = ml.WS2812_Get_Brightness(I2C_add)
onOff = ml.WS2812_Get_On_State(I2C_add)
Where
I2C_add = The I2C address of the module
maxIndex = The number of LEDs in your strip/module
ledIndex = The index of the LED to adjust
redLevel = The red level (0 to 255) of the LED at index ledIndex
greenLevel = The green level (0 to 255) of the LED at index ledIndex
blueLevel = The blue level (0 to 255) of the LED at index ledIndex
bri = The maximum brightness level (0 to 255) of the LED at index ledIndex
onOff = Turns all LEDs on or off. Valid values are
0 = LEDs off
1 = LEDs on
Diagrams, libraries, and example code are provided as an additional free service by Hobby Components and are not sold as part of this product. We do no provide any guarantees or warranties as to their accuracy or fitness for purpose.
Descriptions and diagrams on this page are copyright Hobby Components Ltd and may not be reproduced without permission.