合宙Esp32-c3投屏电脑屏幕
显示过程:
c3将0x01写入红色方框1,按照低位在前的顺序,如图进行显示,而后依次是2/3/4/5
一个十六进制字节0x01可以确定8个像素的状态,由此可知屏幕 所需字节 = 128 ∗ 64 / 8 所需字节=128*64/8 所需字节=128∗64/8即1024字节。
OLED | Esp32 |
---|---|
GND | GND |
VCC | 5V |
SCL | IO5 |
SDA | IO4 |
img_screen = ImageGrab.grab() # 截屏
img_screen = np.asarray(img_screen) # 将截屏转化为array,[[第1行像素],[第2行像素]...]
img_screen = cv.resize(img_screen, (myScreenWidth,myScreenHeight)) # 截切截屏图片为128*64
img_screen = cv.cvtColor(img_screen, cv.COLOR_BGR2GRAY)#转为灰度图
img_screen = cv.adaptiveThreshold(img_screen, 1, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 15, 1)#二值化 img_screen_tcp = Numpy2HexArray(img_screen)
#将'0,1,0,0,1,1,0,1,0,0,0,0,1,1,1,1,....'(1位代表1个像素亮或灭)转化为'b'\xb2\xf0....',前八位反向合并即为0xb2
def Numpy2HexArray(img_screen_01str):
str_bin_8bit = '' # 建立空白字符串,用于存放二进制数字串
len_img_screen = int(len(img_screen_01str))#图像数据为二维数组[[],[],[]],数组的长度为图片的高度,里面每一个数组存放有图片宽度个0.1数字
str_hex=''# 建立空白字符串,用于存放'b2f0......'
#因为imread读取图片的方式为从左往右,从上至下的方式进行
#故应当先读取第一行,再读取第二行,依此类推
for i in range(0, len_img_screen):#图片高度64
for k in range(0,int(myScreenWidth/8)):#图片宽度128除8,用于取出每一个单一数组中的0.1数字
for j in range(7+8*k, -1+8*k, -1): # 低位在前,一次将8位二进制数字(0,1,0,0,1,1,0,1)反向合并为一个字符串'10110010'
str_bin_8bit = str_bin_8bit + str(img_screen_01str[i][j])
mumber = int(str_bin_8bit, 2) # 字符串'00001001'转为10进制数字(178)
str_bin_8bit = ''#二进制数字符串清零,读取下一个8位二进制数
# 将转化得到的10进制数字(178)转化为'0xb2',确保'0xb2'宽度为2位,同时去除0x,得到b2,合并至字符串str_hex('b2f0......')
str_hex=str_hex+hex(mumber)[2:].zfill(2).replace("0x","")
str_hex=str_hex.strip('\n')#去除字符串结尾的'\n',确保字符串为偶数位,防止出现ODD错误
img_screen_hex = binascii.a2b_hex(str_hex)#将'b2f0......'转化为'b'\xb2\xf0....',用于TCP socket传输
return img_screen_hex
def tcp_create_server(self):
tcp = threading.Thread(target=self.tcp_create) # 创建串口接收线程
tcp.start()
def tcp_create(self):
global decision_path, connect_flag,connect_txrx_flag
connect_txrx_flag = 0
HOST = '192.168.42.50'
hoststr = 'IP :' + HOST
self.ui.textEdit.append(hoststr)
PORT = 9999
portstr = '端口:' + str(PORT)
self.ui.textEdit.append(portstr)
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR) # 绑定IP地址和端口号
tcpSerSock.listen(5) # 监听,使得主动变为被动
print('正在等待连接....')
self.ui.textEdit.append('正在等待连接....')
while True:
tcpCliSock, addr = tcpSerSock.accept() # 当来新的连接时,会产生一个的新的套接字为客户端服务
print(tcpCliSock)
print(addr)
print('连接成功')
self.ui.textEdit.append('连接成功'+str(addr))
connect_flag = 1
myrec = threading.Thread(target=rec, args=(tcpCliSock, BUFSIZ,))
myrec.start()
mysend = threading.Thread(target=send, args=(tcpCliSock,))
mysend.start()
tcpSerSock.close()
def send(tcpCliSock):
global connect_flag
global decision_path
global path_change_flag
delay = 0.8
# data = screen_capture_tcp()
while connect_flag:
data = screen_capture_tcp()
tcpCliSock.send(data)
time.sleep(delay) # 间隔delay秒发一次
tcpCliSock.close()
const char* ssid = "XTZJM"; //填写你的wifi名字,笔记本和ESP32连接同一WIFI
const char* password = "XXXX"; //填写你的wifi密码
const int httpPort = 9999; //设置上位机端口
char* IP = "192.168.42.50"; //上位机IP
WiFi.begin(ssid, password); //连接wifi
display.setFont(ArialMT_Plain_10);
delay(1000); //等待1秒
while (WiFi.status() != WL_CONNECTED) //判断wifi是否连接成功
{
delay(1000); //每500毫秒检测一次状态
display.clear();
display.drawString(0, 32,"Connect to wifi....");
display.display();
}
while (client.available())
{
read_count = client.read(buff, 1024); //向缓冲区读取数据
if (read_count == 1024)
{
read_count = 0;
display.clear();
display.drawXbm(0, 0, WiFi_Logo_width, WiFi_Logo_height, buff);
display.display();
}
}
display.clear();
display.drawXbm(0, 0, WiFi_Logo_width, WiFi_Logo_height, buff);
display.display();
}
}