ESP8266图传功能通过UDP客户端给esp8266发送图片数据并显示
✨利用UDP协议实现esp8266图传功能。
arduino高级9-python-opencv取模-esp底层udp设计#跟着John一起学开发
🛠实现原理分析
📜通过udp数据传送,将我们需要发送的数据发给目标–
esp8266
接收板,然后esp8266对数据进行解析,并通过OLED显示出图像出来。
- 📑由于esp8266驱动的显示屏幕是0.96寸的ssd1306 IIC屏幕,我们发送过去的图片最好先提前做好处理,因为esp8266驱动的是0.96寸的屏幕,你不能给他传个1024*1024的图片让其显示吧。
我就以下面这张图片为例:
🚩图片处理步骤
- 🔨处理显示尺寸大小,将图片转换成128, 64
- 🔨格式转换,将图片颜色 BGR2RGB
这里需要借用PY程序,处理图片转码。
import cv2
from PIL import Image
img = cv2.imread('arduino.jpg', cv2.IMREAD_UNCHANGED)
#print('Original Dimensions : ',img.shape)
#scale_percent = 60 # percent of original size
#width = int(img.shape[1] * scale_percent / 100)
#height = int(img.shape[0] * scale_percent / 100)
dim = (128, 64)
# resize image
resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
im = Image.fromarray(cv2.cvtColor(resized,cv2.COLOR_BGR2RGB))
#im.show()
#im = im.convert("L")
im = im.convert("1")
text =''
point = 0
for y in range (64):
for x in range (128):
if im.getpixel((x,y)) <150:
get_point = 0
else:
get_point = 1
now = int( get_point )<<(3-x%4)
#位数1/0 转二进制
point += now
if (x%4 ==3):
text += hex(point)[2:]
#text += "|"
point = 0 #还原
print(text)
#print('Resized Dimensions : ',resized.shape)
#cv2.imshow("Resized image", resized)
#cv2.waitKey(0)
#cv2.destroyAllWindows()
-
自动生成128X64/4个像素点
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa00afffffffffe9015fffffffffffff856d11fffffffe94aca5ffdffffffffc5222aa3ffffff44a522abfd7fffffff2a9544487ffffd2a289445fbfffffffca4a8aaaa9ffff2929552947ffffffff51246a4924fffd4494aaa52bfffffffe8aabfff2523ffa2aafffa950fffffffd54bffffd2a8fe4a4fffffa257ffffffa22ffffff8957d293fffffe94bffffff495ffffffe493a94fffffff521ffffff2abfffffffa49143fffffffc9afffffe92ffffffffaaa45bfff5fffe45fffffe49ffffffffe2552ffff27fff527ffffd55fffffffff9095fffe9ffff297ffffc93fffffffffaa4bffff47fff4afffffd49ff8040fffcaa7ffc0a83ffa47ffffca5ffad2d7ffe257ffed25bff12bffffd15ffa2a2fffd517ffd2947ffd4fffffca5ffffff7ff88a5fffe4ffff227ffffe93fffffffff5553ffff57fff4afffffe48ffffffffe2214ffff2fffea97ffffeaaffffffff955493ffeafffe14ffffff127fffffff51154bfffffff943ffffff493ffffffe94b9247ffffffab5ffffffaa8ffffff84afc92bfffffe48bffffffd253ffffc552ff490fffff9257ffffffe9247ffe552bff54a17ffa492ffffffff4928541248bffcaaa9544a55ffffffffd54a92c925ffff2294a5214bfffffffff224aa2a97ffffd44512ad2ffffffffffd5245495ffffff2a8a910ffffffffffff9528a57ffffffe954aa7fffffffffffff4925fffffffffe9245fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd7faafeabfd7d7aaaf5f5fcaffffffff93f921e907d7e7a49e8f5f257fffffff4bf4f5e5ebd7d7faff575e5cbfffffff35faf4f3e9cbcbf97e272d3e5ffffffeb3f5f2ebf3d7e7faff519cbebffffffeb8f80bebe9cbd7f97ebaaebe5ffffffd4afad7e5ebe7d7faff1a5d7ebffffffca575e3f3e5d7cbf97ebd2e3d3ffffffd7cf8e9e817e12f848f5e9f4afffffff97d35f4e5affaafaaaebf5fa1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-
📓udp工具界面
- 📋esp8266接收板,串口打印信息
📝ESP8266实例代码
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO: A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#ifndef STASSID
#define STASSID "填写WIFI账号"
#define STAPSK "填写WIFI密码"
#endif
unsigned int localPort = 8888; // local port to listen on
// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE + 1]; //buffer to hold incoming packet,
WiFiUDP Udp;
char hex_str[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};//每次发过来的数据
uint8_t hex_list[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x5, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}; //16进制的数
//查询列表的返回
uint8_t check_char (char temp_) {
for (int x = 0 ; x < 16 ; x++)
if (temp_ == hex_str[x])
{
return hex_list[x];
break;
}
}
void setup() {
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;); // Don't proceed, loop forever
}
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
display.display();
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(STASSID, STAPSK);
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(500);
}
Serial.print("Connected! IP address: ");
Serial.println(WiFi.localIP());
Serial.printf("UDP server on port %d\n", localPort);
Udp.begin(localPort);
display.clearDisplay();
display.setTextSize(2); // Normal 1:1 pixel scale
display.setTextColor(SSD1306_WHITE); // Draw white text
display.setCursor(0, 0); // Start at top-left corner
display.println(F("IP:"));
display.println(WiFi.localIP());
display.setTextSize(2);
display.print(F("PORT:"));
display.println(localPort);
display.display();
}
int index_l = 0;
int rows = 0;
void loop() {
// if there's data available, read a packet
int packetSize = Udp.parsePacket();
if (packetSize) {
Serial.printf("Received packet of size %d from %s:%d\n (to %s:%d, free heap = %d B)\n",
packetSize,
Udp.remoteIP().toString().c_str(), Udp.remotePort(),
Udp.destinationIP().toString().c_str(), Udp.localPort(),
ESP.getFreeHeap());
// read the packet into packetBufffer
int n = Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
packetBuffer[n] = 0;
Serial.println("Contents:");
Serial.println(packetBuffer);
for (int x = 0; x < n ; x++)
{
if ( packetBuffer[x] == '*') {
Serial.println("recv start:");
display.clearDisplay();
index_l = 0 ;
rows = 0 ;
}
else if ( packetBuffer[x] == '#') {
Serial.println("over");
display.display();
index_l = 0 ;
rows = 0 ;
}
else {
char t = check_char (packetBuffer[x]);
for (int y = 0 ; y < 4 ; y++)
{
if (index_l == 128) {
index_l = 0;
rows++;
}
int point = 0;
if ( t << (4 + y) >> 7 & 1) {
point = 1;
}
display.drawPixel (index_l, rows, point);
index_l ++;
}
}
}
}
}
/*
test (shell/netcat):
--------------------
nc -u 192.168.esp.address 8888
*/
- 🌿接收前,OLED屏幕会显示esp8266的IP,以及端口号
通过udp网络调试工具,设置该IP和端口号,并进行连接。
- 接收数据后,OLED显示效果
⛳相关问题和解答
- Spyder安装。参考:《Spyder安装教程只需三步_保姆式无基础 2020/11/7最新版》
*Spyder找不到CV2,在WIn +R 键入CMD,如果python已经默认安装在C盘的,直接pip install opencv-contrib-python
参考:《ModuleNotFoundError: No module named ‘cv2’ (安装cv2)》 - 需要注意的是图片的转换,提前准备好图片并放置在目标文件夹里面。然后点击用Spyder来加载.py文件,并运行,会生成我们需要的16进制代码。
- 相关工具下载链接:TCP/UDP 网络调试助手(PC版)https://docs.ai-thinker.com/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B72