【Arduino框架入门指南】嵌入式DIY物联网开源项目复现——访客计数器(Visitors Counter)
文章目录
该开源项目能够实现房间内人数的监测,并将信息通过互联网传输到物联网平外Blynk上进行监控。
博主作为小白,选择了这个简易的开源项目,通过该项目可以学到以下几点:
- Arduino框架下对ESP32单片机的入门(控制引脚,基础函数的使用),顺手练习一下C语言代码。
- 立创EDA绘制简单的PCB板并手动焊接(只需要焊接排针,非常简单)。
开源网址:IoT Visitor Counter using ESP32 & Ultrasonic Sensor,具体的项目说明见原网址。
成品展示
1.硬件
2.应用场景测试
将一个超声探测器放在入口,另一个放在出口,出入走动测试,Blynk界面如下
能够实现房间内人数的监控,当拜访者进入和出去时,蜂鸣器发声,若房间内有人,Blynk模拟的白色LED灯就打开。
一、 Blynk服务器搭建和Blynk组件设置
1. Blynk服务器搭建
由于Blynk的官方服务器目前无法使用,这里推荐的方法是使用阿里云网站免费试用一个服务器(试用时间3个月),创建容器运行Blynk,搭建Blynk服务器具体方法见以下文章:
- 怎么在WIN10系统上搭建blynk服务器
- 如何搭建自己的Blynk云服务器
2.Blynk组件设置
这里建议跟着原文章进行设置:IoT Visitor Counter using ESP32 & Ultrasonic Sensor。
简单来说就是硬件的信号传递给Blynk的控件的虚拟引脚,并能图形化展示。
二、ESP32程序
#include <Arduino.h>
#include <WiFiClient.h>
#define BLYNK_TEMPLATE_ID "**********"
#define BLYNK_TEMPLATE_NAME "***********"
#define BLYNK_AUTH_TOKEN "********************" //我使用的是VSCode的platformIO插件开发Arduino,使用下一行库函数时要求提前定义好上方三个字符串,这三行代码可以先随便写,以避免库函数编译出错,之后重新定义了auth[]字符串。
#include <BlynkSimpleEsp32.h>
#include <Adafruit_GFX.h>
#include <U8g2lib.h>
#include <Wire.h>
// wifi信息
char ssid[] = "*********"; //wifi name
char pass[] = "*********"; //wifi password
// 密钥信息
char auth[] = "*************************"; // the token of your project on Blynk
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define Disntance_Detect 40 //uint:cm
#define PIN_OLED_SDA 21
#define PIN_OLED_SCL 22
#define PIN_TRIG1 18
#define PIN_ECHO1 5
#define PIN_TRIG2 25
#define PIN_ECHO2 26
#define PIN_BUZZER 19
// 超声波传感器类声明
class UltrasonicSensor
{
public:
UltrasonicSensor(int tPin, int ePin); // 构造函数声明
float readDistance(); // 成员函数声明
private:
int trigPin;
int echoPin;
};
// 创建对象
U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0,255,PIN_OLED_SCL,PIN_OLED_SDA);
// 创建两个超声波模块对象
UltrasonicSensor sensor1(PIN_TRIG1, PIN_ECHO1);
UltrasonicSensor sensor2(PIN_TRIG2, PIN_ECHO2);
// blynk控制虚拟led对象
WidgetLED light(V0);
float distance_in;
float distance_out;
int count_in;
int count_out;
int count_now;
bool flag=false;
void setup()
{
Serial.begin(115200);
pinMode(PIN_BUZZER,OUTPUT);
digitalWrite(PIN_BUZZER,HIGH);
// Attempt to connect to Wi-Fi
WiFi.begin(ssid, pass);
Serial.print("Connecting to ");
Serial.print(ssid);
// wifi连接情况调试代码
int attempts = 0;
while (WiFi.status() != WL_CONNECTED && attempts < 50)
{
delay(500);
Serial.print(".");
attempts++;
}
if (WiFi.status() == WL_CONNECTED)
{
Serial.println("Connected to Wi-Fi");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
}
else
{
Serial.println("Failed to connect to Wi-Fi");
}
// 准备连接服务器
Serial.println("prepare to begin...");
Blynk.begin(auth,ssid,pass,"***********",****); //第四个参数为服务器地址,第五个参数为端口号
Serial.println("Blynk.begin down");
Serial.println("Visitor Counter Demo");
// 初始化屏幕
if (!u8g2.begin())
{
Serial.println("Failed to initialize OLED");
while (1); // 停止程序,直到解决问题
}
else
Serial.println("Successed to initialize OLED");
u8g2.enableUTF8Print();
u8g2.setFont(u8g2_font_wqy12_t_chinese1); // 设置字体
u8g2.clearBuffer(); // 清空缓冲区
u8g2.sendBuffer(); // 更新显示
}
void loop()
{
Blynk.run();
distance_in = sensor1.readDistance();
distance_out = sensor2.readDistance();
if (distance_in<=Disntance_Detect)
{
count_in +=1;
flag = true;
}
if (distance_out<=Disntance_Detect)
{
count_out +=1;
flag = true;
}
count_now = count_in - count_out;
if(count_now<=0)
{
light.off();
u8g2.clearBuffer();
u8g2.setCursor(32,16);
u8g2.print("No Visitors");
u8g2.setCursor(32,32);
u8g2.print("Light Off");
u8g2.sendBuffer();
flag = false;
count_now=0;
}
else if(flag==true)
{
light.on();
u8g2.clearBuffer();
u8g2.setCursor(0,16);
u8g2.print("Visitors Number:"); // 打印 UTF-8 字符
u8g2.setCursor(96,16);
u8g2.print(count_now);
u8g2.setCursor(0,32);
u8g2.print("IN:"); // 打印进入次数
u8g2.setCursor(16,32);
u8g2.print(count_in);
u8g2.setCursor(64,32);
u8g2.print("OUT:"); // 打印出去次数
u8g2.setCursor(96,32);
u8g2.print(count_out);
u8g2.sendBuffer();
digitalWrite(PIN_BUZZER,HIGH); //蜂鸣器响200ms
delay(200);
digitalWrite(PIN_BUZZER,LOW);
flag = false;
}
Blynk.virtualWrite(V1,count_in);
Blynk.virtualWrite(V2,count_out);
Blynk.virtualWrite(V3,count_now);
delay(500); //加上蜂鸣器延迟时间,500ms检测一次
}
// 超声构造函数初始化
UltrasonicSensor::UltrasonicSensor(int tPin, int ePin)
{
trigPin = tPin;
echoPin = ePin;
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
float UltrasonicSensor::readDistance()
{
float distance = -1;
// 发送脉冲
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// 计算距离
long duration = pulseIn(echoPin, HIGH);
distance = duration / 58.0; // 将持续时间转换为厘米
return distance;
}
区别:
- 跟原作者不同的是,我练习了一下C语言中类的使用,自己定义了超声探测函数。
- 因为最初使用的是无缘蜂鸣器另外定义了flag,确保没有检测到进出时不会包含delay()函数。
三、PCB绘制
PCB我推荐和我一样的新手使用立创EDA,不仅操作简单而且还可以免费打板。
1.原理图
这个原理图就很简单了,主要内容就是引脚的连接。
2.PCD布线
这里我使用立创EDA的自动布线,推荐新手掌握了PCB设计的基础操作,理解了封装、走线、焊盘、阻焊、丝印、过孔、设计规则、电源线布线注意事项、差分信号布线特点之类的重要概念后再使用该功能,PCB布线如下:
四、可改进的地方
- 如果人保持站在 Unltasonic 传感器前,计数器会不断增加:我只是使用 Delay() 函数来缓解这个问题。
- 每个系统无法区分访客的行进方向:对于只有一扇门(入口和出口)的房间,可以使用两个传感器的顺序来区分方向。
作者:咸蛋烧茄子