~ ESP32
» By Joren on Wednesday 05 April 2017ESP32 Workshop
- Getting Started
- Blink
- Hello WiFi – Connecting to WiFi
- Sending data from the ESP32
- Mesh Networking
Getting Started ^
During the workshop we will use the ESP32 Thing by Sparkfun. It has local distributors. The Sparkfun guide to get started with the ESP32 is useful as well.
- Arduino IDE version 1.8.2
- Installation Instructions
- The server components are in Ruby. The server components are not needed but optionally a Ruby environment with gem osc-ruby installed is practical.
Some common pitfalls: make sure that you have git and a compatible version of python on your system. Python 2.7.10 seems to work on Mac.
Blink ^
As a way to test the setup, connect the ESP32 and upload following code:
Goal: Upload code to the ESP32, make it blink! Check serial communication.
Method: Configure your environment correctly
Needed information: The code below, tip: always use 115200 as baud rate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int ledPin = 5;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
}
void loop()
{
Serial.println("Hello world");
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
When uploading make sure you select the correct serial port.
Perhaps you need to press the 0
button after compilation and before upload.
You should see something like below when uploading:
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
Writing at 0x00001000... (100 %)
Wrote 10128 bytes (6242 compressed) at 0x00001000 in 0.1 seconds (effective 1014.8 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 105...
Writing at 0x00008000... (100 %)
Wrote 3072 bytes (105 compressed) at 0x00008000 in 0.0 seconds (effective 1581.6 kbit/s)...
Hash of data verified.
Compressed 8192 bytes to 47...
Writing at 0x0000e000... (100 %)
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (effective 3926.9 kbit/s)...
Hash of data verified.
Compressed 508720 bytes to 265166...
Writing at 0x00010000... (5 %)
Writing at 0x00014000... (11 %)
Writing at 0x00018000... (17 %)
Writing at 0x0001c000... (23 %)
Writing at 0x00020000... (29 %)
Writing at 0x00024000... (35 %)
Writing at 0x00028000... (41 %)
Writing at 0x0002c000... (47 %)
Writing at 0x00030000... (52 %)
Writing at 0x00034000... (58 %)
Writing at 0x00038000... (64 %)
Writing at 0x0003c000... (70 %)
Writing at 0x00040000... (76 %)
Writing at 0x00044000... (82 %)
Writing at 0x00048000... (88 %)
Writing at 0x0004c000... (94 %)
Writing at 0x00050000... (100 %)
Wrote 508720 bytes (265166 compressed) at 0x00010000 in 5.9 seconds (effective 690.8 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting...
Hello Wifi^
Goal: Connect to WiFi access point and get an IP address
Method: Use function hooks to react to events
Needed information: SSID: ESP32 WEP password: Ghent
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
#include <WiFi.h>
const char* ssid = "ESP32";
const char* password = "ghent";
void WiFiEvent(WiFiEvent_t event){
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
break;
}
}
void setup(){
Serial.begin(115200);
// delete old config
WiFi.disconnect(true);
delay(1000);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
Serial.println();
Serial.println("Wait for WiFi... ");
}
void loop(){
delay(1000);
}
After a sucesful upload you should see something like this in the serial console:
1
2
3
4
5
6
7
Wait for WiFi...
[WiFi-event] event: 2
[WiFi-event] event: 4
[WiFi-event] event: 7
WiFi connected
IP address:
192.168.1.22
Sending data from the ESP32 ^
Sending data using TCP ^
Goal: Connect to TCP server and send and receive data
Method: Use the WiFiClient class to send and receive data
Needed information: There is a TCP server running on port 2222 of 192.168.1.24
Bonus: Run your own TCP server with your own code or the ruby code provided.
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
#include <WiFi.h>
const char* ssid = "esp32";
const char* password = "ghent";
boolean connected = false;
const uint16_t server_tcp_port = 2222;
const char * server_tcp_host = "192.168.1.24"; // ip or dns
void WiFiEvent(WiFiEvent_t event)
{
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connected = true;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
connected = false;
break;
}
}
void setup()
{
Serial.begin(115200);
// delete old config
WiFi.disconnect(true);
delay(1000);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
Serial.println();
Serial.println();
Serial.println("Wait for WiFi... ");
}
void loop(){
//wait 5 seconds
delay(5000);
//if we are connected
if(connected){
//create a tcp connection
WiFiClient client;
//check if the server can be connected to
if (!client.connect(server_tcp_host, server_tcp_port)) {
Serial.println("TCP connection failed, check server config!");
}else{
delay(50);
//read back one lines from server
while(client.available()){
String line = client.readStringUntil('\n');
Serial.println(line);
}
// Send this data to the server
unsigned long time = millis();
client.print("ESP time: ");
client.println(time);
delay(50);
Serial.println("TCP connection close");
client.stop();
}
}
}
Ruby TCP server
1
2
3
4
5
6
7
8
9
10
11
12
require 'socket'
server = TCPServer.new 2222
loop do
Thread.start(server.accept) do |client|
sock_domain, remote_port, remote_hostname, remote_ip = client.peeraddr
client.puts "Sever time is #{Time.now}\n"
data = client.gets
puts "Msg from #{remote_ip}: #{data}"
system("tput bel")
end
end
Broadcast data over UDP ^
Goal: Send some data over UDP!
Method: Send UDP packets over the network
Needed information: SSID: ESP32 WEP password: Ghent. UDP server running on 192.168.1.24
Bonus question: How do you broadcast, is broadcasting possible with TCP?
Bonus bonus: Run your own UDP server and listen to the packets
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
/*
* This sketch sends random data over UDP on a ESP32 device
*
*/
#include <WiFi.h>
#include <WiFiUdp.h>
// WiFi network name and password:
const char * networkName = "esp32";
const char * networkPswd = "ghent";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const char * udpAddress = "192.168.1.24";
const int udpPort = 3333;
//Are we currently connected?
boolean connected = false;
//The udp library class
WiFiUDP udp;
void setup(){
// Initilize hardware serial:
Serial.begin(115200);
//Connect to the WiFi network
connectToWiFi(networkName, networkPswd);
}
void loop(){
//only send data when connected
if(connected){
//Send a packet
udp.beginPacket(udpAddress,udpPort);
udp.printf("Millis since boot: %u", millis());
udp.endPacket();
}
//Wait for 5 seconds
delay(5000);
}
void connectToWiFi(const char * ssid, const char * pwd){
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//register event handler
WiFi.onEvent(WiFiEvent);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//wifi event handler
void WiFiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//When connected set
Serial.print("WiFi connected! IP address: ");
Serial.println(WiFi.localIP());
//initializes the UDP state
//This initializes the transfer buffer
udp.begin(WiFi.localIP(),udpPort);
connected = true;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
connected = false;
break;
}
}
Ruby UDP server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# This ruby script listens on UDP port 3333
# for messages from the ESP32 board and prints them
require 'socket'
include Socket::Constants
udp_socket = UDPSocket.new(AF_INET)
#bind
udp_socket.bind("", 3333)
puts 'Server listening'
while true do
message, sender = udp_socket.recvfrom(1024)
puts message
end
Broadcast data using OSC over UDP ^
Goal: Get a beer, be the first to say your name!
Method: Send your name over OSC to the broadcast address of the network
Needed information: SSID: ESP32 WEP password: Ghent. OSC ‘method’ is /ESP32, 192.168.1.0/16 is the network so the broadcast address is …. You also need the OSC Arduino Library for ESP32 it is a slightly modified version of the official version. The official version does not work.
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
#include <WiFi.h>
#include <WiFiUdp.h>
#include <OSCMessage.h>
// WiFi network name and password:
const char * networkName = "esp32";
const char * networkPswd = "ghent";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const IPAddress udpAddress(192, 168, 1, 255);
const int udpPort = 4444;
//Are we currently connected?
boolean connected = false;
//The udp library class
WiFiUDP udp;
void setup(){
// Initilize hardware serial:
Serial.begin(115200);
//Connect to the WiFi network
connectToWiFi(networkName, networkPswd);
}
void loop(){
//only send data when connected
if(connected){
//Send a packet
int value = random(100);
OSCMessage msg("/esp");
msg.add((unsigned int) millis());
msg.add((unsigned int) value);
udp.beginPacket(udpAddress, udpPort);
msg.send(udp);
udp.endPacket();
msg.empty();
}
//Wait for 5 seconds
delay(5000);
}
void connectToWiFi(const char * ssid, const char * pwd){
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//register event handler
WiFi.onEvent(WiFiEvent);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//wifi event handler
void WiFiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//When connected set
Serial.print("WiFi connected! IP address: ");
Serial.println(WiFi.localIP());
//initializes the UDP state
//This initializes the transfer buffer
udp.begin(WiFi.localIP(),udpPort);
connected = true;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
connected = false;
break;
}
}
Broadcasting sensor data over UDP and OSC ^
Goal: Send sensor data over UDP via OSC and react to it!
Method: Send UDP OSC packets over the network and sonify in “Pure Data”
Needed information: SSID: ESP32 WEP password: Ghent. OSC server running in pd at port 4444, expecting messages
Bonus question: Play with the sonification.
Battery is a single cell li-ion like available here
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
#include <WiFi.h>
#include <WiFiUdp.h>
#include <OSCMessage.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
// WiFi network name and password:
const char * networkName = "esp32";
const char * networkPswd = "ghent";
//IP address to send UDP data to:
// either use the ip address of the server or
// a network broadcast address
const IPAddress udpAddress(192, 168, 1, 255);
const int udpPort = 4444;
Adafruit_BNO055 bno = Adafruit_BNO055();
//Are we currently connected?
boolean connected = false;
//The udp library class
WiFiUDP udp;
void setup(){
// Initilize hardware serial:
Serial.begin(115200);
/* Initialise the sensor */
if(!bno.begin())
{
/* There was a problem detecting the BNO055 ... check your connections */
Serial.print("Ooops, no BNO055 detected ... Check your wiring or I2C ADDR!");
while(1);
}
bno.setExtCrystalUse(true);
//Connect to the WiFi network
connectToWiFi(networkName, networkPswd);
}
void loop(){
//only send data when connected
if(connected){
//Send a packet
int value = random(100);
imu::Vector<3> acc = bno.getVector(Adafruit_BNO055::VECTOR_LINEARACCEL);
double norm = sqrt(acc.x() * acc.x() + acc.y() * acc.y() + acc.z() * acc.z());
Serial.print("norm: ");
Serial.print(norm);
Serial.println("");
OSCMessage msg("/esp");
msg.add((unsigned int) millis());
msg.add((float) norm);
udp.beginPacket(udpAddress, udpPort);
msg.send(udp);
udp.endPacket();
msg.empty();
}
//Wait for 25ms
delay(25);
}
void connectToWiFi(const char * ssid, const char * pwd){
Serial.println("Connecting to WiFi network: " + String(ssid));
// delete old config
WiFi.disconnect(true);
//register event handler
WiFi.onEvent(WiFiEvent);
//Initiate connection
WiFi.begin(ssid, pwd);
Serial.println("Waiting for WIFI connection...");
}
//wifi event handler
void WiFiEvent(WiFiEvent_t event){
switch(event) {
case SYSTEM_EVENT_STA_GOT_IP:
//When connected set
Serial.print("WiFi connected! IP address: ");
Serial.println(WiFi.localIP());
//initializes the UDP state
//This initializes the transfer buffer
udp.begin(WiFi.localIP(),udpPort);
connected = true;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
connected = false;
break;
}
}
Mesh Networking ^
Goal: Make a Mesh network of ESP32’s
Method: Set the ESP in Station and Access Point mode at the same time, scan for open networks and connect
Needed information: See above and the examples to scan for Access Points