Skip to content

Mark-MDO47/UniRemote

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

UniRemote - one remote to rule them all!

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.
alt text

Table Of Contents

The Plan

Top
I have settled on the following hardware for the Universal Remote Control:

Will be trying these to see if they can be a more compact MicroSD sniffer:

May use one or more of the following

The hardware that receives the commands can use basically any ESP32 that includes WiFi.

Guide to the Code

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

Interesting Considerations

Top
Following are things I wanted to document and remember.

General CYD and LVGL and Related Info

Top

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.

Description URL
CYD Pinouts & Connectors https://randomnerdtutorials.com/esp32-cheap-yellow-display-cyd-pinout-esp32-2432s028r
More CYD Pinouts in useful format https://debugdiaries.co.uk/esp32-cheap-display-cyd-pinouts
CYD info in Japanese; need Google Translate but info looks quite good https://macsbug.wordpress.com/2022/08/17/esp32-2432s028
Info/Code for CYD and many variants /~https://github.com/rzeldent/esp32-smartdisplay
--- ---
RFID library I use https://docs.arduino.cc/libraries/rfid_mfrc522v2
LVGL and CYD https://randomnerdtutorials.com/lvgl-cheap-yellow-display-esp32-2432s028r
LVGL and CYD https://rntlab.com/module-1/esp32-lvgl-ebook
CYD and alternative library with lots of good info /~https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display.git
CYD LVGL interesting project /~https://github.com/bitbank2/CYD_Projects.git
/~https://github.com/TheNitek/CYD-LVGL-Template.git
YouTube Ralph S. Bacon "#203 SPIFFS vs LITTLEFS for ESP32 & ESP8266 (not Arduino UNO)" https://www.youtube.com/watch?v=4r6YZlLfKfw
--- ---
Espressif ESP32 example using non-standard SPI pins https://docs.espressif.com/projects/arduino-esp32/en/latest/api/spi.html
Using bit-banging so touch and SD can work in same program /~https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/TROUBLESHOOTING.md#display-touch-and-sd-card-are-not-working-at-the-same-time

DRAM_STR - Move Constant Strings to RAM instead of Program Storage

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.

Entire Screen Pans or Scrolls

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

LVGL Timeout and Crash if Call LVGL Routine inside ESP-NOW callback

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.

Licensing

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.