標籤:

AP3216C 模塊

AP3216C 模塊的核心就是這個晶元本身。這顆晶元集成了光強感測器(ALS:AmbientLight Sensor),接近感測器(PS: Proximity Sensor),還有一個紅外LED(IR LED)。這個晶元設計的用途是給手機之類的使用,比如:返回當前環境光強以便調整屏幕亮度;用戶接聽電話時,將手機放置在耳邊後,自動關閉屏幕避免用戶誤觸碰。

可能是因為模塊接線非常簡單,我在網上找不到模塊的電路圖,只能用晶元的DataSheet對照進行查看。

從上到下分別是 :

VLED

IR LED的供電,IR LED 電流最高為 20ma。使用 3.3v給模塊和IR LED 同時供電時,在IR LED 上串聯了一個200歐姆的電阻,這樣保證電流不會超過20ma。

GND 地

VCC 模塊供電,特別注意:最高 3.6V,對於 Arduino 來說,只能選擇 3.3V供電輸出

SCL I2C 的 CLOCK,對應 A5

SDA I2C 的 DATA,對應 A4

INT 中斷輸出,可以通知 Arduino有數據。對於輪詢,無需使用。

參考【參考1】, 可以使用的代碼如下:

// Interfacing the AP3216 light / proximity sensor withArduino UNO

// By RoboRemo

// www.roboremo.com

// Big thanks to ICStation for providing the AP3216 sensor

//icstation.com/ap3216-am

// Command examples:

// "write 0x00 0x01
" - will write value 0x01 tothe register 0x00

// "read 0x0C
" - will read the value fromregister 0x0C

// "als start
" - will start streaming the valuefrom the ALS (ambient light sensor)

// "ps start
" - will start streaming the valuefrom the PS (proximity sensor)

// "stop
" - will stop streaming the ALS / PSdata.

// Commands can be sent using Serial Monitor / Terminal,

// Or using the RoboRemo app from Google Play.

// RoboRemo app can also display a nice plot of the ALS / PSdata,

// and also log to a file on the sdcard of the phone.

// Hardware wiring:

// Arduino AP3216

// VLED--,

// GND ------- GND |R| 240 Ohm

// 3.3V ------ VCC ---

// A5 -------- SCL

// A4 -------- SDA

long baud = 115200;

#include <Wire.h>

char cmd[100];

int cmdIndex;

bool als_on = false;

bool ps_on = false;

boolean cmdStartsWith(const char *st) { // checks if cmdstarts with st

for(int i=0; ; i++){

if(st==0)return true;

if(cmd==0)return false;

if(cmd!=st)return false;;

}

return false;

}

int hexCharToInt(char c) {

if(c>=a) return(c-a)+10;

if(c>=A) return(c-A)+10;

return c-0;

}

String hexByteToString(int val) {

char digits[] ={0, 1, 2, 3, 4, 5, 6, 7, 8,9, A, B, C, D, E,F};

char a =digits[(val/16) %16];

char b =digits[val%16];

return (String)"" + a + b;

}

void alsStart() {

AP3216_write(0x00,0x01);

als_on = true;

}

void alsPsStop() {

als_on = false;

ps_on = false;

AP3216_write(0x00,0x00);

}

void psStart() {

AP3216_write(0x00,0x02);

ps_on = true;

}

void AP3216_write(int regAddress, int value) {

Wire.beginTransmission(0x1E); // I2C Address of AP3216 sensor is 0x1E

Wire.write(regAddress);

Wire.write(value);

Wire.endTransmission();

}

int AP3216_read(int regAddress) {

Wire.beginTransmission(0x1E); // I2C Address of AP3216 sensor is 0x1E

Wire.write(regAddress);

Wire.endTransmission();

Wire.requestFrom(0x1E, 1, true);

return Wire.read()& 0xFF;

}

void exeCmd() {

if(cmdStartsWith("read 0x") ) { // example: read 0x1A

int a =hexCharToInt(cmd[7]); // 1 -> 1

int b =hexCharToInt(cmd[8]); // A -> 10

int regAddress =(a*16)+b; // 0x1A = 26

int regValue =AP3216_read(regAddress);

Serial.print((String)"reg_0x");

Serial.print(hexByteToString(regAddress) );

Serial.print(" = ");

Serial.print(hexByteToString(regValue) );

Serial.print("
");

}

if(cmdStartsWith("write 0x") ) { // example: write 0x1A 0x55

int a =hexCharToInt(cmd[8]); // 1 -> 1

int b =hexCharToInt(cmd[9]); // A -> 10

int regAddress =(a*16)+b; // 0x1A = 26

a =hexCharToInt(cmd[13]);

b =hexCharToInt(cmd[14]);

int regValue =(a*16)+b;

AP3216_write(regAddress, regValue);

Serial.print((String)"reg_0x");

Serial.print(hexByteToString(regAddress) );

Serial.print(" <- ");

Serial.print(hexByteToString(regValue) );

Serial.print("
");

}

if(cmdStartsWith("als start") ) {

alsStart();

}

if(cmdStartsWith("stop") ) {

alsPsStop();

}

if(cmdStartsWith("ps start") ) {

psStart();

}

}

void setup() {

Wire.begin();

Serial.begin(baud);

cmdIndex = 0;

}

void loop() {

while(Serial.available() ) {

char c =Serial.read();

if(c==
||c==
) {

cmd[cmdIndex] =0; // end cmd string with 0

exeCmd(); // execute the command

cmdIndex = 0; //reset the cmdIndex

} else {

cmd[cmdIndex] =c; // append c to the cmd string

if(cmdIndex<99) cmdIndex++;

}

}

if(als_on) {

int a =AP3216_read(0x0D); // ALS Data HIGH Byte

int b =AP3216_read(0x0C); // ALS Data LOW Byte

long alsValue = a;

alsValue =alsValue << 8;

alsValue =alsValue + b;

Serial.print("als ");

Serial.print(alsValue);

Serial.print("
");

delay(100);

}

if(ps_on) {

int a =AP3216_read(0x0F) & 0b00111111; // PS Data HIGH 6 bits

int b =AP3216_read(0x0E) & 0b00001111; // PS Data LOW 4 bits

long psValue = (a<< 4) + b;

Serial.print("ps ");

Serial.print(psValue);

Serial.print("
");

delay(13);

}

}

使用方法:

串口輸入 als start 獲取當前的光強

串口輸入 ps start獲得當前接近感測器的數值

串口輸入 stop 停止輸出

目前這個模塊沒有成熟的庫供使用,上述代碼只是實現一個大概的功能,如果應用在產品上,還需要根據需求對照DataSheet進行詳細的調試。

參考:

1. roboremo.com/reading-ap


推薦閱讀:

Arduino有什麼炫酷的作品?
arduino與電腦利用wifi數據互通,是怎麼實現的?
Arduino 是什麼?
一種視覺化閱讀方法--在word中打標籤

TAG:Arduino |