前々回のジェスチャーセンサー、前回の近接センサーに引き続き、APDS-9960 の最後の機能である照度・RGBセンサーを使ってみました。
最初に言っておきますが、今回は動作確認程度のかなり適当な内容になっていますのでご了承ください。
今回は照度・RGBセンサー単体で動作させることにします。
設定が必要なのは カラーエンジンの起動と ADCの集積時間、ゲインの設定ぐらいです。
特に詳しく解説することもないので早速動作確認に入ります。
RGBセンサーは反射型ではないので、かざした物体の色を判別するのは難しいです。今回はスマホの画面を光らせてその色を測定しました。
その結果がこちらです。
測定値は 16bit なのですが、それだと LCD に表示しきれないので、上位 8bit だけ表示しています。
色によって明るさの絶対値も違っているのでこの測定値をそのまま使うのは難しいかもしれませんが、RGB の大小関係はしっかり測定できています。
今回は動作確認だけですのでこれで十分とします。
最後にソースコードを載せておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
#pragma config FEXTOSC = OFF // FEXTOSC External Oscillator mode Selection bits (Oscillator not enabled) #pragma config RSTOSC = HFINT1 // Power-up default value for COSC bits (HFINTOSC (1MHz)) #pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; I/O or oscillator function on OSC2) #pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed) #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled) #pragma config MCLRE = ON // Master Clear Enable bit (MCLR/VPP pin function is MCLR; Weak pull-up enabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config WDTE = OFF // Watchdog Timer Enable bits (WDT disabled; SWDTEN is ignored) #pragma config LPBOREN = OFF // Low-power BOR enable bit (ULPBOR disabled) #pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled) #pragma config BORV = LOW // Brown-out Reset Voltage selection bit (Brown-out voltage (Vbor) set to 2.45V) #pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (The PPSLOCK bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle) #pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a Reset) #pragma config DEBUG = OFF // Debugger enable bit (Background debugger disabled) #pragma config WRT = OFF // User NVM self-write protection bits (Write protection off) #pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/VPP must be used for programming.) #pragma config CP = OFF // User NVM Program Memory Code Protection bit (User NVM code protection disabled) #pragma config CPD = OFF // Data NVM Memory Code Protection bit (Data NVM code protection disabled) #include <xc.h> #include <stdio.h> #include "i2c.h" #include "lcd_i2c.h" #define _XTAL_FREQ 16000000 char CRGB[8] = {0,0,0,0,0,0,0,0}; void init(){ OSCFRQ = 0x06; //3 : 4MHz/ 4 : 8MHz/ 6 : 16MHz/ 7 : 32MHz OSCCON1bits.NDIV = 0x0; //Clock Divider 1/1 TRISA = 0b00001000; TRISC = 0b00110000; ANSELA = 0b00000000; ANSELC = 0b00000000; WPUA = 0b00000000; WPUC = 0b00000000; PORTA = 0b00000000; PORTC = 0b00000000; } void putch(char c){ lcd_DATA(c); } void APDS_Send(char address, char data){ I2C_Master_Start(); I2C_Master_Write(0x72); //SlaveAdress + Write I2C_Master_Write(address); //RegisterAdress I2C_Master_Write(data); I2C_Master_Stop(); } void APDS_ReadALS(){ I2C_Master_Start(); I2C_Master_Write(0x72); //SlaveAdress + Write I2C_Master_Write(0x94); //Adress I2C_Master_RepeatedStart(); I2C_Master_Write(0x73); //SlaveAdress + Read for(char i=0; i<7; i++){ CRGB[i] = I2C_Master_Read(0); } CRGB[7] = I2C_Master_Read(1); I2C_Master_Stop(); } char APDS_AVALIDCheck(){ char check = 0; I2C_Master_Start(); I2C_Master_Write(0x72); //SlaveAdress + Write I2C_Master_Write(0x93); //Adress I2C_Master_RepeatedStart(); I2C_Master_Write(0x73); //SlaveAdress + Read check = I2C_Master_Read(1); I2C_Master_Stop(); return check&0x01; } void APDS_ALS_Init(){ APDS_Send(0x80,0x03); //POWER ON, ALS ENALBE APDS_Send(0x81,220); //ADC Integration Time 100ms APDS_Send(0x8F,0x03); //GAIN 64x } int main() { init(); I2C_Master_Init(100000); lcd_Init(); APDS_ALS_Init(); while(1){ if(APDS_AVALIDCheck() == 1){ APDS_ReadALS(); lcd_SetCursor(0,0); printf("C%3dR%3d",CRGB[1],CRGB[3]); lcd_SetCursor(0,1); printf("G%3dB%3d",CRGB[5],CRGB[7]); } } } |
I2Cライブラリ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include<xc.h> #define _XTAL_FREQ 16000000 void I2C_Master_Init(const unsigned long c){ SSP2CON1 = 0x28; //SSP2 Module as Master SSP2CON2 = 0x00; SSP2CON3 = 0x00; SSP2ADD = (_XTAL_FREQ/(4*c))-1; //Setting Clock Speed SSP2STAT = 0x80; SSP2CLKPPS = 0x14; //PPS Settings SSP2DATPPS = 0x15; // SCL : RC4 RC4PPS = 0x1a; // SDA : RC5 RC5PPS = 0x1b; } void I2C_Master_Wait(){ while ((SSP2STAT & 0x04) || (SSP2CON2 & 0x1F)); //Transmit is in progress } void I2C_Master_Start(){ I2C_Master_Wait(); SSP2CON2bits.SEN = 1; //Initiate start condition } void I2C_Master_RepeatedStart(){ I2C_Master_Wait(); SSP2CON2bits.RSEN = 1; //Initiate repeated start condition } void I2C_Master_Stop(){ I2C_Master_Wait(); SSP2CON2bits.PEN = 1; //Initiate stop condition } void I2C_Master_Write(unsigned d){ I2C_Master_Wait(); SSP2BUF = d; //Write data to SSP2BUF } unsigned short I2C_Master_Read(unsigned short a){ unsigned short temp; I2C_Master_Wait(); SSP2CON2bits.RCEN = 1; I2C_Master_Wait(); temp = SSP2BUF; //Read data from SSP2BUF I2C_Master_Wait(); SSP2CON2bits.ACKDT = a; //Acknowledge bit SSP2CON2bits.ACKEN = 1; //Acknowledge sequence return temp; }</xc.h> |
1 2 3 4 5 6 7 |
void I2C_Master_Init(const unsigned long c); void I2C_Master_Wait(); void I2C_Master_Start(); void I2C_Master_RepeatedStart(); void I2C_Master_Stop(); void I2C_Master_Write(unsigned d); unsigned short I2C_Master_Read(unsigned short a); |
LCDライブラリ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
#include "i2c.h" #include <xc.h> #define _XTAL_FREQ 16000000 #define CONTRAST 0x18 //for 3.3V //#define CONTRAST 0x08 //for 5V const char lcd_DDRAM[4] = {0x00, 0x40, 0x14, 0x54}; void lcd_INST(char command){ I2C_Master_Start(); I2C_Master_Write(0x7C); //SlaveAdress + Write I2C_Master_Write(0x00); //Instruction I2C_Master_Write(command); //data byte I2C_Master_Stop(); __delay_us(30); } void lcd_DATA(char data){ I2C_Master_Start(); I2C_Master_Write(0x7C); //SlaveAdress + Write I2C_Master_Write(0x40); //Data I2C_Master_Write(data); //data byte I2C_Master_Stop(); __delay_us(30); } void lcd_Init(){ __delay_ms(40); lcd_INST(0x38); //Function Set lcd_INST(0x39); //Function Set lcd_INST(0x14); //Internal OSC Frequency lcd_INST(0x70 + (CONTRAST & 0x0f)); //Contrast Set lcd_INST(0x54 + ((CONTRAST & 0xf0)>>4)); //Power/ICON/Contrast control lcd_INST(0x6c); //Follower control __delay_ms(200); lcd_INST(0x38); //Function Set lcd_INST(0x0c); //Display ON/OFF control lcd_INST(0x01); //Clear Display __delay_ms(2); } void lcd_SetCursor(char x,char y){ char d = lcd_DDRAM[y] + x; lcd_INST( 0x80+d); }</xc.h> |
1 2 3 4 |
void lcd_INST(char command); void lcd_DATA(char data); void lcd_Init(); void lcd_SetCursor(char x,char y); |