├── README.md
├── rsc
├── ...
├── board-pinout1.jpg
├── board-pinout2.jpg
└── lcd-pinout.jpg
└── sources
├── ...
├── Esp32
├── ...
└── UART-Load-Bitmap
│ ├── CMakeLists.txt
│ ├── include
│ └── lcd.h
│ ├── main
│ ├── lcd.c
│ └── uart_load_bitmap.c
│ ├── sdkconfig
│ └── sdkconfig.old
└── Win
├── ...
└── UartTest
├── UartTest.sln
└── UartTest
├── 9460735_Sz9_icon.ico
├── App.config
├── App.xaml
├── App.xaml.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── UartTest.csproj
├── bin
└── Release
│ ├── UartTest.exe
│ ├── UartTest.exe.config
│ └── UartTest.pdb
└── espressiflogofullglow_9Q4_icon.ico
/README.md:
--------------------------------------------------------------------------------
1 | ## *Load an image bitmap via COM port and display it on LCD (ILI9341)*
2 | The following example demonstrates how to load any image via UART0 (onboard USB-TTL on esp32) that is usually an onboard USB to TTL connection so it is easier for user to connect Esp device right away.
3 |
4 | ## Setup and Test Guide
5 |
6 | - [Hardware parts](#hardware-parts)
7 | - [LCD 320x240 ILI9341 (SPI)](#lcd-display)
8 | - [ESP32 Board](#esp32-board)
9 | - [Code of windows app and esp firmware](#code-of-windows-app-and-esp-firmware)
10 | - [WPF Application in C#](#wpf-application-c)
11 | - [IDF Project in C/C++](#idf-project)
12 | - [Connect Pins](#connect-pins)
13 | - [Compile code](#compile-code)
14 | - [Run and Test](#run-and-test)
15 |
16 | - [How it works](#how-it-works)
17 |
18 | ## Hardware Parts
19 |
20 | ### LCD Display
21 |
22 | I used a popular TFT 32x240 ILI9341 display with SPI interface
23 |
24 | ### ESP32 Board
25 |
26 | ESP32 module used was brown WROOM board with 4Mb flash but you can use any board
27 | like WROVER which will increase speed of transfer if you use PSI RAM (see notes)
28 |
29 | ## Code of Windows app and ESP firmware
30 |
31 | We essentially need a client-server or client-client communication in this case
32 | The data from PC is sent after selecting an image from very simple picture list that points to your folder with pictures
33 | By clicking on the picture the image is instantly sent to ESP32
34 |
35 | ### WPF Application (C#)
36 | It is a very basic application based on WPF written in C#.NET
37 | The solution uses Visual Studio 2017 but feel welcome to upgrade or modify it so it compiles and works
38 |
39 | ### IDF Project
40 | The project follows code example included with idf framework. It uses CMake. The program awaits for UART event when COM data arrives from PC and sends it to TFT via SPI pins.
41 |
42 | ## Connect Pins
43 |
44 |
45 | | LCD | PIN |
46 | | --- | --- |
47 | | CS | 15 |
48 | | MOSI | 13 |
49 | | CLK | 14 |
50 | | DC | 21 |
51 | | RST | 22 |
52 | | LED | 5 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | ## Compile Code
60 |
61 | Application tosend bitmap is compiled with Visual Studio 2017 as C# solution *(.NET 4.6.1).
62 | Just load the project (.sln) and run debugging or execute binary exe included with the source code.
63 | Esp code requires CMake to compile - *idf.py -p COMX flash*
64 | **Important: Do not run monitor as it blocks the acces to the com port**
65 |
66 |
67 | ## Run and Test
68 | First just connect esp onboard usb to PC and make sure it is recognized
69 | Next run Windoes wpf app called UartTest and select your picture to be lozaded
70 | Note: it may take a second to load a full bitmap because UART is very slow
71 | 115200 bits/s is only 14kb/s so be patient during load)
72 |
73 | ## How it works
74 | In brief - windows app acts as a data server sending bytes instantly after clicking image.
75 | Esp program waits for an *UART_DATA* event and starts loading the bitmap in screen portions because of memory limits.
76 | It is defined as *BLOCK_LINES* which is *DISPLAY_HEIGHT / (n)*. *n* is number of loaded image portions.
77 | On 4Mb boards *n*>=2 however if you use PSRAM board *n* could be set to 1
78 | If *BLOCK_LINES=DISPLAY_HEIGHT* you get maximum performance.
79 | I used 565 bitmap pixel format (*Format16bppRgb565*) which is sent already converted and resized on PC side.
80 | All the logging output is disabled and redirected to win app small port monitoring code.
81 | The monitor is very simple and because of ANSI standard being processed there might be some ascii artifacts.
82 | Feel free to experiment with the code - it may turn out to be usefull :wink:
83 |
84 | Here is a result:
85 |
86 |
87 |
--------------------------------------------------------------------------------
/rsc/...:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/rsc/board-pinout1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Deous/ESP32-UART-Load-Bitmap/ea0f42a211b1aea33a15ff212504fa9fb211bc8c/rsc/board-pinout1.jpg
--------------------------------------------------------------------------------
/rsc/board-pinout2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Deous/ESP32-UART-Load-Bitmap/ea0f42a211b1aea33a15ff212504fa9fb211bc8c/rsc/board-pinout2.jpg
--------------------------------------------------------------------------------
/rsc/lcd-pinout.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Deous/ESP32-UART-Load-Bitmap/ea0f42a211b1aea33a15ff212504fa9fb211bc8c/rsc/lcd-pinout.jpg
--------------------------------------------------------------------------------
/sources/...:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sources/Esp32/...:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/sources/Esp32/UART-Load-Bitmap/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # The following four lines of boilerplate have to be in your project's CMakeLists
2 | # in this exact order for cmake to work correctly
3 | cmake_minimum_required(VERSION 3.5)
4 |
5 | set(MAIN_SRCS main/uart_load_bitmap.c main/lcd.c)
6 |
7 | include_directories(include/)
8 | include($ENV{IDF_PATH}/tools/cmake/project.cmake)
9 | project(uart_load_bitmap)
10 |
--------------------------------------------------------------------------------
/sources/Esp32/UART-Load-Bitmap/include/lcd.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __LCD_H_
3 | #define __LCD_H_
4 |
5 | #ifdef __cplusplus
6 | extern "C" {
7 | #endif
8 |
9 | #include "freertos/FreeRTOS.h"
10 | #include "driver/spi_master.h"
11 |
12 | /*
13 | HSPI VSPI
14 | Pin Name GPIO Number
15 | ------------------------
16 | CS0 15 5
17 | SCLK 14 18
18 | MISO 12 19
19 | MOSI 13 23
20 | */
21 |
22 | #define PIN_NUM_MISO 12
23 | #define PIN_NUM_MOSI 13
24 | #define PIN_NUM_CLK 14
25 | #define PIN_NUM_CS 15
26 |
27 | #define PIN_NUM_DC 21
28 | #define PIN_NUM_RST 22
29 | #define PIN_NUM_BCKL 5
30 |
31 | #define DISPLAY_WIDTH 320
32 | #define DISPLAY_HEIGHT 240
33 |
34 | #define BLOCK_LINES (DISPLAY_HEIGHT / 2)
35 |
36 |
37 | typedef struct {
38 | uint8_t cmd;
39 | uint8_t data[16];
40 | uint8_t databytes; //No of data in data; bit 7 = delay after set; 0xFF = end of cmds.
41 | } lcd_init_cmd_t;
42 |
43 |
44 | volatile spi_device_handle_t spi;
45 |
46 |
47 | void initialise_lcd(void);
48 | void display_image_block(spi_device_handle_t spi, int ypos, void *image_data);
49 | void wait_data_done(spi_device_handle_t spi) ;
50 |
51 | #ifdef __cplusplus
52 | }
53 | #endif
54 |
55 | #endif
56 |
57 |
--------------------------------------------------------------------------------
/sources/Esp32/UART-Load-Bitmap/main/lcd.c:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include
4 | #include
5 | #include "freertos/FreeRTOS.h"
6 | #include "freertos/task.h"
7 | #include "esp_system.h"
8 | #include "driver/spi_master.h"
9 | #include "soc/gpio_struct.h"
10 | #include "driver/gpio.h"
11 | #include "lcd.h"
12 |
13 | DRAM_ATTR static const lcd_init_cmd_t ili_init_cmds[]={
14 | {0xCF, {0x00, 0x83, 0X30}, 3},
15 | {0xED, {0x64, 0x03, 0X12, 0X81}, 4},
16 | {0xE8, {0x85, 0x01, 0x79}, 3},
17 | {0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
18 | {0xF7, {0x20}, 1},
19 | {0xEA, {0x00, 0x00}, 2},
20 | {0xC0, {0x26}, 1},
21 | {0xC1, {0x11}, 1},
22 | {0xC5, {0x35, 0x3E}, 2},
23 | {0xC7, {0xBE}, 1},
24 | {0x36, {0x28}, 1},
25 | {0x3A, {0x55}, 1},
26 | {0xB1, {0x00, 0x1B}, 2},
27 | {0xF2, {0x08}, 1},
28 | {0x26, {0x01}, 1},
29 | {0xE0, {0x1F, 0x1A, 0x18, 0x0A, 0x0F, 0x06, 0x45, 0X87, 0x32, 0x0A, 0x07, 0x02, 0x07, 0x05, 0x00}, 15},
30 | {0XE1, {0x00, 0x25, 0x27, 0x05, 0x10, 0x09, 0x3A, 0x78, 0x4D, 0x05, 0x18, 0x0D, 0x38, 0x3A, 0x1F}, 15},
31 | {0x2A, {0x00, 0x00, 0x00, 0xEF}, 4},
32 | {0x2B, {0x00, 0x00, 0x01, 0x3f}, 4},
33 | {0x2C, {0}, 0},
34 | {0xB7, {0x07}, 1},
35 | {0xB6, {0x0A, 0x82, 0x27, 0x00}, 4},
36 | {0x11, {0}, 0x80},
37 | {0x29, {0}, 0x80},
38 | {0, {0}, 0xff},
39 | };
40 |
41 | //Send a command to the LCD. Uses spi_device_transmit, which waits until the transfer is complete.
42 | void lcd_cmd(spi_device_handle_t spi, const uint8_t cmd)
43 | {
44 | esp_err_t ret;
45 | spi_transaction_t t;
46 | memset(&t, 0, sizeof(t)); //Zero out the transaction
47 | t.length=8; //Command is 8 bits
48 | t.tx_buffer=&cmd; //The data is the cmd itself
49 | t.user=0L;//(void*)0; //D/C needs to be set to 0
50 | ret=spi_device_transmit(spi, &t); //Transmit!
51 | assert(ret==ESP_OK); //Should have had no issues.
52 | }
53 |
54 | //Send data to the LCD. Uses spi_device_transmit, which waits until the transfer is complete.
55 | void lcd_data(spi_device_handle_t spi, const uint8_t *data, int len)
56 | {
57 | esp_err_t ret;
58 | spi_transaction_t t;
59 | if (len==0) return; //no need to send anything
60 | memset(&t, 0, sizeof(t)); //Zero out the transaction
61 | t.length=len*8; //Len is in bytes, transaction length is in bits.
62 | t.tx_buffer=data; //Data
63 | t.user=(void*)1; //D/C needs to be set to 1
64 | ret=spi_device_transmit(spi, &t); //Transmit!
65 | assert(ret==ESP_OK); //Should have had no issues.
66 | }
67 |
68 | //This function is called (in irq context!) just before a transmission starts. It will
69 | //set the D/C line to the value indicated in the user field.
70 | void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
71 | {
72 | int dc=(int)t->user;
73 | gpio_set_level(PIN_NUM_DC, dc);
74 | }
75 |
76 | uint32_t lcd_get_id(spi_device_handle_t spi)
77 | {
78 | //get_id cmd
79 | lcd_cmd( spi, 0x04);
80 |
81 | spi_transaction_t t;
82 | memset(&t, 0, sizeof(t));
83 | t.length=8*3;
84 | t.flags = SPI_TRANS_USE_RXDATA;
85 | t.user = (void*)1;
86 |
87 | esp_err_t ret = spi_device_transmit(spi, &t);
88 | assert( ret == ESP_OK );
89 | return *(uint32_t*)t.rx_data;
90 | }
91 |
92 | // somehow this does not work...
93 | uint32_t lcd_get_scanline(spi_device_handle_t spi)
94 | {
95 | lcd_cmd( spi, 0x45);
96 |
97 | spi_transaction_t t;
98 | memset(&t, 0, sizeof(t));
99 | t.length=1;
100 | t.flags = SPI_TRANS_USE_RXDATA;
101 | t.user = (void*)1;
102 | esp_err_t ret = spi_device_transmit(spi, &t);
103 | assert( ret == ESP_OK );
104 |
105 | t.flags = SPI_TRANS_USE_RXDATA;
106 | t.length=10;
107 | ret = spi_device_transmit(spi, &t);
108 |
109 | assert( ret == ESP_OK );
110 | return *(uint32_t*)t.rx_data;
111 | }
112 |
113 |
114 | //Initialize the display
115 | void lcd_init(spi_device_handle_t spi)
116 | {
117 | int cmd=0;
118 | const lcd_init_cmd_t* lcd_init_cmds;
119 |
120 | //Initialize non-SPI GPIOs
121 | gpio_set_direction(PIN_NUM_DC, GPIO_MODE_OUTPUT);
122 | gpio_set_direction(PIN_NUM_RST, GPIO_MODE_OUTPUT);
123 | gpio_set_direction(PIN_NUM_BCKL, GPIO_MODE_OUTPUT);
124 |
125 | //Reset the display
126 | gpio_set_level(PIN_NUM_RST, 0);
127 | vTaskDelay(100 / portTICK_RATE_MS);
128 | gpio_set_level(PIN_NUM_RST, 1);
129 | vTaskDelay(100 / portTICK_RATE_MS);
130 |
131 | //detect LCD type
132 | //uint32_t lcd_id = lcd_get_id(spi);
133 |
134 | lcd_init_cmds = ili_init_cmds;
135 |
136 |
137 | //Send all the commands
138 | while (lcd_init_cmds[cmd].databytes!=0xff) {
139 | lcd_cmd(spi, lcd_init_cmds[cmd].cmd);
140 | lcd_data(spi, lcd_init_cmds[cmd].data, lcd_init_cmds[cmd].databytes&0x1F);
141 | if (lcd_init_cmds[cmd].databytes&0x80) {
142 | vTaskDelay(100 / portTICK_RATE_MS);
143 | }
144 | cmd++;
145 | }
146 |
147 | ///Enable backlight
148 | gpio_set_level(PIN_NUM_BCKL, 1);
149 |
150 | }
151 |
152 | void display_image_block(spi_device_handle_t spi, int ypos, void *image_data)
153 | {
154 | esp_err_t ret;
155 | static spi_transaction_t trans[6];
156 |
157 | for (int x=0; x<6; x++) {
158 | memset(&trans[x], 0, sizeof(spi_transaction_t));
159 | if ((x&1)==0) {
160 | //Even transfers are commands
161 | trans[x].length=8;
162 | trans[x].user=(void*)0;
163 | } else {
164 | //Odd transfers are data
165 | trans[x].length=8*4;
166 | trans[x].user=(void*)1;
167 | }
168 | trans[x].flags=SPI_TRANS_USE_TXDATA;
169 | }
170 |
171 | trans[0].tx_data[0]=0x2A; //Column Address Set
172 | trans[1].tx_data[0]=0; //Start Col High
173 | trans[1].tx_data[1]=0; //Start Col Low
174 | trans[1].tx_data[2]=(DISPLAY_WIDTH)>>8; //End Col High
175 | trans[1].tx_data[3]=(DISPLAY_WIDTH)&0xff; //End Col Low
176 | trans[2].tx_data[0]=0x2B; //Page address set
177 | trans[3].tx_data[0]=ypos>>8; //Start page high
178 | trans[3].tx_data[1]=ypos&0xff; //start page low
179 | trans[3].tx_data[2]=(ypos+BLOCK_LINES)>>8; //end page high
180 | trans[3].tx_data[3]=(ypos+BLOCK_LINES)&0xff; //end page low
181 | trans[4].tx_data[0]=0x2C; //memory write
182 | trans[5].tx_buffer=image_data; //finally send the line data
183 | trans[5].length=DISPLAY_WIDTH*2*8*BLOCK_LINES; //Data length, in bits
184 | trans[5].flags=0; //undo SPI_TRANS_USE_TXDATA flag
185 |
186 | //Queue all transactions.
187 | for (int x=0; x<6; x++) {
188 | ret=spi_device_queue_trans(spi, &trans[x], portMAX_DELAY);
189 | assert(ret==ESP_OK);
190 | }
191 | }
192 |
193 | void wait_data_done(spi_device_handle_t spi)
194 | {
195 | spi_transaction_t *rtrans;
196 | esp_err_t ret=-1;
197 | for (int x=0; x<6; x++) {
198 | ret=spi_device_get_trans_result(spi, &rtrans, portMAX_DELAY);
199 | assert(ret==ESP_OK);
200 | //We could inspect rtrans now if we received any info back. The LCD is treated as write-only, though.
201 | }
202 | uint32_t scl = lcd_get_scanline(spi);
203 | printf("~~scanline: 0x%x\n",scl);
204 |
205 | }
206 |
207 | void initialise_lcd()
208 | {
209 | esp_err_t ret;
210 | spi_bus_config_t buscfg={
211 | .miso_io_num=PIN_NUM_MISO,
212 | .mosi_io_num=PIN_NUM_MOSI,
213 | .sclk_io_num=PIN_NUM_CLK,
214 | .quadwp_io_num=-1,
215 | .quadhd_io_num=-1,
216 | .max_transfer_sz=BLOCK_LINES*DISPLAY_WIDTH*2+8
217 | };
218 | spi_device_interface_config_t devcfg={
219 | .clock_speed_hz=60*1000*1000, //Clock out at 26 MHz
220 | .mode=0, //SPI mode 0
221 | .spics_io_num=PIN_NUM_CS, //CS pin
222 | .queue_size=7, //We want to be able to queue 7 transactions at a time
223 | .pre_cb=lcd_spi_pre_transfer_callback, //Specify pre-transfer callback to handle D/C line
224 | .flags=SPI_DEVICE_NO_DUMMY
225 | };
226 | //Initialize the SPI bus
227 | ret=spi_bus_initialize(HSPI_HOST, &buscfg, 1);
228 | ESP_ERROR_CHECK(ret);
229 | //Attach the LCD to the SPI bus
230 | ret=spi_bus_add_device(HSPI_HOST, &devcfg, &spi);
231 | ESP_ERROR_CHECK(ret);
232 | //Initialize the LCD
233 | lcd_init(spi);
234 |
235 | }
236 |
--------------------------------------------------------------------------------
/sources/Esp32/UART-Load-Bitmap/main/uart_load_bitmap.c:
--------------------------------------------------------------------------------
1 | /* UART Load Bitmap Example
2 | Below code loads a butmap image sent from Windows client
3 | after reading bytes in form of TFT
4 |
5 | This example code is in the Public Domain (or CC0 licensed, at your option.)
6 |
7 | Unless required by applicable law or agreed to in writing, this
8 | software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
9 | CONDITIONS OF ANY KIND, either express or implied.
10 | */
11 | #include
12 | #include "freertos/FreeRTOS.h"
13 | #include "freertos/task.h"
14 | #include "driver/uart.h"
15 | #include "esp_log.h"
16 | #include "lcd.h"
17 |
18 | // this is an LCD line block size to be displayed by one iteration of spi
19 | #define BUF_SIZE (DISPLAY_WIDTH*2*BLOCK_LINES)
20 |
21 | // we substitute esp log functions with our own
22 | int printf_func(const char* str, va_list vl)
23 | {
24 | return 0;
25 | }
26 |
27 | static QueueHandle_t uart0_queue;
28 |
29 | static void uart_task()
30 | {
31 | uart_event_t event;
32 | int n_received=0, n_total=0;
33 |
34 | uint8_t *data = (uint8_t *)malloc(BUF_SIZE);
35 |
36 | for(;;)
37 | {
38 | if(xQueueReceive(uart0_queue, (void*)&event, portMAX_DELAY))
39 | {
40 | if(event.type==UART_DATA)
41 | {
42 | for (int y=0; y
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Data;
5 | using System.Linq;
6 | using System.Threading.Tasks;
7 | using System.Windows;
8 |
9 | namespace UartTest
10 | {
11 | ///
12 | /// Interaction logic for App.xaml
13 | ///
14 | public partial class App : Application
15 | {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Text;
4 | using System.IO;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Input;
9 | using System.Windows.Media;
10 | using System.Windows.Media.Imaging;
11 | using System.IO.Ports;
12 | using System.Management;
13 | using sd=System.Drawing;
14 | using System.Runtime.InteropServices;
15 |
16 | namespace UartTest
17 | {
18 | ///
19 | /// Interaction logic for MainWindow.xaml
20 | ///
21 | public partial class MainWindow : Window
22 | {
23 | public static byte[] sp_buffer;
24 | public static SerialPort Serial_Port;
25 |
26 | public MainWindow()
27 | {
28 | InitializeComponent();
29 |
30 | sp_buffer = new byte[10240]; // 10k memory
31 |
32 | cbPort.SelectionChanged += CbPort_SelectionChanged;
33 | cbPort.DisplayMemberPath = "PortInfo";
34 |
35 | RefreshCOMs();
36 |
37 | ManagementEventWatcher watcher = new ManagementEventWatcher();
38 | WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE (EventType = 2 OR EventType = 3)");
39 | watcher.EventArrived += Watcher_EventArrived;
40 | watcher.Query = query;
41 | watcher.Start();
42 | }
43 |
44 | void RefreshCOMs()
45 | {
46 | var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Caption like '%(COM%'");
47 | var portnames = SerialPort.GetPortNames();
48 | var ports = searcher.Get().Cast().ToList().Select(p => p["Caption"].ToString());
49 | var portList = portnames.Select(n => new { PortInfo = ports.FirstOrDefault(s => s.Contains(n)), Value = new SerialPort(n) });
50 |
51 | cbPort.ItemsSource = portList;
52 | cbPort.SelectedIndex = 0;
53 | }
54 |
55 | void Watcher_EventArrived(object sender, EventArrivedEventArgs e)
56 | {
57 | int evType = (int)(ushort)e.NewEvent.Properties["EventType"].Value;
58 |
59 | Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background,
60 | (Action)delegate () { RefreshCOMs(); });
61 | }
62 |
63 | private void btnLoad_Click(object sender, RoutedEventArgs e)
64 | {
65 | // add more image formats at your requirements
66 | var images = GFL("jpg").Union(GFL("jpeg").Union(GFL("bmp").Union(GFL(("png")))));
67 |
68 | foreach (var p in images)
69 | {
70 | BitmapImage bimg = new BitmapImage();
71 | bimg.BeginInit();
72 | bimg.UriSource = new Uri(p, UriKind.Absolute);
73 | bimg.DecodePixelWidth = 200;
74 | bimg.CacheOption = BitmapCacheOption.OnLoad;
75 | bimg.EndInit();
76 |
77 | Image img = new Image();
78 | img.Source = bimg;
79 | img.Stretch = Stretch.Uniform;
80 | img.Height = 100;
81 | img.Tag = p;
82 |
83 | pnlItems.Children.Add(img);
84 | img.MouseEnter += delegate (object _sender, MouseEventArgs _e) { img.Opacity = .5; };
85 | img.MouseLeave += delegate (object _sender, MouseEventArgs _e) { img.Opacity = 1; };
86 | img.MouseUp += delegate (object _sender, MouseButtonEventArgs _e) { img.Opacity = 1; Task.Run(() => SendSerialDataToEsp(p)); };
87 | }
88 | }
89 |
90 | void SendSerialDataToEsp(string image_path )
91 | {
92 | var ms = new MemoryStream();
93 | var pic = new sd.Bitmap(image_path);
94 | var img = new sd.Bitmap(pic, new sd.Size(320, 240));
95 |
96 | var bmpData = img.LockBits(new sd.Rectangle(0, 0, img.Width, img.Height), sd.Imaging.ImageLockMode.ReadOnly, sd.Imaging.PixelFormat.Format16bppRgb565);
97 | byte[] bmpbytes = new byte[bmpData.Stride * img.Height];
98 | Marshal.Copy(bmpData.Scan0, bmpbytes, 0, bmpbytes.Length);
99 | img.UnlockBits(bmpData);
100 |
101 | // this is for tft byte-swapped format - maybe spi can be setup for that on esp
102 | for (int i = 0; i < bmpbytes.Length; i += 2)
103 | {
104 | byte msb = bmpbytes[i];
105 | byte lsb = bmpbytes[i + 1];
106 | bmpbytes[i] = lsb;
107 | bmpbytes[i + 1] = msb;
108 | }
109 |
110 | // port must be open to receive data
111 | if (!Serial_Port.IsOpen) Serial_Port.Open();
112 | Serial_Port.DataReceived += SerialPort_DataReceived;
113 |
114 | Serial_Port.Write(bmpbytes, 0, bmpbytes.Length);
115 | }
116 |
117 | string[] GFL(string extension) { return Directory.GetFiles(txtPath.Text, "*." + extension); }
118 |
119 | void CbPort_SelectionChanged(object sender, SelectionChangedEventArgs e)
120 | {
121 | if (e.AddedItems.Count == 0) return;
122 |
123 | Serial_Port = cbPort.SelectedItem.GetType().GetProperty("Value").GetValue(cbPort.SelectedItem) as SerialPort;
124 |
125 | Serial_Port.BaudRate = 115200;
126 | Serial_Port.DataBits = 8;
127 | Serial_Port.Parity = Parity.None;
128 | Serial_Port.StopBits = StopBits.One;
129 | Serial_Port.Handshake = Handshake.None;
130 | }
131 |
132 | void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
133 | {
134 | // serial monitor is a simple textbox that most likely
135 | // does not display ANSI console output correctly
136 | // it is possible to improve that with RichTextBox
137 |
138 | int n = Serial_Port.Read(sp_buffer, 0, Serial_Port.BytesToRead);
139 | Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
140 | (Action)delegate ()
141 | {
142 | txtSerMonit.Text += Encoding.ASCII.GetString(sp_buffer, 0, n);
143 | });
144 | }
145 |
146 | private void BtnBrowse_Click(object sender, RoutedEventArgs e)
147 | {
148 | // windows forms old-school dialog - can be improved
149 | using (System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog())
150 | {
151 | dlg.Description = "Select folder with pictures";
152 | dlg.SelectedPath = txtPath.Text;
153 | dlg.ShowNewFolderButton = false;
154 | System.Windows.Forms.DialogResult result = dlg.ShowDialog();
155 | if (result == System.Windows.Forms.DialogResult.OK)
156 | {
157 | txtPath.Text = dlg.SelectedPath;
158 | btnLoad_Click(sender, e);
159 | }
160 | }
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("UartTest")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("HP Inc.")]
14 | [assembly: AssemblyProduct("UartTest")]
15 | [assembly: AssemblyCopyright("Copyright © HP Inc. 2019")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.0")]
55 | [assembly: AssemblyFileVersion("1.0.0.0")]
56 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace UartTest.Properties
12 | {
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources
26 | {
27 |
28 | private static global::System.Resources.ResourceManager resourceMan;
29 |
30 | private static global::System.Globalization.CultureInfo resourceCulture;
31 |
32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
33 | internal Resources()
34 | {
35 | }
36 |
37 | ///
38 | /// Returns the cached ResourceManager instance used by this class.
39 | ///
40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
41 | internal static global::System.Resources.ResourceManager ResourceManager
42 | {
43 | get
44 | {
45 | if ((resourceMan == null))
46 | {
47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UartTest.Properties.Resources", typeof(Resources).Assembly);
48 | resourceMan = temp;
49 | }
50 | return resourceMan;
51 | }
52 | }
53 |
54 | ///
55 | /// Overrides the current thread's CurrentUICulture property for all
56 | /// resource lookups using this strongly typed resource class.
57 | ///
58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
59 | internal static global::System.Globalization.CultureInfo Culture
60 | {
61 | get
62 | {
63 | return resourceCulture;
64 | }
65 | set
66 | {
67 | resourceCulture = value;
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace UartTest.Properties
12 | {
13 |
14 |
15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
18 | {
19 |
20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
21 |
22 | public static Settings Default
23 | {
24 | get
25 | {
26 | return defaultInstance;
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/UartTest.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {3A555C1D-5228-4CB5-9277-C54451EA0209}
8 | WinExe
9 | UartTest
10 | UartTest
11 | v4.6.1
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 | true
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 | 9460735_Sz9_icon.ico
38 |
39 |
40 |
41 | False
42 | bin\Debug\GoogleSearchAPI.dll
43 |
44 |
45 | False
46 | bin\Debug\Newtonsoft.Json.dll
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 4.0
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | MSBuild:Compile
69 | Designer
70 |
71 |
72 | MSBuild:Compile
73 | Designer
74 |
75 |
76 | App.xaml
77 | Code
78 |
79 |
80 | MainWindow.xaml
81 | Code
82 |
83 |
84 |
85 |
86 | Code
87 |
88 |
89 | True
90 | True
91 | Resources.resx
92 |
93 |
94 | True
95 | Settings.settings
96 | True
97 |
98 |
99 | ResXFileCodeGenerator
100 | Resources.Designer.cs
101 |
102 |
103 | SettingsSingleFileGenerator
104 | Settings.Designer.cs
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/bin/Release/UartTest.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Deous/ESP32-UART-Load-Bitmap/ea0f42a211b1aea33a15ff212504fa9fb211bc8c/sources/Win/UartTest/UartTest/bin/Release/UartTest.exe
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/bin/Release/UartTest.exe.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/bin/Release/UartTest.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Deous/ESP32-UART-Load-Bitmap/ea0f42a211b1aea33a15ff212504fa9fb211bc8c/sources/Win/UartTest/UartTest/bin/Release/UartTest.pdb
--------------------------------------------------------------------------------
/sources/Win/UartTest/UartTest/espressiflogofullglow_9Q4_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Deous/ESP32-UART-Load-Bitmap/ea0f42a211b1aea33a15ff212504fa9fb211bc8c/sources/Win/UartTest/UartTest/espressiflogofullglow_9Q4_icon.ico
--------------------------------------------------------------------------------