Use ESP32 to send messages with WiFi
Devices and components
Arduino®Nano ESP32
16x2 LCD screen with I²C interface
Active buzzer
Push button
Resistors
LED (generic)
Software and tools
Arduino IDE
Project description
Message sender
Here is the code I used. HTML is used for the web page.
1#include <vector>
2#include <WiFi.h>
3#include <AsyncTCP.h>
4#include <ESPAsyncWebServer.h>
5#include <Wire.h>
6#include <hd44780.h> // lcd libraries
7#include <hd44780ioClass/hd44780_I2Cexp.h>
8
9hd44780_I2Cexp lcd; // Create lcd object (MUST be named "lcd")
10
11
12const char* ssid = "Your Network";
13const char* password = "Your Password";
14
15AsyncWebServer server(80); // port 80 = normal HTTP
16AsyncEventSource events("/events"); // Global SSE endpoint
17
18struct Message {
19 String text;
20 String mode;
21};
22std::vector<Message> messageQueue;
23
24
25int buzzPin = 19;
26int LEDpin = 27;
27int bPin = 18;
28int bVal;
29
30char letter;
31bool space;
32bool messageSent = false;
33bool playMessage;
34void setup() {
35 // put your setup code here, to run once:
36 Serial.begin(115200);
37 Wire.begin();
38 lcd.begin(16,2);
39 pinMode(buzzPin,OUTPUT);
40 pinMode(bPin,INPUT_PULLUP);
41 pinMode(LEDpin,OUTPUT);
42
43
44 WiFi.begin(ssid, password);
45 Serial.println("Connecting to Wi-Fi...");
46 while (WiFi.status() != WL_CONNECTED) {
47 delay(500);
48 Serial.print(".");
49 }
50 Serial.println();
51 Serial.print("Connected! IP address: ");
52 Serial.println(WiFi.localIP());
53 server.addHandler(&events);
54 server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
55 request->send(200, "text/html", R"rawliteral(
56 <!DOCTYPE html>
57 <html lang="en">
58 <head>
59 <meta charset="UTF-8">
60 <meta name="viewport" content="width=device-width, initial-scale=1.0">
61 <title>Message Sender</title>
62 <style>
63 body { font-family: sans-serif; display:flex; justify-content:center; align-items:center; min-height:100vh; background: #f0f0f0;}
64 .container { background:white; padding:30px; border-radius:15px; max-width:500px; width:100%; text-align:center; box-shadow:0 10px 25px rgba(0,0,0,0.1);}
65 textarea { width:100%; padding:10px; font-size:16px; border-radius:8px; border:1px solid #ccc; margin-bottom:20px; resize:none;}
66 button { padding:12px 40px; font-size:16px; border:none; border-radius:50px; background: #667eea; color:white; cursor:pointer; transition:0.3s;}
67 button:hover { background:#764ba2;}
68 #status { display:none; margin-top:20px; padding:10px; background:#4CAF50; color:white; border-radius:8px; }
69 </style>
70 </head>
71 <body>
72 <div class="container">
73 <h1>Message Sender</h1>
74 <textarea id="message-input" rows="3" placeholder="Type your message here..."></textarea>
75 <br>
76 <div class="mode-section">
77 <label for="mode">Select Mode:</label>
78 <select id="mode">
79 <option value="morse">Morse Encoder</option>
80 <option value="lcd">LCD Display</option>
81 </select>
82 </div>
83 <br>
84 <button onclick="sendMessage()">🚀 Send Message</button>
85 <div id="status">Message received!</div>
86 </div>
87 <script>
88 // Connect to SSE
89 const evtSource = new EventSource("/events");
90 evtSource.onmessage = function(e) {
91 const statusDiv = document.getElementById("status");
92 statusDiv.style.display = "block";
93 statusDiv.innerText = e.data;
94 };
95
96 function sendMessage() {
97 const statusDiv = document.getElementById("status");
98 statusDiv.style.display = "none"; // hide immediately
99
100 const msg = document.getElementById("message-input").value;
101 const mode = document.getElementById("mode").value;
102
103 fetch(`/send?msg=${encodeURIComponent(msg)}&mode=${encodeURIComponent(mode)}`)
104 .then(response => response.text())
105 .then(data => console.log(data));
106 }
107 </script>
108 </body>
109 </html>
110 )rawliteral");
111 });
112
113 // Route to receive message & store to queue
114server.on("/send", HTTP_GET, [](AsyncWebServerRequest *request){
115 if (request->hasParam("msg") && request->hasParam("mode")) {
116 String msg = request->getParam("msg")->value();
117 String mode = request->getParam("mode")->value();
118
119 // Save both message and mode into queue
120 Message newMessage;
121 newMessage.text = msg;
122 newMessage.mode = mode;
123 messageQueue.push_back(newMessage);
124
125 Serial.println("Queued: " + msg + " (mode: " + mode + ")");
126 request->send(200, "text/plain", "Message queued!");
127 } else {
128 request->send(400, "text/plain", "Missing message or mode");
129 }
130});
131 server.begin();
132}
133
134void loop() {
135 // put your main code here, to run repeatedly:
136
137 if(!messageQueue.empty()){
138 digitalWrite(LEDpin,HIGH); //led shows message waiting
139 lcd.setCursor(0,0);
140 lcd.print("message awaiting");
141 bVal = digitalRead(bPin);
142 //wait for button to play message
143 if(bVal == 0){
144 playMessage = true;
145 }
146 }
147
148 if(playMessage == true){
149 digitalWrite(LEDpin,LOW);
150 Message nextMessage = messageQueue[0]; // get first message
151 messageQueue.erase(messageQueue.begin()); // remove it from queue
152
153 if(nextMessage.mode == "morse"){
154 Serial.println("Playing message: " + nextMessage.text);
155 delay(100); // debounce
156 playMorse(nextMessage.text);
157 }else if (nextMessage.mode == "lcd"){
158 Serial.println("Playing message: " + nextMessage.text);
159 delay(100); // debounce
160 lcd.clear();
161 lcd.setCursor(0,0);
162 lcd.print(nextMessage.text);
163 }
164
165
166
167 events.send("Played message: " + nextMessage.text, "message", millis());
168 playMessage = false; // reset playMessage
169 }
170
171
172
173}
174
175void dot(){
176 digitalWrite(buzzPin,HIGH);
177 delay(200);
178 Serial.println("."); // 1 time unit
179 digitalWrite(buzzPin,LOW);
180 delay(200); // 3 times units of space
181}
182void dash(){
183 digitalWrite(buzzPin,HIGH);
184 delay(600);
185 Serial.println("-");
186 digitalWrite(buzzPin,LOW);
187 delay(200); // 3 time units space
188}
189void translate(char c){
190 switch (c){
191 case 'a' : dot(); dash(); break;
192 case 'b' : dash(); dot(); dot(); dot(); break;
193 case 'c' : dash(); dot(); dash(); dot(); break;
194 case 'd' : dash(); dot(); dot(); break;
195 case 'e' : dot(); break;
196 case 'f' : dot(); dot(); dash(); dot(); break;
197 case 'g' : dash(); dash(); dot(); break;
198 case 'h' : dot(); dot(); dot(); dot(); break;
199 case 'i' : dot(); dot(); break;
200 case 'j' : dot(); dash(); dash(); dash(); break;
201 case 'k' : dash(); dot(); dash(); break;
202 case 'l' : dot(); dash(); dot(); dot(); break;
203 case 'm' : dash(); dash(); break;
204 case 'n' : dash(); dot(); break;
205 case 'o' : dash(); dash(); dash(); break;
206 case 'p' : dot(); dash(); dash(); dot(); break;
207 case 'q' : dash(); dash(); dot(); dash(); break;
208 case 'r' : dot(); dash(); dot(); break;
209 case 's' : dot(); dot(); dot(); break;
210 case 't' : dash(); break;
211 case 'u' : dot(); dot(); dash(); break;
212 case 'v' : dot(); dot(); dot(); dash(); break;
213 case 'w' : dot(); dash(); dash(); break;
214 case 'x' : dash(); dot(); dot(); dash(); break;
215 case 'y' : dash(); dot(); dash(); dash(); break;
216 case 'z' : dash(); dash(); dot(); dot(); break;
217 case ' ' : space = true; break;
218 }
219
220}
221void playMorse(String message){
222 for(int i = 0; i<message.length();i++){
223 letter = message.charAt(i);
224 Serial.println(letter);
225 translate(letter);
226 delay(600);
227 if(space == true){
228 delay(800); // 4 time units of space, + 3 units from earlier makes 7 units
229 space = false;
230 }
231 }
232}
Viewing the web page
Note: Content and images are from: https://projecthub.arduino.cc/, with some modifications.
If you want it removed due to copyright reasons, please leave a comment. Thank you.
I want to share this article more widely so that everyone knows about Arduino and your project.