【Arduino框架入门指南】嵌入式DIY物联网开源项目复现——访客计数器(Visitors Counter)

文章目录

  • 成品展示
  • 1.硬件
  • 2.应用场景测试
  • 一、 Blynk服务器搭建和Blynk组件设置
  • 1. Blynk服务器搭建
  • 2.Blynk组件设置
  • 二、ESP32程序
  • 三、PCB绘制
  • 1.原理图
  • 2.PCD布线
  • 四、可改进的地方

  • 该开源项目能够实现房间内人数的监测,并将信息通过互联网传输到物联网平外Blynk上进行监控。

    博主作为小白,选择了这个简易的开源项目,通过该项目可以学到以下几点:

    1. Arduino框架下对ESP32单片机的入门(控制引脚,基础函数的使用),顺手练习一下C语言代码。
    2. 立创EDA绘制简单的PCB板并手动焊接(只需要焊接排针,非常简单)。
      开源网址:IoT Visitor Counter using ESP32 & Ultrasonic Sensor,具体的项目说明见原网址。

    成品展示

    1.硬件

    请添加图片描述

    2.应用场景测试

    将一个超声探测器放在入口,另一个放在出口,出入走动测试,Blynk界面如下
    请添加图片描述
    能够实现房间内人数的监控,当拜访者进入和出去时,蜂鸣器发声,若房间内有人,Blynk模拟的白色LED灯就打开。

    一、 Blynk服务器搭建和Blynk组件设置

    1. Blynk服务器搭建

    由于Blynk的官方服务器目前无法使用,这里推荐的方法是使用阿里云网站免费试用一个服务器(试用时间3个月),创建容器运行Blynk,搭建Blynk服务器具体方法见以下文章:

    1. 怎么在WIN10系统上搭建blynk服务器
    2. 如何搭建自己的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;
    }
    

    区别:

    1. 跟原作者不同的是,我练习了一下C语言中类的使用,自己定义了超声探测函数。
    2. 因为最初使用的是无缘蜂鸣器另外定义了flag,确保没有检测到进出时不会包含delay()函数。

    三、PCB绘制

    PCB我推荐和我一样的新手使用立创EDA,不仅操作简单而且还可以免费打板。

    1.原理图

    这个原理图就很简单了,主要内容就是引脚的连接。

    2.PCD布线

    这里我使用立创EDA的自动布线,推荐新手掌握了PCB设计的基础操作,理解了封装、走线、焊盘、阻焊、丝印、过孔、设计规则、电源线布线注意事项、差分信号布线特点之类的重要概念后再使用该功能,PCB布线如下:
    请添加图片描述

    四、可改进的地方

    1. 如果人保持站在 Unltasonic 传感器前,计数器会不断增加:我只是使用 Delay() 函数来缓解这个问题。
    2. 每个系统无法区分访客的行进方向:对于只有一扇门(入口和出口)的房间,可以使用两个传感器的顺序来区分方向。

    作者:咸蛋烧茄子

    物联沃分享整理
    物联沃-IOTWORD物联网 » 【Arduino框架入门指南】嵌入式DIY物联网开源项目复现——访客计数器(Visitors Counter)

    发表回复