Drawing With the Controller

Start 

Now we will use the buttons on the controller to operate the pen wirelessly!

Controller Code 

If you are still using the example from Robotics Kit 2 with the two button then there is no need to reupload code. If not or just to be sure, upload the code below to the controller.

Upload

Upload the following code to the controller.

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

Robot With Pen Code 

This code is very similar to the chainable LED example from Robotics Kit 2 except it uses the penUp() and penDown() functions.

Upload

Upload the following code. Use the toggle boolean to choose whether you want the buttons change pen state on a click, which would be true . Or if you'd like to hold down the button to draw, which would be false . Try both!

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
//All the libraries used
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include "SoftwareSerial.h"
#include "Grove_I2C_Motor_Driver.h"
#include "ServoDriver.h"
#include <Wire.h>

//Pen control
bool toggle = true;
bool previousPen = false;
bool currentPen = false;

//Your servo limits here
int minVal = 40;
int maxVal = 80;

//Your servo limits here
int leftUp  = 253;
int leftDown = 769;
int rightUp = 775;
int rightDown = 247;

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

//Creating the servo driver object
ServoDriver servoDriver;

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

//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);

  //Open I2C communication
  Wire.begin();

  //Begin communication with driver
  servoDriver.init(0x7f);

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

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 button values
  if (leftButton || rightButton) {
    currentPen = true;
    //Check to see if toggle is on
    if (toggle) {
      //If the button was just pressed
      if (currentPen && !previousPen) {
        //Put the pen down
        penDown();
      }
    } else {
      //If not just put the pen down
      penDown();
    }
    //No buttons pressed
  } else {
    currentPen = true;
    //Check to see if toggle is on
    if (toggle) {
      //If the button was just released
      if (!currentPen && previousPen) {
        //Bring pen up
        penUp();
      }
    } else {
      //If not just put the pen up
      penUp();
    }
  }

  //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();
}

void penDown() {
  //Set servo to down position
  servoDriver.setAngle(1, minVal);
}

void penUp() {
  //Set servo to up position
  servoDriver.setAngle(1, maxVal);
}

Observe

When you drive around the robot, you can press either button on the controller to put the pen down. Try out the toggle feature and see which you like best.