Skip to content

Instantly share code, notes, and snippets.

@ryancor
Last active September 6, 2020 17:39
Show Gist options
  • Save ryancor/6f81427b05b2b1c55a2a71b22348503e to your computer and use it in GitHub Desktop.
Save ryancor/6f81427b05b2b1c55a2a71b22348503e to your computer and use it in GitHub Desktop.
import pandas as pd
################
# Useful docs on how I2C driver communicates with LCD
# https://datasheet4u.com/datasheet-parts/LCD-1602A-datasheet.php?id=519148
# https://www.nxp.com/docs/en/data-sheet/PCF8574_PCF8574A.pdf
# https://controllerstech.com/i2c-lcd-in-stm32/
###
# CSV file was created from using program called Logic which reads data from a Logic Analyzer
# I exported the file after using the I2C decoder for the SDA & SCL pins on logicdata file provided
################
# Every 18 bits is an i2c packet as seen here https://www.picotech.com/images/uploads/library/topics/_med/i2c-packet-format.jpg
# The last 8 bits minus the ACK packet are the data bits
def append_i2c_packets(data, clock):
bit_counter = '' # store the 1's and 0's in here
bin_array = []
n = 1
for _ in range(len(data)-n):
# only after clock is LOW then HIGH, is data bit considered active
if clock[n] == 1 and clock[n-1] == 0:
if len(bit_counter) == 18:
val = int(bit_counter[9:-1], 2)
bin_array.append(val)
bit_counter = ''
else:
bit_counter += str(data[n])
n += 1
return bin_array
# we now place them in 4 byte chunks since the middle two writes (numbers) are the
# RS and EN pins, and they aren't set;
# So the actual writes we want are the first and last byte of the 4 byte chunk.
def seperate_into_4byte_chunks(bin_array):
chunk_array = []
n = 0
for _ in range(int(len(bin_array) / 4)):
chunk_array.append(bin_array[n:n+4])
n += 4
return chunk_array
# Taking only the four data pins, that gives us two nibbles of data.
# The first byte gets shifted left four bits and then the second byte gets added to it.
# ((X >> 4) << 4) | (Y >> 4) = Z.
def decode_chunks(chunk_array):
n = 0
for arr in chunk_array:
for _ in range(len(arr)):
decoded_byte = ((arr[n] >> 4) << 4) | (arr[n+3] >> 4)
if(decoded_byte < 127):
print(chr(decoded_byte), end='')
# password gets printed after every '*' character
def main():
df = pd.read_csv("i2c_data_bin.csv")
print(df.columns)
data = df[' Channel 0']
clock = df[' Channel 1']
packets = append_i2c_packets(data, clock)
chunk_array = seperate_into_4byte_chunks(packets)
decode_chunks(chunk_array)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment