Full Two Arduino Messaging Code

All Together 

Below are the two pieces of code to complete this project.

Arduino With Shield - Upload 

Download file Copy to clipboard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
//All the libraries used
#include <OneButton.h>
#include <rgb_lcd.h>
#include <Wire.h>
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include "SoftwareSerial.h"

//Definable sockets for modules
#define buttonSocket 4
#define dialSocket A0

//Socket of the WiFi module
SoftwareSerial Serial1(8, 9); // RX, TX
//Create UDP object
WiFiEspUDP Udp;

//IP and broadcasting varibles
IPAddress apIP= IPAddress(192, 168, 111, 111);
IPAddress stationIP= IPAddress(192, 168, 111, 112);
IPAddress broadcastIP = IPAddress(0, 0, 0, 0);
IPAddress remoteIp;
bool broadcasting = false;

//WiFi network settings
char ssid[] = "homebase";        // your network SSID (name)
char pass[] = "password";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

//Ports to be used
unsigned int listeningPort = 10002;  // local port to listen on
unsigned int sendingPort = 10003;  // local port to sent on

//Arrays for storing sent and received packets
char packetBuffer[255];          // buffer to hold incoming packet
char ReplyBuffer[] = "ACK";      // a string to send back
String message;
char messageToSend[16];

//Variables used to convert dial to letter
int dialVal;
int alphabetIndex;
char charToShow;

//Transmition variables
bool waitForACK = false;
int transmits = 0;
//How many transmit attempts
int transmitLimit = 2;
unsigned long previousTransmit;
//Time between attempts
int interval = 1000;

//States for state machine
enum states {
  WRITING,
  RECEIVED,
  SENDING,
  SHOW,
  FAIL,
  SUCCESS
};

//Variable to keep track of states
states currentState = WRITING;

//Creates button object
OneButton button = OneButton(buttonSocket, false);
//Creates lcd display object
rgb_lcd lcd;

//LCD Display color variables
const int colorR = 50;
const int colorG = 50;
const int colorB = 50;

//Char array of every char in the alphabet
const char alphabet[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
                         'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
                        };


void setup() {
  // initialize serial for debugging
  Serial.begin(9600);
  // initialize serial for WiFi module
  Serial1.begin(9600);
  // Connect serial to Wifi module
  WiFi.init(&Serial1);
  WiFi.config(stationIP);

  // initalize the LCD Display
  lcd.begin(16, 2);
  // Set to defined color
  lcd.setRGB(colorR, colorG, colorB);
  //Start writing at the top right
  lcd.setCursor(0, 0);
  // Print message to display
  lcd.print(F("Setting up WiFi"));



  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    // Print which SSID it's trying to connect to
    Serial.print(F("Attempting to connect to WPA SSID: "));
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  //Print WiFi status
  Serial.println(F("Connected to wifi"));
  printWifiStatus();

  // Set up UDP listener on port
  Udp.begin(listeningPort);

  // Print out which port
  Serial.print(F("Listening on port "));
  Serial.println(listeningPort);

  // Create button event functions
  button.attachClick(singlePress);
  button.attachDoubleClick(doublePress);
  button.attachLongPressStart(longPress);
  // Lower the double click time
  button.setClickTicks(250);
  //Clear any characters from LCD
  lcd.clear();
}

void loop() {
  // Update button events
  button.tick();

  //Check for incoming packets
  int packetSize = Udp.parsePacket();

  // If there are packets
  if (packetSize) {
    //Print out update
    Serial.println(F("Packets Received"));
    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    //If the packets are an "ACK" message
    if (String(packetBuffer) == String(ReplyBuffer) && waitForACK) {
      // Update current state
      currentState = SUCCESS;
      //If the packet are a text message
    } else {
      //Send "ACK" message
      sendData(ReplyBuffer, apIP, sendingPort);
      //Clear any characters from LCD
      lcd.clear();
      // Set to defined color
      lcd.setRGB(0, 0, 128);
      //Start writing at the top right
      lcd.setCursor(0, 0);
      // Print message to display
      lcd.print("Incoming Message");
      //Start writing at the bottom right
      lcd.setCursor(0, 1);
      // Print message to display
      lcd.print("Press to Show");
      // Update current state
      currentState = RECEIVED;
    }
    // Addtional debugging info
    // Serial.print(F("Packets Rec: "));
    // Serial.println(packetBuffer);
  }



  //Beginning of state machine
  switch (currentState) {
    // Instructions for WRITING state
    case WRITING:
      //Read the dial position
      dialVal = analogRead(dialSocket);
      // Translate to number in the alphabet
      alphabetIndex = map(dialVal, 0, 1023, 25, 0);
      // Translate number to actual letter
      charToShow = alphabet[alphabetIndex];
      //Start writing at the top right
      lcd.setCursor(0, 0);
      // Print char to be written
      lcd.print(charToShow);
      //End of case
      break;

    // Instructions for SENDING state
    case SENDING:
      // If transmit attempts are over the limit
      if (transmits > transmitLimit && waitForACK) {
        // Update current state
        currentState = FAIL;
      }
      // If the interval has passed from the last transmit
      if (millis() - previousTransmit > interval && waitForACK) {
        // Send message on correct port
        sendData(messageToSend, apIP, sendingPort);
      }
      //End of case
      break;

    // Instructions for FAIL state
    case FAIL:
      //Stop waiting for "ACK" message because we won't get it
      waitForACK = false;
      lcd.clear();
      //Set screen to red
      lcd.setRGB(255, 0, 0);
      lcd.setCursor(0, 0);
      lcd.print(F("Transmit Failed"));
      Serial.println(F("Transmit Failed"));
      // Wait for 1.5 seconds to read message
      delay(1500);
      lcd.clear();
      lcd.setRGB(colorR, colorG, colorB);
      //Reprint the message to be sent
      lcd.setCursor(0, 1);
      lcd.print(message);
      // Update current state
      currentState = WRITING;
      //End of case
      break;

    // Instructions for SUCCESS state
    case SUCCESS:
      //Stop waiting for "ACK" message because we got it
      waitForACK = false;
      lcd.clear();
      // Set screen to green
      lcd.setRGB(0, 255, 0);
      lcd.setCursor(0, 0);
      lcd.print(F("ACK Received"));
      Serial.println(F("ACK Received"));
      // Wait for 1.5 seconds to read message
      delay(1500);
      lcd.clear();
      //Clear message by setting equal to nothing
      message = "";
      //Reset all char in the char arrays to 0
      memset(packetBuffer, 0, sizeof packetBuffer);
      memset(messageToSend, 0, sizeof messageToSend);

      //Reset screen color
      lcd.setRGB(colorR, colorG, colorB);
      // Update current state
      currentState = WRITING;
      //End of case
      break;

    // Instructions for RECEIVED state
    case RECEIVED:
      //Does nothing while waiting for input
      //End of case
      break;

    // Instructions for SHOW state
    case SHOW:
      //Does nothing while waiting for input
      //End of case
      break;
  };


}

//Instructions for a single press of the button
void singlePress() {
  //Switch case because of state dependant instructions
  switch (currentState) {
    // Instructions for WRITING state
    case WRITING:
      //Add current char to message
      message = message + charToShow;
      //Print at bottom left
      lcd.setCursor(0, 1);
      //Rewrite message with new char
      lcd.print(message);
      //End of case
      break;

    // Instructions for FAIL state
    case FAIL:
      //Send user back to WRITING state
      currentState = WRITING;
      //End of case
      break;

    // Instructions for SUCCESS state
    case SUCCESS:
      //Send user back to WRITING state
      currentState = WRITING;
      //End of case
      break;

    // Instructions for RECEIVED state
    case RECEIVED:
      lcd.clear();
      //Set screen to blue
      lcd.setRGB(0, 0, 128);
      lcd.setCursor(0, 0);
      lcd.print("Message Contents");
      lcd.setCursor(0, 1);
      //Show the message in the packetBuffer
      lcd.print(packetBuffer);
      //Update state
      currentState = SHOW;
      //End of case
      break;

    //Send user back to SHOW state
    case SHOW:
      //Clear packetBuffer for new messages
      memset(packetBuffer, 0, sizeof packetBuffer);
      lcd.clear();
      lcd.setRGB(colorR, colorG, colorB);
      //Rewrite any unsent message text
      lcd.setCursor(0, 1);
      lcd.print(message);
      //Update state
      currentState = WRITING;
      //End of case
      break;
  }
}

//Instructions for a double press of the button
void doublePress() {
  //Switch case because of state dependant instructions
  switch (currentState) {
    case WRITING:
      //Add a space to the message
      message = message + ' ';
      //Display new message
      lcd.setCursor(0, 1);
      lcd.print(message);
      break;
  }
}

//Instructions for a long press of the button
void longPress() {
  //Switch case because of state dependant instructions
  switch (currentState) {
    case WRITING:
      lcd.setCursor(0, 1);
      lcd.print(F("Sending message"));
      //Set display to yellow
      lcd.setRGB(128, 128, 0);

      //Clear buffers for message about to be sent
      memset(packetBuffer, 0, sizeof packetBuffer);
      memset(messageToSend, 0, sizeof messageToSend);

      //Convert String message into a char array
      message.toCharArray(messageToSend, message.length() + 1);
      //Reset transmit attempts
      transmits = 0;
      //Start listening for an "ACK" packet
      waitForACK = true;
      //Update state
      currentState = SENDING;
      //End of case
      break;
  }
}

//Fucntion to send data
void sendData(char mess[], IPAddress ip, int port) {
  //Toggle for extra info
  if (true) {
    Serial.println(F("Sending Packets"));
    Serial.print(F("Sending to: "));
    Serial.println(remoteIp);
    Serial.print(F("On Port:  "));
    Serial.println(sendingPort);
    Serial.print(F("Message is:  "));
    Serial.println(messageToSend);
  }

  //Toggle broadcasting vs direct ip to ip
  // Create temp ip variable
  IPAddress ipToUse;
  //If broadcasting is on
  if (broadcasting) {
    //Set destination ip to 0.0.0.0
    ipToUse = broadcastIP;
  } else {
    //Use other WiFi module ip
    ipToUse = ip;
  }

  //Update the last transmit time to now
  previousTransmit = millis();
  //Open packet to certain ip at certain port
  Udp.beginPacket(ipToUse, port);
  //Write message to packet
  Udp.write(mess);
  //End the packet
  Udp.endPacket();
  //Increase number of transmits
  transmits++;
}

  void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  }

Arduino Without Shield - Upload 

Download file Copy to clipboard
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
//All the libraries used
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include "SoftwareSerial.h"

//Socket of the WiFi module
SoftwareSerial Serial1(A5, A4); // RX, TX
//Create UDP object
WiFiEspUDP Udp;

//IP and broadcasting varibles
IPAddress apIP = IPAddress(192, 168, 111, 111);
IPAddress stationIP = IPAddress(192, 168, 111, 112);
IPAddress broadcastIP = IPAddress(0, 0, 0, 0);
IPAddress remoteIp;
bool broadcasting = false;

//WiFi network settings
char ssid[] = "homebase";            // your network SSID (name)
char pass[] = "password";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status


//Ports to be used
unsigned int listeningPort = 10003;  // local port to listen on
unsigned int sendingPort = 10002;  // local port to listen on
char packetBuffer[255];          // buffer to hold incoming packet
char ReplyBuffer[] = "ACK";      // a string to send back

//Arrays for storing sent and received packets
String message;
char messageToSend[16];

//Transmition variables
bool waitForACK = false;
//How many transmit attempts
int transmits = 0;
int transmitLimit = 2;
unsigned long previousTransmit;
//Time between attempts
int interval = 1000;

//States for state machine
enum states {
  WRITING,
  RECEIVED,
  SENDING,
  SHOW,
  FAIL,
  SUCCESS
};

//Variable to keep track of states
states currentState = WRITING;


void setup() {
  // initialize serial for debugging
  Serial.begin(9600);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // Connect serial to Wifi module
  WiFi.init(&Serial1);
  WiFi.configAP(apIP);

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    // Make a network
    status =  WiFi.beginAP(ssid, 10, pass, ENC_TYPE_WPA2_PSK);
  }

  //Print WiFi status
  Serial.println("Connected to wifi");
  printWifiStatus();

  // Set up UDP listener on port
  Udp.begin(listeningPort);

  // Print out which port
  Serial.print(F("Listening on port "));
  Serial.println(listeningPort);
}


void loop() {

  //Check for incoming packets
  int packetSize = Udp.parsePacket();

  // If there are packets
  if (packetSize) {
    //Print out update
    Serial.println(F("Packets Received"));
    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }

    //If the packets are an "ACK" message
    if (String(packetBuffer) == String(ReplyBuffer) && waitForACK) {
      // Update current state
      currentState = SUCCESS;
    }
    else {
      //If the packet are a text message
      currentState = RECEIVED;
    }
  }

  //Beginning of state machine
  switch (currentState) {
    // Instructions for WRITING state
    case WRITING:
      //Check to see if something was written and sent
      if (Serial.available() > 0) {
        //Store text in message
        message = Serial.readString();
        Serial.println("Sending message");

        //Clear buffers for message about to be sent
        memset(packetBuffer, 0, sizeof packetBuffer);
        memset(messageToSend, 0, sizeof messageToSend);

        //Convert String message into a char array
        message.toCharArray(messageToSend, sizeof messageToSend);
        //Reset transmit attempts
        transmits = 0;
        //Start listening for an "ACK" packet
        waitForACK = true;
        //Update state
        currentState = SENDING;
        //End of case
      }
      break;

    // Instructions for SENDING state
    case SENDING:
      // If transmit attempts are over the limit
      if (transmits > transmitLimit && waitForACK) {
        // Update current state
        currentState = FAIL;
      }
      // If the interval has passed from the last transmit
      if (millis() - previousTransmit > interval && waitForACK) {
        // Send message on correct port
        sendData(messageToSend, apIP, sendingPort);
      }
      //End of case
      break;

    // Instructions for FAIL state
    case FAIL:
      //Stop waiting for "ACK" message because we won't get it
      waitForACK = false;
      Serial.println(F("Transmit Failed"));
      // Update current state
      currentState = WRITING;
      //End of case
      break;

    // Instructions for SUCCESS state
    case SUCCESS:
      //Stop waiting for "ACK" message because we got it
      waitForACK = false;
      Serial.println(F("ACK Received"));
      //Clear message by setting equal to nothing
      message = "";
      //Reset all char in the char arrays to 0
      memset(packetBuffer, 0, sizeof packetBuffer);
      memset(messageToSend, 0, sizeof messageToSend);

      // Update current state
      currentState = WRITING;
      //End of case
      break;

    // Instructions for RECEIVED state
    case RECEIVED:
      //Send "ACK" message
      sendData(ReplyBuffer, stationIP, sendingPort);
      Serial.println("Incoming Message");
      // Update current state
      currentState = SHOW;
      //End of case
      break;

    // Instructions for SHOW state
    case SHOW:
      Serial.print("Message: ");
      Serial.println(packetBuffer);
      // Update current state
      currentState = WRITING;
      //End of case
      break;
  }
}

void sendData(char mess[], IPAddress ip, int port) {
  //Toggle for extra info
  if (true) {
    Serial.println(F("Sending Packets"));
    Serial.print(F("Sending to: "));
    Serial.println(remoteIp);
    Serial.print(F("On Port:  "));
    Serial.println(sendingPort);
    Serial.print(F("Message is:  "));
    Serial.println(messageToSend);
  }

  //Toggle broadcasting vs direct ip to ip
  // Create temp ip variable
  IPAddress ipToUse;
  //If broadcasting is on
  if (broadcasting) {
    //Set destination ip to 0.0.0.0
    ipToUse = broadcastIP;
  } else {
    //Use other WiFi module ip
    ipToUse = ip;
  }

  //Update the last transmit time to now
  previousTransmit = millis();
  //Open packet to certain ip at certain port
  Udp.beginPacket(ipToUse, port);
  //Write message to packet
  Udp.write(mess);
  //End the packet
  Udp.endPacket();
  //Increase number of transmits
  transmits++;
}

  void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
  }

Observe

Open up the Serial Monitor. When the connected Arduino is ready you will see a listening message. For the LCD equipped Arduino, it's ready when you no longer see the message Setting up WiFi on its display. To create messages, move the dial to get the letter you want then press the button. It will add that letter to the message. For a space, double click. When your message is ready to send, hold down the button and the Arduino will start trying to send the message. Back in the Serial Monitor, you should see a received message. To write one back, simply type into the Serial Monitor and press enter. The LCD Display should change to blue and tell you of an incoming message. Press the button to see the message and press again to return to the writing screen.

Not ready yet
Not ready yet
Ready
Twist to select letter
Twist to select letter
Press to add to message
A typed out message
Long press to send
Success
Sometimes not
You'll see this when you have a message
Press to see content
Another press to clear

Experiment

Try changing out the dial for maybe more button or another sensor for typing. You can use this simple messaging system to send data from other projects. Like the intruder alarm or robot friend.