Adding Additional Controls

Start 

Buttons in Effect

In this section we will use the two buttons on the Controller to control individual LEDs on the robot. You'll see the frame work needs to add other inputs and outputs.

Connecting the Buttons 

Take a cable. Unwrap it and place one end into the left button on the Controller. The other end of the cable should go into D6. Take another cable. Unwrap it and place one end into the right button on the controller. The other end should go into D5.

Parts for this section
Parts for this section
These sockets
D5 for Left
D6 for Right
Take the cables
Make the connections
A little messy but looking good

Upload

Upload the following code.

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
/*
  ________    _           __    __
  /_  __/ /_  (_)___ ___  / /_  / /__
  / / / __ \/ / __ `__ \/ __ \/ / _ \
  / / / / / / / / / / / / /_/ / /  __/
  /_/ /_/ /_/_/_/ /_/ /_/_.___/_/\___/
    ____        __          __  _              __ __ _ __     ___
   / __ \____  / /_  ____  / /_(_)_________   / //_/(_) /_   |__ \
  / /_/ / __ \/ __ \/ __ \/ __/ / ___/ ___/  / ,<  / / __/   __/ /
  / _, _/ /_/ / /_/ / /_/ / /_/ / /__(__  )  / /| |/ / /_    / __/
  /_/ |_|\____/_.___/\____/\__/_/\___/____/  /_/ |_/_/\__/   /____/
*/

//All the libraries used
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include "SoftwareSerial.h"

//Button sockets
#define leftSocket 5
#define rightSocket 6
//Create Serial communication Object
SoftwareSerial Serial1(8, 9); // RX, TX


WiFiEspUDP Udp;

IPAddress apIP = IPAddress(192, 168, 111, 111);
IPAddress stationIP = IPAddress(192, 168, 111, 112);
IPAddress broadcastIP = IPAddress(0, 0, 0, 0);

//Wifi settings
char ssid[] = "My Wifi Robot";    // the name of your access point
char pass[] = "password";        // the password for your access point
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 sent on

//Message Variables
#define arrayLength 8
char data[arrayLength + 1];
String dataAsString;

// Vaiables
int leftData;
int rightData;
int leftButton;
int rightButton;

void setup()
{
  // Start Serial Communication with computer and WiFi module
  Serial.begin(9600);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);
  WiFi.config(stationIP);

  // Connect to robot
  status = WiFi.begin(ssid, pass);

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

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

void loop() {
  //Read the Joystick values
  leftData = analogRead(A0);
  rightData = analogRead(A2);

  //Read button values
  leftButton = digitalRead(leftSocket);
  rightButton = digitalRead(rightSocket);

  //Concatanate all the vlaues into one string
  dataAsString = String(leftData) + String(rightData) + String(leftButton)+ String(rightButton);

  //Convert String to char array
  dataAsString.toCharArray(data, arrayLength + 1);

  //Print out all values
  Serial.println(data);

  //Begin UDP sending
  Udp.beginPacket(apIP, sendingPort);
  //Send the data
  Udp.write(data);
  //Send ending packets
  Udp.endPacket();

  //Battery saving delay
  delay(10);
}

Observe

Taking a quick look at the code you can see that we added two more placed to the data[] array. One for each button. We are adding those values to the string that we send the robot.

Adding the LEDs 

We'll need two Chainable LEDs as well as two more cables. Plug one cable into D6 on the Robot and the other side into the IN socket on one of the Chainable LEDs. Take another cable and plug that into the OUT side of the same LED. The other side of cable should go into the IN side of the remaining and unconnected LED. You can now take some tape and tape them down to the Robot chassis.

Following the instruction from RS1
Following the instruction from RS1
Starting at D8
IN to one LED
OUT of same LED
IN to other LED

Upload

Upload the following code.

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
/*
  ________    _           __    __
  /_  __/ /_  (_)___ ___  / /_  / /__
  / / / __ \/ / __ `__ \/ __ \/ / _ \
  / / / / / / / / / / / / /_/ / /  __/
  /_/ /_/ /_/_/_/ /_/ /_/_.___/_/\___/
    ____        __          __  _              __ __ _ __     ___
   / __ \____  / /_  ____  / /_(_)_________   / //_/(_) /_   |__ \
  / /_/ / __ \/ __ \/ __ \/ __/ / ___/ ___/  / ,<  / / __/   __/ /
  / _, _/ /_/ / /_/ / /_/ / /_/ / /__(__  )  / /| |/ / /_    / __/
  /_/ |_|\____/_.___/\____/\__/_/\___/____/  /_/ |_/_/\__/   /____/
*/

//All the libraries used
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include "SoftwareSerial.h"
#include "Grove_I2C_Motor_Driver.h"
#include <ChainableLED.h>

//Create Chainable LED object
ChainableLED leds(6, 7, 2);

// default I2C address is 0x0f
#define I2C_ADDRESS 0x0f

//Motor names
#define LEFTMOTOR MOTOR2
#define RIGHTMOTOR MOTOR1

//Joystick Limits
int leftUp  = 253;
int leftDown = 769;
int rightUp = 775;
int rightDown = 247;

//Button Variables
int leftButton = 0;
int rightButton = 0;

//Create Serial communication Object
SoftwareSerial Serial1(8, 9); // RX, TX

WiFiEspUDP Udp;

IPAddress apIP = IPAddress(192, 168, 111, 111);
IPAddress stationIP = IPAddress(192, 168, 111, 112);
IPAddress broadcastIP = IPAddress(0, 0, 0, 0);

//Wifi settings
char ssid[] = "My Wifi Robot";    // the name of your access point
char pass[] = "password";        // the password for your access point
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


//Message Variables
#define arrayLength 8
char data[arrayLength + 1];
String dataAsString;

// Vaiables
int leftData = 0;
int rightData = 0;

//Motor Variables
int leftSpeed = 0;
int rightSpeed = 0;

void setup()
{
  // Start Serial Communication with computer and WiFi module
  Serial.begin(9600);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);
  WiFi.configAP(apIP);

  // start motor driver
  Motor.begin(I2C_ADDRESS);
  // correct pwm cycles
  Motor.frequence(F_490Hz);

  // Print out debugging messages
  Serial.print("Attempting to start AP ");
  Serial.println(ssid);

  // start access point
  status =  WiFi.beginAP(ssid, 10, pass, ENC_TYPE_WPA2_PSK);


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

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

  //Initalize the LEDs
  leds.init();

  //Turn both off
  leds.setColorRGB(0, 0, 0, 0);
  leds.setColorRGB(1, 0, 0, 0);

}

void loop()
{

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

  // If there are packets
  if (packetSize) {
    //memset(data, 0, sizeof data);
    //Print out update
    //Serial.println("Packets Received");
    // read the packet into packetBufffer
    int len = Udp.read(data, arrayLength);
    if (len > 0) {
      data[len] = 0;
    }
    //Send received data to function
    dataTranslate(data);

    //Map values to speeds
    leftSpeed = map(leftData, leftDown, leftUp, -100, 100);
    rightSpeed = map(rightData, rightDown, rightUp, -100, 100);
  }

  //Check left button values
  if (leftButton) {
    //Set Left LED to green
    leds.setColorRGB(0, 0, 255, 0);
  } else {
    //Set LED off
    leds.setColorRGB(0, 0, 0, 0);
  }

  //Check left button values
  if (rightButton) {
    //Set Right LED to green
    leds.setColorRGB(1, 0, 255, 0);
  } else {
    //Set LED off
    leds.setColorRGB(1, 0, 0, 0);
  }

  //Check to see if joystick is in deadzone
  if (leftSpeed < 10 && leftSpeed > -10) {
    //Stop motor
    Motor.stop(LEFTMOTOR);
  } else {
    //Set motor to mapped speed
    Motor.speed(LEFTMOTOR, leftSpeed);
  }

  //Check to see if joystick is in deadzone
  if (rightSpeed < 10 && rightSpeed > -10) {
    //Stop motor
    Motor.stop(RIGHTMOTOR);
  } else {
    //Set motor to mapped speed
    Motor.speed(RIGHTMOTOR, rightSpeed);
  }

  //Print out all values
  Serial.println(String(leftSpeed) + "," + String(rightSpeed) + "," + String(leftButton) + "," + String(rightButton));
}

//Function that takes raw string and chops it into values
void dataTranslate(char recData[]) {
  //Set passed array into a temp variable
  dataAsString = recData;
  //Write a section of the array to a value based on location
  leftData = dataAsString.substring(0, 3).toInt();
  rightData = dataAsString.substring(3, 6).toInt();
  leftButton = dataAsString.substring(6, 7).toInt();
  rightButton = dataAsString.substring(7, 8).toInt();
}


Observe

We added variables to store the new information that we are sending. You can find that towards the top of the code. In the dataTranslate function we added two new lines that read the values of the buttons from the string sent over to the Robot.

In the main loop of the code is where we set the LEDs color based on those translated button values.

Going Further 

We could have added a dial or any other sensor to the controller. For simple switches we only see one more byte in the data[] array. For an analog value we would need 4 bytes.

On the receiving side, it's important to keep track of which values are where in the string.