на каком моменте пропадает секунда часы дисплей

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем r13s, 16 июл 2015.

  1. r13s

    r13s Нерд

    тут можно увидеть, что тут перепрыгивание через секунду.
    http://coub.com/view/788kh
    Я так полагаю идет расхождение в отображаемых данных часами. Конечно можно увеличить частоту обновления чем выше тем стабильнее. Но я полагаю так будет кушаться энергия больше. дело в том, что если вывод идет на монитор порта то нет такого пропадания. Подскажите как код оптимизировать, мне просто кажется, что функция делэй не там где надо.
    Код (Text):
    #include <stdio.h>
    #include <DS1302.h>
    #include <Adafruit_ssd1306syp.h>
    #define SDA_PIN 13
    #define SCL_PIN 12
    #define MINUS_PIN 11
    #define PLUS_PIN 10
    Adafruit_ssd1306syp display(SDA_PIN, SCL_PIN);
    namespace {

    // Set the appropriate digital I/O pin connections. These are the pin
    // assignments for the Arduino as well for as the DS1302 chip. See the DS1302
    // datasheet:
    //
    //  http://datasheets.maximintegrated.com/en/ds/DS1302.pdf
    const int kCePin  = 7;  // Chip Enable
    const int kIoPin  = 6;  // Input/Output
    const int kSclkPin = 5;  // Serial Clock

    // Create a DS1302 object.
    DS1302 rtc(kCePin, kIoPin, kSclkPin);

    String dayAsString(const Time::Day day) {
      switch (day) {
        case Time::kSunday: return "Sunday";
        case Time::kMonday: return "Monday";
        case Time::kTuesday: return "Tuesday";
        case Time::kWednesday: return "Wednesday";
        case Time::kThursday: return "Thursday";
        case Time::kFriday: return "Friday";
        case Time::kSaturday: return "Saturday";
      }
      return "(unknown day)";
    }




    }  // namespace
    void setup()
    {
      pinMode(11, OUTPUT);
      pinMode(10, OUTPUT);
      digitalWrite(MINUS_PIN, LOW);
      digitalWrite(PLUS_PIN, HIGH);
      pinMode(4, OUTPUT);
      pinMode(3, OUTPUT);
      digitalWrite(4, LOW);
      digitalWrite(3, HIGH);
      rtc.writeProtect(false);
      rtc.halt(false);
      delay(1000);
      display.initialize();

    }
    void loop()
    {

      display.update();
      delay(1000);
      display.clear();
      display.setTextSize(2);
      display.setTextColor(WHITE);
      display.setCursor(0, 0);

      // Get the current time and date from the chip.
      Time t = rtc.time();

      // Name the day of the week.
      const String day = dayAsString(t.day);

      // Format the time and date and insert into the temporary buffer.
      char buf[50];

      snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
              day.c_str(),
              t.yr, t.mon, t.date,
              t.hr, t.min, t.sec);
      display.print(t.yr); display.print("/"); display.print(t.mon); display.print("/"); display.println(t.date);
      display.print(t.hr); display.print(":"); display.print(t.min); display.print(":"); display.println(t.sec);
      display.print(day);
      // Print the formatted string to serial so we can see the time.
      // Serial.println(buf);

    }
    и еще вопросик, по поводу русского языка на дисплее, как можно писать по русски, быть может вставлять коды букв или еще что?
     
  2. geher

    geher Гуру

    1. По "перескакиванию" секунды.
    Поскольку используется delay(1000), то получается, что общее время работы одного вызова loop() больше секунды. И рано или поздно оказывается, что между измерениями времени проходит две смены секунды.
    Чтобы секунды тикали враз в секунду, надо перейти от delay к контролю millis.
    Что-то вроде
    Код (Text):

    if (!(millis()%1000)) { // проверяем остаток деления millis на 1000, который равен нулю раз в секунду.
       // получаем и выводим время;
    }
    или
    Код (Text):

    static long currentSecond=0;
    if (currentSecond!=millis()/1000) { // проверяем, выводили ли время на текущей секунде
       currentSecond=millis/1000;
       // получаем и выводим время;
    }
    Поскольку delay не останавливает работу процессора, то разница в потреблении если и будет, то незаметная.
    Конечно, точность не будет абсолютной (точность часов, время формирования строк из разных чисел), но она будет по крайней мере гулять относительно собственной секунды часов МК, не убегая от нее далеко.

    2. Если в дисплее зашит русский язык, то для вывода русского символа можно воспользоваться
    display.write(код символа). Коды символов нужно смотреть в описании дисплея.
    Если русского в самом дисплее нет, то придется либо синтезировать свой символ (обычно в дисплеях есть такая возможность), либо воспользоваться графикой (в случае графического дисплея).
     
    Tomasina нравится это.
  3. Megakoteyka

    Megakoteyka Оракул Модератор

    Обычно RTC умеют выдавать импульсы с одной из своих ног раз в секунду. Этот импульс можно завести на ножку контроллера, настроить прерывание по фронту и опрашивать часы по прерыванию равно раз в секунду.
    А между прерываниями контроллер можно вообще в спящий режим отправить, если хотите электричество экономить.
     
  4. r13s

    r13s Нерд

    в принципе логика в ваших словах есть, но я еще только нуб. HTB1fLqRHFXXXXXuXVXXq6xXFXXXq.jpg
    где у него прерывание? и что означают
    CLK �?P02
    DAT �?P01
    RST �?P00

    спс, попробую
     
  5. geher

    geher Гуру

    Читывал описание данных часов.
    Похоже, что такая полезная вещь, как выдача регулярных импульсов, которые можно завести на прерывания, там не предусмотрена как класс.
    RST используется для управления (инициации чтения или записи).
    CLK используется для синхронизации ввода-вывода (обозначаются начала бит при передаче байта)
    DAT используется собственно для передачи данных из регистров и в регистры микросхемы часов.
     
  6. Megakoteyka

    Megakoteyka Оракул Модератор

    Я сразу не обратил внимания, что у вас модуль на DS1302. Эта микросхема не имеет гнать ежесекундные импульсы, это умеет делать DS1307.

    CLK �?P02
    DAT �?P01
    RST �?P00
    Страница 4 даташита на DS1302
     
  7. geher

    geher Гуру

    В случае существенного расхождения хода модуля часов с внутренним таймером МК могут все-таки быть спецэффекты в виде очень долгой секунды или пропуска секунды.
    Лучше все-таки привязаться к показаниям самого модуля часов.
    Например, так
    Код (Text):

    static unsigned long currentSecond=0;
    static unsigned long getTime=0;
    if ((millis()-getTime)>100) { // каждые 100 миллисекунд
      getTime=millis();
      // Получаем время с модуля часов
      Time t = rtc.time();
      if (currentSecond!=t.sec) { // проверяем, выводили ли время на текущей секунде
          currentSecond=t.sec;
          // выводим время;
       }
    }
     
    Не думаю, что десятикратное увеличение частоты опроса часов приведет к существенному росту потребления электроэнергии.
     
  8. DrProg

    DrProg Вечный нерд

    Самый простой способ - сделать delay(100) например. Некошерно, конечно, но пропусков заметно не будет.
     
  9. r13s

    r13s Нерд

    ))) я написал об этом в самом вопросе, я хотел от этого уйти.
     
  10. r13s

    r13s Нерд

    я правильно вставил код? если да, то по прежнему скачет
    Снимок.PNG
     
  11. Megakoteyka

    Megakoteyka Оракул Модератор

    Сделайте переменную getTime глобальной.
     
  12. Максим B

    Максим B Гуру

  13. Megakoteyka

    Megakoteyka Оракул Модератор

  14. Максим B

    Максим B Гуру

    К сожалению так и не разобрался. Сканером i2c получил адрес правильный устройства, даже попробовал получить какие-то значения - но все тщетно. Даташит читал, делал по аналогии - не хотит работать.
     
  15. andriano

    andriano Нерд

    В настоящее время единственного удобного способа подключения кириллицы для Arduino не существует. Одним из вариантов является создание дополнительных таблиц знакогенератора и переключение между шрифтами: http://arduino-project.net/russkie-ukrainskie-shrifty-oled-i2c/
    Минусом такого решения является то, что в коде вместо осмысленных строк присутствует абракадабра.
    Недавно я опубликовал альфа-версию библиотеки, где, на мой взгляд, эта проблема решена. Можете принят участие в тестировании и обсуждении. http://arduino.ru/forum/programmirovanie/kirillitsa-na-displee-ili-chto-ya-delayu-ne-tak