RTC DS1307 вывод времени на 7ми сегментный индикатор

leptodon
Offline
Зарегистрирован: 27.09.2012

Подскажите пожалуйста, как используя ЭТУ библиотеку для часов реального времени DS1307 вытащить значения часов, минут и секунд в отдельные переменные если для получения времени через serial используется rtc.getTimeStr() и формат вывода hh:mm:ss ?

step962
Offline
Зарегистрирован: 23.05.2011

leptodon пишет:
Подскажите пожалуйста, как используя ЭТУ библиотеку для часов реального времени DS1307 вытащить значения часов, минут и секунд в отдельные переменные если для получения времени через serial используется rtc.getTimeStr() и формат вывода hh:mm:ss ?

Попробуйте поработать с функцией sscanf() (<stdio.h>).
Ну и strtok() (<string.h>) вам в помощь.

leptodon
Offline
Зарегистрирован: 27.09.2012

Спасибо, но предложиле несколько лучше решение

  const Time& temp = rtc.getTime();
  int hour = temp.hour;
  const Time& temp2 = rtc.getTime();
  int min = temp.min;


std
Offline
Зарегистрирован: 05.01.2012

all, я Ктулху, или строку 3 в приведенном куске кода можно выкинуть?

leptodon
Offline
Зарегистрирован: 27.09.2012

Почему? Первые 2 строки для получения часов в переменную, вторые 2 для получения минут

step962
Offline
Зарегистрирован: 23.05.2011

leptodon пишет:

Почему? Первые 2 строки для получения часов в переменную, вторые 2 для получения минут

Ну да - считываем информацию в переменную temp2, а минуты извлекаем из temp...

leptodon
Offline
Зарегистрирован: 27.09.2012

Да, точно сразу не понял о чем вы, память нужно экономить))

  const Time& temp = rtc.getTime();
  int hour = temp.hour;
  int min = temp.min;

 

Bim_Sony
Bim_Sony аватар
Offline
Зарегистрирован: 03.10.2012

Добрый день. Использовал библиотеку, которую выложили в первом посту.

Взял оттуда пример DS1307_LCD, только пины перставил, согласно своего подключения.

// A quick demo of how to use my DS1307-library to make a quick
// clock using a DS1307 and a 16x2 LCD.
//
// I assume you know how to connect the DS1307 and LCD.
// DS1302:  SDA pin   -> Arduino Digital 8
//          SCL pin   -> Arduino Digital 9
// LCD:     DB7       -> Arduino Digital 3
//          DB6       -> Arduino Digital 4
//          DB5       -> Arduino Digital 5
//          DB4       -> Arduino Digital 6
//          E         -> Arduino Digital 11
//          RS        -> Arduino Digital 12

#include <LiquidCrystal.h>
#include <DS1307.h>

// Init the DS1307
DS1307 rtc(8, 9);

// Init the LCD
LiquidCrystal lcd(12, 11, 6, 5, 4, 3);

void setup()
{
  // Set the clock to run-mode
  rtc.halt(false);
  
  // Setup LCD to 16x2 characters
  lcd.begin(16, 2);

  // The following lines can be commented out to use the values already stored in the DS1307
  rtc.setDOW(SUNDAY);        // Set Day-of-Week to SUNDAY
  rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  rtc.setDate(8, 11, 2010);   // Set the date to October 3th, 2010

  // Set SQW/Out rate to 1Hz, and enable SQW
  rtc.setSQWRate(SQW_RATE_1);
  rtc.enableSQW(true);
}

void loop()
{
  // Display time centered on the upper line
  lcd.setCursor(4, 0);
  lcd.print(rtc.getTimeStr());
  
  // Display abbreviated Day-of-Week in the lower left corner
  lcd.setCursor(0, 1);
  lcd.print(rtc.getDOWStr(FORMAT_SHORT));
  
  // Display date in the lower right corner
  lcd.setCursor(6, 1);
  lcd.print(rtc.getDateStr());

  // Wait one second before repeating :)
  delay (1000);
}

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

На экране постоянно светится:

27:85:85

ххх 85.85.2165

 

Пробовал другие примеры с СОМ портом, но там тоже самое время.

 

Вывод SDA подключил на 8 пин

Вывод SCL подключил на 9 пин

Вывод DS подключил на 2 пин

 

В других источниках SDA и SCL цепляют на аналоговые пины (4 и 5), а DS на 2. пробовал такое подключение, все равно не работает.

Подскажите в чем проблема, куда копать?

Bim_Sony
Bim_Sony аватар
Offline
Зарегистрирован: 03.10.2012

Заработало. Не понимаю, почему на этих пинах не работало. поставил на 9 и10, все заработало.

Вывод SDA подключил на 9 пин

Вывод SCL подключил на 10 пин

Естественно подправил код:

DS1307 rtc(8, 9);

 

Прочитав кучу литературы, выяснил, что пин DS нужен для считывания показания с датчика температуры, который не распаян на шилде.

inhelp
inhelp аватар
Offline
Зарегистрирован: 23.09.2012

А у меня получился еще проще код для отображения времени на LCD

#include <DS1307.h>
#include <LiquidCrystal.h>

DS1307 rtc(A4, A5);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup()
{
  lcd.begin(16, 2);
  rtc.halt(false);
}

void loop()
{

  lcd.setCursor(3,1);
  lcd.print(rtc.getDateStr());

  lcd.setCursor(4,0);
  lcd.print(rtc.getTimeStr());

  delay (1000);
}

 

mpvs
Offline
Зарегистрирован: 22.07.2014

Здравствуйте. Тоже пытаюсь сообразить часы с RTC модулем на 4 числовом 7 сегментном индикаторе.

В интернете нашел примерчик работы с индикатором, там тикает счетчик. Единственное немного переделал под свои пины и у меня общий катод, а в основном примеры с общим анодом. Вот: 

int digit1 = 9; //PWM Display pin 12
int digit2 = 10; //PWM Display pin 9
int digit3 = 11; //PWM Display pin 8
int digit4 = 12; //PWM Display pin 6
int segA = 2; //Display pin 11
int segB = 3; //Display pin 7
int segC = 4; //Display pin 4
int segD = 5; //Display pin 2
int segE = 6; //Display pin 1
int segF = 7; //Display pin 10
int segG = 8; //Display pin 5
int segP = 13; //Display pin 3 // point- not use now
void setup() {                
  pinMode(segA, OUTPUT);
  pinMode(segB, OUTPUT);
  pinMode(segC, OUTPUT);
  pinMode(segD, OUTPUT);
  pinMode(segE, OUTPUT);
  pinMode(segF, OUTPUT);
  pinMode(segG, OUTPUT);
  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT); 
  pinMode(13, OUTPUT);
}

void loop() {
  displayNumber(millis()/1000);
}

void displayNumber(int toDisplay) {
#define DISPLAY_BRIGHTNESS  5000
#define DIGIT_ON  HIGH
#define DIGIT_OFF  LOW

  long beginTime = millis();

  for(int digit = 4 ; digit > 0 ; digit--) {

    //Turn on a digit for a short amount of time
    switch(digit) {
    case 1:
      digitalWrite(digit1, DIGIT_OFF);
      break;
    case 2:
      digitalWrite(digit2, DIGIT_OFF);
      break;
    case 3:
      digitalWrite(digit3, DIGIT_OFF);
      break;
    case 4:
      digitalWrite(digit4, DIGIT_OFF);
      break;
    }

    //Turn on the right segments for this digit
    lightNumber(toDisplay % 10);
    toDisplay /= 10;

    delayMicroseconds(DISPLAY_BRIGHTNESS); 
    //Display digit for fraction of a second (1us to 5000us, 500 is pretty good)

    //Turn off all segments
    lightNumber(10); 

    //Turn off all digits
    digitalWrite(digit1, DIGIT_ON);
    digitalWrite(digit2, DIGIT_ON);
    digitalWrite(digit3, DIGIT_ON);
    digitalWrite(digit4, DIGIT_ON);
  }

  while( (millis() - beginTime) < 10) ; 
  //Wait for 20ms to pass before we paint the display again
}


//Given a number, turns on those segments
//If number == 10, then turn off number
void lightNumber(int numberToDisplay) {

#define SEGMENT_ON  HIGH
#define SEGMENT_OFF LOW

  switch (numberToDisplay){

  case 0:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 1:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 2:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 3:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 4:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 5:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 6:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 7:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;

  case 8:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_ON);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 9:
    digitalWrite(segA, SEGMENT_ON);
    digitalWrite(segB, SEGMENT_ON);
    digitalWrite(segC, SEGMENT_ON);
    digitalWrite(segD, SEGMENT_ON);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_ON);
    digitalWrite(segG, SEGMENT_ON);
    break;

  case 10:
    digitalWrite(segA, SEGMENT_OFF);
    digitalWrite(segB, SEGMENT_OFF);
    digitalWrite(segC, SEGMENT_OFF);
    digitalWrite(segD, SEGMENT_OFF);
    digitalWrite(segE, SEGMENT_OFF);
    digitalWrite(segF, SEGMENT_OFF);
    digitalWrite(segG, SEGMENT_OFF);
    break;
  }
}

Установка времени на RTC модуль и вывод в последовательный порт тоже вышли благорадя примерам. Сутки без подключения к компу ( на батарейке другими словами) пролежал, сегодня подключил - время корректное. 

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>

void setup() {
  Serial.begin(9600);
  while (!Serial) ; // wait for serial
  delay(200);
}

void loop() {
  tmElements_t tm;

  if (RTC.read(tm)) {
    print2digits(tm.Hour);
    Serial.write(':');
    print2digits(tm.Minute);
    Serial.println();
  } else {
    if (RTC.chipPresent()) {
      Serial.println("The DS1307 is stopped.  Please run the SetTime");
      Serial.println("example to initialize the time and begin running.");
      Serial.println();
    } else {
      Serial.println("DS1307 read error!  Please check the circuitry.");
      Serial.println();
    }
    delay(9000);
  }
  delay(1000);
}

void print2digits(int number) {    // 2-digital showing
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

Теперь мне необходимо придумать алгоритм, который будет считывать минуты и часы, и выводить через switch...case время на дисплей. Наверное надо завести переменную, а потом как то пробегать циклом for (int i=0; i<10, i++) выводить нужную цифру на дисплей через case, но тут уже я уверен сразу ошибка: часы и минуты считываются в двух символьном варианте....

В общем буду рад любой помощи. Заранее спасибо.

bwn
Offline
Зарегистрирован: 25.08.2014

Так возьмите для часов библиотеку, которая в десятичном формате возвращает. Здесь прилепить не знаю как, могу сбросить.

axill
Offline
Зарегистрирован: 05.09.2011

step962 пишет:
leptodon пишет:

Почему? Первые 2 строки для получения часов в переменную, вторые 2 для получения минут

Ну да - считываем информацию в переменную temp2, а минуты извлекаем из temp...

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

строка 3 лишняя. Смысл повторно считывать данные из RTC если между 2 и 3 строкой не пройдет не то что минуты, даже секунды не пройдет, если строу 3 убрать - ничего не изменится

mpvs
Offline
Зарегистрирован: 22.07.2014

bwn пишет:

Так возьмите для часов библиотеку, которая в десятичном формате возвращает. Здесь прилепить не знаю как, могу сбросить.

Вроде как там и так перевариваемый тип. У меня проблемы с реализацией самого алгоритма и отправки его в функцию displayNumber.

У меня появилась идея c целочисленным и остатком от делений, примерно следующая: Берем из RTC переменные tm.Hour, tm.Minute, вводим 4 переменные int a,b,c,d ; int a = tm.Hour/10 , int b =  tm.Hour %10 , аналогично с минутами. И потом это как то передать на дисплей.

avton
avton аватар
Offline
Зарегистрирован: 11.05.2014
 lc.setDigit(0,0,(min_now%10),false);
    lc.setDigit(0,1,(min_now/10),false);   
    lc.setDigit(0,2,(hour_now%10),sec_now % 2);
    if ((hour_now/10)>0){
      lc.setDigit(0,3,(hour_now/10),false);
    }
    else{
      lc.setChar(0,3,' ',false);
    }
  }