#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Servo.h>
// LCD nastaveni
LiquidCrystal_I2C lcd1(0x27, 20, 4);
LiquidCrystal_I2C lcd2(0x28, 20, 4);
// DS18B20 nastaveni
#define ONE_WIRE_BUS 11
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define ONE_WIRE_BUS2 12
OneWire oneWire2(ONE_WIRE_BUS2);
DallasTemperature sensors2(&oneWire2);
// Servo nastaveni
Servo myservo;
#define SERVO_PIN 9
Servo myservo2;
#define SERVO_PIN2 10
// Rotacni enkoder nastaveni
#define ENCODER_CLK 4
#define ENCODER_DT 3
#define ENCODER_SW 2
#define ENCODER2_CLK 7
#define ENCODER2_DT 6
#define ENCODER2_SW 5
bool menuOption = 0; // prepinani menu na displeji
float temperature = 24; // promenna pro nacteni teploty na displeji
float lastTemperature = 0.0; // promenna pro prepsani displeje pri zmene teploty
int angle = 0; // promenna pro uhel serva
float minTemp = 50.0; // promenna pro minimalni rozsah teploty
float maxTemp = 70.0; // promenna pro minimalni rozsah teploty
// promenne pro otaceni rotacniho enkoderu
int currentStateCLK;
int lastStateCLK;
unsigned long lastButtonPress = 0; // promenna pro zmacknuti cudliku na enkoderu
bool menuOption2 = 0; // prepinani menu na displeji 2
float temperature2 = 24; // promenna pro nacteni teploty na displeji 2
float lastTemperature2 = 0.0; // promenna pro prepsani displeje 2 pri zmene teploty
int angle2 = 0; // promenna pro uhel serva 2
float minTemp2 = 50.0; // promenna pro minimalni rozsah teploty 2
float maxTemp2 = 70.0; // promenna pro minimalni rozsah teploty 2
// promenne pro otaceni rotacniho enkoderu 2
int currentStateCLK2;
int lastStateCLK2;
unsigned long lastButtonPress2 = 0; // promenna pro zmacknuti cudliku na enkoderu
unsigned long dsread = 0; // promenna pro cteni cidla co 3 sekundy
// symbol stupne
byte degreeSymbol[8] = {
0b00111,
0b00101,
0b00111,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000
};
void setup() {
// Nastaveni enkoderu jako input
pinMode(ENCODER_CLK, INPUT);
pinMode(ENCODER_DT, INPUT);
pinMode(ENCODER_SW, INPUT_PULLUP);
pinMode(ENCODER2_CLK, INPUT);
pinMode(ENCODER2_DT, INPUT);
pinMode(ENCODER2_SW, INPUT_PULLUP);
// Precteni aktualniho stavu enkoderu
lastStateCLK = digitalRead(ENCODER_CLK);
lastStateCLK2 = digitalRead(ENCODER2_CLK);
// Inicializace LCD
lcd1.init();
lcd2.init();
lcd1.backlight();
lcd2.backlight();
// Vytvoreni znaku pro stupne v pameti
lcd1.createChar(0, degreeSymbol);
lcd2.createChar(0, degreeSymbol);
// Inicializace teplotniho cidla
sensors.begin();
sensors2.begin();
// Inicializace serva
myservo.attach(SERVO_PIN);
myservo.attach(SERVO_PIN2);
// Prvni cteni z cidel
sensors.requestTemperatures();
temperature = sensors.getTempCByIndex(0);
sensors2.requestTemperatures();
temperature2 = sensors2.getTempCByIndex(0);
updateDisplay1();
updateDisplay2();
Serial.begin(9600);
}
void loop() {
// Cteni z cidla co 5 sekund
if (dsread + 5000 < millis()) {
sensors.requestTemperatures();
temperature = sensors.getTempCByIndex(0);
sensors2.requestTemperatures();
temperature2 = sensors2.getTempCByIndex(0);
dsread = millis();
Serial.println("read");
}
// Premapovani rozsahu cidla na rozsah serva
angle = map(temperature, minTemp, maxTemp, 0, 90);
angle = constrain(angle, 0, 90);
myservo.write(angle);
// Premapovani rozsahu cidla 2 na rozsah serva 2
angle2 = map(temperature2, minTemp2, maxTemp2, 0, 90);
angle2 = constrain(angle2, 0, 90);
myservo2.write(angle2);
// Pokud se hodnota teploty zmenila, aktualizuj displej
if (temperature != lastTemperature)
updateDisplay1();
if (temperature2 != lastTemperature2)
updateDisplay2();
// Precti enkoder a pokud se zmenil uprav promennou dle aktualniho menu
currentStateCLK = digitalRead(ENCODER_CLK);
if (currentStateCLK == 1 && currentStateCLK != lastStateCLK) {
// na kterou stranu se enkoder pohnul:
if (digitalRead(ENCODER_DT) != currentStateCLK) {
if (!menuOption) minTemp = minTemp - 0.5;
else maxTemp = maxTemp - 0.5;
} else {
if (!menuOption) minTemp = minTemp + 0.5;
else maxTemp = maxTemp + 0.5;
}
// akutalizuj displej
updateDisplay1();
}
// Zapamatuj si aktualni stav enkoderu
lastStateCLK = currentStateCLK;
// Precti enkoder 2 a pokud se zmenil uprav promennou dle aktualniho menu
currentStateCLK2 = digitalRead(ENCODER2_CLK);
if (currentStateCLK2 == 1 && currentStateCLK2 != lastStateCLK2) {
// na kterou stranu se enkoder 2 pohnul:
if (digitalRead(ENCODER2_DT) != currentStateCLK2) {
if (!menuOption2) minTemp2 = minTemp2 - 0.5;
else maxTemp2 = maxTemp2 - 0.5;
} else {
if (!menuOption2) minTemp2 = minTemp2 + 0.5;
else maxTemp2 = maxTemp2 + 0.5;
}
// akutalizuj displej
updateDisplay2();
}
// Zapamatuj si aktualni stav enkoderu
lastStateCLK2 = currentStateCLK2;
// Precti aktualni stav tlacitka
int btnState = digitalRead(ENCODER_SW);
// Pokud je zmacknuto a nebylo zmacknuti zaregistrovano v poslednich 50 ms, proved zmenu menu a aktualizuj displej
if (btnState == LOW) {
if (millis() - lastButtonPress > 50) {
menuOption = !menuOption;
updateDisplay1();
}
// Zapamatuj si kdy bylo tlacitko zmacknuto
lastButtonPress = millis();
}
// Precti aktualni stav tlacitka
int btnState2 = digitalRead(ENCODER2_SW);
// Pokud je zmacknuto a nebylo zmacknuti zaregistrovano v poslednich 50 ms, proved zmenu menu a aktualizuj displej
if (btnState2 == LOW) {
if (millis() - lastButtonPress2 > 50) {
menuOption2 = !menuOption2;
updateDisplay2();
}
// Zapamatuj si kdy bylo tlacitko zmacknuto
lastButtonPress2 = millis();
}
// Delay pro debouncing enkoderu
delay(1);
}
// Funkce pro napsani udaju na displej vcetne akutalniho menu
void updateDisplay1() {
Serial.println("write1");
lastTemperature = temperature;
lcd1.setCursor(0, 0);
lcd1.print("Teplota: ");
lcd1.print(temperature, 1);
lcd1.write(byte(0));
lcd1.print("C ");
lcd1.setCursor(0, 1);
lcd1.print("Uhel serva: ");
lcd1.print(angle, 1);
lcd1.write(byte(0));
lcd1.print(" ");
lcd1.setCursor(0, 2);
if (menuOption == 0) lcd1.print(">Min: ");
else lcd1.print(" Min: ");
lcd1.print(minTemp, 1);
lcd1.write(byte(0));
lcd1.print("C ");
lcd1.setCursor(0, 3);
if (menuOption == 1) lcd1.print(">Max: ");
else lcd1.print(" Max: ");
lcd1.print(maxTemp, 1);
lcd1.write(byte(0));
lcd1.print("C ");
}
// Funkce pro napsani udaju na druhy displej vcetne akutalniho menu
void updateDisplay2() {
Serial.println("write2");
lastTemperature2 = temperature2;
lcd2.setCursor(0, 0);
lcd2.print("Teplota: ");
lcd2.print(temperature2, 1);
lcd2.write(byte(0));
lcd2.print("C ");
lcd2.setCursor(0, 1);
lcd2.print("Uhel serva: ");
lcd2.print(angle2, 1);
lcd2.write(byte(0));
lcd2.print(" ");
lcd2.setCursor(0, 2);
if (menuOption2 == 0) lcd2.print(">Min: ");
else lcd2.print(" Min: ");
lcd2.print(minTemp2, 1);
lcd2.write(byte(0));
lcd2.print("C ");
lcd2.setCursor(0, 3);
if (menuOption2 == 1) lcd2.print(">Max: ");
else lcd2.print(" Max: ");
lcd2.print(maxTemp2, 1);
lcd2.write(byte(0));
lcd2.print("C ");
}
Loading
ds18b20
ds18b20
Loading
ds18b20
ds18b20