Первичные часы
- Войдите на сайт для отправки комментариев
Пнд, 18/12/2017 - 01:33
Приветствую. Приволокли мне пару вторичных школьных часов. Решил запустить их. Сперва собрал и проверил обычные часы реального времени на DS3231 и дисплее 1602. Теперь дело за управлением шаговым мотором. Нужно чтоб в начале каждой четной минуты срабатывало реле1 на 1 сек, а в начале нечетной - реле2. Для этого делается операция AND минутного таймера со значением 0x01,если в результате 0,то включаем чётное реле,если 1,то нечётное.
Подскажите, как реализовать этот блок. Программист с меня хреновый.
#include <DS3231.h>
#include <Wire.h>
#include <LiquidCrystal.h>
#define DS3231_ADDRESS 0x68
LiquidCrystal lcd(12,11,5,4,3,2);
int button_pin = 6;
int buttonState = 0;
int led = 13;
int led1 = 8;
byte set_second = 0;
byte set_minute = 34;
byte set_hour = 23;
byte set_day = 1;
byte set_date = 14;
byte set_month = 12;
byte set_year = 17;
byte read_second;
byte read_minute;
byte read_hour;
byte read_day;
byte read_date;
byte read_month;
byte read_year;
byte bcd_to_Dec(byte val)
{
return( (val/16*10) + (val%16) );
}
byte dec_to_bcd(byte val)
{
return( (val/10*16) + (val%10) );
}
void setup() {
pinMode(9, OUTPUT); // выход на контрастность lcd
analogWrite(9, 100); // устанавливаем ШИМ выход
pinMode(led, OUTPUT); // устанавливаем вывод 13 как выход
pinMode(led1, OUTPUT); // устанавливаем вывод 8 как выход
Wire.begin();
pinMode(button_pin, INPUT);
buttonState = digitalRead(button_pin);
if (buttonState == HIGH) {
Wire.beginTransmission(DS3231_ADDRESS);
Wire.write(0);
Wire.write(dec_to_bcd(set_second));
Wire.write(dec_to_bcd(set_minute));
Wire.write(dec_to_bcd(set_hour));
Wire.write(dec_to_bcd(set_day));
Wire.write(dec_to_bcd(set_date));
Wire.write(dec_to_bcd(set_month));
Wire.write(dec_to_bcd(set_year));
Wire.endTransmission();
} else {}
lcd.begin(16,2);
lcd.clear();
}
void loop() {
Wire.beginTransmission(DS3231_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_ADDRESS, 7);
read_second = bcd_to_Dec(Wire.read());
read_minute = bcd_to_Dec(Wire.read());
read_hour = bcd_to_Dec(Wire.read());
read_day = bcd_to_Dec(Wire.read());
read_date = bcd_to_Dec(Wire.read());
read_month = bcd_to_Dec(Wire.read());
read_year = bcd_to_Dec(Wire.read());
lcd.clear();
lcd.setCursor(0,0);
if (read_hour<10)
{
lcd.print('0');
}
lcd.print(read_hour);
lcd.print(':');
if (read_minute<10)
{
lcd.print('0');
}
lcd.print(read_minute);
lcd.print(':');
if (read_second<10)
{
lcd.print('0');
}
lcd.print(read_second);
lcd.setCursor(0,1);
lcd.print(read_date);
lcd.print('/');
lcd.print(read_month);
lcd.print('/');
lcd.print(read_year);
delay(500);
}
if((read_minute00)digitalWrite(led,HIGH)&&(read_minute01)digitalWrite(led1,HIGH);
delay(500);
}
А зачем rtc для вторичных часов? Если там тупо требуется раз в минуту импульс давать, для этого и миллис хватит, хотя с точностью хода не уверен, какую погрешность кварц даёт.
чтобы часы шли, нужно менять полярность на моторе.
https://hsto.org/files/369/6d1/b12/3696d1b120b74501ab13b2ec9448b676.gif
попробовал такой вариант, не компилируется, ошибка в строке if((read_minute00()&0x01)==0)
#include <DS3231.h> #include <Wire.h> #include <LiquidCrystal.h> #define DS3231_ADDRESS 0x68 LiquidCrystal lcd(12,11,5,4,3,2); int button_pin = 6; int buttonState = 0; int led = 13; int led1 = 8; byte set_second = 0; byte set_minute = 34; byte set_hour = 23; byte set_day = 1; byte set_date = 14; byte set_month = 12; byte set_year = 17; byte read_second; byte read_minute; byte read_hour; byte read_day; byte read_date; byte read_month; byte read_year; byte bcd_to_Dec(byte val) { return( (val/16*10) + (val%16) ); } byte dec_to_bcd(byte val) { return( (val/10*16) + (val%10) ); } void setup() { pinMode(9, OUTPUT); // выход на контрастность lcd analogWrite(9, 100); // устанавливаем ШИМ выход pinMode(led, OUTPUT); // устанавливаем вывод 13 как выход pinMode(led1, OUTPUT); // устанавливаем вывод 8 как выход Wire.begin(); pinMode(button_pin, INPUT); buttonState = digitalRead(button_pin); if (buttonState == HIGH) { Wire.beginTransmission(DS3231_ADDRESS); Wire.write(0); Wire.write(dec_to_bcd(set_second)); Wire.write(dec_to_bcd(set_minute)); Wire.write(dec_to_bcd(set_hour)); Wire.write(dec_to_bcd(set_day)); Wire.write(dec_to_bcd(set_date)); Wire.write(dec_to_bcd(set_month)); Wire.write(dec_to_bcd(set_year)); Wire.endTransmission(); } else {} lcd.begin(16,2); lcd.clear(); } void loop() { Wire.beginTransmission(DS3231_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_ADDRESS, 7); read_second = bcd_to_Dec(Wire.read()); read_minute = bcd_to_Dec(Wire.read()); read_hour = bcd_to_Dec(Wire.read()); read_day = bcd_to_Dec(Wire.read()); read_date = bcd_to_Dec(Wire.read()); read_month = bcd_to_Dec(Wire.read()); read_year = bcd_to_Dec(Wire.read()); lcd.clear(); lcd.setCursor(0,0); if (read_hour<10) { lcd.print('0'); } lcd.print(read_hour); lcd.print(':'); if (read_minute<10) { lcd.print('0'); } lcd.print(read_minute); lcd.print(':'); if (read_second<10) { lcd.print('0'); } lcd.print(read_second); lcd.setCursor(0,1); lcd.print(read_date); lcd.print('/'); lcd.print(read_month); lcd.print('/'); lcd.print(read_year); delay(500); } if((read_minute00()&0x01)==0) {digitalWrite(led,HIGH); } else {digitalWrite(led1,HIGH); }Хинт: каждая чётная минута - это когда значение минут не даёт остатка от деления на 2. Каждая нечётная - всё остальное:
0%2 == 0
1%2 == 1
2%2 == 0
3%2 == 1
и т.д.
Код:
if(currentMinute%2) { // нечётная минута } else { // чётная минута }if(currentMinute%2) { digitalWrite(led,HIGH); } else { digitalWrite(led1,HIGH); delay(500); }В этом варианте ничего не происходит.
полный код
#include <DS3231.h> #include <Wire.h> #include <LiquidCrystal.h> #define DS3231_ADDRESS 0x68 LiquidCrystal lcd(12,11,5,4,3,2); int button_pin = 6; int buttonState = 0; int led = 13; int led1 = 8; byte set_second = 0; byte set_minute = 34; byte set_hour = 23; byte set_day = 1; byte set_date = 14; byte set_month = 12; byte set_year = 17; byte read_second; byte read_minute; byte read_hour; byte read_day; byte read_date; byte read_month; byte read_year; byte current_second; byte currentMinute; byte bcd_to_Dec(byte val) { return( (val/16*10) + (val%16) ); } byte dec_to_bcd(byte val) { return( (val/10*16) + (val%10) ); } void setup() { pinMode(9, OUTPUT); // выход на контрастность lcd analogWrite(9, 100); // устанавливаем ШИМ выход pinMode(led, OUTPUT); // устанавливаем вывод 13 как выход pinMode(led1, OUTPUT); // устанавливаем вывод 8 как выход Wire.begin(); pinMode(button_pin, INPUT); buttonState = digitalRead(button_pin); if (buttonState == HIGH) { Wire.beginTransmission(DS3231_ADDRESS); Wire.write(0); Wire.write(dec_to_bcd(set_second)); Wire.write(dec_to_bcd(set_minute)); Wire.write(dec_to_bcd(set_hour)); Wire.write(dec_to_bcd(set_day)); Wire.write(dec_to_bcd(set_date)); Wire.write(dec_to_bcd(set_month)); Wire.write(dec_to_bcd(set_year)); Wire.endTransmission(); } else {} lcd.begin(16,2); lcd.clear(); } void loop() { Wire.beginTransmission(DS3231_ADDRESS); Wire.write(0); // set DS3231 register pointer to 00h Wire.endTransmission(); Wire.requestFrom(DS3231_ADDRESS, 7); read_second = bcd_to_Dec(Wire.read()); read_minute = bcd_to_Dec(Wire.read()); read_hour = bcd_to_Dec(Wire.read()); read_day = bcd_to_Dec(Wire.read()); read_date = bcd_to_Dec(Wire.read()); read_month = bcd_to_Dec(Wire.read()); read_year = bcd_to_Dec(Wire.read()); lcd.clear(); lcd.setCursor(0,0); if (read_hour<10) { lcd.print('0'); } lcd.print(read_hour); lcd.print(':'); if (read_minute<10) { lcd.print('0'); } lcd.print(read_minute); lcd.print(':'); if (read_second<10) { lcd.print('0'); } lcd.print(read_second); lcd.setCursor(0,1); lcd.print(read_date); lcd.print('/'); lcd.print(read_month); lcd.print('/'); lcd.print(read_year); delay(500); if(currentMinute%2) { digitalWrite(led,HIGH); } else { digitalWrite(led1,HIGH); } }Скетч загружается, часы работают, светодиоды не моргают.
Между строкой 72 и 73 НАДО проверять, есть ли в приёмном буфере Wire нужное кол-во байты, см. Wire.available. А то получается - отослали письмо, и тут же читаем ответ, а пришёл он или нет - всем пофик.
Сам метод Wire.requestFrom также возвращает, сколько байт получено с девайса - у вас это никак не анализируется.