بي اتش 1750. مستشعر الإضاءة المحيطة مع ناقل I2C.
BH1750 عبارة عن مستشعر للإضاءة المحيطة يتمتع بدقة وحساسية عالية إلى حد معقول. يتصرف في مواجهة الضوء المرئي بطريقة مماثلة لعين الإنسان ولا يتأثر بالأشعة تحت الحمراء ولا يعتمد على درجة حرارة اللون لنوع الإضاءة، أي أنه يعمل بشكل جيد مع الضوء الطبيعي ومعه أنواع مختلفة من الإضاءة الاصطناعية. إنه يتصل رقميًا مع وحدة التحكم الدقيقة، مع حافلة I2C، لذا فهو مقاوم للتداخل إذا تم وضعه على مسافة معينة من الدائرة التي تقرأه. وقت الاستجابة منخفض للغاية، أقل من 200 مللي ثانية في الظروف غير المواتية.
من وجهة النظر الإلكترونية، تنفيذه بسيط للغاية. كل ما عليك فعله هو توصيل الطاقة (بين 2,4 فولت و 3,6 فولت) و حافلة I2C. اختياريًا، يمكن تغيير عنوان الناقل لتوصيل جهازين (مع ADDR عند مستوى منخفض يكون 0B0100011 أو 0x23 ومع ADDR عند مستوى عالٍ يكون 0B1011100 أو 0x5C) ويمكن استخدام خط VDI لوظيفة إعادة التعيين مع متحكم.
لتوصيل BH1750 بـ اردوينو، بالإضافة إلى كونها تعمل بمخرج 3,3 فولت، فالأصح هو استخدام محول المستوى بالإضافة إلى مقاومات السحب إلى حافلة I2C. على الرغم من أن المكون سيدعم الاتصال المباشر بالحافلة حافلة I2C ليس من المستحسن تحديد حجم الدائرة دون النظر في تحويل المستوى.
ونظرًا لشعبيتها التي ترجع إلى كونها رخيصة جدًا بالنسبة إلى دقتها، هناك عدة وحدات، مثل GY-30 المشهورة، والتي يمكن رؤيتها في الصورة في البداية. لتوصيلها بشكل أكثر راحة عند إنشاء نماذج أولية باستخدام وحدة تحكم دقيقة، فإنها تتضمن عادةً محولات مستوى لـ حافلة I2C ومنظمات الجهد لتزويدها بجهد أعلى (يصل إلى 5 فولت) بدلاً من خرج 3,3 فولت اردوينو.
يحتوي جهاز BH1750 على وضعين للقراءة، مستمر وفردي، يتوافقان مع حالتين، الطاقة النشطة والمنخفضة أو النوم. بينما في حالة استخدام وضع القراءة المستمرة، يظل جهاز BH1750 نشطًا بعد أخذ العينات، وبعد إجراء قياس فردي، فإنه يدخل تلقائيًا في وضع السكون والطاقة المنخفضة. تستغرق القراءة الأولى في الوضع المستمر 180 مللي ثانية كحد أقصى، وتستغرق القراءة اللاحقة ما بين 16 مللي ثانية و120 مللي ثانية حسب الدقة.
المستشعر قادر على القياس على فترات (دقة) تبلغ 4 لوكس و1 لوكس و0,5 لوكس. يوصي BH1750 في ورقة البيانات الخاصة به باستخدام دقة 1 لوكس، مما يسمح لنا بتمييز الإضاءة التي تقل عن 10 لوكس (والتي تتوافق مع ضوء الشفق) والتي تكون أكثر مناعة ضد الضوضاء التي قد تؤثر على القياس.
تستخدم دقة 1 لوكس و4 لوكس 16 بت من البيانات لتمثيل الجزء الصحيح بحيث يمكن الوصول إلى الحد الأقصى للقياس وهو 65535 لوكس (يوم مشمس بدون ضوء مباشر). يستخدم وضع 0,5 لوكس البت الأقل أهمية للجزء العشري (يقيس من 0,5 لوكس إلى 0,5 لوكس) لذلك مع الـ 15 بت المتبقية من الممكن تمثيل قيمة قصوى تبلغ 32767 لوكس (خارجي بدون ضوء مباشر)
عادة، تتوافق النافذة البصرية التي يتم من خلالها قياس الضوء المحيط مع الطيف المرئي بأكمله والهدف هو تحقيق توزيع حساسية فيه مماثل لتوزيع البشر. إذا تم تقليل النافذة البصرية (يتم قياس الضوء في نطاق طول موجي أقل) يمكن زيادة حساسية BH1750 (حتى 0,11 لوكس) مع وضع إلغاء تعديل تأثير النافذة البصرية عن طريق زيادة قراءة الوقت في نسبة. نظرًا لأنه في هذا الوضع الخاص (كبير الحجم) يتم أخذ قراءات منفصلة، يجب أن يسمح السياق بذلك دون تغيير ظروف القياس بشكل خاص (على سبيل المثال، يجب أن يظل المستشعر مستقرًا للغاية، ويجب ألا ينتقل إلى منطقة ذات ظروف إضاءة مختلفة)
رموز التشغيل BH1750
استادو
5>
-
0B00000000
(0x00
) وضع الطاقة المنخفضة أو الخمول. -
0B00000001
(0x01
) مفتوح. -
0B00000111
(0x07
) إعادة ضبط. مسح سجلات بيانات BH1750.
قرار
5>
-
0B00010011
(0x13
) قياس مستمر بدقة 4 لوكس (بين 16 مللي ثانية ووقت القراءة) -
0B00010000
(0x10
) قياس مستمر بدقة 1 لوكس (وقت القراءة 120 مللي ثانية) -
0B00010001
(0x11
) قياس مستمر بدقة 0,5 لوكس (وقت القراءة 120 مللي ثانية) -
0B00100011
(0x23
) قياس بدقة 4 لوكس (زمن القراءة 16 مللي ثانية) -
0B00100000
(0x20
) قياس بدقة 1 لوكس (زمن القراءة 120 مللي ثانية) -
0B00100001
(0x21
) قياس بدقة 0,5 لوكس (زمن القراءة 120 مللي ثانية)
تعديل للتغيير في النافذة البصرية
5>
-
0B011MT
[0,1,2,3,4] البتة المنخفضة لسجل MTREG (تسجيل وقت القياس). -
0B01000MT
[5,6,7،XNUMX،XNUMX] يسجل MTREG بتًا عاليًا.
اقرأ BH1750 من اردوينو
لقياس الإضاءة المحيطة باستخدام BH1750 من اردوينو يتم استخدام المكتبة الأسلاك الذي يدير الاتصالات مع حافلة I2C. العملية هي المعتادة في هذا النوع من الاتصالات، حيث يتم تفعيلها أولاً (مرة واحدة في البرنامج) بها Wire.begin()
يبدأ الاتصال مع BH1750 بـ Wire.beginTransmission()
وعنوانك I2C (0x5C أو 0x23 اعتمادًا على ما إذا كان ADDR مرتفعًا أم منخفضًا على التوالي)، يتم تكوينه عن طريق إرسال الكود المقابل مع Wire.write()
ويتم تحرير الحافلة مع Wire.endTransmission()
15
|
Wire.begin();
|
17
18
19
|
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_UN_LUX_BH1750);
Wire.endTransmission();
|
إذا تم استخدام أحد أوضاع القراءة المستمرة، فسيتم استخدام Wire.beginTransmission() للحصول على البيانات مع العنوان I2C المقابلة للوصول إلى BH1750، يتم طلب بايتين (الدقة 16 بت) مع Wire.requestFrom()
التي تتم قراءتها باستخدام Wire.read()
، ويتم تحميلها في عدد صحيح غير موقّع، مع تدوير البايت الأول بمقدار 8 بتات. تم إطلاق سراح الحافلة لاحقًا مع Wire.endTransmission()
. يتم الحصول على النتيجة النهائية بقسمة القيمة المرتجعة على عامل الدقة (1,2 إذا لم يتم تغيير النافذة البصرية)
28
29
|
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.requestFrom(DIRECCION_BH1750_0,2);
|
37
38
|
lectura_BH1750=Wire.read()<<8; // Leer el primer byte y rotarlo 8 bits
lectura_BH1750|=Wire.read(); // Leer el segundo byte y «juntarlo» con el anterior on OR
|
40
|
iluminacion=long(100.0*(float)lectura_BH1750/DIVISOR_PRECISION)/100; // Resultado corregido y sin decimales
|
إذا تم استخدام وضع القراءة الفردية، يدخل جهاز BH1750 في وضع السكون.للعودة إلى الوضع النشط، يمكن إرسال التكوين (نفس وضع القراءة أو وضع جديد) أو رمز التشغيل (0x01). يمكن استخدام رمز إيقاف التشغيل (1750x0) لإجبار BH00 على الدخول في وضع السكون.
من المهم احترام وقت قراءة المستشعر، والذي يعتمد على الدقة. إذا لم يكن الانتظار حرجًا، فيمكن توحيده في قيمة لجميع الحالات التي يمكن أن تكون أكبر قليلاً من الحد الأقصى المتوقع لضمان اكتمال القراءة.
لجعل كتابة التعليمات البرمجية لـ BH1750 أكثر راحة اردوينو، تم العثور على رموز التشغيل الأكثر صلة في مستند الرأس التالي.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#define REPOSAR_BH1750 0x00 // Modo de reposo o bajo consumo
#define ENCENDER_BH1750 0x01
#define RESETEAR_BH1750 0x07
#define MEDIDA_CONTINUA_CUATRO_LUX_BH1750 0x13
#define MEDIDA_CONTINUA_UN_LUX_BH1750 0x10
#define MEDIDA_CONTINUA_MEDIO_LUX_BH1750 0x11
#define MEDIDA_SIMPLE_CUATRO_LUX_BH1750 0x23
#define MEDIDA_SIMPLE_UN_LUX_BH1750 0x20
#define MEDIDA_SIMPLE_MEDIO_LUX_BH1750 0x21
#define ESPERA_BH1750_0 250 // 250 milisegundos de espera de lectura del BH1750 (mayor que la máxima)
#define TIMEOUT_I2C 10 // 10 milisegundos de espera antes de renunciar a leer el bus I2C
#define DIVISOR_PRECISION 1.2 // valor por el que dividir la lectura para calcular la luminosidad 1.2 si no hay cambios en la ventana óptica
#define DIRECCION_BH1750_0 0x23
#define DIRECCION_BH1750_1 0x5C
|
يوضح رمز المثال التالي وضع القراءة الأكثر شيوعًا في مستشعر الضوء I2C بي اتش 1750. الدقة هي 1 لوكس ووضع القراءة مستمر. يوضح المثال استخدام وحدة التحكم التسلسلية اردوينو، كل نتيجة تم الحصول عليها من القيمة المقاسة.
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 “BH1750.h” // Cargar los códigos de operación del BH1750
#include <Wire.h>
unsigned int lectura_BH1750;
unsigned int iluminacion;
//float iluminacion; // Mostrar el valor con decimales
long cronometro_lecturas=0;
long tiempo_transcurrido;
long cronometro_timeout_i2c;
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(ESPERA_BH1750_0); // Espera inicial para estabilizar el BH1750
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_UN_LUX_BH1750);
Wire.endTransmission();
}
void loop()
{
tiempo_transcurrido=millis()–cronometro_lecturas;
if(tiempo_transcurrido>ESPERA_BH1750_0)
{
cronometro_lecturas=millis();
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.requestFrom(DIRECCION_BH1750_0,2);
do
{
tiempo_transcurrido=millis()–cronometro_timeout_i2c;
}
while(Wire.available()<2&&tiempo_transcurrido<TIMEOUT_I2C);
if(Wire.available()>1)
{
lectura_BH1750=Wire.read()<<8; // Leer el primer byte y rotarlo 8 bits
lectura_BH1750|=Wire.read(); // Leer el segundo byte y «juntarlo» con el anterior on OR
//iluminacion=lectura_BH1750/DIVISOR_PRECISION; // Resultado corregido y con decimales (mínimamente más preciso pero menos legible)
iluminacion=long(100.0*(float)lectura_BH1750/DIVISOR_PRECISION)/100; // Resultado corregido y sin decimales
Serial.print(“La iluminación es de “);
Serial.print(iluminacion);
Serial.println(” lux”);
}
}
}
|
كما قلت أعلاه، يستخدم كل من وضعي الدقة 1 لوكس و4 لوكس 16 بت من البيانات للتعبير عن القياس كعدد صحيح. من ناحية أخرى، في الوضع 0,5 لوكس، يمثل البت الأخير جزءًا عشريًا، أي أن القيمة التي تساهم في القياس الإجمالي يتم إزاحتها بقوة اثنين إلى اليمين. في وضع 1 لوكس أو 4 لوكس الجزء الأخير (LSB) يستحق 20، ما قبل الأخير 21، التالي 22…في وضع 0,5 لوكس في الجزء الأخير (LSB) يستحق 2-1، ما قبل الأخير 20، التالي 21...
وفقا لبنية البيانات هذه، ومع الأخذ في الاعتبار أنه يجب إجراء قراءتين I2C من البايت، للحصول على قيمة 16 بت، يجب عليك تحميل البتات الأكثر أهمية من البايت، وهي البتات الأولى التي سيتم قراءتها، وتدويرها 8 بتات إلى اليسار في وضع الدقة 1 لوكس وفي وضع الدقة 4 لوكس و7 بتات فقط عند 0,5 لوكس. لتوحيد طريقة القراءة في وضع 0,5 لوكس، يمكنك تحميل البايت الأكثر أهمية في عدد صحيح غير موقّع، وتدوير 8 بت إلى اليسار، وتحميل البايت الأقل أهمية وتدوير العدد الصحيح غير الموقّع بالكامل 1 بت إلى اليسار. قيمة الجزء العشري الذي يشير إلى LSB (البت الأقل أهمية) لتطبيقه لاحقا.
منطقيًا، بالنسبة إلى الأوضاع 1 لوكس أو 4 لوكس، من الضروري استخدام الأعداد الصحيحة غير الموقعة (unsigned int
) لماذا اردوينو لا تحجز MSB (البت الأكثر أهمية) للعلامة وتكون قادرة على العمل مباشرة مع القيمة الحقيقية للقياس، وليس مع رقم سالب. في اردوينو ديو ليس من الضروري ذلك لأن الأعداد الصحيحة تستخدم 32 بت، ولكن نفس البرنامج سيعمل أيضًا إذا تم استخدامه أيضًا unsigned int
.
يوضح الكود التالي كيفية استخدام وضع 0,5 لوكس
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
|
#include “BH1750.h” // Cargar los códigos de operación del BH1750
#include <Wire.h>
unsigned int lectura_BH1750;
//unsigned int iluminacion;
float iluminacion; // Mostrar el valor con decimales
long cronometro_lecturas=0;
long tiempo_transcurrido;
long cronometro_timeout_i2c;
bool parte_decimal;
void setup()
{
Serial.begin(9600);
Wire.begin();
delay(ESPERA_BH1750_0); // Espera inicial para estabilizar el BH1750
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.write(MEDIDA_CONTINUA_MEDIO_LUX_BH1750);
Wire.endTransmission();
}
void loop()
{
tiempo_transcurrido=millis()–cronometro_lecturas;
if(tiempo_transcurrido>ESPERA_BH1750_0)
{
cronometro_lecturas=millis();
Wire.beginTransmission(DIRECCION_BH1750_0);
Wire.requestFrom(DIRECCION_BH1750_0,2);
do
{
tiempo_transcurrido=millis()–cronometro_timeout_i2c;
}
while(Wire.available()<2&&tiempo_transcurrido<TIMEOUT_I2C);
if(Wire.available()>1)
{
lectura_BH1750=Wire.read()<<8; // Leer el primer byte y rotarlo 8 bits
lectura_BH1750|=Wire.read(); // Leer el segundo byte y «juntarlo» con el anterior on OR
parte_decimal=(lectura_BH1750<<15)>0;
lectura_BH1750>>=1;
iluminacion=((float)lectura_BH1750+(parte_decimal?0.5:0.0))/DIVISOR_PRECISION;
Serial.print(“La iluminación es de “);
Serial.print(iluminacion);
Serial.println(” lux”);
}
}
}
|
قم بتنزيل المستندات للحصول على أمثلة لقياس الإضاءة المحيطة باستخدام مستشعر BH1750 وArduino.
أكتب تعليق