Датчик освещения с фоторезистором в качестве сенсора.

система TinyOneWireNet

Рассказ о простом, дешевом датчике освещения, в котором в качестве измерителя используется фоторезистор.

Предыдущая статья     Навигация по рубрике     Следующая статья

Общее описание устройства.

Точность этого датчика не высокая. У фоторезистора зависимость сопротивления от освещенности нелинейная и несколько изменяется для  конкретных экземпляров. Поэтому я назвал датчик освещенности, а не измеритель освещенности.

Среди сетевых устройств TinyOneWireNet существует люксметр, выполненный на базе микросхемы BH1750. Это точный измеритель освещенности. Не следует его путать с простым датчиком на фоторезисторе.

Хотя датчик освещения с фоторезистором вычисляет показания в люксах, его можно использовать только как устройство, показывающее наличие света. Например, для контроля работы ламп, определения темное или светлое время суток.

В точке калибровки датчик показывает измеренное значение довольно точно. Поэтому его можно использовать для определения превышения или понижения уровня освещенности относительно конкретной, заранее заданной величины.

Принципиальная схема и конструкция датчика.

Фоторезистор R2 и резистор R1 образуют делитель напряжения, выход которого подключен к аналоговому входу RA4.

схема датчика освещенности

В качестве напряжения питания делителя и источника опорного напряжения АЦП используется питание PIC-контроллера. Поэтому изменение напряжение питания не сказывается на точности измерения.

Вывод RA5 замыкается на землю только в момент измерения, для того чтобы уменьшить потребляемый делителем ток.

Во время измерения производятся и усредняются 8192 выборок значений АЦП, чтобы исключить влияние пульсаций светового потока  ламп.

Время преобразования датчика составляет 650 мс.

Конструктивно датчик освещенности выполнен на универсальной плате. О ней рассказывал в предыдущей статье.

Мой первый вариант выглядит так.

датчик освещенности

Работа с датчиком освещенности в системе Ардуино.

Подключил устройство по привычной схеме.

подключение датчика освещенности к Ардуино

Задал адрес.

тип датчика

Датчик у меня откалиброван в точке 1000 люкс.

Собственно для измерения освещенности в библиотеке TinyOneWireNet.h, по аналогии со многими типами датчиков, существуют 3 функции:

uint8_t startMeasurement_LightSensor(uint8_t adr);  // запуск измерения датчика освещенности

uint8_t readCode_LightSensor(uint8_t adr, uint16_t * code); // чтение результата измерений датчика освещенности (код)

uint8_t readLight_LightSensor(uint8_t adr, uint32_t * light); // чтение результата измерений датчика освещенности (люкс)

Необходимо:

  • запустить измерение;
  • выдержать паузу 650 мс;
  • считать результат.

// измерение освещенности (фоторезистор)
#include <TinyOneWireNet.h>

#define NET_PIN 2 // вывод данных сети
#define BETWEEN_COM_TIME 2 // пауза между командами (мс)

TinyOneWireNet sens(NET_PIN);
uint32_t lx;

void setup() {
  Serial.begin(9600);
  sens.onLine(10);
}

void loop() {
  if( sens.startMeasurement_LightSensor(14) == 0 ) {
    delay(1000);
    if( sens.readLight_LightSensor(14, & lx) == 0 ) {
      Serial.print("Light= ");
      Serial.print(lx);
     Serial.println(" lx");
    }
    else Serial.println("Error");
  }
  else {
    Serial.println("Error");
    delay(1000);
  }
  delay(BETWEEN_COM_TIME);
}

показания датчика

Для калибровки устройства используются следующие методы:

void loadCoeff_LightSensor(uint8_t adr, uint32_t cf); // загрузка калибровочного коэффициента освещения

uint8_t readCoeff_LightSensor(uint8_t adr, uint32_t * cf); // чтение калибровочного коэффициента освещения

Давайте модернизируем предыдущую программу. Она будет также в цикле измерять значение освещенности, но при вводе калибровочного коэффициента через монитор последовательного порта, будет загружать его в устройство.

// измерение освещенности (фоторезистор) с калибровкой
#include <TinyOneWireNet.h>

#define NET_PIN 2 // вывод данных сети
#define BETWEEN_COM_TIME 2 // пауза между командами (мс)

TinyOneWireNet sens(NET_PIN);
uint32_t lx;

void setup() {
  Serial.begin(9600);
  sens.onLine(10);
}

void loop() {
  if( sens.startMeasurement_LightSensor(14) == 0 ) {
    delay(1000);
    if( sens.readLight_LightSensor(14, & lx) == 0 ) {
      Serial.print("Light= ");
      Serial.print(lx);
      Serial.println(" lx");
    }
    else Serial.println("Error");
  }
  else {
    Serial.println("Error");
    delay(1000);
  }
  delay(BETWEEN_COM_TIME);

  if( Serial.available() != 0 ) {
    delay(20);
    uint8_t i=0;
    char str[20];
    while( (Serial.available() != 0) && (i < 20) ) {
      str[i]= Serial.read();
      i++;
    }
    str[i]=0;
    sens.loadCoeff_LightSensor(14, atol(str) * 65536);
  }
}

показания датчика

Я запустил на смартфоне программу-люксметр. Установил его на таком расстоянии от лампы, чтобы показания были равны 1000 люкс. Рядом положил датчик освещенности. Изменением калибровочного коэффициента добился показаний датчика тоже 1000 люкс.

Значение коэффициента для 1000 люкс у меня получилось 860.

Далее я изменял освещенность и сравнивал показания смартфона и датчика.

Показания люксметра на смартфоне Показания датчика
600 724
1000 1000
3000 1624
4000 1924

При отдалении от точки калибровки погрешность измерения значительно увеличивается.

Внутренние математические преобразования датчика только вводят гиперболическую зависимость показаний освещенности от измеренного напряжения. Но вы можете считывать код и производить свои математические операции.

В следующей статье будет рассказ о диммере для светодиодных и ламп накаливания.

Предыдущая статья     Навигация по рубрике     Следующая статья

0

Автор публикации

не в сети 6 часов

Эдуард

280
Комментарии: 1936Публикации: 197Регистрация: 13-12-2015

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Нажимая кнопку "Отправить" Вы даёте свое согласие на обработку введенной персональной информации в соответствии с Федеральным Законом №152-ФЗ от 27.07.2006 "О персональных данных".