This tutorial is designed to be a quick guide to help users build innovative projects using DFRobot & Hackster EEDU kits with the Arduino IoT cloud. The EEDU kits are all built around an Arduino-compatible, ESP32-based FireBeetle 2 Board and include rich application-specific peripherals such as AI camera HuskyLens, multifunctional Environmental Sensor, URM37 ultrasonic sensor, DFPlayer module, and so on. In this tutorial, we demonstrate three cases involving AI, IoT, and environmental sensing respectively, and also offer some guidelines for getting started with Arduino IoT cloud.
How to Get Documents Resources1. Click to open the EEDU Kit wiki page, then you will find all the product information here. Each product's wiki is linked to the table at the position marked in orange below.
2. On the wiki page, you can find the related library, connection diagram, sample codes, and so on.
Please follow the steps above to get details about using each hardware unit. Here we only provide you with some basics in four demos: a face recognition switch, an anti-theft alarm device, environmental data monitoring, and VOC index monitoring.
1. Face Recognition SwitchDescription
Use the DFRobot HuskyLens camera to recognize the human face. If a learned face is recognized, the relay turns on. If the face is unlearned, it stays off.
Hardware List
1. HuskyLens AI Vision Sensor ×1
2. FireBeetle 2 ESP32-E IoT Microcontroller ×1
3. Digital Relay Module ×1
Connection
Connect the hardware using the DuPont wires that come with the kit.
Upload Codes to Arduino Cloud Editor
1. Sign up and log in to www.arduino.cc.
2. Open the Arduino cloud editor.
3. Follow the prompts to install and run the Arduino Create Agent, which will provide the following functions:
- Identify the Arduino board and other supported devices connected to the computer via USB
- Upload the sketch from the Web browser to the board via USB or the network
- Read data from the serial monitor, and write data
When completing the steps above, you will see the agent icon in the system tray. Make sure it is black/green. If it's grey, click it and select "Resume Agent".
4. Create a new sketch. Copy and paste the sample codes into the program editing area.
#include "HUSKYLENS.h"
HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL
void printResult(HUSKYLENSResult result);
void setup() {
Serial.begin(115200);
Wire.begin();
while (!huskylens.begin(Wire))
{
Serial.println(F("Begin failed!"));
Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
Serial.println(F("2.Please recheck the connection."));
delay(100);
}
pinMode(D6, OUTPUT);
}
void loop() {
if (!huskylens.request()) Serial.println(F("Fail to request data from HUSKYLENS, recheck the connection!"));
else if(!huskylens.isLearned()) Serial.println(F("Nothing learned, press learn button on HUSKYLENS to learn one!"));
else if(!huskylens.available()) Serial.println(F("No block or arrow appears on the screen!"));
else
{
Serial.println(F("###########"));
while (huskylens.available())
{
HUSKYLENSResult result = huskylens.read();
printResult(result);
}
}
}
void printResult(HUSKYLENSResult result){
if (result.command == COMMAND_RETURN_BLOCK){
Serial.println(String()+F("Block:xCenter=")+result.xCenter+F(",yCenter=")+result.yCenter+F(",width=")+result.width+F(",height=")+result.height+F(",ID=")+result.ID);
if(result.ID==1){
digitalWrite(D6, HIGH);
delay(2000);
digitalWrite(D6, LOW);
}
}
}
#include "HUSKYLENS.h"
HUSKYLENS huskylens;
//HUSKYLENS green line >> SDA; blue line >> SCL
void printResult(HUSKYLENSResult result);
void setup() {
Serial.begin(115200);
Wire.begin();
while (!huskylens.begin(Wire))
{
Serial.println(F("Begin failed!"));
Serial.println(F("1.Please recheck the \"Protocol Type\" in HUSKYLENS (General Settings>>Protocol Type>>I2C)"));
Serial.println(F("2.Please recheck the connection."));
delay(100);
}
pinMode(D6, OUTPUT);
}
void loop() {
if (!huskylens.request()) Serial.println(F("Fail to request data from HUSKYLENS, recheck the connection!"));
else if(!huskylens.isLearned()) Serial.println(F("Nothing learned, press learn button on HUSKYLENS to learn one!"));
else if(!huskylens.available()) Serial.println(F("No block or arrow appears on the screen!"));
else
{
Serial.println(F("###########"));
while (huskylens.available())
{
HUSKYLENSResult result = huskylens.read();
printResult(result);
}
}
}
void printResult(HUSKYLENSResult result){
if (result.command == COMMAND_RETURN_BLOCK){
Serial.println(String()+F("Block:xCenter=")+result.xCenter+F(",yCenter=")+result.yCenter+F(",width=")+result.width+F(",height=")+result.height+F(",ID=")+result.ID);
if(result.ID==1){
digitalWrite(D6, HIGH);
delay(2000);
digitalWrite(D6, LOW);
}
}
}
5. Import the library. Download the HuskyLens Arduino library zip first, and then import it to the Arduino Cloud. (Skip it if you don't need to use a library)
The Arduino library provides additional functions
- It mainly contains some driver files for sensors or actuators and some common functions
- For beginners, you only need to know how to use the functions provided in the library without getting deeply into how these functions or drivers are implemented, which greatly reduces development difficulty
6. Connect ESP32 to the computer via a Type-C cable and upload the program to the board.
7. Select the corresponding board & port, click to upload program, and wait for the uploading success.
Result
When a learned face is recognized by HuskyLens, the relay turns on; when an unlearned face is recognized, it stays off.
Description
The PIR sensor detects the presence of human beings (detected: 1; not detected: 0). If the controller receives signals from the sensor and human presence is determined, report the message "intrusion alarm" to Blynk.
Hardware List
1. FireBeetle 2 ESP32-E IoT Microcontroller ×1
2. Gravity: Digital PIR (Motion) Sensor for Arduino ×1
Connection
Upload Codes to Arduino Cloud Editor
The steps here are the same as those of the first application case, so please refer to the first project to upload the program to Arduino Cloud Editor. The library and codes of this sample are as follows.
Library
Codes
#define BLYNK_TEMPLATE_ID "TMPLxxxxxx"
#define BLYNK_DEVICE_NAME "Device"
#define BLYNK_AUTH_TOKEN "YourAuthToken"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
BlynkTimer timer;
int inPin = D7;
void myTimerEvent() {
if (digitalRead(inPin) == 0) {
Blynk.virtualWrite(V3, "Intrusion alarm");
}
}
void setup() {
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
timer.setInterval(1000L, myTimerEvent);
pinMode(inPin, INPUT);
}
void loop() {
Blynk.run();
timer.run();
}
#define BLYNK_TEMPLATE_ID "TMPLxxxxxx"
#define BLYNK_DEVICE_NAME "Device"
#define BLYNK_AUTH_TOKEN "YourAuthToken"
#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleEsp32.h>
char auth[] = BLYNK_AUTH_TOKEN;
char ssid[] = "YourNetworkName";
char pass[] = "YourPassword";
BlynkTimer timer;
int inPin = D7;
void myTimerEvent() {
if (digitalRead(inPin) == 0) {
Blynk.virtualWrite(V3, "Intrusion alarm");
}
}
void setup() {
Serial.begin(115200);
Blynk.begin(auth, ssid, pass);
timer.setInterval(1000L, myTimerEvent);
pinMode(inPin, INPUT);
}
void loop() {
Blynk.run();
timer.run();
}
Connect the device to Blynk
1. Sign up and log in to Blynk, then create a new template (select ESP32 as hardware and WiFi as the connection type).
2. Create a new device and choose "From template".
3. Select the template just created.
4. Enter the device to view its template ID, device name, and AuthToken.
5. Edit the dashboard to configure the gauge of the device.
6. Drag and drop Gauge to set up.
7. Set the Gauge TITLE & Datastream.
Result
When the PIR sensor has detected the presence of human beings, the message "intrusion alarm" will be reported to Blynk.
Description
- Connect to the WiFi "Beetle ESP32E", and the set password is 12345678
- Visit the website http://192.168.4.1/GET to get the environmental data information on the LAN
- Refresh the webpage to update the sensor data
Hardware List
1. FireBeetle 2 ESP32-E IoT Microcontroller ×1
2. Multifunctional Environmental Sensor ×1
Connection
Upload Codes to Arduino Cloud Editor
The steps here are the same as those of the first application case, so please refer to the first project to upload the program to Arduino Cloud Editor. The library and codes of this sample are as follows.
Library
Codes
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include "DFRobot_EnvironmentalSensor.h"
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
#include <SoftwareSerial.h>
#endif
#define MODESWITCH /*UART:*/0 /*I2C: 1*/
#if MODESWITCH
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
DFRobot_EnvironmentalSensor environment(/*addr =*/SEN050X_DEFAULT_DEVICE_ADDRESS, /*s =*/&mySerial);//Create an object for broadcast address, which can configure all devices on the bus in batches
#else
DFRobot_EnvironmentalSensor environment(/*addr =*/SEN050X_DEFAULT_DEVICE_ADDRESS, /*s =*/&Serial1); //Create an object for broadcast address, which can configure all devices on the bus in batches
#endif
#else
DFRobot_EnvironmentalSensor environment(/*addr = */SEN050X_DEFAULT_DEVICE_ADDRESS, /*pWire = */&Wire);
#endif
// Set the WIFI name and password
const char *ssid = "Beetle ESP32E";//WIFI name
const char *password = "12345678";//password
WiFiServer server(80);//The default web service port is 80
void setup() {
//pinMode(myLED, OUTPUT);
#if MODESWITCH
//Initialize MCU communication serial port
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
mySerial.begin(9600);
#elif defined(ESP32)
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
Serial1.begin(9600);
#endif
#endif
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
//If you want to use the network without a password, delete it
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
while(environment.begin() != 0){
Serial.println(" Sensor initialize failed!!");
delay(1000);
}
Serial.println(" Sensor initialize success!!");
}
void loop() {
WiFiClient client = server.available(); // Check if server is available
if (client) { // Check connectivity
Serial.println("New Client.");
String currentLine = ""; // Create String variable to store data
while (client.connected()) { // Repeat when connected
if (client.available()) { // Check if there is data coming
char c = client.read(); // Read the received data
//Serial.write(c); // Print on serial monitor
if (c == '\n') { // If a newline character is read
//Clear the cached content
if (currentLine.length() == 0) {
client.print(" ");
break;
} else { // Clear data stored by variable if there is a newline character
currentLine = "";
}
} else if (c != '\r') { // If a character except CR is obtained
currentLine += c; // Add the obtained character to the end of the variable
}
// Check if /GET is at the end
if (currentLine.endsWith("/GET")) {
//Read environmental data and print them on the web
client.print("Temp: "); client.print(environment.getTemperature(TEMP_C));client.println(" ℃");
client.print("Humidity: "); client.print(environment.getHumidity());client.println(" %");
client.print("Ultraviolet intensity: "); client.print(environment.getUltravioletIntensity());client.println(" mw/cm2");
client.print("LuminousIntensity: "); client.print(environment.getLuminousIntensity());client.println(" lx");
client.print("Atmospheric pressure: "); client.print(environment.getAtmospherePressure(HPA));client.println(" hpa");
client.print("Elevation: "); client.print(environment.getElevation());client.println(" m");
}
}
}
// Disconnect
client.stop();
Serial.println("Client Disconnected.");
}
}
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
#include "DFRobot_EnvironmentalSensor.h"
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
#include <SoftwareSerial.h>
#endif
#define MODESWITCH /*UART:*/0 /*I2C: 1*/
#if MODESWITCH
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
SoftwareSerial mySerial(/*rx =*/4, /*tx =*/5);
DFRobot_EnvironmentalSensor environment(/*addr =*/SEN050X_DEFAULT_DEVICE_ADDRESS, /*s =*/&mySerial);//Create an object for broadcast address, which can configure all devices on the bus in batches
#else
DFRobot_EnvironmentalSensor environment(/*addr =*/SEN050X_DEFAULT_DEVICE_ADDRESS, /*s =*/&Serial1); //Create an object for broadcast address, which can configure all devices on the bus in batches
#endif
#else
DFRobot_EnvironmentalSensor environment(/*addr = */SEN050X_DEFAULT_DEVICE_ADDRESS, /*pWire = */&Wire);
#endif
// Set the WIFI name and password
const char *ssid = "Beetle ESP32E";//WIFI name
const char *password = "12345678";//password
WiFiServer server(80);//The default web service port is 80
void setup() {
//pinMode(myLED, OUTPUT);
#if MODESWITCH
//Initialize MCU communication serial port
#if defined(ARDUINO_AVR_UNO)||defined(ESP8266)
mySerial.begin(9600);
#elif defined(ESP32)
Serial1.begin(9600, SERIAL_8N1, /*rx =*/D3, /*tx =*/D2);
#else
Serial1.begin(9600);
#endif
#endif
Serial.begin(115200);
Serial.println();
Serial.println("Configuring access point...");
//If you want to use the network without a password, delete it
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(myIP);
server.begin();
Serial.println("Server started");
while(environment.begin() != 0){
Serial.println(" Sensor initialize failed!!");
delay(1000);
}
Serial.println(" Sensor initialize success!!");
}
void loop() {
WiFiClient client = server.available(); // Check if server is available
if (client) { // Check connectivity
Serial.println("New Client.");
String currentLine = ""; // Create String variable to store data
while (client.connected()) { // Repeat when connected
if (client.available()) { // Check if there is data coming
char c = client.read(); // Read the received data
//Serial.write(c); // Print on serial monitor
if (c == '\n') { // If a newline character is read
//Clear the cached content
if (currentLine.length() == 0) {
client.print(" ");
break;
} else { // Clear data stored by variable if there is a newline character
currentLine = "";
}
} else if (c != '\r') { // If a character except CR is obtained
currentLine += c; // Add the obtained character to the end of the variable
}
// Check if /GET is at the end
if (currentLine.endsWith("/GET")) {
//Read environmental data and print them on the web
client.print("Temp: "); client.print(environment.getTemperature(TEMP_C));client.println(" ℃");
client.print("Humidity: "); client.print(environment.getHumidity());client.println(" %");
client.print("Ultraviolet intensity: "); client.print(environment.getUltravioletIntensity());client.println(" mw/cm2");
client.print("LuminousIntensity: "); client.print(environment.getLuminousIntensity());client.println(" lx");
client.print("Atmospheric pressure: "); client.print(environment.getAtmospherePressure(HPA));client.println(" hpa");
client.print("Elevation: "); client.print(environment.getElevation());client.println(" m");
}
}
}
// Disconnect
client.stop();
Serial.println("Client Disconnected.");
}
}
Result
Access the website from a cell phone, computer, etc. to get the results below (environmental data obtained from the multifunctional environmental sensor under LAN).
Description
1. Display the VOC index on a screen in real-time
2. Prompt audios corresponding to the VOC index in different ranges
3. Monitor air quality change trends by collecting accurate VOC index data and then display data on Arduino IoT Cloud in a visual way that is easy to understand.
VOC Index Air Quality Suggested Action
0-100 Excellent No ventilation needed
100-200 Good No ventilation needed
200-300 Lightly Polluted Ventilation suggested
300-400 Moderately Polluted Increased ventilation suggested
400-500 Heavily Polluted Strong ventilation suggested
Hardware List
1. FireBeetle 2 ESP32-E IoT Microcontroller ×1
2. SGP40 Air Quality Sensor ×1
3. DFPlayer Pro - A mini MP3 Player with On-board 128MB Storage ×1
4. I2C OLED-2864 Display ×1
Connection
Upload Codes to Arduino Cloud Editor
The steps here are the same as those of the first application case, so please refer to the first project to upload the program to Arduino Cloud Editor. The library and codes of this sample are as follows.
Library
Codes
Transfer audio files into the MP3 Player module
Before use, connect the module to the computer using a USB cable and store the audio files in the MP3 player module.
Name the audio files as follows. Use the function 'DF1201S.playFileNum(/*File Number = */1);' to play the audio file with the specified number."
Connect the device to Arduino IoT Cloud
1. Open Arduino IoT Cloud, and click "ADD DEVICE".
2. Select "Set up a 3rd party device", and choose the device type as ESP32 and FireBeetle-ESP32.
3. You'll get the device ID and secret key, and you need to save them.
- 4. Create a thing and name it.
5. Create a variable VOC, and configure it as "int", "Read Only" and "On change"
6. Select the device to be associated with.
7. Then configure the network. Enter the WiFi name, password, and secret key saved in step 3.
8. Now the Things-related configuration is completed.
9. Click "Sketch" and "Open full editor" to write a program sketch.
10. Modify the routine and upload the final program.
11. Set up the dashboard
12. Set the linked variable, the minimum and maximum value in Widget Settings.
13. Set up the chart similarly.
Result
1. Display the VOC index on the OLED screen.
2. Play audio prompts corresponding to the VOC index in different ranges(Audios need to be put into the MP3 player in advance).
3. View the VOC index directly on the dashboard in real time.
Please note that the wiki resources for MP3 Player and ultrasonic ranging sensor in the kits are based on Arduino UNO, and you may need to make some changes in the codes to use them with ESP32.
MP3 Player (DFR0768)
Connection
Codes
When powered on, the module enters music mode and starts playing audio files, and the serial will print the current operation.
#include <DFRobot_DF1201S.h>
DFRobot_DF1201S DF1201S;
void setup(void){
Serial.begin(115200);
Serial2.begin(115200);
while(!DF1201S.begin(Serial2)){
Serial.println("Init failed, please check the wire connection!");
delay(1000);
}
/*Set volume to 20*/
DF1201S.setVol(/*VOL = */20);
Serial.print("VOL:");
/*Get volume*/
Serial.println(DF1201S.getVol());
/*Enter music mode*/
DF1201S.switchFunction(DF1201S.MUSIC);
/*Wait for the end of the prompt tone*/
delay(2000);
/*Set playback mode to "repeat all"*/
DF1201S.setPlayMode(DF1201S.ALLCYCLE);
Serial.print("PlayMode:");
/*Get playback mode*/
Serial.println(DF1201S.getPlayMode());
}
void loop(){
Serial.println("Start playing");
DF1201S.start();
delay(3000);
Serial.println("Pause");
DF1201S.pause();
delay(3000);
Serial.println("Play the next song");
DF1201S.next();
delay(3000);
Serial.println("Play the previous song");
DF1201S.last();
delay(3000);
Serial.println("Start playing");
DF1201S.fastForward(/*FF = */10);
Serial.print("File number:");
Serial.println(DF1201S.getCurFileNumber());
Serial.print("The number of files available to play:");
Serial.println(DF1201S.getTotalFile());
Serial.print("The time length the current song has played:");
Serial.println(DF1201S.getCurTime());
Serial.print("The total length of the currently-playing song:");
Serial.println(DF1201S.getTotalTime());
Serial.print("The name of the currently-playing file:");
Serial.println(DF1201S.getFileName());
delay(3000);
DF1201S.playFileNum(/*File Number = */1);
while(1);
}
#include <DFRobot_DF1201S.h>
DFRobot_DF1201S DF1201S;
void setup(void){
Serial.begin(115200);
Serial2.begin(115200);
while(!DF1201S.begin(Serial2)){
Serial.println("Init failed, please check the wire connection!");
delay(1000);
}
/*Set volume to 20*/
DF1201S.setVol(/*VOL = */20);
Serial.print("VOL:");
/*Get volume*/
Serial.println(DF1201S.getVol());
/*Enter music mode*/
DF1201S.switchFunction(DF1201S.MUSIC);
/*Wait for the end of the prompt tone*/
delay(2000);
/*Set playback mode to "repeat all"*/
DF1201S.setPlayMode(DF1201S.ALLCYCLE);
Serial.print("PlayMode:");
/*Get playback mode*/
Serial.println(DF1201S.getPlayMode());
}
void loop(){
Serial.println("Start playing");
DF1201S.start();
delay(3000);
Serial.println("Pause");
DF1201S.pause();
delay(3000);
Serial.println("Play the next song");
DF1201S.next();
delay(3000);
Serial.println("Play the previous song");
DF1201S.last();
delay(3000);
Serial.println("Start playing");
DF1201S.fastForward(/*FF = */10);
Serial.print("File number:");
Serial.println(DF1201S.getCurFileNumber());
Serial.print("The number of files available to play:");
Serial.println(DF1201S.getTotalFile());
Serial.print("The time length the current song has played:");
Serial.println(DF1201S.getCurTime());
Serial.print("The total length of the currently-playing song:");
Serial.println(DF1201S.getTotalTime());
Serial.print("The name of the currently-playing file:");
Serial.println(DF1201S.getFileName());
delay(3000);
DF1201S.playFileNum(/*File Number = */1);
while(1);
}
Ultrasonic Ranging Sensor(SEN0001)
Connection
Codes
Measure the distance between the sensor and the object in the detecting range.
int URECHO = D3; // PWM Output 0-50000US,Every 50US represent 1cm
unsigned int Distance = 0;
uint8_t AutomaticModelCmd[4] = {0x44, 0x02, 0xaa, 0xf0}; // distance measure command
void setup()
{
Serial.begin(9600); // Serial initialization
delay(5000); // wait for sensor setup
AutomaticModelSetup(); //Automatic measurement model set
}
void loop()
{
AutomaticMeasurement();
delay(100);
}
void AutomaticModelSetup(void)
{
pinMode(URECHO, INPUT);
for (int i = 0; i < 4; i++)
{
Serial.write(AutomaticModelCmd[i]);// Sending Automatic measurement model command
}
}
void AutomaticMeasurement(void)
{
unsigned long DistanceMeasured = pulseIn(URECHO, LOW);
if (DistanceMeasured >= 50000) // the reading is invalid.
{
Serial.print("Invalid");
}
else
{
Distance = DistanceMeasured / 50; // every 50us low level stands for 1cm
Serial.print("Distance=");
Serial.print(Distance);
Serial.println("cm");
}
}
int URECHO = D3; // PWM Output 0-50000US,Every 50US represent 1cm
unsigned int Distance = 0;
uint8_t AutomaticModelCmd[4] = {0x44, 0x02, 0xaa, 0xf0}; // distance measure command
void setup()
{
Serial.begin(9600); // Serial initialization
delay(5000); // wait for sensor setup
AutomaticModelSetup(); //Automatic measurement model set
}
void loop()
{
AutomaticMeasurement();
delay(100);
}
void AutomaticModelSetup(void)
{
pinMode(URECHO, INPUT);
for (int i = 0; i < 4; i++)
{
Serial.write(AutomaticModelCmd[i]);// Sending Automatic measurement model command
}
}
void AutomaticMeasurement(void)
{
unsigned long DistanceMeasured = pulseIn(URECHO, LOW);
if (DistanceMeasured >= 50000) // the reading is invalid.
{
Serial.print("Invalid");
}
else
{
Distance = DistanceMeasured / 50; // every 50us low level stands for 1cm
Serial.print("Distance=");
Serial.print(Distance);
Serial.println("cm");
}
}
Comments