Документация Engee
Notebook

Пакет поддержки Arduino: аналоговый вход - фоторезистор

В предыдущих примерах для пакета поддержки Arduino были широко рассмотрены цифровые выходы/выходы, в этом примере мы перейдём к работе с аналоговым входом. При помощи пакета поддержки Arduino реализуем в модели Engee программу считывания сигнала от фоторезистора и обработки поступающих данных для реализации датчика освещённости.

Введение

Ранее реализация логика работы датчика освещённости была смоделирована в похожем примере для МИК 32 Амур. Здесь мы используем пакет поддержи, чтобы переносить модель на контроллер автоматически.

В примере используются:

  • отладочная плата Arduino Mega,
  • макетная плата,
  • фоторезистор (LDR) GL5516,
  • резистор 4.7 кОм (2шт),
  • соединительные провода.

Задача модели: по поступающему на аналоговый вход значению падения напряжения на токоограничивающих резисторах в цепи фоторезистора рассчитать освещённость.

Аппаратная часть

Соединим элементы, как показано на схеме ниже:

scheme_bb.png

Величина падения напряжения на токоограничивающих резисторах будет обработана АЦП на аналоговом входе A0 микроконтроллера. Модель Engee для обработки поступающего сигнала представлена ниже.

Модель примера

Настройки блока конфигурации таргета (EDM-Target-Arduino) оставим такими, как в предыдущем примере - светодиодная матрица.

В блоге чтения с аналогового канала (Arduino-analogRead) установим номер пина используемого аналогового канала A0 - 54.

model.png

В схеме при помощи простейших математических блоков рассчитывается сопротивление фоторезистора R_LDR исходя из цифрового значения от АЦП канала A0.

Освещённость Lux в свою очередь определяется по значению сопротивления фоторезистора из функции связи переменных .

Определение функции

Связь сопротивления фоторезистора и освещённости может быть определена из его характеристик - например, согласно Fig.1 на стр. 4 из паспортных данных.

Возьмём следующие центральные точки из области характеристики:

In [ ]:
x_Ohm = [3e4, 7e3, 2e3];
y_Lux = [1, 10, 100];

Саму же зависимость можно определить как степенную функцию вида

где - сопротивление фоторезистора [Ом], - освещённость [Лк], - коэффициент, - показатель степени.

Для оптимизации функции и нахождения коэффициентов по определённым ранее точкам характеристики добавим следующие пакеты:

In [ ]:
]add LsqFit
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`
In [ ]:
]add Statistics
   Resolving package versions...
  No Changes to `~/.project/Project.toml`
  No Changes to `~/.project/Manifest.toml`

Далее перейдём к непосредственному нахождению коэффициентов функции:

In [ ]:
using Plots; gr(format=:png)
using LsqFit, Statistics

model(x_Ohm, p) = p[1] .* x_Ohm .^ p[2]

# Начальные параметры
p0 = [1e7, -1.0]

# Подгонка кривой
fit = curve_fit(model, x_Ohm, y_Lux, p0)

# Параметры формулы
a, b = fit.param
println("Формула: y = $a * x ^ ($b)")

# Расчет R²
ss_res = sum((y_Lux .- model(x_Ohm, fit.param)).^2)  # сумма квадратов остатков
ss_tot = sum((y_Lux .- mean(y_Lux)).^2)              # общая сумма квадратов
r2 = 1 - ss_res/ss_tot

println("R² = $r2")
Формула: y = 1.1357055990804273e8 * x ^ (-1.8343597148570423)
R² = 0.9999842359959972

Конечно, расчёт для двух точек при подгонке функции не является необходимостью. Мы используем данную оценку для того, чтобы удостовериться, что построенная кривая проходит через исходные точки. Построим кривую и точки на плоскости:

In [ ]:
plot(x_Ohm, y_Lux)
plot!(collect(1e3:3e4), a.*collect(1e3:3e4).^b)
Out[0]:
No description has been provided for this image

Полученные коэффициенты:

In [ ]:
@show a;
@show b;
a = 1.1357055990804273e8
b = -1.8343597148570423

также вписаны в обратные вызовы модели.

Подготовка

При помощи этого блока кода автоматизируем запуск серверной программы Engee.Интеграции:

In [ ]:
import .engee.package as epkg

const PKGNAME = "Engee-Device-Manager"

function epkg_start(pkg::String)
    if !epkg.isinstalled(pkg)
        @info "Package not installed. Installing and Starting..."
        epkg.install(pkg)
        @info "Package is up to date. Starting..."
        println("Ссылка для подключения к серверу:\n"*epkg.start(pkg))
    else
        updates = epkg.checkupdates(pkg)
        if isnothing(updates)
            @info "Package is up to date. Starting..."
            println("Ссылка для подключения к серверу:\n"*epkg.start(pkg))
        else
            @info "Updates available. Reinstalling and Starting..."
            epkg.update(pkg)
            @info "Package is up to date. Starting..."
            println("Ссылка для подключения к серверу:\n"*epkg.start(pkg))
        end
    end
end

epkg_start(PKGNAME)
Пакет поддержки 'Engee-Device-Manager' установлен.
У вас установлена актуальная версия пакета поддержки 'Engee-Device-Manager'.
[ Info: Package is up to date. Starting...

Также за кадром, как обычно, запустим клиентскую программу Engee.Интеграции и подключим наше устройство.

Выполнение модели

Запустим в интерактивном режиме работу модели и будем наблюдать ход расчётов сопротивления фоторезистора и освещённости при изменении яркости света в помещении.

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

Заключение

В примере, как нам и требовалось, мы рассмотрели работу с блоком цифрового входа из пакета поддержки Arduino, начав реализацию датчика освещённости.