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
//http://www.icstation.com/ap3216-ambient-light-sensorals-proximity-sensorps-p-7958.html
// 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. http://www.roboremo.com/reading-ap3216-with-arduino.html
推薦閱讀:
※Arduino有什麼炫酷的作品?
※arduino與電腦利用wifi數據互通,是怎麼實現的?
※Arduino 是什麼?
※一種視覺化閱讀方法--在word中打標籤
TAG:Arduino |