const byte led_pins[] = {4, 16, 17, 18, 19, 21, 22, 23}; // номери пінів, до яких підключені світлодіоди
const byte switch_pin = 32; // номер піна, до якого підключений діп-перемикач
const byte ldr_pin = 14; // номер піна, до якого підключений підтягнутий контакт фоторезістора
const byte ntc_pin = 12; // номер піна, до якого підключений вихід термодатчика
const byte lightRes = 10; // роздільна здатність АЦП при вимірюванні освітленості
const byte temperatureRes = 7; // роздільна здатність АЦП при вимірюванні температури
const int ldr_min = 8, ldr_max = 1016; // нижня і верхня межа зчитаних значень освітленості для відображення
const int ntc_min = -24, ntc_max = 80; // нижня і верхня межа температури для відображення
byte last_resolution = 0; // останнє виставлене значення роздільної здатності
void setup() {
for (byte i = 0; i < 8; i++) {
pinMode(led_pins[i], OUTPUT); // встановлення пінів світлодіодів як виходів
}
pinMode(switch_pin, INPUT_PULLUP); // встановлення піна діп-перемикача як входу з підтягненням до живлення
pinMode(ldr_pin, INPUT); // встановлення піна фоторезистора як входу
pinMode(ntc_pin, INPUT); // встановлення піна термодатчика як входу
}
void loop() {
if (readSwitch()) {
analogReadResolution(lightRes);
double val = readLdr(); // зчитування відносної освітленості
setLedScale(int(8 * val)); // увімкнення світлодіодів
}
else { // якщо перемикач не увімкнений
analogReadResolution(temperatureRes);
double temp = readNtc(); // зчитування температури
setLedScale(int(8 * (temp - ntc_min)/(ntc_max - ntc_min))); // увімкнення світлодіодів
}
}
////////////////////////////////////// readSwitch /////////////////////////////////////
// Зчитування значення перемикача з заданого піна
// Результат readSwitch: логічне значення на перемикачі.
///////////////////////////////////////////////////////////////////////////////////////
bool readSwitch() {
return !digitalRead(switch_pin);
}
/////////////////////////////////////// readLdr ///////////////////////////////////////
// Зчитування значення освітленості з фоторезистора на заданому піні
// Результат readLdr: відносне значення з плаваючою крапкою (0.0 - 1.0)
// яке показує освітленість відносно встановлених
// мінімальної і максимальної меж сигналу елементу.
///////////////////////////////////////////////////////////////////////////////////////
double readLdr() {
int val = analogRead(ldr_pin);
// відносне значення на вході = (поточне - min) / (max - min)
// фінальне = 1 - відносне, бо при збільшенні освітленості зменшується
// опір фоторезистора, а отже і зменшується падіння напруги на ньому
return (1-double (val-ldr_min)/(ldr_max-ldr_min));
}
/////////////////////////////////////// readNtc ///////////////////////////////////////
// Зчитування значення температури з термодатчика на заданому піні
// Результат readNtc: значення з плаваючою крапкою показів температури
// давача, у градусах цельсія, розраховане за
// характеристичними даними давача.
///////////////////////////////////////////////////////////////////////////////////////
double readNtc() {
int analogValue = analogRead(ntc_pin);
double celsius = 1 / (log(1 / ((pow(2.,temperatureRes)-1) / analogValue - 1)) / 3950 + 1.0 / 298.15) - 273.15;
return celsius;
}
///////////////////////////////////// setLedScale /////////////////////////////////////
// Увімкнення потрібної кількості світлодіодів, знизу догори
// Вхід: n - число світлодіодів для увімкнення
///////////////////////////////////////////////////////////////////////////////////////
void setLedScale(int n) {
for (byte i = 0; i < 8; i++) {
// встановлення значення світлодіодів відповідно заданому числу
digitalWrite(led_pins[i], i < n);
}
}