Реально задолбали часы!!!

maxvalin
Offline
Зарегистрирован: 22.02.2016

ЕвгенийП пишет:

 символ ':' как-то особо отрабатывает. 

я об этом. 

фоткать уже не хочу но с этим символом мусор есть как раз между показаниями

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А-а-а, значит просто символа ':' нет в тамошнем шрифте (или у него другой код). Можно посмотреть и поковыряться - найти его там. Если хотите, расскажу как.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Спасибо огромное УЖЕ за уделенное внимаение!

- но сейчас времени уже нету, не профильная специальность кодить(   Хотя и интересно. 

Я так по станкам ЧПУ лажу в основном. А вот ардуино это как 2 шаг к STM взял, чтоб можно было доработки всячесские делать так как то что выходит на ардуино уже радует ибо применение есть(для меня)

maxvalin
Offline
Зарегистрирован: 22.02.2016

ну и вконце темы наверное уже рабочий код, может кто-то тоже будет искать по форуму вывод часов на 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);

}

 

PaulIV
Offline
Зарегистрирован: 11.10.2015

Всем привет.

Мне понравились вот эти часы 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];
}

 

maxvalin
Offline
Зарегистрирован: 22.02.2016

как они отображают начало часа?

к прирмеру 12:6:15

или 

12:06:15?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Минуты и секунды с лидирующими нулями, а часы с лидирующим пробелом

PaulIV
Offline
Зарегистрирован: 11.10.2015

Нормально отображают, т.е. цифры стоят на своих местах.

Там по ссылке видео ролики... Можно все нюансы увидеть.  Я применил 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];
}

Спасибо. Всем удачи.

 

fogary
Offline
Зарегистрирован: 05.03.2016

Вроде правильно.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Евгений, вопрос по старому скетчу (пост 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);
  }
  
}
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Попробуйте добавить в начало строки 4 слово volatile. А там посмотрим. Да кстати, прерывание должно приходить раз в минуту, зачем Вы так часто перчатете (200 мс в строке 151). Поставьте там вместо 200, например, 30000ul - полминуты - нормально.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Не считает.

 volatile это для того чтоб переменную внести в особую область памяти - для прерываний одним словом?

А вообще как в 3231 по-минутный сигнал установить? Железно никак?

Вы помню говорили что в этом модуле поминутный а 1302 по-секундный.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Стоп, у Вас-то что? Какие часы. Если 3231, так мы поминутное перывание и устанавливаем.

У Вас вообще, часы работают? Время меняется? Может Вы подключики не так или там ещё чего.

maxvalin
Offline
Зарегистрирован: 22.02.2016

Евгений. все нормально, часы идут точно, проблем нет с подключением- паралельно висит мой скетч, там показывает все ок.

С вашим вариантом не. Тоисть я не могу сказать точно ведь выводить инфу о минутах в скетче нету и я не допишу ибо это же без библиотеки все. "прямыми" командами точно мозгов не хватит. 

У меня модуль 3231.

 

"по-минутное прерывание устанавливаем"- тоисть это делается не один раз? Я думал что подобные установки записываются в регистр один раз.

Получается что оно работает только в вашем скетче?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, нет, ну, я не знаю, что Вы запускаете.

Ежеминутное прерывание в моём скетче устанавливается функцией EnableMinuteInterrupt. Она вызывается один раз из функции clockInit, а та, в свою очереь, из setup.

maxvalin
Offline
Зарегистрирован: 22.02.2016

а как насчет 

RS2 RS1 SQUARE-WAVE OUTPUT FREQUENCY
0 0 1Hz 
0 1 1.024kHz 
1 0 4.096kHz 
1 1 8.192kHz

 Получается 00 и есть раз в секунду? потом отсчитать второй ногой (прерыванием) 60 раз и сделать свои действия, так?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Хотите делайте так. Я сделал чтобы там импульс раз в минуту шёл. Сделано это через будильник.

maxvalin
Offline
Зарегистрирован: 22.02.2016

осталось понять как выставить регистры, даташит читаю пока что но ... )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Удачи!

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

maxvalin пишет:

 читать ТО-ЕСТЬ вместо  - тоисть