Benewake(北醒) 单点TF系列雷达基于Arduino UNO实现行人进出统计的例程

在这里插入图片描述

一、 人流身高测量仪说明

本方案为利用北醒公司产品单点系列产品、Arduino-UNO板以及0.91寸OLED结合开发出的小设备。
功能:统计单道人行的进出量

二、 试验设备及接线

2.1 实验设备

  • Benewake TF系列产品
    TFmini-s
    Arduino-UNO板
    在这里插入图片描述
    关于Arduino的详细介绍和学习请参考以下两个网站:

中文社区:http://www.arduino.cn/
英文官网:https://www.arduino.cc/

  • 0.91寸OLED液晶屏
    在这里插入图片描述
    规格:0.91寸OLED屏,128*32点阵,IIC控制接口,兼容3.3-5V

2.2 接线

在这里插入图片描述
TFmini Plus产品线序定义为:红色+5V,黑色GND,绿色TX,白色RX;TFmini-Plus供电电压为5V,所以直接连接Arduino板的5V和GND即可,其他雷达请查阅产品规格书,确保供电正常;
0.91寸OLED屏连接5V和GND供电,接口接SCL和SDA

三、 进出统计原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 雷达倾斜安装,雷达启动后,设置安装高度、身高限度、下限值。
  • 当人进入探测区域时,数据会出现突破身高限定
  • 当人从里面走出外面时,身高会一直上升,人从外面走进里面时,身高会一直下降。
  • x初值为“0”,身高上升一次“x+1”,身高下降一次“x-1”
  • 当人走出探测区域时,若x大于0,则判断“出”,若x小于0,则判断“进”,x重新置零

四、 程序编写

该例程需要添加OLED的库
共三个库文件

Adafruit_BusIO-1.5.0
Adafruit_GFX_Library-1.10.1
Adafruit_SSD1306-2.4.0
下载链接:
链接: https://pan.baidu.com/s/1i3e8hXs5SxJC6YFNhlHlQg
提取码: 53cp

源代码
程序文件


```c
/**************************************************************************
  This is an application of the inbound and outbound traffic statistics

  Use the Benewake TF series Lidars
  TFluna/TFmini-S/TFmini-Plus/TF02-pro

  Author:benewake_zoran
  Date:2020-11-04

  Release version:First version

  This procedure is for reference and study only
 **************************************************************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define NUMFLAKES     10 // Number of snowflakes in the animation example

#define LOGO_HEIGHT   16
#define LOGO_WIDTH    16

unsigned int Lasthigh = 0; //Last Heigh Value
unsigned int HumanHigh;     //Heigh Value
int x = 0;

unsigned int in = 0;
unsigned int out = 0;

unsigned int distance = 0;
unsigned int strength = 0;
boolean receiveComplete = false;

/*--  宽度x高度=128x32  --*/
static const unsigned char PROGMEM benewake_logo_bmp[] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x61, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x61, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x61, 0x83, 0x87, 0xE0, 0x70, 0xC2, 0x03, 0x1E, 0x0C, 0x20, 0xE0,
  0x00, 0x00, 0x0C, 0x00, 0x20, 0x63, 0x8F, 0xE7, 0xF1, 0xFC, 0xC3, 0x03, 0xBF, 0xEC, 0x73, 0xF8,
  0x00, 0x00, 0x0C, 0x00, 0x60, 0x7F, 0x9F, 0xF7, 0xFB, 0xFE, 0xE3, 0x83, 0x7F, 0xEC, 0xF7, 0xFC,
  0x00, 0x00, 0x0E, 0x00, 0xC0, 0x7F, 0x9C, 0x7F, 0x3B, 0x8F, 0xE3, 0x87, 0xF1, 0xED, 0xEF, 0x1C,
  0x0C, 0x00, 0x1E, 0x01, 0x80, 0x63, 0xF9, 0xFE, 0x1F, 0x3F, 0x71, 0xCE, 0xE0, 0xEF, 0xCE, 0x7C,
  0x06, 0x00, 0x1E, 0x01, 0x80, 0x61, 0xFB, 0xE6, 0x1F, 0x7C, 0x73, 0xCE, 0xC0, 0xEF, 0x0D, 0xF0,
  0x03, 0x00, 0x1E, 0x03, 0x00, 0x60, 0xFF, 0x86, 0x1F, 0xF0, 0x3B, 0xFC, 0xC0, 0xEF, 0x8F, 0xE0,
  0x03, 0x00, 0x1E, 0x03, 0x00, 0x60, 0xFF, 0x86, 0x1F, 0xF0, 0x3B, 0xFC, 0xC0, 0xEF, 0x8F, 0xE0,
  0x01, 0x80, 0x1F, 0x07, 0x00, 0x61, 0xFE, 0x3E, 0x1F, 0xC7, 0x1F, 0xFC, 0xE1, 0xEF, 0xCF, 0x8C,
  0x00, 0xE0, 0x1F, 0x0E, 0x00, 0x61, 0xDE, 0x7E, 0x1B, 0xCF, 0x1E, 0x78, 0xF1, 0xED, 0xEF, 0x1C,
  0x00, 0x70, 0x1F, 0x9E, 0x00, 0x7F, 0x9F, 0xF6, 0x19, 0xFE, 0x0E, 0x78, 0x7F, 0xEC, 0xF7, 0xFC,
  0x00, 0x30, 0x1F, 0xFC, 0x00, 0x7F, 0x07, 0xE6, 0x18, 0xFC, 0x0C, 0x30, 0x3F, 0x6C, 0x73, 0xF0,
  0x00, 0x00, 0x1F, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x3F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xF7, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xF7, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x73, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

void getTFLidarData(unsigned int* distance, unsigned int* strength, boolean* complete) {
  static char i = 0;
  char j = 0;
  int checksum = 0;
  static int rx[9];
  if (Serial.available()) {
    rx[i] = Serial.read();
    if (rx[0] != 0x59) {
      i = 0;
    } else if (i == 1 && rx[1] != 0x59) {
      i = 0;
    } else if (i == 8) {
      for (j = 0; j < 8; j++) {
        checksum += rx[j];
      }
      if (rx[8] == (checksum % 256)) {
        *distance = rx[2] + rx[3] * 256;
        *strength = rx[4] + rx[5] * 256;
        *complete = true;
      }
      i = 0;
    } else {
      i++;
    }
  }
}

void Display(void) {
  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0, 0);

  display.setCursor(0, 0);
  display.println(F("IN :"));

  display.setCursor(0, 16);
  display.println(F("OUT:"));

  display.setCursor(48, 0);
  display.println(in);

  display.setCursor(48, 16);
  display.println(out);

  display.display();
}

void StatInfo(unsigned int LidarInstallHigh, unsigned int DistHighLimit, unsigned int DistLowLimit) {
  HumanHigh = LidarInstallHigh - distance; //calculate height value
  /*People statistics*/
  if (HumanHigh >= DistHighLimit & Lasthigh < DistLowLimit)
  {
    Lasthigh = HumanHigh;
  }
  if (HumanHigh >= DistHighLimit & Lasthigh >= DistLowLimit)
  {
    if (HumanHigh > Lasthigh) //Height rise,x+1
    {
      x = x + 1;
    }
    if (HumanHigh < Lasthigh) //Height decrease,x-1
    {
      x = x - 1;
    }
    Lasthigh = HumanHigh;
  }
  if (HumanHigh < DistLowLimit & Lasthigh >= DistHighLimit) //When the person is leaving the measurement area
  {
    if (x > 0) // Status:Out
    {
      out = out + 1;
    }
    if (x < 0) //Status:In
    {
      in = in + 1;
    }
    x = 0;
    Lasthigh = HumanHigh;
  }
}

void setup() {
  Serial.begin(115200);
  delay(500);
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x32
    Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  //remove initial display buffer and display benewake_logo
  display.clearDisplay();
  display.drawBitmap(0, 0,  benewake_logo_bmp, 128, 32, 1);
  display.display();
  delay(2000);
}

void loop() {
  if (receiveComplete) {
    receiveComplete = false;
    StatInfo(240, 50, 40);
    Display();
  }
}

//Use interrupts to read Lidar data
void serialEvent() {
  getTFLidarData(&distance, &strength, &receiveComplete);
}

五. 注意事项

  • 雷达是倾斜安装,安装高度的设置需要偏大,要求精度不高。
  • 此方案只适用单行道出入统计,两个人挨着走会出现误差,实现多人可以增加雷达数量。
  • 缓冲区域为“身高限定-下限值”,避免探测高度恰好在“身高限定”的物体时,数据波动导致统计人数重复增加的情况。
  • 如果光斑未完全打到身体,人数统计会出现误差。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值