EasyVolts + Python = I2C master!


today I want to tell you about my progress with adding new features to EasyVolts project. This time I added software I2C master implementation written in Python 3. This software uses Tx and Rx pins on EasyVolts as GPIO. As you know these pins of EasyVolts have very flexible configuration and can be used as pushPull output, input or Z-state with pullUp/pullDown input. This makes possible to implement the i2c master functionality. Because we will use Python script to control each pin separately and these commands are sent over virtual com port to EasyVolts (which also needs some time to parse these command and execute them) I don’t expect a high-speed communication. But it’s not a problem because I2C was designed with the idea of low-speed support where it’s needed. My test setup showed ~1.2KHz clock speed which is good enough for a practical use in a lab.


So I created a module called EasyVolts_SWI2C.py, it contains all needed functionality to let PC communicate with i2c slaves using EasyVolts as an i2c gateway. For my tests, I used GY-85 board which contains ADXL345 accelerometer, HMC5883L magnetometer and ITG-3205 gyroscope connected to the same i2c bus.

IMG_20171108_144157The code below scans bus to detect all available devices and then reads ADXL345 accelerometer in a loop.

import serial
import struct
import EasyVolts_SWI2C

def initADXL345(serialPort):
    writeBuff = bytearray([0x2d,0x08]) #write 0x08 in 0x2D register to enable measurements. Default mode (10bit, +-2g) is used
    EasyVolts_SWI2C.DoI2cTransaction(serialPort, 0x53,len(writeBuff), writeBuff, 0, 0, 0)

def readADXL345_XYZ(serialPort):
    #define needed data register addr in the request buffer
    writeBuff = bytearray([0x32])
    readBuff = bytearray(6) #we will read all 3 signed int values, one for each axis
    EasyVolts_SWI2C.DoI2cTransaction(serialPort,0x53,len(writeBuff), writeBuff, len(readBuff), readBuff, 1) #do StartRepeat because it's reading
    axisXYZ_out = struct.unpack('<hhh', readBuff)
    return axisXYZ_out

#main program starts here
print("Open control serial port. To exit press CTRL+C")
serialPort = serial.Serial('COM24')#set your port name here
print('Set voltage:2800mV. Set current protection limit: 50mA.')
serialPort.write(b'u2800\r') #set voltage value
serialPort.write(b'i50\r') #set current limit value

print("Init I2C bus")
print("Scan I2C devices")
detectDevicesArray = EasyVolts_SWI2C.ScanDevices(serialPort)
print("Detected devices:")
for device in detectDevicesArray:
    print('\t' + hex(device))

#init ADXL345 sensor
print("Init ADXL345(0x53) accelerometer")

print("Measure acceleration on all 3 axis")
        xyz = readADXL345_XYZ(serialPort)
        print('x=' + '{:6}'.format(xyz[0]) + '; y=' + '{:6}'.format(xyz[1]) + '; z=' + '{:6}'.format(xyz[2]) + '\r', end='')

except KeyboardInterrupt:

#before exit set output power to 0 and TxRx pins to Z state

All files related to the demo you can find in GY-85_demo archive. As you can see it’s very simple. Video with the demonstration:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s