Controlling electronic components with I2C bus communication and pyMCU

Check out the new site at https://rkblog.dev.

BlinkM is a tricolor LED board that uses I2C bus to communicate with a microcontroller. Also minipH and many other boards use this computer bus to communicate. Multiple microcontroller boards or single board computers support I2C - like Arduino, pyMCU, Raspberry Pi and others.

In this article I'll showcase how to use those two board with pyMCU, and some general I2C tips and tricks.

BlinkM

BlinkM connected to pyMCU using pullup resistors

This board has a very bright LED which consists from three internal LEDs - red, green and blue. Using a composition of those colors it is possible to get any other, including white. Through I2C communication we can control colors or color change sequences. It's a very simple and cheap board, and it's quite easy to start with I2C or to test it on a less popular microcontroller board. It can be bought in multiple shops too. Documentation is a must to read. You will find Arduino example there (as well as a list of all commands).

To do I2C communication you need two pins (clock and data). In case of pyMCU data is on D4 and clock is on D11 pin. BlinkM also needs power so you need to connect VCC/GND too.

BlinkM has some Arduino examples in the documentation. pyMCU uses bit older, different schema of the API for I2C communication, which makes it harder to port Arduino code snippets. PyMCU uses two address format while Arduino just one doing all the bit shifting in the background. In case of problems, ask on the forums.

Basic BlinkM Python example code for pyMCU looks like so:
import pymcu

mb = pymcu.mcuModule()


class BlinkM(object):
    ADDRESS = 0x12
    BLINK_TO_COLOR = 0x63
    STOP_SCRIPT = 0x6f
    RED = 0xff
    GREEN = 0x30
    BLUE = 0xc4

mb.i2cWrite(BlinkM.ADDRESS, BlinkM.STOP_SCRIPT)
mb.pausems(200)

while True:
    mb.i2cWrite(BlinkM.ADDRESS, [BlinkM.BLINK_TO_COLOR, BlinkM.RED, 0x00, 0x00])
    mb.pausems(1000)
    mb.i2cWrite(BlinkM.ADDRESS, [BlinkM.BLINK_TO_COLOR, 0x00, 0x00, BlinkM.BLUE])
    mb.pausems(1000)

I2C communications starts with stopping the default color chance sequence. Then we do our own sequence by sending instructions in a loop. Due to the API differences the device address is 0x12 instead of 0x09.

Pullup resistors

Some microcontroller boards have to use pull-up resistors to make I2C communication working. You need to check description/examples for your microcontroller to see if it's needed or built-in. In case of pyMCU we have to add them on our own. We will need two 4,7 kilo-ohm (or more) resistors connected from VCC (+) to clock (first resistor) and data (second). Below you is the drawing of the circuit:

I2C with pullup resistors

MinipH

MinipH with BNC electrode

MinipH is a quite interesting board, which allows measuring pH of liquids using a BNC electrode. More scientific sensors are quite rare, and can't be bought in most of microcontroller-related stores. SparkFun offers some Atlas Scientific sets, but they cost much more as they are laboratory equipment of quite high quality. MinipH is cheaper and can work with cheap aquarium or more expensive and precise laboratory-quality BNC electrodes. You can find those electrodes on eBay (and also in some aquarium shops).

The board when connected to a microcontroller is available via I2C under 0x4D address. Reading two bits will give you the measured pH value:

from time import sleep

import pymcu

mb = pymcu.mcuModule()
ADDRESS = 0x4D
R = 1
W = 0
while True:
    result = mb.i2cRead((ADDRESS << 1) + R,  2)
    sleep(0.1)

mb.i2cWrite()
I used a cheap aquarium electrode and I got such results:
  • Purified water: [7, 94]
  • pH 4,003 calibration solution: [4, 141]
  • Citric acid: [3, 77]
  • Sodium bicarbonate solution: [8, 111]

Precision of measurement depends on the exact voltage the board gets as well on the electrode quality. To get good measurements you will have to calibrate your setup first.

RkBlog

Check out the new site at https://rkblog.dev.
Comment article
Comment article RkBlog main page Search RSS Contact