繼前一篇使用 xantorohara.github.io 產生方向箭頭的 8x8 LED 矩陣程式碼後,接著繼續使用 APS9960 手勢感測器來當作方向控制,當往左方揮手時,方向燈箭頭往左移動;當手勢往右揮時,箭頭方向往右移動。
一開始撰寫程式,就因為讀取手勢值 readGesture()這個指令,它會讓程式停在這裡等候新的手勢變化,無法讓迴圈內的 LED燈產生動畫的效果。想改用硬體插斷的方式,結果不行。後來找了 Arduino_APDS9960 的函式庫,是否能偵測手勢的讀取,結果找到一個判斷是否有讀取值的函式 gestureAvailable(),才順利完成程式。以下就來看看如何完成手勢控制方向燈實作。
APDS-9960是一個極小的感測器,內置紫外線和紅外線阻隔濾鏡,四個單獨的二極體不同方向的敏感,以及一個I2C相容介面。其他規格如下:
一開始撰寫程式,就因為讀取手勢值 readGesture()這個指令,它會讓程式停在這裡等候新的手勢變化,無法讓迴圈內的 LED燈產生動畫的效果。想改用硬體插斷的方式,結果不行。後來找了 Arduino_APDS9960 的函式庫,是否能偵測手勢的讀取,結果找到一個判斷是否有讀取值的函式 gestureAvailable(),才順利完成程式。以下就來看看如何完成手勢控制方向燈實作。
APDS-9960是一個極小的感測器,內置紫外線和紅外線阻隔濾鏡,四個單獨的二極體不同方向的敏感,以及一個I2C相容介面。其他規格如下:
- 工作電壓:3.3V
- 環境光及RGB色彩感應
- 接近檢測
- 手勢檢測
- 測量範圍:4-8in (10-20CM)
- I2C介面 (I2C位址:0x39)
[安裝APDS9960 Library]
Arduino_APDS9960 函式庫提供用於從 APDS-9960 手勢感測器,可以偵測環境光線讀取數據。本實作需要安裝以下程式庫: 您可以在 Arduino IDE的介面上的「管理程式庫」找到這個程式庫。有關程式庫(Library)安裝方法請參考另一篇文章: Arduino筆記:安裝 Arduino IDE 程式庫(Library)。[材料]
- Arduino Uno
- APDS-9960 顏色、非接觸手勢檢測傳感器模組 x1
- MAX7219 8x8 LED矩陣模組 x1
- 連接線 x n
[接線圖]
Arduino Uno | APDS-9960 | 8x8 LED Matrix 模組 |
---|---|---|
3.3V | VCC | - |
GND | GND | GND |
A5 | SCL | - |
A4 | SDA | - |
D2 | INT | - |
+5V | - | VCC |
D10 | - | CS |
D11 | - | CLK |
D12 | - | Data In(DIN) |
[程式]
#include <Arduino_APDS9960.h> #include <LedControl.h> // Pin 12:Data in, Pin 11: Clock, Pin 10: CS(Load) LedControl display = LedControl(12,11,10,1); const uint64_t R_IMAGES[] = { //往右箭頭 0x0000000100000000, 0x0000010301000000, 0x0001030703010000, 0x0103070f07030100, 0x02060f1f0f060200, 0x040c1f3f1f0c0400, 0x08183f7f3f180800, 0x08183f7f3f180800, 0x10307fff7f301000, 0x2060fefefe602000, 0x40c0fcfcfcc04000, 0x8080f8f8f8808000, 0x0000f0f0f0000000, 0x0000e0e0e0000000, 0x0000c0c0c0000000, 0x0000808080000000, 0x0000000000000000 }; const int R_IMAGES_LEN = sizeof(R_IMAGES)/8; const uint64_t L_IMAGES[] = { //往左箭頭 0x0000008000000000, 0x000080c080000000, 0x0080c0e0c0800000, 0x80c0e0f0e0c08000, 0x4060f0f8f0604000, 0x2030f8fcf8302000, 0x1018fcfefc181000, 0x080cfefffe0c0800, 0x04067f7f7f060400, 0x02033f3f3f030200, 0x01011f1f1f010100, 0x00000f0f0f000000, 0x0000070707000000, 0x0000030303000000, 0x0000010101000000, 0x0000000000000000 }; const int L_IMAGES_LEN = sizeof(L_IMAGES)/8; int LastGesture = 0; //紀錄最後一次的手勢 int i = 0; void setup() { Serial.begin(115200); if(!APDS.begin()){ Serial.println("failed to initialize device! Please check your wiring."); } else Serial.println("Detecting gestures ..."); display.clearDisplay(0); // 清除螢幕 display.shutdown(0, false); // 關閉省電模式 display.setIntensity(0, 10); // 設定亮度為 8 (介於0~15之間) } void displayImage(uint64_t image) { for (int i = 0; i < 8; i++) { byte row = (image >> i * 8) & 0xFF; for (int j = 0; j < 8; j++) { display.setLed(0, i, j, bitRead(row, j)); } } } void loop() { if (APDS.gestureAvailable()) { //讀取 APDS9960 的值 uint8_t gesture = APDS.readGesture(); if(gesture == GESTURE_DOWN) Serial.println("DOWN"); if(gesture == GESTURE_UP) Serial.println("UP"); if(gesture == GESTURE_LEFT) { Serial.println("LEFT"); LastGesture = 1; } if(gesture == GESTURE_RIGHT) { Serial.println("RIGHT"); LastGesture = 2; } } if (LastGesture == 1) { displayImage(L_IMAGES[i]); if (++i >= L_IMAGES_LEN ) { i = 0; } delay(10); } if (LastGesture == 2) { displayImage(R_IMAGES[i]); if (++i >= R_IMAGES_LEN ) { i = 0; } delay(10); } }
張貼留言