#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Definicje makr dla operacji na bitach
#ifndef _BV
#define _BV(bit) (1 << (bit))
#endif
#ifndef sbi
#define sbi(reg, bit) reg |= (_BV(bit))
#endif
#ifndef cbi
#define cbi(reg, bit) reg &= ~(_BV(bit))
#endif
#ifndef tbi
#define tbi(reg, bit) reg ^= (_BV(bit))
#endif
// Inicjalizacja wyświetlacza LCD z adresem I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);
void ADC_init() {
sbi(ADMUX, REFS0);
cbi(ADMUX, REFS1);
sbi(ADCSRA, ADEN);
sbi(ADCSRA, ADPS2);
sbi(ADCSRA, ADPS1);
sbi(ADCSRA, ADPS0);
cbi(ADMUX, MUX0);
cbi(ADMUX, MUX1);
cbi(ADMUX, MUX2);
cbi(ADMUX, MUX3);
}
uint16_t ADC_10bit() {
sbi(ADCSRA, ADSC);
while (ADCSRA & _BV(ADSC)); // Czekaj na zakończenie konwersji
return ADC;
}
uint16_t adcChannel(uint8_t channel) {
ADMUX = (ADMUX & 0xF8) | (channel & 0x07); // Wybór kanału, maskowanie nieistotnych bitów
sbi(ADCSRA, ADSC); // Start konwersji
while (ADCSRA & _BV(ADSC)); // Czekaj na zakończenie konwersji
return ADC; // Zwróć wynik konwersji
}
int main() {
init();
sbi(DDRD,PD7);; // Ustawienie pinu 7 na portu D jako wyjście
Wire.begin();
lcd.init();
lcd.backlight();
ADC_init();
while (1) {
uint16_t lightLevel = adcChannel(1); // Odczyt z fotorezystora
uint16_t voltageLevel = adcChannel(0); // Odczyt z potencjometru
float voltage = voltageLevel * 5.0 / 1023; // Przeliczenie na napięcie
lcd.setCursor(0, 0);
lcd.print("V: ");
lcd.print(voltage, 2); // Dwa miejsca po przecinku
lcd.print("V L: ");
lcd.print(lightLevel);
for (int i = 0; i < (4 - String(voltageLevel).length()); i++) {
lcd.print(" ");
}
static bool ledState = false;
int hysteresis = 25;
if (!ledState && lightLevel < voltageLevel - hysteresis) {
ledState = true;
PORTD |= (1 << PD7); // Włączenie LED
lcd.setCursor(0, 1);
lcd.print("LED ON ");
} else if (ledState && lightLevel > voltageLevel + hysteresis) {
ledState = false;
PORTD &= ~(1 << PD7); // Wyłączenie LED
lcd.setCursor(0, 1);
lcd.print("LED OFF ");
}
delay(500);
}
return 0;
}