Arduino Uno подключение RTC DS3231

Nodit
Offline
Зарегистрирован: 15.01.2014

Добрый день.

Не могу найти схему подключения DS3231 к Arduino. Попадалось несколько схем, где RTC включался как часть внешней обвязки Arduino, при этом часть разъемов была подключена к внешним устройствам. А напрямую, без помошников, RTC к Arduino можно подключить?

Предварительно предполагается, что устройство будет состоять из Arduino Uno, ультразвукового датчика HC-SR04, RTC DS3231 и Serial LCD 1602 и отображать текущее время на экран при попадении человека в зону действия ультразвукового датчика.

 

Sky
Offline
Зарегистрирован: 04.04.2012

Электрически подключается так же как и DS1307. А вот карта регистров по-моему разная. придется править библиотеку. Смотрите даташиты на эти микросхемы.

Nodit
Offline
Зарегистрирован: 15.01.2014

Большое спасибо.

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

у вас шилд или голая микросхема? Если шилд, то для часов достаточно подключить VCC/GND/SDA/SCL, все остальное что нужно на шилде уже есть

если голая микросхема - то стоит прочитать даташит. Основное - подтяжка SDA/SCL и блокирующий керамический конденсатор по питания. В ультразвуковой ванне мыть не стоить, чтобы не испортить кварц внутри микросхемы

 

 

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

Sky пишет:

Электрически подключается так же как и DS1307. А вот карта регистров по-моему разная. придется править библиотеку. Смотрите даташиты на эти микросхемы.

библиотека от  ds1307 запускается с 3231 сразу. Основные регистры все теже и адрес на шине I2C тот же.

Отличия в будильниках и еще ряде служебных битов. В частности бит старта-остановки находится по другому адресу, но в отличии от 1307 которая с магазина требует запустить часы, 3231 ходить начинают сами

a5021
Offline
Зарегистрирован: 07.07.2013

Править обычно ничего не надо. Код, работющий на 1307, будет без изменений работать и на 3231. Я в одной своей старой самоделке на 1307, у которой даже исходников не осталось за давностью времен, выкусил эту самую 1307, а на проводках подпаял ардуиновский модуль на 3231. Заработало без всяких вопросов.

Nodit
Offline
Зарегистрирован: 15.01.2014

axill пишет:

у вас шилд или голая микросхема?

У меня вот такой вот девайс будет-  https://dx.com/p/ds3231-high-precision-real-time-clock-module-blue-3-3-5-5v-222910 Кажется, там уже вся обвязка микросхемы имеется.

axill пишет:

Отличия в будильниках и еще ряде служебных битов. В частности бит старта-остановки находится по другому адресу, но в отличии от 1307 которая с магазина требует запустить часы, 3231 ходить начинают сами

Ну, я в любом случае потом почитаю подробные описание самих микросхем. Скорее всего, лишним не будет. :)

 

Господа, премного благодарен. :)

 

a5021
Offline
Зарегистрирован: 07.07.2013

Nodit пишет:

У меня вот такой вот девайс будет...

Да, это именно та же плата, что и на моем снимке, приведенном выше. Единственное, я выпаял разъем, т.к. мне он только мешался. Прежде, чем вставлять в свою самоделку, немного погонял модуль с ардуиной, заодно сразу время правильное выставил. Уже не вспомню, откуда вытянул скетч для работы с 3231,  но предлагаю взглянуть, чтобы составить начальное представление, что как работает.

#include <Wire.h>

#define DS3231_I2C_ADDRESS 104

byte seconds, minutes, hours, day, date, month, year;
char weekDay[4];

byte tMSB, tLSB;
float temp3231;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  //set control register to output square wave on pin 3 at 1Hz
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(0x0E); // 
  Wire.write(B00000000);
  Wire.write(B10001000);
  Wire.endTransmission();
}

void loop() {
  
  watchConsole();
  
  
  get3231Date();
  
  Serial.print(weekDay); Serial.print(", "); Serial.print(month, DEC); Serial.print("/"); Serial.print(date, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" - ");
  Serial.print(hours, DEC); Serial.print(":"); Serial.print(minutes, DEC); Serial.print(":"); Serial.print(seconds, DEC);
  
  Serial.print("   Temperature: "); Serial.print(get3231Temp());Serial.print("; ");Serial.println(get3231Register(0x0F));

  delay(1000);
}

// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

void watchConsole()
{
  if (Serial.available()) {      // Look for char in serial queue and process if found
    if (Serial.read() == 84) {      //If command = "T" Set Date
      set3231Date();
      get3231Date();
      Serial.println(" ");
    }
  }
}
  
void set3231Date()
{ 
//T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year)
//T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99)
//Example: 02-Feb-09 @ 19:57:11 for the 3rd day of the week -> T1157193020209

  seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result.  
  minutes = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  hours   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  day     = (byte) (Serial.read() - 48);
  date    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  month   = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  year    = (byte) ((Serial.read() - 48) *10 +  (Serial.read() - 48));
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x00);
  Wire.write(decToBcd(seconds));
  Wire.write(decToBcd(minutes));
  Wire.write(decToBcd(hours));
  Wire.write(decToBcd(day));
  Wire.write(decToBcd(date));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.endTransmission();
}

byte get3231Register(byte regNo) {
  // send request to receive data starting at register regNo
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(regNo); // start at register regNo
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 1); // request one byte
  if(Wire.available()) return  Wire.read();
}

void set3231Register(byte regNo, byte value) { 
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(regNo);
  Wire.write(value);
  Wire.endTransmission();
}

void get3231Date()
{
  // send request to receive data starting at register 0
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address
  Wire.write(0x00); // start at register 0
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes

  if(Wire.available()) { 
    seconds = Wire.read(); // get seconds
    minutes = Wire.read(); // get minutes
    hours   = Wire.read();   // get hours
    day     = Wire.read();
    date    = Wire.read();
    month   = Wire.read(); //temp month
    year    = Wire.read();
       
    seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal
    minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal
    hours   = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode)
    day     = (day & B00000111); // 1-7
    date    = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31
    month   = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow
    year    = (((year & B11110000)>>4)*10 + (year & B00001111));
  }
  else {
    //oh noes, no data!
  }
  
  switch (day) {
    case 1:
      strcpy(weekDay, "Sun");
      break;
    case 2:
      strcpy(weekDay, "Mon");
      break;
    case 3:
      strcpy(weekDay, "Tue");
      break;
    case 4:
      strcpy(weekDay, "Wed");
      break;
    case 5:
      strcpy(weekDay, "Thu");
      break;
    case 6:
      strcpy(weekDay, "Fri");
      break;
    case 7:
      strcpy(weekDay, "Sat");
      break;
  }
}

float get3231Temp()
{
  //temp registers (11h-12h) get updated automatically every 64s
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 2);
  
  if(Wire.available()) {
    tMSB = Wire.read(); //2's complement int portion
    tLSB = Wire.read(); //fraction portion
    
    temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
    temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
  }
  else {
    //oh noes, no data!
  }
    
  return temp3231;
}

 

Nodit
Offline
Зарегистрирован: 15.01.2014

ОГРОМНОЕ человеческое спасибо за код! :) В ходе изучения даташита наткнулся на описание двух будильников (стр.11) и полдня убил на попытки добраться через найденную библиотеку к значениям в памяти. А тут почти все что мне было нужно в одном листинге!

Спасибо! :)

ssergo
Offline
Зарегистрирован: 10.05.2013

Прошу извинить,

#define DS3231_I2C_ADDRESS 104

адрес порта в какой кодировке?

У меня программка I2C_scanner отображает адреса:

Scanning...
I2C device found at address 0x57  !
I2C device found at address 0x68  !
done
Пушной звер
Пушной звер аватар
Offline
Зарегистрирован: 17.03.2013

0x68

0x57 это еепром 24с32

 

 

zhenious
Offline
Зарегистрирован: 03.07.2014

Nodit пишет:

Предварительно предполагается, что устройство будет состоять из Arduino Uno, ультразвукового датчика HC-SR04, RTC DS3231 и Serial LCD 1602 и отображать текущее время на экран при попадении человека в зону действия ультразвукового датчика.

Человека в шубе HC-SR04 не увидит

termex
Offline
Зарегистрирован: 22.04.2015

axill пишет:

у вас шилд или голая микросхема? Если шилд, то для часов достаточно подключить VCC/GND/SDA/SCL, все остальное что нужно на шилде уже есть

если голая микросхема - то стоит прочитать даташит. Основное - подтяжка SDA/SCL и блокирующий керамический конденсатор по питания. В ультразвуковой ванне мыть не стоить, чтобы не испортить кварц внутри микросхемы

 

 

Добрый день! У меня шилд RTC3231 (такой же, как у автора чата) и я никак не разберусь, к чему цеплять SDA и SCL. Подскажите пожалуйста! Соединяю я ее с Наной

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Найдите SDA, SCL здесь и подключайте. На разных Ардуинах, SDA, SCL могут быть на разных пинах.

 

termex
Offline
Зарегистрирован: 22.04.2015

Да,спасибо большое!!

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Подскажите плиз как подключить этот магический код, который привел a5021, на А6 и А7,,

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

exez, в МК ардуино  реализована аппаратная шина I2C, она никуда со своих пинов не двигается :) Есть ещё какие-то программные эмуляции этой шины, но тут я в тонкости не вникал за ненадобностью. В любом случае А6 и А7 -это чисто аналоговые входы, и использовать их для чего либо помимо АЦП невозможно.

exez
exez аватар
Offline
Зарегистрирован: 04.04.2015

Спасибо! Не обратил на это внимание. В моем проэкте просто А4,А5 уже заняты. Придется перепаять схемку..

зы: хорошо что есть такие специалисты, которые реально могут помочь!