Created
August 19, 2022 01:57
-
-
Save obstruse/a3ea854c7bda6235aa7b2bf8fedb8e2e to your computer and use it in GitHub Desktop.
I2C on the HDMI port
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
import os | |
os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" | |
import pygame.time as time | |
import i2cVC | |
import random | |
random.seed() | |
i2c = i2cVC.i2cVC(addr=0x71, bus=3) | |
timer = time.Clock() | |
active = True | |
RED = 0b000000000000111111111111 | |
GREEN = 0b111111111111000000000000 | |
Rshift = 1 | |
Gshift = 0 | |
while active: | |
try : | |
if (RED & 1<<23) : | |
Rshift = 0 | |
if (RED & 1) : | |
Rshift = 1 | |
if (GREEN & 1<<23) : | |
Gshift = 0 | |
if (GREEN & 1) : | |
Gshift = 1 | |
if Rshift : | |
RED = RED << 1 | |
else: | |
RED = RED >> 1 | |
if Gshift : | |
GREEN = GREEN << 1 | |
else : | |
GREEN = GREEN >> 1 | |
i2c.writeBar(RED, GREEN) | |
timer.tick(15) | |
except KeyboardInterrupt: | |
#except : | |
active = False | |
i2c.writeClear() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from smbus2 import SMBus | |
import random | |
alpha = [0b0000000000000001, | |
0b0000000000000010, | |
0b0000000000000100, | |
0b0000000000001000, | |
0b0000000000010000, | |
0b0000000000100000, | |
0b0000000001000000, | |
0b0000000010000000, | |
0b0000000100000000, | |
0b0000001000000000, | |
0b0000010000000000, | |
0b0000100000000000, | |
0b0001000000000000, | |
0b0010000000000000, | |
0b0100000000000000, | |
0b1000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0000000000000000, | |
0b0001001011001001, | |
0b0001010111000000, | |
0b0001001011111001, | |
0b0000000011100011, | |
0b0000010100110000, | |
0b0001001011001000, | |
0b0011101000000000, | |
0b0001011100000000, | |
0b0000000000000000, # | |
0b0000000000000110, # ! | |
0b0000001000100000, # " | |
0b0001001011001110, # # | |
0b0001001011101101, # $ | |
0b0000110000100100, # % | |
0b0010001101011101, # & | |
0b0000010000000000, # ' | |
0b0010010000000000, # ( | |
0b0000100100000000, # ) | |
0b0011111111000000, # * | |
0b0001001011000000, # + | |
0b0000100000000000, # , | |
0b0000000011000000, # - | |
0b0000000000000000, # . | |
0b0000110000000000, # / | |
0b0000110000111111, # 0 | |
0b0000000000000110, # 1 | |
0b0000000011011011, # 2 | |
0b0000000010001111, # 3 | |
0b0000000011100110, # 4 | |
0b0010000001101001, # 5 | |
0b0000000011111101, # 6 | |
0b0000000000000111, # 7 | |
0b0000000011111111, # 8 | |
0b0000000011101111, # 9 | |
0b0001001000000000, # : | |
0b0000101000000000, # ; | |
0b0010010000000000, # < | |
0b0000000011001000, # = | |
0b0000100100000000, # > | |
0b0001000010000011, # ? | |
0b0000001010111011, # @ | |
0b0000000011110111, # A | |
0b0001001010001111, # B | |
0b0000000000111001, # C | |
0b0001001000001111, # D | |
0b0000000011111001, # E | |
0b0000000001110001, # F | |
0b0000000010111101, # G | |
0b0000000011110110, # H | |
0b0001001000000000, # I | |
0b0000000000011110, # J | |
0b0010010001110000, # K | |
0b0000000000111000, # L | |
0b0000010100110110, # M | |
0b0010000100110110, # N | |
0b0000000000111111, # O | |
0b0000000011110011, # P | |
0b0010000000111111, # Q | |
0b0010000011110011, # R | |
0b0000000011101101, # S | |
0b0001001000000001, # T | |
0b0000000000111110, # U | |
0b0000110000110000, # V | |
0b0010100000110110, # W | |
0b0010110100000000, # X | |
0b0001010100000000, # Y | |
0b0000110000001001, # Z | |
0b0000000000111001, # [ | |
0b0010000100000000, # | |
0b0000000000001111, # ] | |
0b0000110000000011, # ^ | |
0b0000000000001000, # _ | |
0b0000000100000000, # ` | |
0b0001000001011000, # a | |
0b0010000001111000, # b | |
0b0000000011011000, # c | |
0b0000100010001110, # d | |
0b0000100001011000, # e | |
0b0000000001110001, # f | |
0b0000010010001110, # g | |
0b0001000001110000, # h | |
0b0001000000000000, # i | |
0b0000000000001110, # j | |
0b0011011000000000, # k | |
0b0000000000110000, # l | |
0b0001000011010100, # m | |
0b0001000001010000, # n | |
0b0000000011011100, # o | |
0b0000000101110000, # p | |
0b0000010010000110, # q | |
0b0000000001010000, # r | |
0b0010000010001000, # s | |
0b0000000001111000, # t | |
0b0000000000011100, # u | |
0b0010000000000100, # v | |
0b0010100000010100, # w | |
0b0010100011000000, # x | |
0b0010000000001100, # y | |
0b0000100001001000, # z | |
0b0000100101001001, # { | |
0b0001001000000000, # | | |
0b0010010010001001, # } | |
0b0000010100100000, # ~ | |
0b0011111111111111] | |
class i2cVC : | |
def __init__(self, bus=1, addr=0x70, bright=8) : | |
self.bus = SMBus(bus) | |
self.addr = addr | |
self.bus.write_byte(self.addr,0x21) # oscillator on | |
self.bus.write_byte(self.addr,0x81) # no blink | |
self.bus.write_byte(self.addr,0xe2) # brightness 8 | |
def writeChar(self, pos, char=' ') : | |
if isinstance(char,int) : | |
if char < 10 : | |
font = alpha[ord('0')+char] | |
else: | |
font = alpha[char%len(alpha)] | |
else: | |
font = alpha[ord(char)] | |
self.bus.write_byte_data(self.addr,pos*2,font & 0xff) | |
self.bus.write_byte_data(self.addr,pos*2+1,font >>8 ) | |
def writeRandom(self) : | |
# 24 - 127 | |
low = 48 | |
high = 91 | |
self.writeChar(0,random.randint(low,high)) | |
self.writeChar(1,random.randint(low,high)) | |
self.writeChar(2,random.randint(low,high)) | |
self.writeChar(3,random.randint(low,high)) | |
def writeClear(self) : | |
self.writeChar(0) | |
self.writeChar(1) | |
self.writeChar(2) | |
self.writeChar(3) | |
def writeWord(self, word ) : | |
if isinstance(word,int) : | |
w = word | |
for i in range(3, -1, -1) : | |
if w == 0 : | |
self.writeChar(i) | |
else: | |
self.writeChar(i,w%10) | |
w = w//10 | |
else: | |
for i in range(0,4) : | |
if i < len(word) : | |
self.writeChar(i,word[i]) | |
else : | |
self.writeChar(i) | |
def writeBar(self, RED=0, GREEN=0 ) : | |
# input is 2 24-bit words for RED and GREEN | |
# bargraph output written as 6 8-bit bytes | |
# (24 bars * 2 bits for color = 48 bits) | |
B = [0]*6 | |
# the even bytes are RED | |
B[0] = (RED & 0x00000f) | ((RED & 0x00f000)>>8) | |
B[2] = ((RED & 0x0000f0)>>4) | ((RED & 0x0f0000)>>12) | |
B[4] = ((RED & 0x000f00)>>8) | ((RED & 0xf00000)>>16) | |
# the odd bytes are GREEN | |
B[1] = (GREEN & 0x00000f) | ((GREEN & 0x00f000)>>8) | |
B[3] = ((GREEN & 0x0000f0)>>4) | ((GREEN & 0x0f0000)>>12) | |
B[5] = ((GREEN & 0x000f00)>>8) | ((GREEN & 0xf00000)>>16) | |
for i in range(0,6) : | |
self.bus.write_byte_data(self.addr,i,B[i]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is an old hack: connecting an I2C device to the DDC pins of an unused video port. DDC gives a low speed (80KHz) I2C bus - mostly used on old Linux workstations that had no other way to interface to I2C devices.
Also useful on a Raspberry Pi when the case blocks access to the I2C pins.
It works fine on a Pi-4, but i2cdetect is a little weird:
It's only reporting on addresses 0x30 - 0x37 and 0x50 - 0x5f. All of the addresses work however. The GIF above is an LED BarGraph on address 0x71, connected to the HDMI port on a Raspberry Pi 4 through an Adafruit HDMI breakout; Python with SMBus2
So, cool, right? Well... it only works at low speed, and there's only 50 mA of 5V available, and it takes some changes to use the standard device libraries, so really you're only going to use it for simple I2C interfaces like the Adafruit LED Backpack.... but, still...?