А-а-а, значит просто символа ':' нет в тамошнем шрифте (или у него другой код). Можно посмотреть и поковыряться - найти его там. Если хотите, расскажу как.
- но сейчас времени уже нету, не профильная специальность кодить( Хотя и интересно.
Я так по станкам ЧПУ лажу в основном. А вот ардуино это как 2 шаг к STM взял, чтоб можно было доработки всячесские делать так как то что выходит на ардуино уже радует ибо применение есть(для меня)
Нормально отображают, т.е. цифры стоят на своих местах.
Там по ссылке видео ролики... Можно все нюансы увидеть. Я применил DS3231 вот такой
- уменьшил размер тем самым. В даташит вижу, что можно сделать Alarm 2 и автор наглядно сделал Alarm 1 в соответствии с текстом даташит, но я не догоняю, как ... Идею автора я не понимаю до конца с Alarm 1
Может, найдется добрая душа, подскажет ... правильно ли я делаю Alarm 2...
//Subroutine to set alarm 2
void set_alarm2()
{
// flags define what calendar component to be checked against the current time in order
// to trigger the alarm - see datasheet
// A2M2 (minutes) (0 to enable, 1 to disable)
// A2M3 (hour) (0 to enable, 1 to disable)
// A2M4 (day) (0 to enable, 1 to disable)
// DY/DT (dayofweek == 1/dayofmonth == 0)
byte flags[4] = { 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match
// set Alarm2
DS3231_set_a2(wake_MINUTE, wake_HOUR, 0, flags); //Set alarm 2 RTC registers
}
//Subroutine to get alarm 2
void get_alarm2()
{
uint8_t n[3];
uint8_t t[3]; //second,minute,hour,day
uint8_t f[4]; // flags
uint8_t i;
Wire.beginTransmission(DS3231_I2C_ADDR);
Wire.write(DS3231_ALARM2_ADDR);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDR, 3);
for (i = 0; i <= 2; i++) {
n[i] = Wire.read();
f[i] = (n[i] & 0x80) >> 7; // 0x80 -> 128
t[i] = bcdtodec(n[i] & 0x7F); // 0x7F -> 127
}
f[3] = (n[2] & 0x40) >> 6; // 0x40 - 64
t[2] = bcdtodec(n[2] & 0x3F); // 0x3F - 63
wake_MINUTE = t[0];
wake_HOUR = t[1];
}
Попробуйте добавить в начало строки 4 слово volatile. А там посмотрим. Да кстати, прерывание должно приходить раз в минуту, зачем Вы так часто перчатете (200 мс в строке 151). Поставьте там вместо 200, например, 30000ul - полминуты - нормально.
Евгений. все нормально, часы идут точно, проблем нет с подключением- паралельно висит мой скетч, там показывает все ок.
С вашим вариантом не. Тоисть я не могу сказать точно ведь выводить инфу о минутах в скетче нету и я не допишу ибо это же без библиотеки все. "прямыми" командами точно мозгов не хватит.
У меня модуль 3231.
"по-минутное прерывание устанавливаем"- тоисть это делается не один раз? Я думал что подобные установки записываются в регистр один раз.
Получается что оно работает только в вашем скетче?
Ежеминутное прерывание в моём скетче устанавливается функцией EnableMinuteInterrupt. Она вызывается один раз из функции clockInit, а та, в свою очереь, из setup.
символ ':' как-то особо отрабатывает.
я об этом.
фоткать уже не хочу но с этим символом мусор есть как раз между показаниями
А-а-а, значит просто символа ':' нет в тамошнем шрифте (или у него другой код). Можно посмотреть и поковыряться - найти его там. Если хотите, расскажу как.
Спасибо огромное УЖЕ за уделенное внимаение!
- но сейчас времени уже нету, не профильная специальность кодить( Хотя и интересно.
Я так по станкам ЧПУ лажу в основном. А вот ардуино это как 2 шаг к STM взял, чтоб можно было доработки всячесские делать так как то что выходит на ардуино уже радует ибо применение есть(для меня)
ну и вконце темы наверное уже рабочий код, может кто-то тоже будет искать по форуму вывод часов на OLED с нолем и попадет на данную тему.
#include <SPI.h> #include <OLED_I2C.h> // подключение библиотеки для OLED OLED myOLED(9, 10); // подключение дисплея 8 SDA 9 SCK /////////////////////датчик температуры и влажности #include "DHT.h" #define DHTPIN 7 // вывод, к которому подключается датчик #define DHTTYPE DHT22 // DHT 22 (AM2302) DHT dht(DHTPIN, DHTTYPE); ////////////////////////////////////#include <Wire.h> #include "Sodaq_DS3231.h" // подключение часов Uno, Nano A4 (SDA), A5 (SCL) extern uint8_t RusFont[]; // Русский шрифт extern uint8_t SmallFont[]; // маленький шрифт extern uint8_t MediumNumbers[]; //средний шрифт extern uint8_t MegaNumbers[]; extern uint8_t MediumFont[]; extern uint8_t BigNumbers[]; //большой шрифт #define fotorez A0 // фоторезистор с 10 коомным шунтирующим #define vutyazhka 2 // включение вытяжки #define fotorez A1 // включение подсветки через транзистор с рампса //DateTime dt(2017, 8, 28, 11, 42, 0, 1); // здесь установить дату и время год.месяц.день.часы.минуты.секунды.день int houre = 0;// переменная для часов int minutu = 0;// переменная для минут char buffer[6]; // масив для строки (для двух символов, на один идет 3) void setup() { delay(300); Serial.begin(9600); // Wire.begin(); rtc.begin(); myOLED.begin(); myOLED.setFont(RusFont); // подключаю русский шрифт myOLED.setFont(SmallFont); pinMode(vutyazhka, OUTPUT); pinMode(fotorez, OUTPUT); //rtc.setDateTime(dt); // установка времени если понадобится } void loop() { DateTime now = rtc.now(); //Получить текущую дату-время float h = dht.readHumidity(); // Считывание влажности в процентах float t = dht.readTemperature(); // Считывание температуры в цельсиях houre = now.hour();//переменная для часов minutu = now.minute();//переменная для минут sprintf(buffer, "%02d/%02d", houre,minutu); myOLED.clrScr(); myOLED.setFont(RusFont); // подключаю русский шрифт myOLED.print("NTVGTHFNEHF DKF:YJCNM", CENTER, 0); // вывожу надпись "температура и влажность" myOLED.setFont(MediumNumbers); // включаю средний шрифт цифр myOLED.printNumF(t, 1, 15, 10);// пишу на экране переменную температуры. один знак после запятой.25 пикселей отступа. 12 пикселейотступа с верху. myOLED.printNumF(h, 1, 80, 10); //тоже самое только влажность myOLED.setFont(MegaNumbers); //подключаю большие цифры myOLED.print(buffer, 6, 29); //myOLED.print("/", CENTER, 27); //myOLED.printNumF(minutu,0, 75, 27); myOLED.update(); Serial.print(now.year(), DEC); Serial.print('/'); Serial.print(now.month(), DEC); Serial.print('/'); Serial.print(now.date(), DEC); Serial.print(' '); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(buffer); Serial.println();// выводим время delay(200); }Всем привет.
Мне понравились вот эти часы http://www.instructables.com/id/DS3231-OLED-clock-with-2-button-menu-setting-and-t/ Возможно, кому-то этот вариант пригодиться...
Ходят точно. Убрал анимацию, увеличил цифры... Вполне доволен. Хотел сделать второй alarm, но так и застрял с alarm 2 :) опыта маловато...
//Subroutine to set alarm 1 void set_alarm() { // flags define what calendar component to be checked against the current time in order // to trigger the alarm - see datasheet // A1M1 (seconds) (0 to enable, 1 to disable) // A1M2 (minutes) (0 to enable, 1 to disable) // A1M3 (hour) (0 to enable, 1 to disable) // A1M4 (day) (0 to enable, 1 to disable) // DY/DT (dayofweek == 1/dayofmonth == 0) byte flags[5] = { 0, 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match // set Alarm1 DS3231_set_a1(0, wake_MINUTE, wake_HOUR, 0, flags); //Set alarm 1 RTC registers } //Subroutine to get alarm 1 void get_alarm() { uint8_t n[4]; uint8_t t[4]; //second,minute,hour,day uint8_t f[5]; // flags uint8_t i; Wire.beginTransmission(DS3231_I2C_ADDR); Wire.write(DS3231_ALARM1_ADDR); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDR, 4); for (i = 0; i <= 3; i++) { n[i] = Wire.read(); f[i] = (n[i] & 0x80) >> 7; // 0x80 -> 128 t[i] = bcdtodec(n[i] & 0x7F); // 0x7F -> 127 } f[4] = (n[3] & 0x40) >> 6; // 0x40 - 64 t[3] = bcdtodec(n[3] & 0x3F); // 0x3F - 63 wake_SECOND = t[0]; wake_MINUTE = t[1]; wake_HOUR = t[2]; }как они отображают начало часа?
к прирмеру 12:6:15
или
12:06:15?
Минуты и секунды с лидирующими нулями, а часы с лидирующим пробелом
Нормально отображают, т.е. цифры стоят на своих местах.
Там по ссылке видео ролики... Можно все нюансы увидеть. Я применил DS3231 вот такой
- уменьшил размер тем самым. В даташит вижу, что можно сделать Alarm 2 и автор наглядно сделал Alarm 1 в соответствии с текстом даташит, но я не догоняю, как ... Идею автора я не понимаю до конца с Alarm 1
Может, найдется добрая душа, подскажет ... правильно ли я делаю Alarm 2...
//Subroutine to set alarm 2 void set_alarm2() { // flags define what calendar component to be checked against the current time in order // to trigger the alarm - see datasheet // A2M2 (minutes) (0 to enable, 1 to disable) // A2M3 (hour) (0 to enable, 1 to disable) // A2M4 (day) (0 to enable, 1 to disable) // DY/DT (dayofweek == 1/dayofmonth == 0) byte flags[4] = { 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match // set Alarm2 DS3231_set_a2(wake_MINUTE, wake_HOUR, 0, flags); //Set alarm 2 RTC registers } //Subroutine to get alarm 2 void get_alarm2() { uint8_t n[3]; uint8_t t[3]; //second,minute,hour,day uint8_t f[4]; // flags uint8_t i; Wire.beginTransmission(DS3231_I2C_ADDR); Wire.write(DS3231_ALARM2_ADDR); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDR, 3); for (i = 0; i <= 2; i++) { n[i] = Wire.read(); f[i] = (n[i] & 0x80) >> 7; // 0x80 -> 128 t[i] = bcdtodec(n[i] & 0x7F); // 0x7F -> 127 } f[3] = (n[2] & 0x40) >> 6; // 0x40 - 64 t[2] = bcdtodec(n[2] & 0x3F); // 0x3F - 63 wake_MINUTE = t[0]; wake_HOUR = t[1]; }Спасибо. Всем удачи.
Вроде правильно.
Евгений, вопрос по старому скетчу (пост 31) :
пробую вот сейчас посмотреть как он работает, добавил флаг туда где вы указали, но смотрю в порт, ничего не меняется. Не растет.
SQW к 2 ноге. A4 и A5 стандартно. строки в twi.h добавил и поместил в папку скетча
Поправьте пожалуйста- что не так делаю?
#include "twi.h" uint8_t Flag = 0; // // Пин, на который заведено прерывание с пина SQW модуля часов // может быть 2 или 3 // #define PIN_SQW 2 // // I2C адрес часов // #define CLOCK_ADDRESS 0x68 // // Преобразование формата чисел // static inline uint8_t bcdToDec(uint8_t val) { return ((val/16*10) + (val%16)); } static inline uint8_t decToBcd(uint8_t val) { return ((val/10*16) + (val%10)); } // // Функции чтения/записи регистров часов // static uint8_t getElement(uint8_t el) { twi_writeTo(CLOCK_ADDRESS, &el, 1, true, true); twi_readFrom(CLOCK_ADDRESS, &el, 1, true); return el; } static void setElement(uint8_t addr, uint8_t val) { uint8_t buffer[2] = { addr, val }; twi_writeTo(CLOCK_ADDRESS, buffer, 2, true, true); } static inline uint8_t getRegisterE(void) { return getElement(0x0e); } // 0 static inline uint8_t getRegisterF(void) { return getElement(0x0F); } // 1 static inline void setRegisterE(uint8_t val) { setElement(0x0e, val); } // 0 static inline void setRegisterF(uint8_t val) { setElement(0x0F, val); } // 1 // // Установить время второго будильника // static void setA2Time(const uint8_t A2Day, const uint8_t A2Hour, const uint8_t A2Minute, const uint8_t AlarmBits, const bool A2Dy) { uint8_t buffer [4]; buffer[0] = 0xb; // Alarm 2 address buffer[1] = decToBcd(A2Minute) | ((AlarmBits & 0x10) << 3); buffer[2] = decToBcd(A2Hour) | ((AlarmBits & 0x20) << 2); buffer[3] = ((AlarmBits & 0x40) << 1) | decToBcd(A2Day); if (A2Dy) buffer[3] |= 0x40; twi_writeTo(CLOCK_ADDRESS, buffer, 4, true, true); } // // Включить будильник // static void turnOnAlarm(const uint8_t Alarm) { setRegisterE(getRegisterE() | ((Alarm==1) ? 5 : 6)); } // // Выключить будильник // static void turnOffAlarm(const uint8_t Alarm) { setRegisterE(getRegisterE() & ((Alarm==1) ? 0xFE : 0xFD)); } // // Включить ежеминутные прерывания // static void EnableMinuteInterrupt(void) { setA2Time(1, 1, 1, 0x70, false); setRegisterF(getRegisterF() & (~2)); setRegisterE(getRegisterE() | 4); turnOnAlarm(2); } // // "Заткнуть" будильник № alarm // static void clearAlarmSignal(const uint8_t alarm) { setRegisterF(getRegisterF() & (~alarm)); } // // Проверка сработал ли будильник № Alarm // static bool checkIfAlarm(const uint8_t Alarm) { bool result; uint8_t temp_buffer = getRegisterF(); if (Alarm == 1) { result = temp_buffer & 1; temp_buffer &= 0xFE; } else { result = temp_buffer & 2; temp_buffer &= 0xFD; } setRegisterF(temp_buffer); return result; } // // Включается прерывание и заодно назначается ISR // inline static void _attachInterrupt0(void) { pinMode(PIN_SQW, INPUT); #if PIN_SQW == 2 EICRA = bit(ISC01); // FALLING edge EIMSK = bit(INT0); // INT0 interrupt } ISR(INT0_vect) #else EICRA = bit(ISC11); // FALLING edge EIMSK = bit(INT1); // INT1 interrupt } ISR(INT1_vect) #endif { const uint8_t oldSReg = SREG; sei(); if (checkIfAlarm(2)) { // Если мы попали сюда, значит произошёл переход на новую минуту // Здесь можно обновить экран часов и т.д. и т.п. // в конце обязательно ... Flag++; clearAlarmSignal(2); // очистить сигнал будильника } SREG = oldSReg; } void clockInit(void) { setRegisterE(getRegisterE() & 0x7F); // Запустить осциллятор setRegisterF(getRegisterF() & 0x7F); // Очистить OSF flag setElement(2, getElement(2) & 0xBF); // 24-часа clearAlarmSignal(2); // Выключить будильник 2 (от греха) EnableMinuteInterrupt(); // Включить прерывания на переходе минуты _attachInterrupt0(); // назначить функцию обработчик прерывания } uint32_t PortPreviosMil = 0; void setup(void) { Serial.begin(9600); clockInit(); } void loop(void) { if (millis() - PortPreviosMil > 200) { PortPreviosMil = millis(); Serial.println(Flag); } }Попробуйте добавить в начало строки 4 слово volatile. А там посмотрим. Да кстати, прерывание должно приходить раз в минуту, зачем Вы так часто перчатете (200 мс в строке 151). Поставьте там вместо 200, например, 30000ul - полминуты - нормально.
Не считает.
volatile это для того чтоб переменную внести в особую область памяти - для прерываний одним словом?
А вообще как в 3231 по-минутный сигнал установить? Железно никак?
Вы помню говорили что в этом модуле поминутный а 1302 по-секундный.
Стоп, у Вас-то что? Какие часы. Если 3231, так мы поминутное перывание и устанавливаем.
У Вас вообще, часы работают? Время меняется? Может Вы подключики не так или там ещё чего.
Евгений. все нормально, часы идут точно, проблем нет с подключением- паралельно висит мой скетч, там показывает все ок.
С вашим вариантом не. Тоисть я не могу сказать точно ведь выводить инфу о минутах в скетче нету и я не допишу ибо это же без библиотеки все. "прямыми" командами точно мозгов не хватит.
У меня модуль 3231.
"по-минутное прерывание устанавливаем"- тоисть это делается не один раз? Я думал что подобные установки записываются в регистр один раз.
Получается что оно работает только в вашем скетче?
Да, нет, ну, я не знаю, что Вы запускаете.
Ежеминутное прерывание в моём скетче устанавливается функцией EnableMinuteInterrupt. Она вызывается один раз из функции clockInit, а та, в свою очереь, из setup.
а как насчет
Получается 00 и есть раз в секунду? потом отсчитать второй ногой (прерыванием) 60 раз и сделать свои действия, так?
Хотите делайте так. Я сделал чтобы там импульс раз в минуту шёл. Сделано это через будильник.
осталось понять как выставить регистры, даташит читаю пока что но ... )))
Удачи!
читать ТО-ЕСТЬ вместо - тоисть