005.Python制作客户端截屏通过合宙ESP32-C3投屏到0.96OLED

Python制作客户端截屏通过ESP32-C3投屏到0.96’OLED

一、实现原理

    1. Python对屏幕进行截屏,并进行数据处理
    1. Python与ESP32-C3通过WIFI建立tcp连接
    1. Python将处理后的数据发送给ESP32-C3
    1. ESP32-C3将接受到的数据推送给0.96’OLED
      005.Python制作客户端截屏通过合宙ESP32-C3投屏到0.96OLED_第1张图片

合宙Esp32-c3投屏电脑屏幕

二、0.96’OLED显示原理

1.显示原理

OLED显示屏宽128像素,高64像素,即128x64,共8192个像素
为了清晰这里以32x16进行展示
005.Python制作客户端截屏通过合宙ESP32-C3投屏到0.96OLED_第2张图片

显示过程:
c3将0x01写入红色方框1,按照低位在前的顺序,如图进行显示,而后依次是2/3/4/5
一个十六进制字节0x01可以确定8个像素的状态,由此可知屏幕 所需字节 = 128 ∗ 64 / 8 所需字节=128*64/8 所需字节=12864/8即1024字节。

2.OLED与Esp32连接

OLED Esp32
GND GND
VCC 5V
SCL IO5
SDA IO4

三、Python截屏原理

1.截屏

img_screen = ImageGrab.grab()  # 截屏

2.数据处理

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)

3.将数据转化为ESP32-C3能读取的信息

#将'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

四、开启TCP传输

1.创建线程

def tcp_create_server(self):
        tcp = threading.Thread(target=self.tcp_create)  # 创建串口接收线程
        tcp.start()

2.创建TCP连接

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()

3.发送数据

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()

五、ESP32-C3接受并显示

1.连接WIFI

 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); //等待1while (WiFi.status() != WL_CONNECTED) //判断wifi是否连接成功
  {
    delay(1000); //500毫秒检测一次状态
    display.clear();
    display.drawString(0, 32,"Connect to wifi....");
    display.display();
  }

2.接受数据

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();
    }
  }

你可能感兴趣的:(ESP32-C3,Pyqt5,python,opencv,开发语言)