
في الآونة الأخيرة ، تومض مقال على Habr.com ، من بين أمور أخرى ، ذكرت على مستشعر الضوء. منذ بعض الوقت ، وجدت شيئًا مثيرًا للاهتمام واكتسبته - وحدة صنعتها RobotDyn استنادًا إلى مستشعر APDS-9960 ، والتي تعرف أيضًا كيفية قياس مستوى الإضاءة. بعد البحث وعدم التمكن من العثور على مراجع لهذا الجهاز على هذا المورد ، قررت أن هذا كان سببًا جيدًا لكتابة مقال.
في المقالة ، أود أن أعرض القراء بإيجاز على الإمكانيات التي يوفرها هذا المستشعر وأن أدرس بمزيد من التفصيل كيف يمكن استخدامه لتحديد اللون وقياس مستوى الإضاءة.
APDS-9960 هو مستشعر من Avago ، وهو عبارة عن مستشعر رقمي مدمج مع عدد من الوظائف المثيرة للاهتمام والمفيدة المختلفة.
إنه يعرف كيف يتعرف على الإيماءات ، ويحدد القرب ، ويعرف أيضًا كيفية تسجيل شدة الضوء المحيط وتحديد اللون.
هذا هو بالضبط ما ستتم مناقشته في هذه المقالة - بمساعدة STM32VLDISCOVERY و APDS-9960 القديمة ، سنقيس الإضاءة وسنحدد اللون بكل ثرائها من ظلال الأحمر والأخضر والأزرق.
ومع ذلك ، قبل أن ندخل في الجزء العملي ، دعوني أولاً أكتب بضع كلمات حول الميزات العامة لـ APDS-9960.
يظهر الرسم الوظيفي لـ APDS-9960 في الشكل أدناه.

التعرف على الإيماءات
يتم عرض فكرة كيف يبدو التعرف على الإيماءات على APDS-9960 بشكل جيد جدًا في هذا الفيديو .
تصف الوثائق مبدأ تسجيل الإيماءات:
للتعرف على الإيماءة ، يتم استخدام أربعة صمامات ضوئية اتجاهية تسجل الضوء المنعكس (في نطاق الأشعة تحت الحمراء) المنبعث من LED المدمج.

وظيفة كشف القرب
استنادًا إلى الوصف من نفس الوثائق ، تعمل آلية الكشف (التقريب) على نفس المبدأ تمامًا مثل التعرف على الإيماءات.
التعرف على الألوان ومستوى الإضاءة المحيطة (اللون / ALS)
وفقًا للرسم الوظيفي ، يحدد المستشعر مستوى اللون / الضوء باستخدام الثنائيات الضوئية المناسبة. ويذكر أيضًا أن APDS-9960 يحتوي على فلاتر مدمجة تحجب نطاقات الأشعة فوق البنفسجية والأشعة تحت الحمراء.
مبسطة ، يبدو الأمر كما يلي: يتم قياس الإشارات المسجلة بواسطة الثنائيات الضوئية باستخدام ADC ، ويتم إدخالها في المخزن المؤقت ، ثم يتم إرسال البيانات عبر i2c.

يتم أخذ الرسوم البيانية في الصورة أعلاه من وثائق المستشعر ، يتم تقديم الاستجابة الطيفية لـ Sense Color (RGBC) في أعلى اليسار.
تتراكم إشارة RGBC للصمامات الضوئية خلال الفترة الزمنية التي تحددها قيمة سجل ATIME. بالنسبة لـ SparkFun (في "apds9960.h") يتم تحديد هذه القيمة بواسطة DEFAULT_ATIME الثابت وهي تساوي 219 والتي تقابل 103 مللي ثانية.
الكسب قابل للتعديل من 1x إلى 64x ويتم تحديده من خلال تعيين معلمة CONTROL AGAIN. الثابت DEFAULT_AGAIN ، والذي بدوره يساوي 1 ، وهو ما يتوافق مع الكسب 4 أضعاف.
جزء عملي
أنا شخصياً كنت مهتمًا فقط بوظيفة Color / ALS في APDS-9960 ، لذلك قررت النظر فيها بمزيد من التفاصيل وكتبت كودًا صغيرًا يوضح عملها.
لقد حاولت عن قصد أن أجعل الشفرة مدمجة وموجزة وبسيطة للغاية لفهمها قدر الإمكان ؛ سيتم تقديم جميع التعليمات البرمجية في نهاية المقالة.
لذا ، فإن جميع الوثائق (الرسم ، والدبابيس ومخطط الدائرة) للوحدة متاحة على موقع الشركة المصنعة.

قم بتوصيل وحدة APDS-9960 الخاصة بنا بـ STM32VLDISCOVERY
يستخدم APDS9960 واجهة i2c للتواصل مع العالم الخارجي ، لذلك بالنسبة لـ STM32VLDISCOVERY ، نستخدم ناقل I2C1 عن طريق توصيل دبوس وحدة SCL بمسمار PB6 ، ودبوس SDA إلى دبوس PB7 ، على التوالي. لا تنس توصيل الطاقة والأسلاك المشتركة. لن يتم استخدام المقاطعات في هذه الحالة ، لذلك يمكن حذف إخراج Int. في صورتي ، تم توصيله ، ولكن لم يتم استخدامه.

والآن كود صغير. نظرًا لأن جميع الاتصالات مع الوحدة تحدث باستخدام i2c ، فسننشئ التكوين اللازم ونحدد وظائف القراءة / الكتابة لـ i2c.
تهيئة I2C.
التهيئةvoid 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); }
قراءة التسجيل.
وظيفة لقراءة قيمة من التسجيل 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; }
كتابة قيمة في السجل
تسجيل دالة القيمة 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)) {}; }
لكي تعمل الوحدة بشكل صحيح ، يجب أولاً تكوينها بشكل صحيح. تحديدًا للتعرف على الألوان والإضاءة ، يجب عليك القيام بما يلي:
1) تحديد سجل ATIME. بشكل افتراضي ، عندما تبدأ الوحدة ، يكون لسجل ATIME القيمة 0xFF وإذا لم تقم بتغيير أي شيء ، فسيؤثر ذلك على حساسية المستشعر - ستكون الحساسية منخفضة.
i2c1_write(APDS9960_ATIME, DEFAULT_ATIME);
2) في الخطوة التالية ، قمنا بتعيين حقل المعلمة AGAIN (ALS والتحكم في اكتساب اللون) في سجل التحكم One Register (0x8F) إلى القيمة المقابلة للربح الذي يساوي x4 (DEFAULT_AGAIN يساوي AGAIN_4X).
i2c1_write(APDS9960_CONTROL, DEFAULT_AGAIN);
3) تمكين خيار ALS عن طريق تعيين بت AEN الخاص بالسجل Enable Register (0x80)
4) قم بتشغيل قوة الوحدة عن طريق ضبط بت PON من نفس السجل
مثل هذا:
i2c1_write(APDS9960_ENABLE, (APDS9960_PON | APDS9960_AEN));
هذا هو الإعداد بأكمله. مستشعرنا جاهز للعمل والدفاع ، يمكنك البدء في قياس جميع الألوان.
ولكن أولاً ، قم بقياس مستوى الإضاءة
Colour_tmpL = i2c1_read(APDS9960_CDATAL); Colour_tmpH = i2c1_read(APDS9960_CDATAH); Colour_Clear = (Colour_tmpH << 8) + Colour_tmpL;
والآن وصل عملنا إلى الزهور التي طال انتظارها
والآن الرمز بالكامل:
الرئيسية ج #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
لم أقم عن قصد بتعريف الثوابت في رأس منفصل للراحة.
بالمناسبة ، اقترض الثوابت من مستودع SparkFun Electronics الرسمي. من هنا .
لقد أحببت حقًا APDS-9960 - شيء مثير للاهتمام ، كان من المثير للاهتمام البحث ، كان من المثير كتابة مقال. آمل أن يجد شخص ما هذه المواد مفيدة. شكرا لكم على اهتمامكم.