
Baru-baru ini, sebuah artikel muncul di Habr.com yang, antara lain, melaporkan pada sensor cahaya. Beberapa waktu lalu, saya menemukan dan memperoleh hal yang menarik - modul yang diproduksi oleh RobotDyn berdasarkan sensor APDS-9960, yang juga tahu bagaimana mengukur tingkat pencahayaan. Setelah mencari dan tidak dapat menemukan referensi ke perangkat ini di sumber ini, saya memutuskan bahwa ini adalah alasan yang baik untuk menulis artikel.
Dalam artikel tersebut, saya ingin memperkenalkan secara singkat kepada pembaca tentang kemungkinan yang disediakan oleh sensor ini dan untuk memeriksa lebih detail bagaimana sensor ini dapat digunakan untuk menentukan warna dan mengukur tingkat pencahayaan.
APDS-9960 adalah sensor dari Avago, ini adalah sensor digital gabungan dengan sejumlah fungsi menarik dan berguna yang berbeda.
Dia tahu cara mengenali gerakan, menentukan kedekatan, dan dia juga tahu cara merekam intensitas cahaya sekitar dan menentukan warna.
Inilah yang akan dibahas dalam artikel ini - dengan bantuan STM32VLDISCOVERY dan APDS-9960 yang lama, kami akan mengukur iluminasi dan akan menentukan warna dalam semua kekayaannya nuansa Merah, Hijau dan Biru.
Namun, sebelum kita masuk ke bagian praktis, izinkan saya terlebih dahulu menulis beberapa kata tentang fitur umum dari APDS-9960.
Diagram fungsional APDS-9960 ditunjukkan pada gambar di bawah ini.

Pengenalan gerakan
Gagasan tentang bagaimana pengenalan gerakan pada APDS-9960 ditampilkan dengan sangat baik dalam video ini.
Dokumentasi menjelaskan prinsip pendaftaran gerakan:
Untuk mengenali gerakan itu, empat fotodioda arah digunakan untuk mendaftarkan cahaya yang dipantulkan (dalam rentang inframerah) yang dipancarkan oleh LED bawaan.

Fungsi deteksi kedekatan
Dilihat oleh deskripsi dari dokumentasi yang sama, mekanisme deteksi (perkiraan) bekerja pada prinsip yang sama persis seperti pengenalan gerakan tubuh.
Pengenalan warna dan tingkat cahaya sekitar (Warna / ALS)
Menurut diagram fungsional, sensor menentukan tingkat warna / cahaya menggunakan fotodioda yang sesuai. Disebutkan pula bahwa APDS-9960 memiliki filter bawaan yang menghalangi rentang ultraviolet dan inframerah.
Sederhana, terlihat seperti ini: sinyal yang direkam oleh fotodioda diukur menggunakan ADC, dimasukkan ke dalam buffer, dan kemudian data dikirim melalui i2c.

Grafik pada gambar di atas diambil dari dokumentasi sensor, respons spektral Color Sense (RGBC) disajikan di kiri atas.
Sinyal RGBC dari fotodioda diakumulasikan selama periode waktu yang ditentukan oleh nilai register ATIME. Untuk SparkFun (dalam "apds9960.h"), nilai ini ditentukan oleh DEFAULT_ATIME konstan dan sama dengan 219 yang sesuai dengan 103 ms.
Gain dapat disesuaikan dari 1x hingga 64x dan ditentukan dengan mengatur parameter CONTROL AGAIN. DEFAULT_AGAIN konstan, yang, pada gilirannya, sama dengan 1, yang sesuai dengan kenaikan 4 kali lipat.
Bagian praktis
Secara pribadi, saya hanya tertarik pada fungsi Color / ALS di APDS-9960, jadi saya memutuskan untuk mempertimbangkannya secara lebih rinci dan menulis kode kecil yang menunjukkan operasinya.
Saya sengaja mencoba membuat kode yang ringkas, ringkas, dan sangat sederhana untuk dipahami sebisa mungkin; semua kode akan disajikan di akhir artikel.
Jadi, semua dokumentasi (gambar, pinout dan diagram rangkaian) untuk modul tersedia di situs web pabrikan.

Hubungkan modul APDS-9960 kami ke STM32VLDISCOVERY
APDS9960 menggunakan antarmuka i2c untuk berkomunikasi dengan dunia luar, jadi untuk STM32VLDISCOVERY kami menggunakan bus I2C1 dengan menghubungkan pin modul SCL ke pin PB6, dan pin SDA ke pin PB7, masing-masing. Jangan lupa menghubungkan kabel power dan common. Interupsi dalam hal ini tidak akan digunakan, sehingga output dari Int dapat dihilangkan. Di foto saya itu terhubung, tetapi tidak digunakan.

Dan sekarang kode kecil. Karena semua komunikasi dengan modul terjadi menggunakan i2c, kami akan membuat konfigurasi yang diperlukan dan mendefinisikan fungsi baca / tulis untuk i2c.
Inisialisasi I2C.
Inisialisasivoid I2C1_init(void) { I2C_InitTypeDef I2C_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_AFIO , ENABLE); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_StructInit(&I2C_InitStructure); I2C_InitStructure.I2C_ClockSpeed = 100000; I2C_InitStructure.I2C_OwnAddress1 = 0x01; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); }
Membaca register.
Fungsi untuk membaca nilai dari register uint8_t i2c1_read(uint8_t addr) { uint8_t data; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, APDS9960_I2C_ADDR<<1, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, addr); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, APDS9960_I2C_ADDR<<1, I2C_Direction_Receiver); while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)); data = I2C_ReceiveData(I2C1); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); I2C_AcknowledgeConfig(I2C1, DISABLE); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); return data; }
Menulis nilai ke register
Mendaftar fungsi nilai void i2c1_write(uint8_t addr, uint8_t data) { I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, APDS9960_I2C_ADDR<<1, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, addr); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1, data); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1, ENABLE); while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)) {}; }
Agar modul berfungsi dengan baik, modul itu harus terlebih dahulu dikonfigurasi dengan benar. Khusus untuk pengenalan warna dan pencahayaan, Anda harus melakukan hal berikut:
1) Tentukan register ATIME. Secara default, ketika modul dimulai, register ATIME memiliki nilai 0xFF dan jika Anda tidak mengubah apa pun, ini akan memengaruhi sensitivitas sensor - sensitivitasnya akan rendah.
i2c1_write(APDS9960_ATIME, DEFAULT_ATIME);
2) pada langkah berikutnya kita mengatur bidang parameter LAGI (ALS dan Kontrol Penguatan Warna) dari register Register Satu Kontrol (0x8F) ke nilai yang sesuai dengan gain sama dengan x4 (DEFAULT_AGAIN sama dengan AGAIN_4X).
i2c1_write(APDS9960_CONTROL, DEFAULT_AGAIN);
3) aktifkan opsi ALS dengan mengatur bit AEN dari daftar Enable Register (0x80)
4) nyalakan daya modul dengan mengatur bit PON dari register yang sama
seperti ini:
i2c1_write(APDS9960_ENABLE, (APDS9960_PON | APDS9960_AEN));
Itu seluruh pengaturan. Sensor kami siap bekerja dan bertahan, Anda dapat mulai mengukur semua warna.
Tapi pertama-tama, ukur tingkat iluminasi
Colour_tmpL = i2c1_read(APDS9960_CDATAL); Colour_tmpH = i2c1_read(APDS9960_CDATAH); Colour_Clear = (Colour_tmpH << 8) + Colour_tmpL;
Dan sekarang bisnis kami telah sampai pada bunga yang telah lama ditunggu
Dan sekarang seluruh kode:
main.c #include "stm32f10x.h" #define APDS9960_I2C_ADDR 0x39 #define APDS9960_ATIME 0x81 #define APDS9960_CONTROL 0x8F #define APDS9960_ENABLE 0x80 #define APDS9960_CDATAL 0x94 #define APDS9960_CDATAH 0x95 #define APDS9960_RDATAL 0x96 #define APDS9960_RDATAH 0x97 #define APDS9960_GDATAL 0x98 #define APDS9960_GDATAH 0x99 #define APDS9960_BDATAL 0x9A #define APDS9960_BDATAH 0x9B #define APDS9960_PON 0x01 #define APDS9960_AEN 0x02 #define APDS9960_PEN 0x04 #define APDS9960_WEN 0x08 #define APSD9960_AIEN 0x10 #define APDS9960_PIEN 0x20 #define APDS9960_GEN 0x40 #define APDS9960_GVALID 0x01 #define AGAIN_1X 0 #define AGAIN_4X 1 #define AGAIN_16X 2 #define AGAIN_64X 3 #define DEFAULT_ATIME 219
Saya sengaja tidak membuat definisi konstanta di header terpisah untuk kenyamanan.
Omong-omong, Konstanta meminjam dari repositori resmi SparkFun Electronics. Dari sini
Saya sangat menyukai APDS-9960 - hal yang menarik, itu menarik untuk diteliti, itu menarik untuk menulis artikel. Saya harap seseorang akan menemukan bahan ini bermanfaat. Terima kasih atas perhatian anda