Помогите разобраться с часами DS1307

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Здравствуйте! Нужна Ваша помощь!

У меня Ардуина Мега 2560, хочу подключить к ней RTC DS1307. Купил на ебае вот такой модуль http://www.ebay.com/itm/130702223257?ssPageName=STRK:MEWNX:IT&_trksid=p3...

и возникли вопросы. Вроде как бы все понятно, но ничего не понятно.

1. Как подключить. Если я все правильно понял, то SDA цепляем на 20 пин ардуины, а SCL на 21 (на этих ногах ардуины реализована  шина I2C) GND - на землю. Vcc +5V. Если я планирую использовать не одно устройство на этой шине, то нужно ли мне использовать подтягивающие резисторы на SDA и SCL к 5 вольтам? Если нужно то какой должен быть номинал резисторов 4,7К или 10К ? В интернете вроде полно примеров, но все выполнены по разному, запутали меня.

2. Какую библиотеку лучше использовать? У меня IDE 1.0.1 Опять же в интернете полно всяких библиотек для RTC (некторые примеры реализованы просто через wire.h),  но какая точно подойдет, конечно можно методом "тыка"...

3. Хотелось бы найти заведомо рабочие примеры скетчей.

Интернет ковырял, гуглил, копал форум ардуины, инфы много... а вопросов еще больше.

leshak
Offline
Зарегистрирован: 29.09.2011

>Если я планирую использовать не одно устройство на этой шине

Рояля не играет сколько устройст. Подтягивающий резистор должен быть. Одна штука. Вне зависимости от того сколько устройст.

 >какой должен быть номинал резисторов 4,7К или 10К ?

По даташиту, вроде 4.7K. Но и с 10K ничего страшного не случится. Это тот случай когда "больше не меньше".

Нужно просто понять смысл этого резистора. Представте себе что линия эта "натянутая струна". Котрую устройство "дергает вниз" (подключает к нулю) что-бы передать какую-то информацию морзянкой. Но устройство только может только "дергать вниз". Что-бы, после того как устройство "отпустило" эту струну, она вернулась в верхнее положение  (логическая 1) - нужна какая-то пружинка-резиночка, которая будет ее возвращать в 1. Вот этот резистор и есть эта "пружинка". Чем больше его номинал (слабее пружинка) - тем легче линию "придавить к нулю" (и при этом меньше ток идет), но и "возвращатся в 1" соотвественно линия будет более медленно. И наоборот, при малом номинале (тугая пружина)- труднее придавить к нулю, но зато, после отпускания, логическая 1 востановится быстрее.

Так что какой именно резистор вы тут возьмете - не сильно критично. Какой есть под руками.  Безопастно - в любом случае. Ну а дальше просто смотреть работает стабильно или нет.

Если погуглить "ds1307 application note" то можно найти пример-рекомендацию от производителя микрухи

 http://www.maxim-ic.com/app-notes/index.mvp/id/95

Как видим они используеют 5K (вообщем фактически те же 4,7K из стандартного ряда)

Samodelkin
Offline
Зарегистрирован: 07.06.2012

leshak , спасибо за ответ! Все на пальцах объяснили. Но у меня еще тут вопросец появился.

Есть у меня RTC DS1307 и датчик давления BMP085. Питание у DS1307 +5В, а у BMP085 3,3В. Как их подключить к шине I2C. Точней я запутался с подтягивающими резисторами. Исходя из даташита каждого устройства я понимаю как их подключить по отдельности, а как вместе, если питание у каждого устройства разное? Вот например так или нет? (не получается вставить картинку на форум, закинул на хостинг).

http://s3.itrash.ru/idb/00399af77a0efaf25f75a66bf8f2e84c/oP1070646.jpg

leshak
Offline
Зарегистрирован: 29.09.2011

 Объяснить-то объяснили, но не похоже что поняли :)

Иначе как объяснить попытку всандалить два подтягивающих резистора? Хотя четко написал "Рояля не играет сколько устройст. Подтягивающий резистор должен быть. Одна штука. Вне зависимости от того сколько устройст."

Вот в соотвествии с этими объяснениями, какое напряжение, по вашему, должно в этой схеме образоватся когда ни одно устройство не давит линию к нулю? Одна "пружинка" тянет к 5v, другая к 3v. Что на линии будет? Вы же, фактически, еще линия питания 5v и 3v между собой соединили. Через резистор 9.4K и у вас ток пойдейт вкачиватца в  3v из 5v.

Честно говоря я не готов сказать 100% "как правильно", но то что ваша схема "неправильно" - это точно.

Подключать на одну шину устройства с разными уровнями питания - я не пробовал. Беглое гугление дало такие результаты:

Питают его от 3.3V, а вот линиюю SDA,SLC подключают просто к шине. Не обращая внимание на что там бывает 5v. Хотя прямого указания, в даташите, что эти входы допускают подачу на них 5v - я не нашел. Но у шилдов, на его базе, такое упоминине есть. Так что если "параноится", то нужно еще какое-то согласование уровней мудрить.... но во всех примерах что мне попались никаким согласованием не пахнет.

Вот один из примеров: http://wiring.org.co/learning/libraries/bmp085.html или вот http://www.sparkfun.com/tutorials/253. На втором примере можон еще и схематику ихнего брекаута посмотреть. 

Обратите внимание что в этих примерах не видно вообще никаких подтягивающих резисторов. Это объясняется тем что они уже есть на брекауте. Так что самому их ставить уже не нужно (даже если у вас есть еще и другие устройства на шине). Если же у вас "голый" чип, то этим нужно озаботится. Вообщем на линии должен быть один резистор.

Я бы попробовал делать наверное так: запитал DS1307 от 5v, а BPM от 3.3v, и подключил подключил их обоих к линииям SDA,SLC, а сами линии подтянул-бы резисторами 4.7K (по резистору на линию) к 3.3v. Если DS1307 так работать не захочет, тогда попробовал бы рискнуть и подтянуть не к 3.3v, а 5v (но при этом BPM все равно питать нужно от 3.3v).

Для ардуины и DS1707. оба варианта будут безопастны. Рискует только BPM в варианте подтяжки к 5v. Но риск весьма "условный" Если верить фразе "Logic: 3 to 5V compliant" на http://www.adafruit.com/products/391 то риска нет.

Итого: какую-то пару резисторов с вашей схемы нужно убрать. Либо левую, либо правую. Безопастней, для BMP, - убрать левую пару резисторов (подтягивающих к 5v). Если юзаете не голый чип, а брекаут от спаркфуда - убрать все. Правая пара уже "встроена" в сам брекаут.

 

 

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Спасибо за ответ :) На счет своей схемы, конечно, вы правы это полная ерунда! Да я и сам понял, получилось что засиделся допоздна, голова уже не работала и в порыве отправил сообщение. Попробую сначада подтянуть к 3,3 v. Рассмотрел внимательно свои брекауты, на датчике давления резисторов нет,  пины SDA и SCL распаяны прямо на чип, так что думаю резисторы будут не лишними.

На счет "параноиться", с согласованием уровней - почему бы и нет, мне как самостоятельно изучающему эту "науку" было бы не лишне разобраться и в этом вопросе. Вот кстати нашел у буржуев по данной тематике.. http://arduino.cc/playground/Main/I2CBi-directionalLevelShifter

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Собрал все воедино, RTC и BPM085 подтянул к 3,3 V. Заработало сразу, и без проблем.

leshak
Offline
Зарегистрирован: 29.09.2011

Samodelkin пишет:

На счет "параноиться", с согласованием уровней - почему бы и нет, мне как самостоятельно изучающему эту "науку" было бы не лишне разобраться и в этом вопросе. Вот кстати нашел у буржуев по данной тематике.. http://arduino.cc/playground/Main/I2CBi-directionalLevelShifter

Архиправильный подход :)

"Наши" люди тоже умеют писать на эти темы Согласование логических уровней 5В и 3.3В устройств

Лично мне нравится диодный вариант. Просто потому что "я смог понять как он работает" и соотношение надежность/простота меня устраивает.

Baltazor
Offline
Зарегистрирован: 20.07.2012

Чтобы не множыть темы напишу здесь.

Ардуино нано и такие же часы как здесь обсужалить. Брал тут.

Делал:

1. Подключил к часам GND и +5v. SDA к пину 4 и SCL к пину 5. Не работает.

2. Понял что туплю подключил подтягивающие резисторы. Напряжение на резисторах 0.28 вольт. Не работает.

3. Пробовал использовать различные библиотеки (4 разных). Не работает. Один из скетчей:

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop () {
    DateTime now = RTC.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);
}

Как не работает:  Выше приведенный скетч выдает такое в независимо от того подключены часы или нет.

2165/165/165 165:165:85 
 since midnight 1/1/1970 = 1402357585s = 16230d 
 now + 7d + 30s: 2014/6/16 23:46:55 

Вопрос: Что я делаю неправильно, в чем может быть проблема. Как проверить вообще рабочие ли часы?

leshak
Offline
Зарегистрирован: 29.09.2011

 >Напряжение на резисторах 0.28 вольт.

Что-то сильно странное. Правда не понятно что вы имеете ввиду под "напряжение на резисторах".  Падение на резисторе?

Лучше померять между землей и самой линией (SDA/SLC) там, когда нет передачи, благодаря резисторам должно быть "что-то близкое к пяти" (четыре с копейками). То есть лучше проверить что "Резисторы делают что нужно", а не сами резисторы мерять :)

>Как проверить вообще рабочие ли часы?

Можете попробовать вот что-то типа такого

http://todbot.com/blog/2009/11/29/i2cscanner-pde-arduino-as-i2c-bus-scan...

Скетчик опрашивает все адреса от 0 до 100, и говорит есть ли кто-то откликнувшийся. Узнаете слышыт ли вообще ардуина вашу железку.

leshak
Offline
Зарегистрирован: 29.09.2011

 И да, вот еще веточка может быть полезная

http://arduino.ru/forum/obshchii/sokhranenie-kartinok-na-forume

Там она расписывается как "Загружать на сервер" картинку, но в вашем случае, когда "картинка уже в инете и вы знаете ее урл" - на первом скриншоте достаточно вставить ее адрес в поле URL и нажать OK. И она будет видна прямо в посте.

Примерно так:

Baltazor
Offline
Зарегистрирован: 20.07.2012

 > Лучше померять между землей и самой линией

Если так мерять то напряжение ~ 5 вольт, как и предполагалось.

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

Спасибо за ссылку на I2C сканер, проверю.

Baltazor
Offline
Зарегистрирован: 20.07.2012

Глупость я делал. Подключал I2C на цифровые пины.

Сейчас все работает, извините за ненужные вопросы.

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

Baltazor пишет:

Глупость я делал. Подключал I2C на цифровые пины.

Сейчас все работает, извините за ненужные вопросы.

Боюсь спросить - а на какие пины надо подключать линию цифрового обмена данными?

leshak
Offline
Зарегистрирован: 29.09.2011

step962 пишет:

Baltazor пишет:

Глупость я делал. Подключал I2C на цифровые пины.

Сейчас все работает, извините за ненужные вопросы.

Боюсь спросить - а на какие пины надо подключать линию цифрового обмена данными?

Есть предположение что "цифровыми" обозвали аналоговые. А цифровые "просто пинами". Тогда все встает на свои места - при подключении на аналоговые не работало, а при подключении на "просто пины" - заработало :)

Baltazor
Offline
Зарегистрирован: 20.07.2012

Я имел ввиду что нужно подключать сюда:

Тоесть к аналоговым входам.

leshak
Offline
Зарегистрирован: 29.09.2011

 >Я имел ввиду что нужно подключать сюда:

Вот же блин. И в голову не пришло что это могут быть аналоговые пины. Пять раз перечитывал "I2C: 4 (SDA) и 5 (SCL)" и был свято уверен что речь идет про цифровые пины (обычно аналоговость отдельно оговорена).

У меня на меге, они просто без нумерации так и подписанны SDA, SCL :)  И таки цифровые.

Так что " извините за ненужные вопросы" - лишние. Вопросы оказались очень даже нужными. Да еще сами и ответ нашли. И другим рассказали.

repon
Offline
Зарегистрирован: 23.08.2013

у меня arduino mega.

подключаю ds1307 к sda/20 и scl/21 пинам + питание и земля

без резистора

со стандартными примерами выдает время ...

сканер портов пробовал запускать - 

I2CScanner ready!
starting scanning of I2C bus from 8 to 119...
 
по всем адресам пусто
 
пробовал на 3,3 переключить
пробовал с батареей и без
 
что делать? без резистора не будет работать?
DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ты её (DS1307) голую подключаешь, или модуль? 

без какова резистора? 

repon
Offline
Зарегистрирован: 23.08.2013

читал,что нужны подтягивающие резисторы линий SDA и SCL

подключаю модуль.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Может родные примеры подтягивают шины к "+" ?

repon
Offline
Зарегистрирован: 23.08.2013

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

bool isTimeSet = false; //флаг, указывающий на то, была ли уже задана дата

void setup()  {
  Serial.begin(9600);

  setSyncProvider(RTC.get);   // получаем время с RTC
  
  Serial.println("timeSet = " + timeSet);
  Serial.println("timeStatus() = " + timeStatus());

  if (timeStatus() != timeSet)
    Serial.println("Unable to sync with the RTC"); //синхронизация не удаласть
  else
    Serial.println("RTC has set the system time");
}

void loop()
{
  //01.08.19 14:40:00
  if (Serial.available()) { //поступила команда с временем
      setTimeFromFormatString(Serial.readStringUntil('\n'));
      isTimeSet = true; //дата была задана
  }
  if (isTimeSet)  //если была задана дата
  {
    digitalClockDisplay(); //вывод времени
  }

//Serial.println(RTC. get(DS1307 SEC, false));
  
  delay(1000);
}

void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits) {
  //выводим время через ":"
  Serial.print(":");
  if (digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

void setTimeFromFormatString(String time)
{
  //ДД.ММ.ГГ чч:мм:сс
  int day = time.substring(0, 2).toInt();
  int month = time.substring(3, 5).toInt();
  int year = time.substring(6, 8).toInt();
  int hours = time.substring(9, 11).toInt();
  int minutes = time.substring(12, 14).toInt();
  int seconds = time.substring(15, 17).toInt();
  TimeElements te;
  te.Second = seconds;
  te.Minute = minutes;
  te.Hour = hours;
  te.Day = day;
  te.Month = month;
  te.Year = year + 30; //год в библиотеке отсчитывается с 1970. Мы хотим с 2000
  time_t timeVal = makeTime(te);
  RTC.set(timeVal);
  setTime(timeVal);
}

 

код стандартный, из примеров)

попереключался, i2c сканер нашел 2 занятых порта!

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

15:19:26.881 -> 15:20:07 1 8 2019
15:19:27.862 -> 15:20:08 1 8 2019
 
но, если отключаю питание ардуини или нажимаю reset - приходит в первонач состояние -
15:19:29.422 -> Unable to sync with the RTC
 
и меня смущает, что timeStatus() пустой и timeSet - что это ?)) не isTimeSet
Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

В стране проблема с резисторами на 4К7 ?

repon
Offline
Зарегистрирован: 23.08.2013

все-таки они нужны?)))

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

они нужны по стандарту I2C