#include <Wire.h> // I2C
#include <LiquidCrystal_I2C.h> // подключаем библиотеку для работы с LCD дисплеем
#include <iarduino_RTC.h> // подключаем библиотеку для работы с RTC модулем
LiquidCrystal_I2C lcd(0x27,16,2); // объявляем переменную для работы с LCD дисплеем, указывая параметры дисплея (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2)
iarduino_RTC time(RTC_DS1307); // объявляем переменную для работы с RTC модулем, указывая название модуля
// Объявляем переменные и константы:
const uint8_t PIN_button_SET = 10; // указываем номер вывода arduino, к которому подключена кнопка SET
const uint8_t PIN_button_UP = 9; // указываем номер вывода arduino, к которому подключена кнопка UP
const uint8_t PIN_button_DOWN = 8; // указываем номер вывода arduino, к которому подключена кнопка DOWN
uint8_t VAR_mode_SHOW = 1; // режим вывода: 1-время 2-дата
uint8_t VAR_mode_SET = 0; // режим установки времени: 0-нет 1-сек 2-мин 3-час 4-день 5-мес 6-год 7-день_недели
#include <DallasTemperature.h>
#include <OneWire.h>
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея, в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях
// SSD1306, подключенного к I2C (выводы SDA, SCL)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
#define button1 9 // Кнопка B1 подключена к контакту Arduino 9
#define button2 8 // Кнопка B2 подключена к контакту Arduino 8
//подключил датчики температуры ds18b20
#define ONE_WIRE_BUS_1 7 // к входу d7
#define ONE_WIRE_BUS_2 6 // к входу d6
OneWire oneWire_in(ONE_WIRE_BUS_1);
OneWire oneWire_out(ONE_WIRE_BUS_2);
DallasTemperature sensors(&oneWire_in);
DallasTemperature sensors_out(&oneWire_out);
void setup(void) {
Serial.begin(9600);
Wire.begin();
pinMode(button1, INPUT_PULLUP);
pinMode(button2, INPUT_PULLUP);
delay(500);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // инициализировать с помощью I2C адресс 0x3C (для 128x64)
// Очистить дисплей.
display.clearDisplay();
display.display();
display.cp437(true);
display.setTextColor(WHITE, BLACK);
//display.drawRect(117, 56, 3, 3, WHITE); // Поставить символ степени ( ° )
//draw_text(0, 56, "Temperatura =", 1);
//draw_text(122, 56, "C", 1);
}
byte i, second, minute, hour, day, date, month, year, Temperatura;
void DS3231_display() {
char Time[] = " : ";
char Calendar[] = " / /20 ";
//char temperature[] = " 00.00";
//char temperature_msb;
// Преобразовать в десятичную
minute = (minute >> 4) * 10 + (minute & 0x0F);
hour = (hour >> 4) * 10 + (hour & 0x0F);
date = (date >> 4) * 10 + (date & 0x0F);
month = (month >> 4) * 10 + (month & 0x0F);
year = (year >> 4) * 10 + (year & 0x0F);
Time[4] = minute % 10 + 48;
Time[3] = minute / 10 + 48;
if (second % 2)
Time[2] = 32;
else
Time[2] = 58;
Time[1] = hour % 10 + 48;
Time[0] = hour / 10 + 48;
Calendar[9] = year % 10 + 48;
Calendar[8] = year / 10 + 48;
Calendar[4] = month % 10 + 48;
Calendar[3] = month / 10 + 48;
Calendar[1] = date % 10 + 48;
Calendar[0] = date / 10 + 48;
//display.clearDisplay();
draw_text(4, 12, Calendar, 2); // Показать дату (формат: дд / мм / гггг)
draw_text(20, 30, Time, 3); // Показать время
if (!digitalRead(button1)) { // Если кнопка B1 нажата
i = 0;
while (!digitalRead(button1)); // Дождитесь отпускания кнопки B1
while (true) {
// Пока кнопка B2 нажата
blink_parameter(); // Вызов функции blink_parameter
if (!digitalRead(button1)) // Если кнопка B1 нажата
break;
}
date = edit(4, 12, date, 2); // Изменить дату
month = edit(40, 12, month, 2); // Изменить month
year = edit(100, 12, year, 2); // Изменить year
hour = edit(20, 30, hour, 3); // Изменить hours
minute = edit(74, 30, minute, 3); // Изменить minutes
// Преобразовать десятичную в BCD
minute = ((minute / 10) << 4) + (minute % 10);
hour = ((hour / 10) << 4) + (hour % 10);
date = ((date / 10) << 4) + (date % 10);
month = ((month / 10) << 4) + (month % 10);
year = ((year / 10) << 4) + (year % 10);
// End conversion
// Записать данные в DS3231 RTC
Wire.beginTransmission(0x68); // Запустите протокол I2C с адресом DS3231
Wire.write(0); // Отправить адрес регистрации
Wire.write(0); // Сбросьте sesonds и запустите генератор
Wire.write(minute); // Запишем минуту
Wire.write(hour); // Запишем hour
Wire.write(day); // Запишем day
Wire.write(date); // Запишем date
Wire.write(month); // Запишем month
Wire.write(year); // Запишем year
Wire.endTransmission(); // Остановите передачу и отпустите шину I2C
delay(200); // Ждем 200ms
}
}
void blink_parameter() {
byte j = 0;
while (j < 10 && digitalRead(button1) && digitalRead(button2)) {
j++;
delay(25);
}
}
byte edit(byte x_pos, byte y_pos, byte parameter, byte text_size) {
char text[3];
sprintf(text, "%02u", parameter);
while (!digitalRead(button1)); // Подождите, пока кнопка B1 отпущена
while (true) {
while (!digitalRead(button2)) { // Если кнопка B2 нажата
parameter++;
if (i == 0 && parameter > 31) // Если date > 31 ==> date = 1
parameter = 1;
if (i == 1 && parameter > 12) // Если month > 12 ==> month = 1
parameter = 1;
if (i == 2 && parameter > 99) // Если year > 99 ==> year = 0
parameter = 0;
if (i == 3 && parameter > 23) // Если hours > 23 ==> hours = 0
parameter = 0;
if (i == 4 && parameter > 59) // Если minutes > 59 ==> minutes = 0
parameter = 0;
sprintf(text, "%02u", parameter);
draw_text(x_pos, y_pos, text, text_size);
delay(200); // Ждем 200ms
}
// display.clearDisplay();
draw_text(x_pos, y_pos, " ", text_size);
blink_parameter();
draw_text(x_pos, y_pos, text, text_size);
blink_parameter();
if (!digitalRead(button1)) { // Если кнопка B1 нажата
i++; // Увеличение «i» для следующего параметра
return parameter; // Вернуть значение параметра и выйти
}
}
}
void draw_text(byte x_pos, byte y_pos, char *text, byte text_size) {
display.setCursor(x_pos, y_pos);
display.setTextSize(text_size);
display.print(utf8rus(text));
display.display();
}
void loop() {
Wire.beginTransmission(0x68); // Запустите протокол I2C с адресом DS3231
Wire.write(0); // Отправить адрес регистрации
Wire.endTransmission(false); // Перезапуск I2C
Wire.requestFrom(0x68, 7); // Запросите 7 байтов от DS3231 и освободите шину I2C
second = Wire.read(); // Считать секунды из регистра 0
minute = Wire.read(); // Считать minuts из регистра 1
hour = Wire.read(); // Считать hour из регистра 2
day = Wire.read(); // Считать day из регистра 3
date = Wire.read(); // Считать date из регистра 4
month = Wire.read(); // Считать month из регистра 5
year = Wire.read(); // Считать year из регистра 6
if (second <= 10 || second >20 ) // выставляем условие показа времени
{DS3231_display(); } //вызов функции отображения времени
else if (second >10 && second <=20 ) // выставляем условие показа температуры
{temp();
} //вызов функции отображения температуры
Serial.println(second);
delay(50); // Ждем 50ms
}
void temp() {
sensors.begin();
sensors.requestTemperatures();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("T room:");
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(19,10);
display.print(sensors.getTempCByIndex(0));
display.display();
Serial.print("T room:");
Serial.println(sensors.getTempCByIndex(0));
delay(5000);
sensors_out.begin();
sensors_out.requestTemperatures();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.print("T street:");
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(19,10);
display.print(sensors_out.getTempCByIndex(0));
display.display();
Serial.print("T street:");
Serial.println(sensors_out.getTempCByIndex(0));
delay(5000);
}
/* Функция перекодировки русских букв из UTF-8 в Win-1251 */
String utf8rus(String source)
{
int i, k;
String target;
unsigned char n;
char m[2] = { '0', '\0' };
k = source.length(); i = 0;
while (i < k) {
n = source[i]; i++;
if (n >= 0xC0) {
switch (n) {
case 0xD0: {
n = source[i]; i++;
if (n == 0x81) {
n = 0xA8;
break;
}
if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
break;
}
case 0xD1: {
n = source[i]; i++;
if (n == 0x91) {
n = 0xB8;
break;
}
if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
break;
}
}
}
m[0] = n; target = target + String(m);
}
return target;
}