Introduction: CYD - WiFi Image Display Tool - C# to ESP32-2432S028R
I've been working on a couple of electronics widgets that I can use at the gaming table to help to "enhance" the RPG experience for me and my players.
Occasionally, I will present the players with a new NPC, monster, situation, etc. that I want the players to be able to see. Sometimes, this will be from an image that I have prepared that I want the players to see.
Originally, I was playing with an ILI9341 TFT display that I was linking with an ESP32 board for which I designed and had a PCB fabricator build for me. The circuit was "fine" but it took a LOT of effort to refine. In the end I kind of gave up on the idea. Then, Rui Santos of RandomNerdTutorials released a tutorial on the CYD (Cheap Yellow Display) module that is ... cheap, yellow AND a display! The CYD has an inbuilt ESP32 WiFi module and a 3" display ... WOOHOO! I thought, back to the build!
I quickly ordered one of these modules and started planning for when it arrived. The module cost @$20AUD from EBay.
The nice thing about this project is that there is nothing to solder, no parts other than the CYD and a suitable USB cable.
Supplies
- CYD from your favorite supplier (mine cost @ $20AUD from EBay)
- Visual C# (community edition is free) from Microsoft
- Something to generate/produce/edit images ...
Step 1: The ESP32 Side of the Story (TCPIP Server)
There are some pretty good resources out there for the ESP32 and also the CYD. Brian Lough (witnessmenow) has a pretty good GitHub channel for the CYD here: ESP32-Cheap-Yellow-Display I made use of the info here to start my testing and prototyping. As mentioned Rui Santos from RandomNerdTutorials has a great primer on the CYD that was very useful.
My Arduino Sketch makes use of a bunch of libraries that help connect to the functionality that I want.
- FS (with Arduino IDE)
- SPI (with Arduino IDE)
- SD (version 1.2.4)
- ArduinoJson (version 7.04)
- WiFi (with Arduino IDE)
- TFT_eSPI (version 2.5.43)
- JPEGDecoder (version 2.0.0)
I've had problems with reading the SD card on an ESP32 and so the version of the ESP32 board is NOT the most recent version ... I'm using the Espressif Systems version 2.0.10 board library.
Both Brian Lough and Rui Santos both provide a very useful User_Setup.h file that is already configured for this board, so I have used that. Both gentlemen also describe how to use the User_Setup.h file and why.
The basic workflow of the sketch is
- Instantiate the TFT display
- Instantiate the SD card
- Read the configuration from a .json file found on the SD Micro (8Gb)
- Connect to the WiFi using the configuration values
- Display the default image onto the TFT display
- Wait for an inbound client connection
- Write the inbound WiFi stream client value to a .jpg file
- Send the new .jpg file to the display.
- Wait for an inbound client connection ... etc.
The configuration file is stored on the SD Micro in /etc/config.json and looks like this:
{
"SSID": "your network SSID",
"pass": "your network password",
"ep": "192.168.1.21",
"port": 4096
}
Replace the SSID value with your network SSID, and replace the pass value with your WiFi password.
The ep is not really used, but leave it there anyway :) Originally, this was to set the allowed client IP address, but I'm not using it. It's no harm to leave this value there for later use.
Download the attached sketch
The sketch sends some info out to the IDE Serial stream, so you can see what's happening as it goes along:
Initializing SD card ...
Configuration file found
Loading configuration...
Connecting to WiFi..
Connected to the WiFi network
192.168.1.9
Port: 4096
Ready to connect.
===========================
Drawing file: /images/cedric.jpg
===========================
and when you send an image from the client:
........................................................................File Closed
===========================
Drawing file: /images/tfer.jpg
===========================
Attachments
Step 2: The C# Side of the Story (TCPIP Client)
The C# application is a Windows Forms application that is used to select a .JPG file and stream it to the CYD (in a nutshell).
The client has a couple of Text fields
- txtEndPoint
- txtPort
- txtImageFile
The End Point is the server IP address. The Port is the TCPIP Listen Port, and the Image File is the path to the source image file.
The client has a button "Send" that opens the image to a Stream object and writes the Stream object to a NetworkStream object ... that's pretty much it.
The important bit of code (without all of the other crud in the form) is as follows:
private void btnImageSend_Click(object sender, EventArgs e)
{
Stream imageFileStream = File.OpenRead(txtImageFile.Text);
byte[] byteArray = new byte[imageFileStream.Length];
imageFileStream.Read(byteArray, 0, (int)imageFileStream.Length);
TcpClient client = new TcpClient(txtEndPoint.Text, Int32.Parse(txtPort.Text));
NetworkStream network = client.GetStream();
network.Write(byteArray, 0, byteArray.GetLength(0));
network.Close();
}
The Windows Form emits the Stream object to the NetworkStream using the TcpClient module.
In my set up, both the CYD and the C# application are on the same network, so it's a pretty simple transfer without having to worry about interception, injection, malicious agents, etc.
Step 3: Into the Future!
Eventually, I will be making the CYD wireless ... that is, adding a LiPo battery, DC 5V booster, LiPo charge module and probably a QI receiver so that it doesn't have to be tethered to a USB cable while it is running.
The good news is that I have designed and received the boards for that, I am just waiting for the parts to arrive to make it happen ;)
Anyway, good luck and happy gaming!