SMUR Radio Tech Notes

Arduino Encoded Song Library
https://github.com/robsoncouto/arduino-songs

 HiLetGo MP3 Player. $7.19

HiLetgo GD3300 UART Control Serial MP3 Music Player Module Replace YX5300

HiLetgo 2pcs TDA2822M DC 1.8-12V 2.0 Channel Stereo Amplifier Mini AUX Audio Amplifier Board Module AMP. $7.99



Gikfun 2" 4Ohm 3W Full Range Audio Speaker




----------------------------------

Modify code to receive input and display text using ILI9341 240x320 TFT LCD Touch Screens

Adding a touch screen elevates this from a simple script to a fully functional standalone device. To achieve this, we will use the popular Adafruit ILI9341 library for the display and the XPT2046_Touchscreen library for the touch input.

You will need to install these three libraries in your Arduino IDE via the Library Manager:

  1. Adafruit GFX Library

  2. Adafruit ILI9341

  3. XPT2046_Touchscreen (by Paul Stoffregen)

Standard ESP32 SPI Wiring

Both the Sender and Receiver will use the SPI bus for the display. Wire both ESP32s to their respective screens as follows:

ILI9341 PinESP32 PinNote
VCC3.3VPower
GNDGNDGround
CSGPIO 15TFT Chip Select
RESETGPIO 4TFT Reset
DCGPIO 2Data/Command
SDI (MOSI)GPIO 23SPI MOSI
SCKGPIO 18SPI Clock
LED3.3VBacklight
MISOGPIO 19SPI MISO
T_CSGPIO 33Touch Chip Select (Sender Only)

(Note: T_IRQ, T_DO, T_DIN, and T_CLK share the SPI pins with the display, except for the Touch Chip Select T_CS)

1. Sender Code (The Touch Controller)

This code draws a large "PLAY" button on the screen. When you tap the button, it maps the raw touch coordinates to the screen dimensions and sends the Bluetooth command.

#include "BluetoothSerial.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <XPT2046_Touchscreen.h>

// Display and Touch Pins
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4
#define TS_CS 33

// Initialize Display and Touch
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
XPT2046_Touchscreen ts(TS_CS);

// Initialize Bluetooth
BluetoothSerial SerialBT;
String targetName = "ESP32_Speaker";
bool connected = false;

// Button dimensions
int btnX = 40, btnY = 100, btnW = 160, btnH = 80;
bool buttonPressed = false;

void setup() {
Serial.begin(115200);
// Start TFT
tft.begin();
tft.setRotation(1); // Landscape mode
tft.fillScreen(ILI9341_BLACK);
// Start Touch
ts.begin();
ts.setRotation(1);
// UI Setup
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(10, 10);
tft.print("Connecting to Speaker...");

// Start Bluetooth
SerialBT.begin("ESP32_Controller", true);
connected = SerialBT.connect(targetName);
tft.fillRect(0, 0, 320, 40, ILI9341_BLACK); // Clear top bar
tft.setCursor(10, 10);
if(connected) {
tft.setTextColor(ILI9341_GREEN);
tft.print("Connected!");
drawPlayButton(ILI9341_BLUE);
} else {
tft.setTextColor(ILI9341_RED);
tft.print("Connection Failed.");
}
}

void loop() {
if (ts.touched() && connected) {
TS_Point p = ts.getPoint();
// Map raw touch coordinates to screen coordinates (values may need tweaking based on your specific screen)
int touchX = map(p.x, 300, 3800, 0, 320);
int touchY = map(p.y, 300, 3800, 0, 240);
// Check if touch is within button bounds
if (touchX > btnX && touchX < (btnX + btnW) && touchY > btnY && touchY < (btnY + btnH)) {
if (!buttonPressed) {
buttonPressed = true;
drawPlayButton(ILI9341_DARKCYAN); // Visual feedback
SerialBT.println("PLAY");
Serial.println("Command Sent");
delay(300); // Debounce
drawPlayButton(ILI9341_BLUE); // Revert button color
}
}
} else {
buttonPressed = false;
}
}

void drawPlayButton(uint16_t color) {
tft.fillRoundRect(btnX, btnY, btnW, btnH, 10, color);
tft.drawRoundRect(btnX, btnY, btnW, btnH, 10, ILI9341_WHITE);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(4);
tft.setCursor(btnX + 35, btnY + 25);
tft.print("PLAY");

------------------

2. Receiver Code (The Display Speaker)

This code waits for the Bluetooth command and updates the screen to show what the device is currently doing.

#include "BluetoothSerial.h"
#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>

// Display Pins
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST 4

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);

BluetoothSerial SerialBT;
const int BUZZER_PIN = 25;

// Song Data
int melody[] = {262, 262, 392, 392, 440, 440, 392, 349, 349, 330, 330, 294, 294, 262};
int noteDurations[] = {500, 500, 500, 500, 500, 500, 1000, 500, 500, 500, 500, 500, 500, 1000};
int numNotes = sizeof(melody) / sizeof(melody[0]);

void setup() {
Serial.begin(115200);
pinMode(BUZZER_PIN, OUTPUT);
// Start TFT
tft.begin();
tft.setRotation(1); // Landscape
tft.fillScreen(ILI9341_BLACK);
// Start Bluetooth
SerialBT.begin("ESP32_Speaker");
updateScreen("Waiting for command...", ILI9341_YELLOW);
}

void loop() {
if (SerialBT.available()) {
String message = SerialBT.readStringUntil('\n');
message.trim();
if (message == "PLAY") {
updateScreen("Playing Song...", ILI9341_GREEN);
playSong();
updateScreen("Waiting for command...", ILI9341_YELLOW);
}
}
}

void playSong() {
for (int i = 0; i < numNotes; i++) {
tone(BUZZER_PIN, melody[i], noteDurations[i] * 0.9);
delay(noteDurations[i]);
}
}

void updateScreen(String text, uint16_t color) {
tft.fillScreen(ILI9341_BLACK);
tft.setTextColor(color);
tft.setTextSize(3);
// Center text roughly
int cursorX = 10;
int cursorY = 100;
tft.setCursor(cursorX, cursorY);
tft.print(text);
}

1 comment:

  1. Something to check on the MP3 player module: if the chip used is a clone of the widely used VS1053B, it may have the problem of introducing a ground loop when connected to an external amplifier.

    In the VS1053B chip, the speaker output is referenced to a signal called GBUF. This is not a signal ground, but is instead a common reference that is biased above zero volts.
    This is fine when connecting to something like headphones or powered speakers, but can produce a short if wired to something like a PC sound card input.
    See my warning here:
    https://github.com/TheSaturdayThing/laser_seal_arduino/wiki/DANGER

    ReplyDelete