Всем привет, столкнулся вот с такой проблемой таймер реального времени ds1307 выдает данные 165/165/165 45:165:85 на выходе, какое-то время все работало отлияно без проблем. Вот мой скетч
#include <_I2C.h>
#include <Wire.h>
#include <Servo.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo myservo;
const int servoPin = 13; // Пин, к которому подключен сервопривод
const int servoOpenAngle = 180; // Угол, на который открывается сервопривод
const int servoCloseAngle = 10; // Угол, в который закрывается сервопривод
const int buttonPinSetTime = 9; // Пин для кнопки установки времени
const int buttonPinServo = 10; // Пин для кнопки управления сервоприводом
const int buttonPinServoDelay = 8; // Пин для кнопки установки времени до открытия сервопривода
const int ledPin = 12; // Пин для встроенного светодиода (для отладки)
const int mySDA = 4; // Pin for SDA
const int mySCL = 5; // Pin for SCL
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
byte lastMinute = 0; // Переменная для хранения предыдущей минуты
bool servoActive = false; // Флаг, указывающий, активен ли сервопривод в данный момент
bool setServoDelayMode = false; // Флаг, указывающий, находимся ли в режиме установки задержки перед открытием сервопривода
unsigned long lastServoActionTime = 0; // Переменная для хранения времени последнего действия сервопривода
int servoDelayMinutes = 1; // Переменная для хранения времени задержки перед открытием сервопривода (установим по умолчанию 1 минута)
unsigned long timeToNextServo = 0;
enum SettingState { DAY, MONTH, YEAR, HOUR, MINUTE, SECOND };
SettingState currentState = DAY;
#define SDA_LOW() (digitalWrite(mySDA, LOW))
#define SDA_HIGH() (digitalWrite(mySDA, HIGH))
#define SCL_LOW() (digitalWrite(mySCL, LOW))
#define SCL_HIGH() (digitalWrite(mySCL, HIGH))
#define SDA_READ() (digitalRead(mySDA))
void resetRTC() {
pinMode(mySDA, INPUT_PULLUP);
pinMode(mySCL, INPUT_PULLUP);
do {
SDA_HIGH();
SCL_HIGH();
if (SDA_READ()) {
SDA_LOW();
delay(1); // Short delay to ensure the signal is set
SDA_HIGH();
}
SCL_LOW();
delay(1); // Short delay to ensure the signal is set
} while (SDA_READ() == 0);
}
void setup() {
myservo.attach(servoPin);
myservo.write(servoCloseAngle); // Установка сервопривода в начальное положение
pinMode(buttonPinSetTime, INPUT_PULLUP);
pinMode(buttonPinServo, INPUT_PULLUP);
pinMode(buttonPinServoDelay, INPUT_PULLUP);
pinMode(ledPin, OUTPUT);
lcd.begin(16, 2);
Wire.begin();
resetRTC(); // Reset the RTC at the start
}
void loop() {
unsigned long currentTime = millis(); // Получаем текущее время
lcd.backlight();
// Получаем данные от таймера DS1307
getDS1307Time();
// Отображаем данные на LCD
displayTime();
// Проверяем, если прошла новая минута, то активируем сервопривод
if (!servoActive && (currentTime - lastServoActionTime) >= (servoDelayMinutes * 60000)) {
activateServo();
}
// Обновляем время до следующего открытия сервопривода
if (servoDelayMinutes > 0 && !servoActive) {
timeToNextServo = (servoDelayMinutes * 60000) - (currentTime - lastServoActionTime);
}
// Проверяем нажатие кнопки для установки времени
if (digitalRead(buttonPinSetTime) == LOW && !servoActive) {
setCurrentState(HOUR);
setNewDateTime();
}
// Проверяем нажатие кнопки для управления сервоприводом
if (digitalRead(buttonPinServo) == LOW) {
toggleServo();
} else {
// Если кнопка отпущена, закрываем сервопривод
myservo.write(servoCloseAngle);
servoActive = false; // Сбрасываем флаг активации сервопривода
}
// Проверяем нажатие кнопки для установки времени до открытия сервопривода
if (digitalRead(buttonPinServoDelay) == LOW && !servoActive) {
setServoDelayMode = true;
setServoDelayTime();
}
delay(100); // Небольшая задержка для стабильной работы
}
// Функция для установки текущего состояния настройки
void setCurrentState(SettingState state) {
currentState = state;
}
// Функция для настройки новой даты и времени
void setNewDateTime(){
lcd.clear();
switch (currentState) {
case HOUR:
lcd.print("Set Hour:");
break;
case MINUTE:
lcd.print("Set Minute:");
break;
case SECOND:
lcd.print("Set Second:");
break;
}
lcd.setCursor(0, 1);
lcd.print("Press to adjust");
while (digitalRead(buttonPinSetTime) == LOW) {
switch (currentState) {
case HOUR:
adjustValue(hour, 0, 23);
break;
case MINUTE:
adjustValue(minute, 0, 59);
break;
case SECOND:
adjustValue(second, 0, 59);
break;
}
lcd.setCursor(0, 1);
switch (currentState) {
case HOUR:
printDigits(hour);
break;
case MINUTE:
printDigits(minute);
break;
case SECOND:
printDigits(second);
break;
}
delay(200);
}
// Сохранение новой даты и времени в DS1307
Wire.beginTransmission(0x68);
switch (currentState) {
case HOUR:
Wire.write(2); // Адрес для часов
Wire.write(decToBcd(hour)); // Часы
break;
case MINUTE:
Wire.write(1); // Адрес для минут
Wire.write(decToBcd(minute)); // Минуты
break;
case SECOND:
Wire.write(0); // Адрес для секунд
Wire.write(decToBcd(second)); // Секунды
break;
}
Wire.endTransmission();
lcd.clear();
lcd.print("Updated!");
delay(2000);
}
// Функция для установки времени задержки перед открытием сервопривода
void setServoDelayTime() {
lcd.clear();
lcd.print("Set Delay (min):");
lcd.setCursor(0, 1);
lcd.print(servoDelayMinutes);
lcd.print(" min");
while (digitalRead(buttonPinServoDelay) == LOW) {
adjustServoDelay();
lcd.setCursor(0, 1);
lcd.print(servoDelayMinutes);
lcd.print(" min");
delay(200);
}
lcd.clear();
}
// Функция для увеличения значения времени задержки
void adjustServoDelay() {
servoDelayMinutes++;
if (servoDelayMinutes > 480) {
servoDelayMinutes = 0;
}
}
// Функция для получения данных от таймера DS1307
void getDS1307Time() {
Wire.beginTransmission(0x68);
Wire.write(0); // Указываем начальный адрес данных
Wire.endTransmission();
Wire.requestFrom(0x68, 7); // Запрашиваем 7 байт данных
second = bcdToDec(Wire.read() & 0x7F); // Секунды
minute = bcdToDec(Wire.read()); // Минуты
hour = bcdToDec(Wire.read() & 0x3F); // Часы (в 24-часовом формате)
dayOfWeek = bcdToDec(Wire.read()); // День недели
dayOfMonth = bcdToDec(Wire.read()); // День месяца
month = bcdToDec(Wire.read()); // Месяц
year = bcdToDec(Wire.read()); // Год
// Отладочное сообщение для проверки получения времени
Serial.print("Time: ");
Serial.print(hour);
Serial.print(":");
Serial.print(minute);
Serial.print(":");
Serial.println(second);
}
// Функция для отображения данных на LCD
void displayTime() {
lcd.setCursor(0, 0);
lcd.print("Time: ");
printDigits(hour);
lcd.print(":");
printDigits(minute);
lcd.print(":");
printDigits(second);
lcd.setCursor(0, 1);
lcd.print("Delay: ");
lcd.print(servoDelayMinutes);
lcd.print("m ");
if (!servoActive) {
unsigned long secondsLeft = timeToNextServo / 1000;
unsigned int minutesLeft = secondsLeft / 60;
secondsLeft = secondsLeft % 60;
lcd.print(minutesLeft);
lcd.print("m ");
printDigits(secondsLeft); // Используем функцию printDigits для сек
lcd.print("s");
} else {
lcd.print("Active");
}
}
// Функция для активации сервопривода
void activateServo() {
if (servoDelayMinutes > 0 && (millis() - lastServoActionTime) >= (servoDelayMinutes * 60000)) {
servoActive = true;
myservo.write(servoOpenAngle); // Открываем сервопривод
delay(10000); // Задержка для стабилизации положения
myservo.write(servoCloseAngle); // Закрываем сервопривод
lastServoActionTime = millis(); // Обновляем время последнего действия сервопривода
timeToNextServo = servoDelayMinutes * 60000; // Сбрасываем время до следующего открытия сервопривода
// Возвращаем сервопривод на исходное положение только если он был открыт
if (digitalRead(buttonPinServo) == LOW) {
myservo.write(servoCloseAngle);
servoActive = false; // Устанавливаем флаг активации сервопривода в false
}
}
}
// Функция для управления сервоприводом
void resetServoTimer() {
lastServoActionTime = millis(); // Сброс времени последнего действия сервопривода
timeToNextServo = servoDelayMinutes * 60000; // Сбрасываем таймер
}
void toggleServo() {
// Если кнопка нажата и сервопривод не активен, то запускаем таймер
if (digitalRead(buttonPinServo) == LOW && !servoActive) {
myservo.write(servoOpenAngle); // Открываем сервопривод
servoActive = true; // Устанавливаем флаг активации сервопривода
resetServoTimer(); // Сбрасываем таймер
lcd.clear();
}
// Если кнопка отпущена, закрываем сервопривод и сбрасываем флаг активации сервопривода
if (digitalRead(buttonPinServo) == HIGH) {
myservo.write(servoCloseAngle); // Закрываем сервопривод
servoActive = false;
resetServoTimer(); // Сбрасываем таймер
}
}
// Функция для преобразования двоично-десятичного кода в десятичное число
byte bcdToDec(byte val) {
return ((val / 16 * 10) + (val % 16));
}
// Функция для преобразования десятичного числа в двоично-десятичный код
byte decToBcd(byte val) {
return ((val / 10 * 16) + (val % 10));
}
// Функция для вывода числа с ведущими нулями, если оно меньше 10
void printDigits(byte digits) {
if (digits < 10) {
lcd.print("0");
}
lcd.print(digits);
}
// Функция для увеличения значения с ограничениями
void adjustValue(byte &value, byte minVal, byte maxVal) {
value++;
if (value > maxVal) {
value = minVal;
}
}
Может знаете в чем проблема