当前位置: 首页 > news >正文

【毕业设计】基于单片机的手势检测识别系统 - arduino 物联网嵌入式

文章目录

  • 0 前言
  • 1 简介
  • 2 主要器件
  • 3 实现效果
  • 4 设计原理
  • 5 部分核心代码
  • 5 最后


0 前言

🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。

为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是

🚩 基于单片机的手势检测识别系统

🥇学长这里给一个题目综合评分(每项满分5分)

  • 难度系数:4分
  • 工作量:4分
  • 创新点:3分

🧿 选题指导, 项目分享:

https://gitee.com/dancheng-senior/project-sharing-1/blob/master/%E6%AF%95%E8%AE%BE%E6%8C%87%E5%AF%BC/README.md


1 简介

2 主要器件

  • Arduino Nano R3
  • PIR传感器
  • OLED显示模块(128X64)
  • 热阵列传感器

3 实现效果

成品展示
在这里插入图片描述

在这里插入图片描述

4 设计原理

PIR传感器:

PIR传感器:一种电子传感器,测量从其视野内的物体辐射的红外(IR)光。最常用于基于PIR的运动检测器。所有温度高于绝对零度的物体都会以辐射的形式放出热能,通常这种辐射对人眼来说是不可见的,因为它是以红外波长辐射,但它可以被为此目的设计的电子设备检测到。

在这种情况下,术语“无源”指的是这样一个事实,即PIR设备不产生或辐射用于检测目的的能量。它们完全通过探测物体发射或反射的红外辐射来工作,它们不能探测或测量热量。
在这里插入图片描述
TPA81:

热电堆阵列,检测2微米~22微米内的红外线(辐射热的波长)
同时测量8个相邻点的温度
控制伺服系统来平移模块并建立热成像
检测2米(6英尺)范围内的蜡烛火焰,不受环境光影响
Arduino IDE

在这里插入图片描述
电路图:
在这里插入图片描述
如果想使用8个PIR传感器,应将8个单个PIR传感器连接到Arduino板上,并逐个读取它们
在这里插入图片描述
软件部分

运行Arduino板步骤:

  • 在www.arduino.cc/en/Main/Software下载操作系统软件,并按照说明安装集成开发环境软件
  • 运行Arduino IDE,清除文本编辑器,在文本编辑器中复制下面的代码
  • 导航至草图并包含库(从以下链接下载库),点击添加压缩库并添加库
  • 在工具和电路板中选择电路板,选择Arduino Nano
  • 将Arduino连接到电脑,并在工具和端口中设置通讯端口
  • 按上传(箭头符号)按钮

在这里插入图片描述
在这里插入图片描述
运行此代码后,在 Arduino IDE 中打开串行终端并查看 TPA81 感应到的 8 阵列温度。每行的第一个数字属于总温度。

要手动定义手势,需知道手部温度,并将其设置为偏移量。

将偏移量设置为 29 度,上传以下一代码查看在 TPA81 前的手部动作。
在这里插入图片描述

5 部分核心代码

#include <Wire.h>
#include <TPA81.h>

// Create new TPA81 instance
TPA81 tpa;

void setup() {
  Serial.begin(9600);

  // You need to begin the Wire library to use TPA81 library
  Wire.begin();
}

void loop() {
  // Print temperature light
  Serial.print(tpa.getAmbient());
  Serial.print(" ");

  // Print all temperature point
  for (int i = 1; i <= 8; i++)
  {
    Serial.print(tpa.getPoint(i));
    Serial.print(" ");
  }
  Serial.println("\n");
  
  delay(500);
}

const uint8_t Signal816[16] PROGMEM = //mobie signal
{
    0xFE,0x02,0x92,0x0A,0x54,0x2A,0x38,0xAA,0x12,0xAA,0x12,0xAA,0x12,0xAA,0x12,0xAA
};

const uint8_t Msg816[16] PROGMEM =  //message
{
    0x1F,0xF8,0x10,0x08,0x18,0x18,0x14,0x28,0x13,0xC8,0x10,0x08,0x10,0x08,0x1F,0xF8
};

const uint8_t Bat816[16] PROGMEM = //batery
{
    0x0F,0xFE,0x30,0x02,0x26,0xDA,0x26,0xDA,0x26,0xDA,0x26,0xDA,0x30,0x02,0x0F,0xFE
};

const uint8_t Bluetooth88[8] PROGMEM = // bluetooth
{
    0x18,0x54,0x32,0x1C,0x1C,0x32,0x54,0x18
};

const uint8_t GPRS88[8] PROGMEM = //GPRS
{
    0xC3,0x99,0x24,0x20,0x2C,0x24,0x99,0xC3
};

const uint8_t Alarm88[8] PROGMEM = //alram
{
    0xC3,0xBD,0x42,0x52,0x4E,0x42,0x3C,0xC3
};

void command(uint8_t cmd){
    digitalWrite(OLED_DC, LOW);
    SPIWrite(&cmd, 1);
}

void SPIWrite(uint8_t *buffer, int bufferLength) {
    int i;
    for (i = 0; i < bufferLength; i++) {
        SPI.transfer(buffer[i]);
    }
}

void SSD1306_begin()
{

    pinMode(OLED_RST, OUTPUT);
    pinMode(OLED_DC, OUTPUT);
    pinMode(OLED_CS, OUTPUT);
    SPI.begin();
    
    SPI.setClockDivider(SPI_CLOCK_DIV128);
    
    digitalWrite(OLED_CS, LOW);
    digitalWrite(OLED_RST, HIGH);
    delay(10);
    digitalWrite(OLED_RST, LOW);
    delay(10);
    digitalWrite(OLED_RST, HIGH);
    
    command(SSD1306_DISPLAYOFF);
    command(SSD1306_SETDISPLAYCLOCKDIV);
    command(0x80);                              // the suggested ratio 0x80
    
    command(SSD1306_SETMULTIPLEX);
    command(0x3F);
    command(SSD1306_SETDISPLAYOFFSET);
    command(0x0);                               // no offset
    command(SSD1306_SETSTARTLINE | 0x0);        // line #0
    command(SSD1306_CHARGEPUMP);
    command((VCCSTATE == SSD1306_EXTERNALVCC) ? 0x10 : 0x14);
    
    command(SSD1306_MEMORYMODE);
    command(0x00);                              // 0x0 act like ks0108
    
    command(SSD1306_SEGREMAP | 0x1);
    command(SSD1306_COMSCANDEC);
    command(SSD1306_SETCOMPINS);
    command(0x12);           // TODO - calculate based on _rawHieght ?
    command(SSD1306_SETCONTRAST);
    command((VCCSTATE == SSD1306_EXTERNALVCC) ? 0x9F : 0xCF);
    command(SSD1306_SETPRECHARGE);
    command((VCCSTATE == SSD1306_EXTERNALVCC) ? 0x22 : 0xF1);
    command(SSD1306_SETVCOMDETECT);
    command(0x40);
    command(SSD1306_DISPLAYALLON_RESUME);
    command(SSD1306_NORMALDISPLAY);
    command(SSD1306_DISPLAYON);
}

void SSD1306_clear(uint8_t* buffer)
{
	int i;
	for(i = 0;i < WIDTH * HEIGHT / 8;i++)
	{
		buffer[i] = 0;
	}
}

void SSD1306_pixel(int x, int y, char color, uint8_t* buffer)
{
    if(x > WIDTH || y > HEIGHT)return ;
    if(color)
        buffer[x+(y/8)*WIDTH] |= 1<<(y%8);
    else
        buffer[x+(y/8)*WIDTH] &= ~(1<<(y%8));
}

void SSD1306_char1616(uint8_t x, uint8_t y, uint8_t chChar, uint8_t* buffer)
{
	uint8_t i, j;
	uint8_t chTemp = 0, y0 = y, chMode = 0;

	for (i = 0; i < 32; i++) {
		chTemp = pgm_read_byte(&Font1612[chChar - 0x30][i]);
		for (j = 0; j < 8; j++) {
			chMode = chTemp & 0x80? 1 : 0; 
			SSD1306_pixel(x, y, chMode, buffer);
			chTemp <<= 1;
			y++;
			if ((y - y0) == 16) {
				y = y0;
				x++;
				break;
			}
		}
	}
}

void SSD1306_char(unsigned char x, unsigned char y, char acsii, char size, char mode, uint8_t* buffer)
{
    unsigned char i, j, y0=y;
    char temp;
    unsigned char ch = acsii - ' ';
    for(i = 0;i<size;i++) {
        if(size == 12)
        {
            if(mode)temp = pgm_read_byte(&Font1206[ch][i]);
            else temp = ~pgm_read_byte(&Font1206[ch][i]);
        }
        else 
        {            
            if(mode)temp = pgm_read_byte(&Font1608[ch][i]);
            else temp = ~pgm_read_byte(&Font1608[ch][i]);
        }
        for(j =0;j<8;j++)
        {
            if(temp & 0x80) SSD1306_pixel(x, y, 1, buffer);
            else SSD1306_pixel(x, y, 0, buffer);
            temp <<= 1;
            y++;
            if((y-y0) == size)
            {
                y = y0;
                x++;
                break;
            }
        }
    }
}

void SSD1306_string(uint8_t x, uint8_t y, const char *pString, uint8_t Size, uint8_t Mode, uint8_t* buffer)
{
    while (*pString != '\0') {       
        if (x > (WIDTH - Size / 2)) {
            x = 0;
            y += Size;
            if (y > (HEIGHT - Size)) {
                y = x = 0;
            }
        }
        
        SSD1306_char(x, y, *pString, Size, Mode, buffer);
        x += Size / 2;
        pString++;
    }
}

void SSD1306_char3216(uint8_t x, uint8_t y, uint8_t chChar, uint8_t* buffer)
{
    uint8_t i, j;
    uint8_t chTemp = 0, y0 = y, chMode = 0;

    for (i = 0; i < 64; i++) {
        chTemp = pgm_read_byte(&Font3216[chChar - 0x30][i]);
        for (j = 0; j < 8; j++) {
            chMode = chTemp & 0x80? 1 : 0; 
            SSD1306_pixel(x, y, chMode, buffer);
            chTemp <<= 1;
            y++;
            if ((y - y0) == 32) {
                y = y0;
                x++;
                break;
            }
        }
    }
}

void SSD1306_bitmap(uint8_t x,uint8_t y,const uint8_t *pBmp, uint8_t chWidth, uint8_t chHeight, uint8_t* buffer)
{
	uint8_t i, j, byteWidth = (chWidth + 7)/8;
	for(j = 0;j < chHeight;j++){
		for(i = 0;i <chWidth;i++){
			if(pgm_read_byte(pBmp + j * byteWidth + i / 8) & (128 >> (i & 7))){
				SSD1306_pixel(x + i,y + j, 1, buffer);
			}
		}
	}		
}

void SSD1306_display(uint8_t* buffer)
{
	command(SSD1306_COLUMNADDR);
	command(0);         //cloumn start address
	command(WIDTH -1); //cloumn end address
	command(SSD1306_PAGEADDR);
	command(0);         //page atart address
	command(PAGES -1); //page end address
    digitalWrite(OLED_DC, HIGH);
    SPIWrite(buffer, WIDTH * HEIGHT / 8);
}


5 最后

相关文章:

  • 【Node.js】深度解析常用核心模块-path模块
  • C语言指针操作(六)*返回指针值的函数
  • 10. Vue 常用的修饰符的作用详解?
  • 第五篇 python 基本语法(一)
  • 猿创征文| JAVA Web的环境部署
  • Python基础(一) | Python的基本语法
  • 110道Java初级面试题及答案(最新Java初级面试题大汇总)
  • 简易版实现vue1.0
  • 6大面试技能树:JAVA基础+JVM+算法+数据库+计算机网络+操作系统,时刻为面试做准备!!
  • sobel算子边缘提取及程序优化(C语言)
  • python数据结构与算法
  • cookie,storage,sesstion区别
  • 学生家乡网页设计作品静态HTML网页—— HTML+CSS+JavaScript制作辽宁沈阳家乡主题网页源码(11页)
  • MKD调试下载的时候提示:Contents mismatch at: xxxxxxxxH (Flash=xxH Required=xxH)
  • 【Python基础入门技能树笔记】数据类型-基本数据类型
  • [case10]使用RSQL实现端到端的动态查询
  • [译] React v16.8: 含有Hooks的版本
  • 「面试题」如何实现一个圣杯布局?
  • 230. Kth Smallest Element in a BST
  • PHP的类修饰符与访问修饰符
  • Python 基础起步 (十) 什么叫函数?
  • Python爬虫--- 1.3 BS4库的解析器
  • rabbitmq延迟消息示例
  • SwizzleMethod 黑魔法
  • webpack项目中使用grunt监听文件变动自动打包编译
  • Yeoman_Bower_Grunt
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 使用Swoole加速Laravel(正式环境中)
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 小程序button引导用户授权
  • No resource identifier found for attribute,RxJava之zip操作符
  • Python 之网络式编程
  • 带你开发类似Pokemon Go的AR游戏
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • (20050108)又读《平凡的世界》
  • (6)设计一个TimeMap
  • (70min)字节暑假实习二面(已挂)
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (ZT)一个美国文科博士的YardLife
  • (二十三)Flask之高频面试点
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (转)Groupon前传:从10个月的失败作品修改,1个月找到成功
  • .net 4.0发布后不能正常显示图片问题
  • .NET BackgroundWorker
  • .NET C# 使用 SetWindowsHookEx 监听鼠标或键盘消息以及此方法的坑
  • .NET Core 成都线下面基会拉开序幕
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET Framework 的 bug?try-catch-when 中如果 when 语句抛出异常,程序将彻底崩溃
  • .NET MVC 验证码