I wanted a way to control all the projects I make.
- Note: it is not a remote for A/V systems. It is for my projects.
I wanted this to work not just at home in my WiFi zone but also at remote locations like a Maker Faire.
It communicates with my projects via ESP-NOW WiFi
Current state of software and tools: v0.9 "basics work: CYD, Tiny Code Reader for QRcodes, Mifare RC522 RF IC via MicroSD sniffer for 13.56MHz MIFARE Classic 1K cards, XPT2046_Bitbang lib to free up VSPI"
Here is my breadboard setup with the Cheap Yellow Display, the QR code reader and the RFID reader.
Table Of Contents
Top
I have settled on the following hardware for the Universal Remote Control:
- CYD - Cheap Yellow Display
- I am using the ESP32-2432S028R (Cheap Yellow Display or CYD) based on ESP32-D0WDQ6 controller.
- I purchased this one: https://www.aliexpress.us/item/3256805697430313.html
- This schematic might reflect the CYD: https://oshwlab.com/mariusmym/esp32_cyd_cheap_yellow_display
- QR code reader
- I am using the Tiny Code Reader from Useful Sensors
- I purchased this one: https://www.sparkfun.com/products/23352
- https://cdn.sparkfun.com/assets/e/9/d/9/f/TCR_Datasheet.pdf
- /~https://github.com/usefulsensors/tiny_code_reader_docs/blob/main/README.md
- /~https://github.com/usefulsensors/tiny_code_reader_arduino
- RFID Reader
- I am using the HiLetgo 3pcs RFID Kit - Mifare RC522 RF IC Card Sensor Module + S50 Blank Card + Key Ring
- I purchased this one: https://www.amazon.com/dp/B07VLDSYRW
- This doesn't support I2C or UART without board modifications; just SPI
- look for Adrianotiger post #4 on Mar 2023 on https://forum.arduino.cc/t/esp32-rfid-rc522-i2c/1100200/3
- here is webpage for the module including schematic https://www.sunrom.com/p/rfid-readerwriter-1356mhz-rc522-spi-module-with-cardkeychain
- I am using the Meikuler 13.56MHz MIFARE Classic 1K, RFID Smart Cards / M1 Cards, ISO14443A Printable Blank RFID PVC Cards
- I purchased this one: https://www.amazon.com/dp/B07S63VT7X
- https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf
- A.K.A. PICC = Proximity Integrated Circuit Card (Contactless Card)
- See following for more RFID Reader details:
- A bit of effort to use this. Got a "sniffer" card to use the SPI pins in the MicroSD slot, needed to do "bit banging" for touchscreen so could use hardware SPI for SD card.
- I am using the HiLetgo 3pcs RFID Kit - Mifare RC522 RF IC Card Sensor Module + S50 Blank Card + Key Ring
Will be trying these to see if they can be a more compact MicroSD sniffer:
- Extender cable 1: https://www.aliexpress.com/item/3256804754907124.html
- Extender cable 2: https://www.aliexpress.com/item/3256805782352551.html
- Alternative MicroSD sniffer to JTAG: https://shop.blinkinlabs.com/products/microsd-to-jtag-adapter-for-esp32
May use one or more of the following
- Alternative QR code reader
- Voice Input - perhaps one of these
- Joystick or rotary encoder, buttons
- BlueTooth keyboard
The hardware that receives the commands can use basically any ESP32 that includes WiFi.
Top
Here is what the code is:
Link | Description |
---|---|
code/UniRemoteCYD | "Cheap Yellow Display"-based UniRemote code sending ESP-NOW commands - attributions in the code. Commands are input with either the QR code reader (I2C) or the RFID Reader (SPI via MicroSD sniffer). To free up access to the CYD hardware VSPI port for the RFID Reader, the code uses the XPT2046_Bitbang software-based SPI library instead of the TFT_eSPI hardware based SPI library for the touchscreen. This technique of using XPT2046_Bitbang for the touchscreen could alternatively be used to access the MicroSD card on the CYD if the MicroSD pins weren't being used for the RFID Reader. |
code/UniRemoteRcvrTemplate | UniRemote code template for generic receiver of the commands - attributions in the code. UniRemoteRcvrTemplate.ino shows an example of using UniRemoteRcvr.h and UniRemoteRcvr.cpp to receive ESP-NOW commands from UniRemoteCYD |
code/Uni_RW_PICC | UniRemote PICC read/write routines - attribution in the README |
code/tiny_code_reader | *.h file for using the QR code reader - attribution in its README |
--- | --- |
code/readMacAddress | Code to read the WiFi MAC address of pretty much any ESP32 - used on remotes to get info - attribution in its README |
MDOpythonUtils QRCode.py | Python routine to generate QR code based on directions in a text file |
code/CYDbitBangCalibrate | Modified Random Nerds CYD Calibrate routine that uses the XPT2046_Bitbang software-based SPI library instead of the TFT_eSPI hardware based SPI library for the touchscreen - attributions in the code |
code/WriteRFID_CYD | Code with same hardware setup as UniRemoteCYD to write RFID cards using input text strings in same format as input to QRCode.py - attributions in the code |
--- | --- |
code/CYDtest | ESP32-2432S028R (Cheap Yellow Display or CYD) pointers to tutorials and hardware information |
code/RFIDRC522test | RFID RC522 pointers to tutorials and hardware information |
code/UniRemote | UniRemote code with QR code reader and generic ESP32 module - attributions in the code. This is now unused and deprecated. I am switching to the CYD and the code in UniRemoteCYD. |
code/UniTestRcvr | UniRemote code testbench for receiver of the commands - attributions in the code. This is now unused and deprecated. All further development for the receiver will go to the generic UniRemoteRcvrTemplate. |
--- end of table --- | --- end of table --- |
Top
Following are things I wanted to document and remember.
One key thing I found out was that all four of the ESP-32 hardware SPI ports are in use in the "standard" LVGL configuration. In order to use a hardware SPI port for the MicroSD slot, I had to use the XPT2046_Bitbang library instead of the TFT_eSPI library for the touchscreen.
Top
Since I am using an ESP-32 CYD with WiFi and LVGL, there is a lot of code included in libraries and I quickly ran to the limits of program storage versus RAM.
Sketch uses 1208557 bytes (92%) of program storage space. Maximum is 1310720 bytes.
Global variables use 61544 bytes (18%) of dynamic memory, leaving 266136 bytes for local variables. Maximum is 327680 bytes.
I discovered that I need to do the opposite of what I do with the Arduino Nano. I need use the "DRAM_STR" macro to move constant strings (easiest to find) from program storage into dynamic memory. On the Arduino Nano it was often helpful to use the "F" macro to move constant strings in the other direction since the dynamic memory was so limited.
Top
I didn't find a good way to prevent the entire screen from "panning" or "scrolling" during a "long press". I tried the following without success.
Routine | Description |
---|---|
void lv_indev_set_long_press_time(lv_indev_t * indev, uint16_t long_press_time); | Setting value to 65,535 after creating indev did not help |
void lv_indev_reset_long_press(lv_indev_t * indev); | Calling within indev read_cb function (cyd_input_read() in my code) when .tirqTouched() or .touched() caused buttons to not operate |
Top
I guess I should have predicted that a callback, which is somewhat similar to an interrupt routine, shouldn't assume it can call a lot of routines that might not be re-entrant.
- Result - just set flags in callback routines, do the work of the flags in loop() and its routines.
The symptom was:
- If I did ESP-NOW messages (using PICC card as the source) for which the receiver was present and receiving, I could seemingly send as many as I wanted with the physical scanning of a PICC card giving a timing interval.
- If I did 2 or sometimes up to 3 ESP-NOW messages with no receiver, even if done quite slowly, the CYD would get an LVGL watchdog timer timeout and then it would crash and reboot.
It was a little mysterious because the processing was the same for both of them, only the status message itself was different.
My guess at the mechanism is:
- If the receiver was present, the response was so quick that the LVGL routines were not doing anything when the ESP-NOW send callback routine was called.
- If the receiver was absent, the response was a timeout and this could happen when the loop and/or LVGL refresh was happening so problem if calling non-reentrant LVGL routine from ESP-NOW send callback.
Top
This repository has a LICENSE file for Apache 2.0. There may be code included that I have modified from other open sources (such as Arduino, Espressif, SparkFun, Seeed Studio, DFRobot, RandomNerds, etc.). These other sources may possibly be licensed using a different license model. In such a case I will include some notation of this. Typically I will include verbatim the license in the included/modified source code, but alternatively there might be a LICENSE file in the source code area that points out exceptions to the Apache 2.0 license.