Arduino Yún Bridge

Access the pins of the board with a web browser.

This example for a Yún device shows how to use the Bridge library to access the digital and analog pins on the board through REST calls. It demonstrates how you can create your own API when using REST style calls through the browser.

When running this example, make sure your computer is on the same network as the Yún device. When you have have programmed the board, you can request the value on a pin, write a value to a pin, and configure a pin as an input or output.

When the REST password is turned off, you can use a browser with the following URL structure :

You can use the CURL command from the command line instead of a browser if you prefer.

Hardware Required

  • Yún board or shield

  • computer and Yún device on the same wireless or wired network

Software Required

  • web browser

Circuit

There is no circuit for this example.

The circuit for this tutorial.
The circuit for this tutorial.

image developed using Fritzing. For more circuit examples, see the Fritzing project page

Code

The example code shows how it is possible to make REST requests to the Yún device to read from and write information to the board's pins.

You need to include the Bridge, YunServer, and YunClient libraries :

1#include <Bridge.h>
2#include <YunServer.h>
3#include <YunClient.h>

Instantiate a server enabling the the Yún device to listen for connected clients.

YunServer server;

In

setup()
, start serial communication for debugging purposes, and turn the built-in LED on pin 13 high while Bridge begins.
Bridge.begin()
is blocking, and should take about 2 seconds to complete. Once Bridge starts up, turn the LED off.

1void setup() {
2
3 Serial.begin(9600);
4
5 pinMode(13,OUTPUT);
6
7 digitalWrite(13, LOW);
8
9 Bridge.begin();
10
11 digitalWrite(13, HIGH);

In the second part of

setup()
, tell the instance of YunServer to listen for incoming connections only coming from localhost. Connections made to Linux will be passed to the 32U4 processor for parsing and controlling the pins. This happens on port 5555. Start the server with
server.begin()
.

1server.listenOnLocalhost();
2
3 server.begin();
4}

In

loop()
, you'll create an instance of the YunClient for managing the connection. If the client connects, process the requests in a custom function (described below) and close the connection when finished.

Putting a delay at the end of

loop()
will be helpful in keeping the processor from doing too much work.

1void loop() {
2
3 YunClient client = server.accept();
4
5 if (client) {
6
7 process(client);
8
9 client.stop();
10
11 }
12
13 delay(50);
14}

Create a function named

process
that accepts the YunClient as its argument. Read the command by creating a string to hold the incoming information. Parse the REST commands by their functionality (digital, analog, and mode) and pass the information to the appropriately named function.

1void process(YunClient client) {
2
3 String command = client.readStringUntil('/');
4
5 if (command == "digital") {
6
7 digitalCommand(client);
8
9 }
10
11 if (command == "analog") {
12
13 analogCommand(client);
14
15 }
16
17 if (command == "mode") {
18
19 modeCommand(client);
20
21 }
22}

Create a function to deal with digital commands. Accept the client as the argument. Create some local variables to hold the pin and value of the command.

1void digitalCommand(YunClient client) {
2
3 int pin, value;

Parse the client's request for the pin to work with using

client.parseInt()
.

If the character after the pin is a "/", it means the URL is going to have a value of 1 or 0 following. This value will assign a value to the pin, turning it HIGH or LOW. If there is no trailing "/", read the value from the specified pin.

1pin = client.parseInt();
2
3 if (client.read() == '/') {
4
5 value = client.parseInt();
6
7 digitalWrite(pin, value);
8
9 }
10
11 else {
12
13 value = digitalRead(pin);
14
15 }

Print the value to the client and update the datastore key with the current pin value.

By wrapping the value to the client in

F()
, you'll be printing form the flash memory. This helps conserve space in SRAM, which is useful when dealing with long strings like URLs.

The key will be the pin, and type. For example D2 will be saved for for digital pin 2. The value will be whatever value the pin is currently set to, or was read from the pin.

1client.print(F("Pin D"));
2
3 client.print(pin);
4
5 client.print(F(" set to "));
6
7 client.println(value);
8
9 String key = "D";
10
11 key += pin;
12
13 Bridge.put(key, String(value));
14}

Set up a function to handle analog calls in the same fashion, except setting the key to A instead of D when working with the analog input pins :

1void analogCommand(YunClient client) {
2
3 int pin, value;
4
5 pin = client.parseInt();
6
7 if (client.read() == '/') {
8
9 value = client.parseInt();
10
11 analogWrite(pin, value);
12
13 // Send feedback to client
14
15 client.print(F("Pin D"));
16
17 client.print(pin);
18
19 client.print(F(" set to analog "));
20
21 client.println(value);
22
23 String key = "D";
24
25 key += pin;
26
27 Bridge.put(key, String(value));
28
29 }
30
31 else {
32
33 value = analogRead(pin);
34
35 client.print(F("Pin A"));
36
37 client.print(pin);
38
39 client.print(F(" reads analog "));
40
41 client.println(value);
42
43 String key = "A";
44
45 key += pin;
46
47 Bridge.put(key, String(value));
48
49 }
50}

Create one more function to handle pin mode changes. Accept the YunClient as the argument, and create a local variable to hold the pin number. Read the pin value just as you did in the digital and analog functions.

1void modeCommand(YunClient client) {
2
3 int pin;
4
5 pin = client.parseInt();

Check to make sure the URL is valid

1if (client.read() != '/') {
2
3 client.println(F("error"));
4
5 return;
6
7 }

If it's a valid URL, store the URL as a string. If the mode is an

input
or
output
, configure the pin and report it to client. If the string doesn't match those values, return an error.

1String mode = client.readStringUntil('\r');
2
3 if (mode == "input") {
4
5 pinMode(pin, INPUT);
6
7 // Send feedback to client
8
9 client.print(F("Pin D"));
10
11 client.print(pin);
12
13 client.print(F(" configured as INPUT!"));
14
15 return;
16
17 }
18
19 if (mode == "output") {
20
21 pinMode(pin, OUTPUT);
22
23 // Send feedback to client
24
25 client.print(F("Pin D"));
26
27 client.print(pin);
28
29 client.print(F(" configured as OUTPUT!"));
30
31 return;
32
33 }
34
35 client.print(F("error: invalid mode "));
36
37 client.print(mode);
38}

The complete sketch is below :

1/*
2
3 Arduino Yún Bridge example
4
5 This example for the YunShield/Yún shows how
6
7 to use the Bridge library to access the digital and
8
9 analog pins on the board through REST calls.
10
11 It demonstrates how you can create your own API when
12
13 using REST style calls through the browser.
14
15 Possible commands created in this shetch:
16
17 "/arduino/digital/13" -> digitalRead(13)
18
19 "/arduino/digital/13/1" -> digitalWrite(13, HIGH)
20
21 "/arduino/analog/2/123" -> analogWrite(2, 123)
22
23 "/arduino/analog/2" -> analogRead(2)
24
25 "/arduino/mode/13/input" -> pinMode(13, INPUT)
26
27 "/arduino/mode/13/output" -> pinMode(13, OUTPUT)
28
29 This example code is part of the public domain
30
31 http://www.arduino.cc/en/Tutorial/Bridge
32
33*/
34
35#include <Bridge.h>
36#include <BridgeServer.h>
37#include <BridgeClient.h>
38
39// Listen to the default port 5555, the Yún webserver
40// will forward there all the HTTP requests you send
41
42BridgeServer server;
43
44void setup() {
45
46 // Bridge startup
47
48 pinMode(13, OUTPUT);
49
50 digitalWrite(13, LOW);
51
52 Bridge.begin();
53
54 digitalWrite(13, HIGH);
55
56 // Listen for incoming connection only from localhost
57
58 // (no one from the external network could connect)
59
60 server.listenOnLocalhost();
61
62 server.begin();
63}
64
65void loop() {
66
67 // Get clients coming from server
68
69 BridgeClient client = server.accept();
70
71 // There is a new client?
72
73 if (client) {
74
75 // Process request
76
77 process(client);
78
79 // Close connection and free resources.
80
81 client.stop();
82
83 }
84
85 delay(50); // Poll every 50ms
86}
87
88void process(BridgeClient client) {
89
90 // read the command
91
92 String command = client.readStringUntil('/');
93
94 // is "digital" command?
95
96 if (command == "digital") {
97
98 digitalCommand(client);
99
100 }
101
102 // is "analog" command?
103
104 if (command == "analog") {
105
106 analogCommand(client);
107
108 }
109
110 // is "mode" command?
111
112 if (command == "mode") {
113
114 modeCommand(client);
115
116 }
117}
118
119void digitalCommand(BridgeClient client) {
120
121 int pin, value;
122
123 // Read pin number
124
125 pin = client.parseInt();
126
127 // If the next character is a '/' it means we have an URL
128
129 // with a value like: "/digital/13/1"
130
131 if (client.read() == '/') {
132
133 value = client.parseInt();
134
135 digitalWrite(pin, value);
136
137 } else {
138
139 value = digitalRead(pin);
140
141 }
142
143 // Send feedback to client
144
145 client.print(F("Pin D"));
146
147 client.print(pin);
148
149 client.print(F(" set to "));
150
151 client.println(value);
152
153 // Update datastore key with the current pin value
154
155 String key = "D";
156
157 key += pin;
158
159 Bridge.put(key, String(value));
160}
161
162void analogCommand(BridgeClient client) {
163
164 int pin, value;
165
166 // Read pin number
167
168 pin = client.parseInt();
169
170 // If the next character is a '/' it means we have an URL
171
172 // with a value like: "/analog/5/120"
173
174 if (client.read() == '/') {
175
176 // Read value and execute command
177
178 value = client.parseInt();
179
180 analogWrite(pin, value);
181
182 // Send feedback to client
183
184 client.print(F("Pin D"));
185
186 client.print(pin);
187
188 client.print(F(" set to analog "));
189
190 client.println(value);
191
192 // Update datastore key with the current pin value
193
194 String key = "D";
195
196 key += pin;
197
198 Bridge.put(key, String(value));
199
200 } else {
201
202 // Read analog pin
203
204 value = analogRead(pin);
205
206 // Send feedback to client
207
208 client.print(F("Pin A"));
209
210 client.print(pin);
211
212 client.print(F(" reads analog "));
213
214 client.println(value);
215
216 // Update datastore key with the current pin value
217
218 String key = "A";
219
220 key += pin;
221
222 Bridge.put(key, String(value));
223
224 }
225}
226
227void modeCommand(BridgeClient client) {
228
229 int pin;
230
231 // Read pin number
232
233 pin = client.parseInt();
234
235 // If the next character is not a '/' we have a malformed URL
236
237 if (client.read() != '/') {
238
239 client.println(F("error"));
240
241 return;
242
243 }
244
245 String mode = client.readStringUntil('\r');
246
247 if (mode == "input") {
248
249 pinMode(pin, INPUT);
250
251 // Send feedback to client
252
253 client.print(F("Pin D"));
254
255 client.print(pin);
256
257 client.print(F(" configured as INPUT!"));
258
259 return;
260
261 }
262
263 if (mode == "output") {
264
265 pinMode(pin, OUTPUT);
266
267 // Send feedback to client
268
269 client.print(F("Pin D"));
270
271 client.print(pin);
272
273 client.print(F(" configured as OUTPUT!"));
274
275 return;
276
277 }
278
279 client.print(F("error: invalid mode "));
280
281 client.print(mode);
282}

Contribute to Arduino

Join the community and suggest improvements to this article via GitHub. Make sure to read out contribution policy before making your pull request.

Missing something?

Check out our store and get what you need to follow this tutorial.