Serial communication control with python and I2C communication (using USBGPIO8 device)

About this article

Since it is assumed that you have experience in electronic circuits and know the words GPIO and I2C, we will omit the terminology in that area.

What is USBGPIO8?

A device that can control GPIO via serial communication Numato Labs' USB GPIO (digital input / output) board can be purchased from Elefine mail order in Japan. https://www.elefine.jp/SHOP/USBGPIO8.html It also comes with an AD converter, which is convenient for various unit experiments.

About I2C communication

http://www.picfun.com/f1/f06.html This explanation is very easy to understand.

What to do

Control serial communication with python, control USBGPIO8, write 1 byte to EEPROM, and then check that it is read and written. The EEPROM uses 24LC64. 24LC64 is this product → http://akizukidenshi.com/catalog/g/gI-00194/

Hardware preparation

Let SDA be port 0 of USBGPIO8. Let SCL be port 1 of USBGPIO8. Pull up with 10kΩ each. It is connected on the breadboard with the above configuration.

GPIO8_I2C_回路図.png

About USBGPIO8 commands

You can download the manual from the Elefine website or officially, so please refer to that for details. It is recommended to perform control experiments from serial terminal software such as Teraterm instead of program control from the beginning.

gpio [command] [arg]\r

The format is, arg may or may not be present, be careful not to forget the trailing \ r. When you send a write command

[Command sent]\n\r>
#For example gpio set 0\n\r>

Will be returned with a prompt. Also, when you send a read command

[Command sent]\n\r[Return value]\n\r>
#For example gpio read 0\n\r1\n\r>
# \n\1 sandwiched between r is the return value

And returns with a return value and prompt.

GPIO LOW-HIGH control

Use the clear command to set port 0 to LOW

SerialInstance = serial.Serial("COM4", 115200, timeout=0.01)
SerialInstance.write("gpio clear 0\r".encode())

Use the set command to set port 0 to HIGH

SerialInstance = serial.Serial("COM4", 115200, timeout=0.01)
SerialInstance.write("gpio set 0\r".encode())

command

Set the timeout as timeout = 0.01, otherwise it will not return a response for the rest of your life, so it is better to set it.

GPIO reading

To read the LOW-HIGH status of port 0

SerialInstance = serial.Serial("COM4", 115200, timeout=0.01)
SerialInstance.write("gpio read 0\r".encode())

will do

gpio read 0\n\r0\n\r>

If the response is returned, the GPIO status is 0 (LOW).

Program structure

0=LOW 1=HIGH 2 = read clock Is defined as. Create an array according to the definition and control SCL and SDA according to the array.

Example When writing 1 byte EEPROM device address 0x50 Write address 0xa0 Write data 0x33 Under this condition, create the following array

[
1, 0, 1, 0, 0, 0, 0, 0, 2,
0, 0, 0, 0, 0, 0, 0, 0, 2,
1, 0, 1, 0, 0, 0, 0, 0, 2,
0, 0, 1, 1, 0, 0, 1, 1, 2
]

Explain each line [1, 0, 1, 0, 0, 0, 0, 0, 2] The first 7 bits represent the address of 0x50, the 8th bit is the write flag, and the 9th bit is the read of ACK. [0, 0, 0, 0, 0, 0, 0, 0, 2] The first 8 bits are the upper byte of the write address, and the 9th bit is the read of ACK. [1, 0, 1, 0, 0, 0, 0, 0, 2] The first 8 bits are the lower bytes of the write address, and the 9th bit is the read of ACK. [0, 0, 1, 1, 0, 0, 1, 1, 2] The first 8 bits are 1-byte data to be written, and the 9th bit is ACK read.

When reading 1 byte next

[
1, 0, 1, 0, 0, 0, 0, 1, 0,
2, 2, 2, 2, 2, 2, 2, 2, 1
]

Explain each line [1, 0, 1, 0, 0, 0, 0, 0, 0] Represents the address of the first 7 bits 0x50, the 8th bit is the read flag, and the 9th bit is the transmission of ACK. [2, 2, 2, 2, 2, 2, 2, 2, 1] The first 8 bits are read, and the 9th bit is NOACK transmission (notification of read completion).

The SDA pattern is arranged as described above, and the clock and data are transmitted / received according to the arrangement.

Source code

# i2c_byte_write_and_read.py
import serial
import sys
import time
import threading

SerialInstance = None

def SerialInit(comString):
    global SerialInstance
    SerialInstance = serial.Serial(comString, 115200, timeout=0.01)
    #SerialInstance = serial.Serial(comString, 19200, timeout=0.1)

def SerialEnd():
    SerialInstance.close()

def SerialTalk(cmd, response=False):
    readLen = len(cmd) + 1 # gpio read 0\n\r #From the beginning\Because it has r+Not 2+1 do
    if response == True:
        readLen += 3 # N\n\r
    readLen += 1 # >
    cnt = SerialInstance.write(cmd.encode())
    res = SerialInstance.read(readLen)
    res = res.decode("utf-8").strip()
    return res
    #Accurately read the number of characters returned, and if there is an excess or deficiency of even one character, the response waiting state will continue.

def gpioHigh(n):
    SerialTalk("gpio set {}\r".format(n))

def gpioLow(n):
    SerialTalk("gpio clear {}\r".format(n))

def gpioRead(n):
    res = SerialTalk("gpio read {}\r".format(n), response=True)
    return res

def ByteToLH(b):
    lh = []
    for i in range(8):
        if (b << i & 128) == 0:
            lh.append(0)
        else:
            lh.append(1)
    return lh

def SDA_LOW():
    gpioLow(0)

def SDA_HIGH():
    gpioHigh(0)

def SCL_LOW():
    gpioLow(1)

def SCL_HIGH():
    gpioHigh(1)
def READ_DATA():
    return gpioRead(0)

def parseData(all):
    res = []
    for l in all:
        a = l.split("\n\r")
        res.append(a[1])
    return res

# 0 = LOW
# 1 = HIGH
# 2 = READ
#Start condition:Set SDA LOW while SCL is HIGH
#Stop condition:Set SCL to HIGH and then SDA to HIGH
def WriteProc():
    ctrlByte = ByteToLH(constDeviceAddress << 1)
    addrHigh = ByteToLH((constDataAdress >> 8) & 0xff)
    addrLow = ByteToLH(constDataAdress & 0xff)
    write1Byte = ByteToLH(constData)
    cmdWrite = ctrlByte + [2] + addrHigh + [2] + addrLow + [2] + write1Byte + [2]
    
    # START CONDITION
    SCL_HIGH()
    SDA_LOW()
    
    size = len(cmdWrite)
    data = []
    for i in range(size):
        SCL_LOW()
        d = cmdWrite[i]
        if d == 0:
            SDA_LOW()
        elif d == 1:
            SDA_HIGH()
        SCL_HIGH()
        if d == 2:
            response = READ_DATA()
            data.append(response)
    SCL_LOW() #Return to LOW
    SDA_LOW() #Return to LOW
    
    # STOP CONDITION
    SDA_LOW()
    SCL_HIGH()
    SDA_HIGH()
    
    #Waiting for writing, 5ms by specification, but wait for a long time
    time.sleep(0.1)
    print(parseData(data))
    print("write end")

def ReadProc():
    #
    #
    # set address
    ctrlByte = ByteToLH(constDeviceAddress << 1)
    addrHigh = ByteToLH((constDataAdress >> 8) & 0xff)
    addrLow = ByteToLH(constDataAdress & 0xff)
    cmdSetAddress = ctrlByte + [2] + addrHigh + [2] + addrLow + [2]
    
    # START CONDITION
    SCL_HIGH()
    SDA_LOW()
    
    size = len(cmdSetAddress)
    data = []
    for i in range(size):
        SCL_LOW()
        #print(i)
        d = cmdSetAddress[i]
        if d == 0:
            SDA_LOW()
        elif d == 1:
            SDA_HIGH()
        SCL_HIGH()
        if d == 2:
            response = READ_DATA()
            data.append(response)
    SCL_LOW() #Return to LOW
    SDA_LOW() #Return to LOW
    
    # STOP CONDITION
    SCL_HIGH()
    SDA_HIGH()
    
    print(parseData(data))
    
    #
    #
    # read data
    ctrlByte = ByteToLH((constDeviceAddress << 1) | 0x01)
    readByte = [2] * 8
    cmdReadByte = ctrlByte + [0] + readByte + [1]
    
    # START CONDITION
    SCL_HIGH()
    SDA_LOW()
    
    size = len(cmdReadByte)
    data = []
    for i in range(size):
        SCL_LOW()
        #print(i)
        d = cmdReadByte[i]
        if d == 0:
            SDA_LOW()
        elif d == 1:
            SDA_HIGH()
        SCL_HIGH()
        if d == 2:
            response = READ_DATA()
            data.append(response)
    SCL_LOW() #Return to LOW
    SDA_LOW() #Return to LOW
    
    # STOP CONDITION
    SCL_HIGH()
    SDA_HIGH()
    
    print(parseData(data))
    print("read end")

# defines
constDeviceAddress = 0x50 #Follow the IC settings
constDataAdress = 0x0a88 #Determine appropriately within the address range of the IC, this time up to 2 bytes (0)-Code assumed to be 65535), code correction is required for 3-byte address
constData = 0x44 # 0-Determine appropriately within the range of 255

def run(comString):
    SerialInit(comString)
    
    WriteProc()
    ReadProc()
    
    SerialEnd()

if __name__ == "__main__":
    run(sys.argv[1])
# python i2c_byte_write_and_read.py COM4

Source code explanation

How to use

For Linux

python i2c_byte_write_and_read.py /dev/ttyUSB0

For Windows

python i2c_byte_write_and_read.py COM4

How to read the return value

['0', '0', '0', '0'] #Control byte ACK, address upper byte ACK, address lower byte ACK, write data ACK
write end
['0', '0', '0'] #Control byte ACK, address upper byte ACK, address lower byte ACK
['0', '0', '1', '1', '0', '0', '1', '1'] #Read 8-bit state
read end

that's all

Recommended Posts

Serial communication control with python and I2C communication (using USBGPIO8 device)
Serial communication control with python and SPI communication (using USBGPIO8 device)
Serial communication with Python
Serial communication with python
Using Python and MeCab with Azure Databricks
Socket communication using socketserver with python now
[Python] [Windows] Serial communication in Python using DLL
I'm using tox and Python 3.3 with Travis-CI
Send and receive binary data via serial communication with python3 (on mac)
Let's control EV3 motors and sensors with Python
Socket communication with Python
WiringPi-SPI communication using Python
HTTP communication with Python
Control other programs from Python (communication between Python and exe)
Get and automate ASP Datepicker control using Python and Selenium
Version control of Node, Ruby and Python with anyenv
Programming with Python and Tkinter
Encryption and decryption with Python
Python and hardware-Using RS232C with Python-
[S3] CRUD with S3 using Python [Python]
Using Quaternion with Python ~ numpy-quaternion ~
[Python] Using OpenCV with Python (Basic)
IP spoof using tor on macOS and check with python
Using Python with SPSS Modeler extension nodes ① Setup and visualization
Instrument control using Python [pyvisa]
View Python communication with Fiddler
python with pyenv and venv
Using OpenCV with Python @Mac
This and that for using Step Functions with CDK + Python
Works with Python and R
Send using Python with Gmail
Control the motor with a motor driver using python on Raspberry Pi 3!
[Python] Error and solution memo when using venv with pyenv + anaconda
Communicate with FX-5204PS with Python and PyUSB
Complement python with emacs using company-jedi
Harmonic mean with Python Harmonic mean (using SciPy)
Socket communication with Python LEGO Mindstorms
Robot running with Arduino and python
Install Python 2.7.9 and Python 3.4.x with pip.
[Python] Using OpenCV with Python (Image Filtering)
Neural network with OpenCV 3 and Python 3
AM modulation and demodulation with python
[Python] font family and font with matplotlib
Scraping with Node, Ruby and Python
Using Rstan from Python with PypeR
Authentication using tweepy-User authentication and application authentication (Python)
[Python] Using OpenCV with Python (Image transformation)
Scraping with Python, Selenium and Chromedriver
Serial communication with Raspberry Pi + PySerial
[Python] Using OpenCV with Python (Edge Detection)
JSON encoding and decoding with python
Hadoop introduction and MapReduce with Python
[GUI with Python] PyQt5-Drag and drop-
Just check serial communication with tk
Using Sessions and Reflections with SQLAlchemy
Reading and writing NetCDF with Python
Python3 socket module and socket communication flow
I played with PyQt5 and Python3
Notes on using rstrip with python.
Reading and writing CSV with Python
Try frequency control simulation with Python