找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 10624|回復(fù): 6
打印 上一主題 下一主題
收起左側(cè)

2018年TI杯電賽D題作品,FDC2214手勢(shì)識(shí)別源代碼分享

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:219605 發(fā)表于 2018-7-26 09:45 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
  此次電賽,指定TI的fdc2214芯片,前期申請(qǐng)階段也是一波三折,到后來拿到EVM板測(cè)試,也費(fèi)了一番周折。  個(gè)人認(rèn)為,這個(gè)題目還是很簡(jiǎn)單的,比的就是數(shù)據(jù)處理的思想,畢竟不需要?jiǎng)e的東西,只需要準(zhǔn)備一塊單片機(jī)開發(fā)板,一個(gè)fdc2214評(píng)估板,再加一塊履銅板,還就是一些按鍵之類的基本元器件了。
  先附上題目要求,具體題目內(nèi)容的話,大家去自己下載吧。
http://www.torrancerestoration.com/bbs/dpj-129251-1.html
  arduino開發(fā)系統(tǒng),一直以來都是簡(jiǎn)單,上手快的代名詞,的確,arduino用起來比stm32簡(jiǎn)單多了,沒有復(fù)雜的寄存器操作,非常適合新手做東西,也可以說是非常適合所有人用吧,工具嘛,肯定是越容易用越好,所以我這次選用arduino來做這個(gè)題。
  手勢(shì)識(shí)別,題目要求有訓(xùn)練模式和判決模式,有的同學(xué)想法過于高大上,以為訓(xùn)練模式要用到那種記憶的算法,然后越想越難,最后搞得結(jié)果不理想。我這邊認(rèn)真讀題過后,果斷確定了一套簡(jiǎn)單有效的方案。
  首先分析傳感器:fdc2214的arduino庫中的測(cè)試?yán)�,我們可以發(fā)現(xiàn)(當(dāng)然,數(shù)據(jù)手冊(cè)里更加詳細(xì)),fdc2214傳感器的返回值是8位十進(jìn)制數(shù)(其實(shí)讀取的是28位二進(jìn)制數(shù),不過是arduino的串口打印出來默認(rèn)轉(zhuǎn)換成十進(jìn)制了,反正靈敏度還是不得不佩服),我們就以這8位的十進(jìn)制數(shù)來進(jìn)行分析處理。
  如何理解訓(xùn)練模式?我是這樣想的,訓(xùn)練模式,我可以理解成是系統(tǒng)在開始就錄入你的手勢(shì)數(shù)據(jù)(不同的手勢(shì)的返回值不同),由此可以區(qū)別不同的手勢(shì)。但是錄入這塊,很多人就有了疑問,寄存器?數(shù)組?這些我都想過,最后都沒用,我寫了一套更加簡(jiǎn)單的“錄入”程序。就是定義全局變量,然后賦值再去調(diào)用就可以了。
  如何理解判決模式?我這樣想,判決,就是一個(gè)比較,兩個(gè)值之間的比較,所以當(dāng)a=b(臨時(shí)假設(shè))時(shí),就得出結(jié)論:這個(gè)手勢(shì)就是錄入時(shí)候的手勢(shì)。但是這下就出了一點(diǎn)問題。
  問題一:如何確保判決模式時(shí)你的手勢(shì)值完全等于你當(dāng)時(shí)錄入的值?
  要完全等于,這個(gè)操作難度過大了,也不容易判決,所以這里我用了一種用范圍來確定的思想。就是錄入手勢(shì)值,給這個(gè)手勢(shì)值加減一個(gè)相同的值,就可以得出一個(gè)范圍,我們將用這個(gè)范圍去進(jìn)行判決,如果判決模式下采集到的值屬于這個(gè)范圍,那么就顯示判決結(jié)果。
  問題二:如何確保錄入手勢(shì)時(shí)沒有誤差?
  當(dāng)然,沒有誤差的系統(tǒng)是不存在的,穩(wěn)態(tài)也有穩(wěn)態(tài)誤差,所以,我們是要盡量的避免誤差,使誤差最小化,近似消滅誤差。這里,在我錄入手勢(shì)值的時(shí)候,采用了一種簡(jiǎn)單的濾波————算術(shù)平均濾波法。簡(jiǎn)單說就是取平均值,取采樣多少次的一個(gè)平均值作為錄入值,再給其加減一設(shè)定值,得到一個(gè)范圍,就是我的判定范圍了。
整個(gè)程序的思想就是這樣,具體的話,我貼上程序吧。

// ARDUINO <--> FDC
// A4 <-------> SDA
// A5 <-------> SCL

#include <Wire.h>
#include "FDC2214.h"
int Filter_Value;
#define FILTER_N 30
unsigned long mean,Min,Max,fw=8,X,Min1,Max1,Min2,Max2,Min3,Max3,Min4,Max4,Min5,Max5,Min6,Max6;
int XL = 5;
int CQ = 6;
int HQ = 7;
FDC2214 capsense(FDC2214_I2C_ADDR_0);
void setup() {
  pinMode(XL, INPUT_PULLUP);
  pinMode(CQ, INPUT_PULLUP);
  pinMode(HQ, INPUT_PULLUP);
  digitalWrite(XL, HIGH);
  digitalWrite(CQ, HIGH);
  digitalWrite(HQ, HIGH);
  Wire.begin();
  Serial.begin(115200);
  Serial.println("\nFDC2x1x test");
  bool capOk = capsense.begin(0x3, 0x4, 0x5);
  if (capOk) Serial.println("Sensor OK");  
  else Serial.println("Sensor Fail");   
}
void loop()
{  
  X=capsense.getReading28(0)/1000;
  if(digitalRead(XL) == LOW)//開啟訓(xùn)練模式
  {   
     train();   
   if(digitalRead(CQ) == LOW)//開啟猜拳模式
  {
   decide1();
   }
  if(digitalRead(HQ) == LOW)//開啟劃拳模式
  {
    decide2();
   }
  }
}
/****訓(xùn)練模式*****/

void train()
{   
  if(Serial.available()>0)
  {      
  // a = Serial.parseInt();
    switch(Serial.parseInt())
     {         
  case 1:deal();Min1=Min;Max1=Max;Serial.print("   ");Serial.print(Min1);Serial.print("   ");Serial.print(Max1);Serial.print("   ");Serial.println("1 FINISH");break;
  case 2:deal();Min2=Min;Max2=Max;Serial.print("   ");Serial.print(Min2);Serial.print("   ");Serial.print(Max2);Serial.print("   ");Serial.println("2 FINISH");break;
  case 3:deal();Min3=Min;Max3=Max;Serial.print("   ");Serial.print(Min3);Serial.print("   ");Serial.print(Max3);Serial.print("   ");Serial.println("3 FINISH");break;
  case 4:deal();Min4=Min;Max4=Max;Serial.print("   ");Serial.print(Min4);Serial.print("   ");Serial.print(Max4);Serial.print("   ");Serial.println("4 FINISH");break;
  case 5:deal();Min5=Min;Max5=Max;Serial.print("   ");Serial.print(Min5);Serial.print("   ");Serial.print(Max5);Serial.print("   ");Serial.println("5 FINISH");break;
  case 6:deal();Min6=Min;Max6=Max;Serial.print("   ");Serial.print(Min6);Serial.print("   ");Serial.print(Max6);Serial.print("   ");Serial.println("6 FINISH");break;
  case 7:Serial.print("   ");Serial.println("ALL FINISH");break;
      }
  }
}
/**判斷***猜拳模式******/

void decide1()
{
    //oled(顯示猜拳模式)
    //oled(顯示按鍵進(jìn)入猜拳模式)
   Serial.print(Min2);
   Serial.print(Max2);
   Serial.println(mean);
     if(Min2<X&&X<Max2)
    {
      Serial.println("jiandao");
     }
     if(Min5<X&&X<Max5)
    {
      Serial.println("baofu");
     }
     if(Min6<X&&X<Max6)
    {
      Serial.println("chuizi");
     }     
}
/***判斷**劃拳模式******/

void decide2()
{
    //oled(顯示猜拳模式)
    //oled(顯示按鍵進(jìn)入猜拳模式)
   if(Min1<X&&X<Max1)
   {
     Serial.println("1");
    }
    if(Min2<X&&X<Max2)
   {
     Serial.println("2");
    }
    if(Min3<X&&X<Max3)
   {
     Serial.println("3");
    }
    if(Min4<X&&X<Max4)
   {
     Serial.println("4");
    }
    if(Min5<X&&X<Max5)
   {
     Serial.println("5");
    }
}


/*****錄入手勢(shì)范圍約束,返回******/
unsigned long deal()
{
  Filter();
  Min=mean-fw;
  Max=mean+fw;
  return (Min&&Max);
}

/***********求平均值返回mean********/
unsigned long Filter() //測(cè) 次的平均值
{
  int i;
unsigned long filter_sum = 0;
  for(i = 0; i < FILTER_N; i++)
  {
    filter_sum +=capsense.getReading28(0)/1000;
    delay(1);
  }
  mean=filter_sum / FILTER_N;
return (unsigned long)(mean);

}

4060D,我的作品編號(hào),作品使用的按鍵控制,用六個(gè)按鍵來分別錄入1,2(剪刀)3,4,5(布)和6(石頭)。這樣連線多的話會(huì)出現(xiàn)干擾的情況,可以構(gòu)建一個(gè)通信,讓藍(lán)牙給arduino發(fā)數(shù)據(jù)來實(shí)現(xiàn)手勢(shì)采集,從而替代按鍵,以達(dá)到消除電磁干擾的目的。



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏4 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:399007 發(fā)表于 2019-8-7 18:41 | 只看該作者
請(qǐng)問您用的是什么極板
回復(fù)

使用道具 舉報(bào)

板凳
ID:511461 發(fā)表于 2019-10-12 19:08 | 只看該作者
有沒有原理圖
回復(fù)

使用道具 舉報(bào)

地板
ID:219605 發(fā)表于 2019-11-1 18:36 | 只看該作者
shaoduidui 發(fā)表于 2019-8-7 18:41
請(qǐng)問您用的是什么極板

是mega2560
回復(fù)

使用道具 舉報(bào)

5#
ID:219605 發(fā)表于 2019-11-1 18:38 | 只看該作者

您是指mega2560的原理圖還是整個(gè)系統(tǒng)的接線圖?
回復(fù)

使用道具 舉報(bào)

6#
ID:513617 發(fā)表于 2020-2-16 12:12 | 只看該作者
xprice 發(fā)表于 2019-11-1 18:38
您是指mega2560的原理圖還是整個(gè)系統(tǒng)的接線圖?

整個(gè)系統(tǒng)的連接圖有嗎
回復(fù)

使用道具 舉報(bào)

7#
ID:733810 發(fā)表于 2020-4-20 18:55 | 只看該作者
請(qǐng)問下 bool capOk = capsense.begin(0x3, 0x4, 0x5);報(bào)錯(cuò)說沒有這個(gè)功能該怎么辦
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表