Измерители освещенности (люксметры) , 3 варианта на основе BH1750
Вариант первый :
Вывод данных с одного датчика освещенности на жидкокристаллический индикатор
К сожалению данный тип датчиков имеет верхний предел в 54,612клюкс , что как минимум в два раза ниже потолка освещенности в яркий солнечный день
Приходится хитрить , помещать датчик в корпус из материала с ограниченной прозрачностью и вводить поправочный коэффициент в расчетах
Комплектация :
Arduino nano
HD44780 1602 + модуль посл.интерфейса
BH1750
Схема подключения :
Так выглядит в работе :
Программа (скетч) :
#include <Wire.h>//библиотека под LCD
#include <BH1750FVI.h>//библиотека датчика освещенности
#include <LiquidCrystal_I2C.h>//библиотека под LCD
LiquidCrystal_I2C lcd(0x27,16,2);//прописываем свой LCD дисплей по адресу 27 или 3F и его знакоместам
BH1750FVI Oko;
byte X8[8] = {B00011,B00111,B00101,B00101,B01101,B01001,B11001,B00000,}; // Буква "Л"
byte X15[8] = {B10101,B10101,B10101,B10101,B10101,B10101,B11111,B00001,}; // Буква "Щ"
byte X16[8] = {B10000,B10000,B10000,B11110,B10001,B10001,B11110,B00000,}; // Буква "Ь"
byte X18[8] = {B10010,B10101,B10101,B11101,B10101,B10101,B10010,B00000,}; // Буква "Ю"
void setup() {
lcd.init();// Инициализация lcd дисплея
lcd.backlight();// Включение подсветки дисплея
Oko.begin();
Oko.SetAddress(Device_Address_L);
Oko.SetMode(Continuous_L_resolution_Mode);
}
void loop() {
lcd.createChar(1,X8); //1 синтезированный знак (Л)
lcd.createChar(2,X15); //2 синтезированный знак (Щ)
lcd.createChar(3,X16); //3 синтезированный знак (Ь)
lcd.createChar(4,X18); //4 синтезированный знак (Ю)
uint16_t X = Oko.GetLightIntensity();//опрос датчика
lcd.setCursor(2, 0);
lcd.print("OCBE\2EHHOCT\3"); //ОСВЕЩЕННОСТЬ
lcd.setCursor(3, 1);
lcd.print("\1\4KC"); //ЛЮКС
lcd.setCursor(9, 1);
lcd.print(" "); //протир 5 знакомест перед выводом значения
lcd.setCursor(9, 1);
lcd.print(X); //вывод значения датчика
delay(500);//0,5сек. Период обращения к датчику
}
Вариант второй :
Довольно таки часто возникает необходимость использовать не текущие данные освещенности , а усредненные
При домашних измерениях могут мешать пульсации от ламп , при контроле за освещенностью на улице солнце иной раз так в прятки начнет играть что не определишься притенять или нет те или иные посадки или рассаду
Вот тут усреднение освещенности здорово может пригодится , за какой период , 10мин. , полчас , час - сразу так и не определишься , тут надо выбирать на практике золотую середину и под каждый конкретный случай
Для этого варианта и комплектация , и сборка та же , только прошивка будет другая
Комплектация :
Arduino nano
HD44780 1602 + модуль посл.интерфейса
BH1750
Схема подключения :
Так выглядит в работе :
первый цикл среднее значение не высвечивается , пока массив данных на набьется полностью показаниями , чтобы не вводить нас в заблуждение заниженными цифрами
после уже постоянно будут высвечиваться оба параметра , и текущие , и усредненные
Программа (скетч) :
#include <Wire.h>//библиотека под LCD
#include <BH1750FVI.h>//библиотека датчика освещенности
#include <LiquidCrystal_I2C.h>//библиотека под LCD
LiquidCrystal_I2C lcd(0x27,16,2);//прописываем свой LCD дисплей по адресу 27 или 3F и его знакоместам
BH1750FVI Oko;
const int Razmer = 500;//размерность массива
unsigned int massiv[Razmer]; // массив для хранения текущих значений
int Nomer = 0; // индекс последнего значения
float Summa = 0; // сумма значений
unsigned int Seredina = 0; // скользящее среднее
int FL = 0;//флаг на вывон на индикацию среднего значения
byte X3[8] = {B01111,B00101,B00101,B01001,B10001,B11111,B10001,B00000,}; // Буква "Д"
byte X8[8] = {B00011,B00111,B00101,B00101,B01101,B01001,B11001,B00000,}; // Буква "Л"
byte X10[8] = {B10001,B10001,B10001,B01010,B00100,B01000,B10000,B00000,}; // Буква "У"
byte X15[8]= {B10101,B10101,B10101,B10101,B10101,B10101,B11111,B00001,}; // Буква "Щ"
void setup() {
Serial.begin(9600);// серийный порт поставил для вывода на плоттер , так удобней выбрать подходящий размер массива
lcd.init();// Инициализация lcd дисплея
lcd.backlight();// Включение подсветки дисплея
Oko.begin();
Oko.SetAddress(Device_Address_L);
Oko.SetMode(Continuous_L_resolution_Mode);
for (int a = 0; a < Razmer; a++) {//зануляем массив
massiv[a] = 0;
}
}
void loop() {
lcd.createChar(1,X3);
lcd.createChar(2,X8);
lcd.createChar(3,X10);
lcd.createChar(4,X15);
lcd.setCursor(0, 0);
lcd.print("TEK\3\4EE \2k");//ТЕКУЩЕЕ Лк
lcd.setCursor(0, 1);
lcd.print("CPE\1HEE \2k");//СРЕДНЕЕ Лк
Summa = Summa - massiv[Nomer];// вычитанем последнее значение из суммы
massiv[Nomer] = Oko.GetLightIntensity(); // считываем значение
lcd.setCursor(11, 0);
lcd.print(" "); //протир 5 знакомест перед выводом текущего значения
lcd.setCursor(11, 0);
lcd.print(massiv[Nomer]); //вывод текущего значения на экран
Serial.print(massiv[Nomer]);//дублирование в порт
Serial.print(" ");//пробел он и есть пробел
Summa = Summa + massiv[Nomer];// добавляем значение к сумме
Nomer = Nomer + 1;// переставляем индекс на следующую позицию
if (Nomer >= Razmer) {// проверяем если мы выскочили индексом за пределы массива
Nomer = 0;// если да, то индекс на ноль
}
Seredina = Summa / Razmer;// считаем среднее:
Serial.println(Seredina);//среднее значение в порт
Serial.print(" ");
if (Nomer == Razmer-1) {
FL=1 ;//выставляем флаг при первом полном заполнении массива
}
if (FL==1) {
lcd.setCursor(11, 1);
lcd.print(" "); //протир 5 знакомест перед выводом значения
lcd.setCursor(11, 1);
lcd.print(Seredina); //теперь среднее значение реально и его можно выводить на экран
}
delay(7200); // задержка перед следующим измерением 7,2сек цикл 1час при размерности массива 500
}
В программе есть два значимых параметра , размерность массива и переод обращения к датчику
Произведение этих параметров и есть время за которое вычисляется среднее значение освещенности
С теми значениями что у меня выставлены в скетче это 1 час , большее время брать не имеет смысл , даже его наверно будет лишку
Я сейчас о использовании люксмерта на улице , скоре всего 10-15 минут будет практичнее
Размерность массава у меня тут выставлена 500 , много большие значения ставить не прокатит , памяти ардуинки не хватит
но усреднение по 500м замерам более чем достаточно
Вот картинка теста с плоттера , синее это текущие , красное усредненное , достаточно вполне определиться какая погода преимущественно , солнечно или пасмурно
Так что если надо уменьшить время усреднения размерность массива лучше не трогать , а изменить период обращения к датчику
Для 1 часа этод период у меня выставлен 7,2сек , для 10мин. ставим 1,2сек , для 20мин. 2,4сек и т.д.
А вот для домашних нужд я ставил размерность массива 20-25 и време очередности датчика в пределах 0,1сек
тут подобная картинка на плоттере выскакивает , на ровном плато где я руками не махал , видно что показания не стабильны пилой али синусоидой дрожат (следствие работы ламп) по этому участку среднее значение (красная линия) прямеханька по середине прет
А острые броски текуших плавно повторяет без зубов , только чуть притормаживая
Конечно это тоже все просто приборчик посмотрелка , на практике , чтоб от него больше пользы было , надо выводить с него команды на исполнительное устройство , буть то зуммер , шторки закрывания рассады или система орошения какая к примеру
Перешагнуло среднее значение некий выставленный порог - выдается команда на исполнительный механизм , самое простое это конечно зуммер , а исполнительный механизм это я
Вариант третий :
Повторяет первый вариант , только с той разницей что тут подключено два датчика освещенности , меняя уровень на пятой ноге (все же есть от пятой ноги польза
) можно подличить эти датчики по разным адресам
Комплектация :
Arduino nano
HD44780 1602 + модуль посл.интерфейса
BH1750 - два модуля
Схема включения :
Так выглядит в работе :
Программа (скетч) :
#include <Wire.h>//библиотека под LCD
#include <BH1750FVI.h>//библиотека датчика освещенности
#include <LiquidCrystal_I2C.h>//библиотека под LCD
LiquidCrystal_I2C lcd(0x27,16,2);//прописываем свой LCD дисплей по адресу 27 или 3F и его знакоместам
BH1750FVI Oko1;
BH1750FVI Oko2;
byte X8[8] = {B00011,B00111,B00101,B00101,B01101,B01001,B11001,B00000,}; // Буква "Л"
byte X13[8] = {B10001,B10001,B10001,B01111,B00001,B00001,B00001,B00000,}; // Буква "Ч"
void setup() {
lcd.init();// Инициализация lcd дисплея
lcd.backlight();// Включение подсветки дисплея
Oko1.begin();
Oko1.SetAddress(Device_Address_H);
Oko1.SetMode(Continuous_H_resolution_Mode);
Oko2.begin();
Oko2.SetAddress(Device_Address_L);
Oko2.SetMode(Continuous_L_resolution_Mode);
}
void loop() {
lcd.createChar(1,X8); //1 синтезированный знак (Л)
lcd.createChar(2,X13); //2 синтезированный знак (Ч)
uint16_t X1 = Oko1.GetLightIntensity();//опрос первого датчика
uint16_t X2 = Oko2.GetLightIntensity();
lcd.setCursor(0, 0);
lcd.print("TO\2KA 1 \1k"); //ТОЧКА 1 Лк
lcd.setCursor(11, 0);
lcd.print(" "); //протир 5 знакомест перед выводом значения
lcd.setCursor(11, 0);
lcd.print(X1); //вывод значения первого датчика
lcd.setCursor(0, 1);
lcd.print("TO\2KA 2 \1k");
lcd.setCursor(11, 1);
lcd.print(" ");
lcd.setCursor(11, 1);
lcd.print(X2);
delay(500);
}
На этом пока все , следраз помучаю датчик освещенности VEML7700 , получше разберемся что он может
Перейти к содержанию
0 Комментариев
Рекомендуемые комментарии
Комментариев нет
Для публикации сообщений создайте учётную запись или авторизуйтесь
Вы должны быть пользователем, чтобы оставить комментарий
Создать учетную запись
Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!
Регистрация нового пользователяВойти
Уже есть аккаунт? Войти в систему.
Войти