The WiFi Module

Adding the WiFi Module to the Robot 

The WiFi Module

First, add the WiFi Module to the robot. Please note the orientation in the photos. Do not plug the module in backwards.

Your robot should look similar to the one in the photo below.

WiFi Module in placeWiFi Module in place

Testing the WiFi Module 

The following code tests the WiFi Module. Make sure to install the WiFiEsp library through the Arduino Library Manager. The steps to do this are shown in the images below.

Open Arduino Library Manager
Open Arduino Library Manager
Type the name of the library into the "Filter your search.." text field and click install.
You have installed the library!

The following code tests that you have installed the ESP8266 properly and that it is able to connect to your network. Open the Serial monitor (as shown in the images below) and check to see a similar output. In this example, E100 was the ssid of the network it connected to. You should see your ssid in place of E100.

ESP8266-BasicTest.ino

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
/*
   WiFiEsp test: BasicTest

   Performs basic connectivity test and checks.
*/

#include "WiFiEsp.h"

// Emulate Serial1 on pins 7/6 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(8, 9); // RX, TX
#endif


char ssid[] = "ssid";     // your network SSID (name)
char pwd[] = "password";  // your network password
char pwdErr[] = "xxxx";   // wrong password


void setup()
{
    Serial.begin(115200);
    Serial1.begin(9600);
    WiFi.init(&Serial1);
}

void loop()
{
    assertEquals("Firmware version", WiFi.firmwareVersion(), "1.5.4");
    assertEquals("Status is (WL_DISCONNECTED)", WiFi.status(), WL_DISCONNECTED);
    assertEquals("Connect", WiFi.begin(ssid, pwd), WL_CONNECTED);
    assertEquals("Check status (WL_CONNECTED)", WiFi.status(), WL_CONNECTED);
    assertEquals("Check SSID", WiFi.SSID(), ssid);

    IPAddress ip = WiFi.localIP();
    assertNotEquals("Check IP Address", ip[0], 0);
    Serial.print("IP Address: ");
    Serial.println(ip);

    byte mac[6]={0,0,0,0,0,0};
    WiFi.macAddress(mac);

    Serial.print("MAC: ");
    Serial.print(mac[5], HEX);
    Serial.print(":");
    Serial.print(mac[4], HEX);
    Serial.print(":");
    Serial.print(mac[3], HEX);
    Serial.print(":");
    Serial.print(mac[2], HEX);
    Serial.print(":");
    Serial.print(mac[1], HEX);
    Serial.print(":");
    Serial.println(mac[0], HEX);
    Serial.println();

    assertEquals("Disconnect", WiFi.disconnect(), WL_DISCONNECTED);
    assertEquals("Check status (WL_DISCONNECTED)", WiFi.status(), WL_DISCONNECTED);
    assertEquals("IP Address", WiFi.localIP(), 0);
    assertEquals("Check SSID", WiFi.SSID(), "");
    assertEquals("Wrong pwd", WiFi.begin(ssid, pwdErr), WL_CONNECT_FAILED);

    IPAddress localIp(192, 168, 168, 111);
    WiFi.config(localIp);

    assertEquals("Connect", WiFi.begin(ssid, pwd), WL_CONNECTED);
    assertEquals("Check status (WL_CONNECTED)", WiFi.status(), WL_CONNECTED);

    ip = WiFi.localIP();
    assertNotEquals("Check IP Address", ip[0], 0);


    Serial.println("END OF TESTS");
    delay(60000);
}


////////////////////////////////////////////////////////////////////////////////////


void assertNotEquals(const char* test, int actual, int expected)
{
    if(actual!=expected)
        pass(test);
    else
        fail(test, actual, expected);
}

void assertEquals(const char* test, int actual, int expected)
{
    if(actual==expected)
        pass(test);
    else
        fail(test, actual, expected);
}

void assertEquals(const char* test, char* actual, char* expected)
{
    if(strcmp(actual, expected) == 0)
        pass(test);
    else
        fail(test, actual, expected);
}


void pass(const char* test)
{
    Serial.print(F("********************************************** "));
    Serial.print(test);
    Serial.println(" > PASSED");
    Serial.println();
}

void fail(const char* test, char* actual, char* expected)
{
    Serial.print(F("********************************************** "));
    Serial.print(test);
    Serial.print(" > FAILED");
    Serial.print(" (actual=\"");
    Serial.print(actual);
    Serial.print("\", expected=\"");
    Serial.print(expected);
    Serial.println("\")");
    Serial.println();
    delay(10000);
}

void fail(const char* test, int actual, int expected)
{
    Serial.print(F("********************************************** "));
    Serial.print(test);
    Serial.print(" > FAILED");
    Serial.print(" (actual=");
    Serial.print(actual);
    Serial.print(", expected=");
    Serial.print(expected);
    Serial.println(")");
    Serial.println();
    delay(10000);
}

Controlling the Robot via UDP 

UDP packets are a core transport layer internet protocol technology. It is a connectionless model, meaning there is no prior arrangement to a packet being sent. UDP is useful because it is a very simple protocol and a very fast protocol. However, because it is connectionless, there is no guarantee that a packet arrives at its destination.

The following example receives UDP packets from the local network and responds with an ACK. If you combine this with the motor control code, you can use UDP packets to drive the robot.

Under this sketch configuration, packets are sent from a remote device on the local network to the ESP WiFi module. The WiFi module then sends the data to the Arduino over a software serial interface. The sketch running on the Arduino recognizes this data and prints it to the serial monitor and sends a response.

Load this sketch onto your Arduino and then open the Serial monitor. You should see the WiFiEsp library connect to your SSID, print an IP address, and then print a message indicating it is "Lisenting on port 3333"

Monitor the results of the WifiBotUDP.ino SketchMonitor the results of the WifiBotUDP.ino Sketch

Now you are ready to send a packet to the robot. On OSX or Linux, you can send a UDP packet via the terminal using the command below, replacing 10.0.7.106 with the IP address of your robot. Also, ensure your computer is on the same wifi network as your robot:

Download file Copy to clipboard
1
echo -n "test packet" > /dev/udp/10.0.7.106/3333

OSX TerminalOSX Terminal

On Windows, you will need to install an additional program in order to send UDP packets. Netcat can be installed via cygwin, or there are apps in the Microsoft store that may serve the purpose. Packet Sender is a cross platform utility that you may consider as well.

If you are on an iOS or Android device, there are a number of apps in the iOS app store or play store that can send and receive UDP packets.

Whatever you use to send the packets, set the port to 3333 and the "to" IP address to the one reported by your robot on the serial terminal.

Below is an example command for sending a packet via netcat:

Download file Copy to clipboard
1
echo -n "w" | nc -u -w1 10.0.7.106 3333

WiFiBotUDP.ino

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
/*
 WiFiEsp example: WiFi UDP Send and Receive String

 This sketch wait an UDP packet on localPort using a WiFi shield.
 When a packet is received an 'ACK' packet is sent to the client on port remotePort.

 For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-client.html
*/


#include <WiFiEsp.h>
#include <WiFiEspUdp.h>

#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(8, 9); // RX, TX
#endif

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

unsigned int localPort = 3333;  // local port to listen on

char packetBuffer[255];          // buffer to hold incoming packet
char ReplyBuffer[] = "ACK";      // a string to send back

WiFiEspUDP Udp;

void setup() {
  // initialize serial for debugging
  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield:
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue:
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }
  
  Serial.println("Connected to wifi");
  printWifiStatus();

  Serial.println("\nStarting connection to server...");
  // if you get a connection, report back via serial:
  Udp.begin(localPort);
  
  Serial.print("Listening on port ");
  Serial.println(localPort);
}

void loop() {

  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply, to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
}


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");
}

Once you have loaded the sketch above, and opened the serial monitor, you should see the IP address printed to the serial monitor and you should see

The solution to this challenge is shown below. Try it for yourself first, though!!

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
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>

// Emulate Serial1 on pins 6/7 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(8, 9); // RX, TX
#endif

char ssid[] = "E100";            // your network SSID (name)
char pass[] = "QAwR75?Wru?w";        // your network password
int status = WL_IDLE_STATUS;     // the Wifi radio's status

unsigned int localPort = 3333;  // local port to listen on

char packetBuffer[255];          // buffer to hold incoming packet
char ReplyBuffer[] = "ACK";      // a string to send back

byte leftOffset = 0;
byte rightOffset = 0;
/* This could be a pwm class */
unsigned long pwmTimeout = 0;

#define AIN1 3
#define AIN2 4
#define APWM 5
#define BIN1 12
#define BIN2 13
#define BPWM 11
#define STBY 6
#define STEPTIME 600 
#define STRAIGHTSPEED 200
#define TURNSPEED 120
#define TURNTIME 300

#include <SoftwareSerial.h>
SoftwareSerial esp(8, 9);

int pwms[] = {APWM, BPWM};

void writePwms ( int left, int right) {
    analogWrite (pwms[0], left);
    analogWrite (pwms[1], right);
}

void goForward ( ) {
    digitalWrite(STBY, HIGH);
    digitalWrite(AIN1, LOW);
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);
    writePwms (STRAIGHTSPEED-leftOffset,STRAIGHTSPEED-rightOffset);
    pwmTimeout = millis() + STEPTIME;
}

void goBack() {
    digitalWrite(STBY, HIGH);
    digitalWrite(AIN1, HIGH);
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);
    writePwms (STRAIGHTSPEED-leftOffset,STRAIGHTSPEED-rightOffset);
    pwmTimeout = millis() + STEPTIME;
}

void goLeft () {
    digitalWrite(STBY, HIGH);
    digitalWrite(AIN1, HIGH);
    digitalWrite(AIN2, LOW);
    digitalWrite(BIN1, LOW);
    digitalWrite(BIN2, HIGH);

    writePwms (TURNSPEED,TURNSPEED);
    pwmTimeout = millis() + TURNTIME;
}

void goRight () {
    digitalWrite(STBY, HIGH);
    digitalWrite(AIN1, LOW);
    digitalWrite(AIN2, HIGH);
    digitalWrite(BIN1, HIGH);
    digitalWrite(BIN2, LOW);

    writePwms (TURNSPEED,TURNSPEED);
    pwmTimeout = millis() + TURNTIME;
}

void stop(){
    //enable standby  
    digitalWrite(STBY, LOW); 
}

WiFiEspUDP Udp;

void setup() {
    pinMode (STBY, OUTPUT);
    pinMode (AIN1, OUTPUT);
    pinMode (AIN2, OUTPUT);
    pinMode (APWM, OUTPUT);
    pinMode (BIN1, OUTPUT);
    pinMode (BIN2, OUTPUT);
    pinMode (BPWM, OUTPUT);

    // initialize serial for debugging
    Serial.begin(115200);
    // initialize serial for ESP module
    Serial1.begin(9600);
    // initialize ESP module
    WiFi.init(&Serial1);

    // check for the presence of the shield:
    if (WiFi.status() == WL_NO_SHIELD) {
        Serial.println("WiFi shield not present");
        // don't continue:
        while (true);
    }

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

    Serial.println("Connected to wifi");
    printWifiStatus();

    Serial.println("\nStarting connection to server...");
    // if you get a connection, report back via serial:
    Udp.begin(localPort);

    Serial.print("Listening on port ");
    Serial.println(localPort);
}

void loop() {
    // If pwmTimeout has been set
    if (pwmTimeout > 0) {
        // Compare the current time to pwmTimeout
        if (millis() > pwmTimeout) {
            // If pwmTimeout has elapsed, zero pwmTimeout and stop the motors by zeroing the PWM signals
            pwmTimeout = 0;
            writePwms (0,0);       
        }
    }

    // if there's data available, read a packet
    int packetSize = Udp.parsePacket();
    if (packetSize) {
        Serial.print("Received packet of size ");
        Serial.println(packetSize);
        Serial.print("From ");
        IPAddress remoteIp = Udp.remoteIP();
        Serial.print(remoteIp);
        Serial.print(", port ");
        Serial.println(Udp.remotePort());

        // read the packet into packetBufffer
        int len = Udp.read(packetBuffer, 255);
        if (len > 0) {
            packetBuffer[len] = 0;
        }
        Serial.println("Contents:");
        Serial.println(packetBuffer);

        // Use a switch statement to examine the first character of the packet buffer
        switch(packetBuffer[0]){
            case 'w':
                // If the value is 'w', move the robot forward
                goForward();
                break;
            case 'a':
                // If the value is 'a', move the robot left
                goLeft();
                break;
            case 's':
                // If the value is 's', move the robot backward
                goBack();
                break;
            case 'd':
                // If the value is 's', move the robot right
                goRight();
                break;
        }

        // send a reply, to the IP address and port that sent us the packet we received
        Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
        Udp.write(ReplyBuffer);
        Udp.endPacket();

        // Zero the packetBuffer first character until we receive a new packet
        packetBuffer[0] = 0;
    }
}

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");
}

Controlling remotely 

There are a number of ways to further control the robot remotely. We will explore one of these in the next section. Feel free to play around, however. The WiFiEsp Library includes a number of examples, nearly all of which can be modified to work with the WiFi Robot.